Skip to content

feat(cli): maintenance-windows topic + monitors test --config#31

Merged
caballeto merged 2 commits into
mainfrom
feat/maintenance-windows-and-test-config
May 6, 2026
Merged

feat(cli): maintenance-windows topic + monitors test --config#31
caballeto merged 2 commits into
mainfrom
feat/maintenance-windows-and-test-config

Conversation

@caballeto
Copy link
Copy Markdown
Contributor

Summary

Two CLI features for v1 launch, both touching only the CLI repo (no
SDK / MCP / mono changes).

1. devhelm maintenance-windows topic — NEW

Maintenance windows let users suppress alerts during planned downtime.
Per the v1 launch decision, they're state, not infrastructure: imperative
CLI commands only. Intentionally not added to devhelm.yml /
config-loader, and intentionally not a Terraform resource — this PR
does not touch src/lib/yaml/** or any deploy-YAML schema.

Five new commands wire the existing /api/v1/maintenance-windows endpoints:

Command API Notes
maintenance-windows list GET /api/v1/maintenance-windows `--status active
maintenance-windows get <id> GET .../{id} strict envelope parse
maintenance-windows create POST .../ `--start --end --reason {--monitor
maintenance-windows update <id> PUT .../{id} fetches existing window first to back-fill start/end on partial updates
maintenance-windows cancel <id> DELETE .../{id} semantic verb (you cancel scheduled / active windows, not "delete")

Divergence from the original task spec (constrained by the API):

  • The API stores one monitorId per window (or null for org-wide), so
    --monitor is single-value and we added --org-wide instead of repeatable
    flags. There's no --component because the API doesn't model that.
  • Status filter is active|upcoming (the only values the server understands).
    cancelled doesn't apply (cancel = DELETE → 404 on the list endpoint).
  • CreateMaintenanceWindowRequest has no managedBy field on the wire,
    so we don't synthesise one client-side.

The package.json oclif.topics entry uses the requested copy:

Schedule downtime windows that suppress alerts during planned changes

2. devhelm monitors test --config <file> — NEW flag

monitors test <id> already runs a live probe against an existing monitor.
This adds the sibling flow:

  • Pass a YAML or JSON file containing a CreateMonitorRequest payload.
  • The CLI validates it locally against the generated Zod schema, with
    field-path error messages.
  • On success, it strips the persistence-only fields and POSTs the
    MonitorTestRequest subset to the existing /api/v1/monitors/test
    endpoint so the user sees a real probe result for the proposed config.
  • Mutual exclusion: passing both <id> and --config is a hard error.

Sample invocations

# List currently-active windows for one monitor
devhelm maintenance-windows list --status active --monitor <uuid>

# Schedule a 30-minute deploy window
devhelm maintenance-windows create \
  --start 2026-06-01T14:00:00Z --end 2026-06-01T14:30:00Z \
  --reason "Backend deploy" --monitor <uuid>

# Org-wide MAINTENANCE — no monitor scoping
devhelm maintenance-windows create \
  --start 2026-06-01T14:00:00Z --end 2026-06-01T14:30:00Z \
  --reason "DC failover drill" --org-wide

# Reschedule
devhelm maintenance-windows update <id> --start 2026-06-01T15:00:00Z --end 2026-06-01T15:30:00Z

# Cancel
devhelm maintenance-windows cancel <id> --yes

# Pre-save validation of a YAML monitor config
devhelm monitors test --config monitor.yml

# Same, but JSON + machine-readable output for CI
devhelm monitors test --config monitor.json --output json

Test plan

  • npm run typecheck clean
  • npm run lint clean
  • npm test — 36 files / 998 tests pass (20 new tests across 3 new files)
  • npm run build && oclif manifest — manifest registers all 5
    maintenance-windows:* commands
  • Smoke --help against bin/dev.js for each new command + the
    modified monitors test
  • Smoke negative paths: missing flags, mutually-exclusive flags,
    malformed config files, missing config files, invalid Zod payloads —
    all produce clear actionable errors
  • CI green (will populate once the workflow runs)

Constraints honoured

  • No changes to src/lib/yaml/** (deploy YAML / config-loader untouched)
  • No changes to apiSchemas.generated.ts shape — only fed two existing
    request DTOs into extract-descriptions.mjs so flag help text tracks
    the OpenAPI spec
  • Stayed inside cli/ — no SDK, MCP, or mono changes

Made with Cursor

caballeto and others added 2 commits May 6, 2026 12:32
Maintenance windows are a state-only resource (intentionally not exposed
in `devhelm.yml` or as a Terraform resource) used to suppress alerts during
planned changes. Wires the existing `/api/v1/maintenance-windows` endpoints
into five oclif commands and registers a topic description in package.json.

The list command supports the server-supported `--status active|upcoming`
filter and a `--monitor <id>` filter. Create accepts `--start`, `--end`,
`--reason`, and either `--monitor <id>` or `--org-wide` (the API stores a
single monitorId, with null meaning org-wide). Update fetches the current
window and back-fills timestamps when the user provides a partial change,
so `update <id> --reason "Rescheduled"` works without re-passing start/end.
Cancel maps to DELETE with the same confirmation prompt as the generic
delete factory.

Adds shared `buildMaintenanceWindowBody` plus unit tests, and threads the
two new request DTOs into `extract-descriptions.mjs` so flag descriptions
track the OpenAPI spec.

Co-authored-by: Cursor <cursoragent@cursor.com>
…dation

Today `devhelm monitors test <id>` runs a probe against an existing
monitor. This adds a sibling entry point: `devhelm monitors test --config
<file>` reads a YAML or JSON file, validates it against the generated
`CreateMonitorRequest` Zod schema, and (when validation passes) dispatches
the test subset to the existing `/api/v1/monitors/test` ad-hoc endpoint
so the user sees a real probe result before deciding to save the monitor.

The id arg is now optional so the same command supports both flows.
Passing both an id and `--config` errors out — there's no scenario where
a live test against an existing monitor and a dry-run of a proposed
config make sense in one shot.

Validation errors print with field paths so `name`, `managedBy`, and
config-discriminator failures all surface a clear actionable message
instead of bouncing off a server 400.

Co-authored-by: Cursor <cursoragent@cursor.com>
@caballeto caballeto merged commit 83f0eee into main May 6, 2026
3 checks passed
@caballeto caballeto deleted the feat/maintenance-windows-and-test-config branch May 6, 2026 10:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant