Skip to content

feat(cli): relative-time flags on generated commands' unix-seconds timestamps#47

Merged
ysyneu merged 3 commits into
feat/ai-srefrom
feat/generated-relative-time
Jun 15, 2026
Merged

feat(cli): relative-time flags on generated commands' unix-seconds timestamps#47
ysyneu merged 3 commits into
feat/ai-srefrom
feat/generated-relative-time

Conversation

@ysyneu

@ysyneu ysyneu commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

What

Generated CLI commands forced raw unix integers on their time flags, while curated commands (incident list --since/--until) accepted ergonomic relative time (7d, now, dates). This closes that inconsistency — part of the generated-as-single-source convergence (Phase 2, after #46's generic table renderer).

Every unix-SECONDS timestamp flag on a generated command now accepts:

  • a duration — 7d, 24h (= now minus that)
  • +7d for the future
  • now
  • a date / datetime / RFC3339
  • raw unix seconds (back-compatible — the old int form still works)

…parsed at runtime via timeutil.Parse, the exact logic curated commands already use.

How

The generator (internal/cmd/cligen) detects unix-seconds timestamp fields and emits a string flag + a genParseTimeFlag pre-parse instead of an int flag. Detection is deliberately precise so it never corrupts a non-timestamp int:

Field kind Example Treated as Why
unix-seconds timestamp start_time, end_time, start, end, *_at_*_seconds relative-time string a point in time
millisecond timestamp RUM/sourcemap/webhook start_time stays int64 Parse yields seconds → 1000× wrong
duration delay_seconds, seconds_to_ack stays int64 a count of seconds, not a point in time

Beyond the description-keyword signal (unix/epoch + second), two name conventions catch fields the spec under-documents — eliminating asymmetric start/end pairs:

  • bare start/end window boundaries (schedule list --start was prose-only)
  • the <point>_at_*_seconds convention (close_at_seconds, created_at_start_seconds, created_at_end_seconds) — the _at_ point-in-time marker is what distinguishes these from a delay_seconds-style duration.

Help stays consistent: both the cobra flag usage and the Long "Request fields" block render these as string + the accepted-forms hint.

Verification

  • go build/vet/test ./... green; gofumpt clean; new unit tests for the detector (incl. ms/duration exclusions + the deficient-field cases) and the runtime parse helper.
  • Live testback E2E: incident post-mortem-list --created-at-start-seconds 30d --created-at-end-seconds now and insight account --start-time 7d --end-time now return data; raw-unix still works; invalid values error cleanly client-side (invalid --start: ...).
  • Full e2e suite (-tags=e2e) vs base: zero new failures (138 pass / 27 pre-existing env fails / 6 skip — same set as base).

…mestamps

Generated commands forced raw unix integers on time flags while curated
commands (incident list --since/--until) accepted "7d"/"now"/dates. This
closes that gap: every unix-SECONDS timestamp flag on a generated command
now accepts a relative duration ("7d", "24h"), "+7d" for the future,
"now", a date, or raw unix seconds (back-compatible), parsed at runtime
via timeutil.Parse — the same logic curated commands use.

The generator (cligen) detects unix-seconds timestamp fields and emits a
string flag plus a genParseTimeFlag pre-parse instead of an int flag.
Detection is precise to avoid corrupting non-timestamp ints:

  - millisecond timestamps (RUM/sourcemap/webhook) stay int64 — parsing
    yields seconds, which would be 1000x wrong;
  - durations (delay_seconds, seconds_to_ack) stay int64 — a count of
    seconds, not a point in time;
  - fields the spec under-documents are caught by name convention: bare
    start/end window boundaries (schedule list) and the <point>_at_*_seconds
    timestamp convention (close_at_seconds, created_at_*_seconds), which the
    `_at_` marker distinguishes from a delay_seconds-style duration.

Help is consistent: both the cobra flag usage and the Long "Request
fields" block render these as string + the accepted-forms hint.

Verified on the local testback: incident post-mortem-list and insight
account accept relative + raw-unix values; invalid values error cleanly
client-side; full e2e suite shows zero new failures vs base.
Comment thread internal/cmd/cligen/main.go Fixed
ysyneu added 2 commits June 15, 2026 17:16
The cligen example help wrapped the spec's example JSON in single quotes
(--data '<json>') without escaping embedded single quotes, so an example
whose JSON contained a "'" produced a command that breaks out of the
shell quoting when copy-pasted. This was live: the monit query-diagnose
example carries a VictoriaLogs query `_stream:{status='500'}`, whose
quotes split the argument in a real shell.

Escape embedded single quotes as the standard '\'' sequence via a
shellSingleQuote helper. The escaped example round-trips through bash back
to valid JSON. Also clears the pre-existing go/unsafe-quoting CodeQL alert,
which this PR's exampleHelp refactor had re-attributed to the diff.
@ysyneu ysyneu merged commit 0ac50b9 into feat/ai-sre Jun 15, 2026
12 checks passed
ysyneu added a commit that referenced this pull request Jun 15, 2026
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.

2 participants