Skip to content

feat(cli): positional <id> args for generated commands#50

Merged
ysyneu merged 1 commit into
feat/ai-srefrom
feat/cli-generated-positional
Jun 15, 2026
Merged

feat(cli): positional <id> args for generated commands#50
ysyneu merged 1 commit into
feat/ai-srefrom
feat/cli-generated-positional

Conversation

@ysyneu

@ysyneu ysyneu commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

What

Generated OpenAPI commands were flag/--data-only (no positional args), while curated commands accept <id> [<id2>...]. That gap blocks the next stage of the generated-single-source convergence: the curated ID-based shadows (incident/alert verbs) can't be dropped without ergonomic regression.

This adds positional-argument capability to the generator. Non-breaking — it adds an optional positional onto generated commands; it removes/modifies no curated command. Foundation for a reviewed follow-up that drops the clean ID-verb shadows.

How

A generated command whose request has a required *_id (scalar) or *_ids (array) body field now accepts that id positionally. The positional is folded onto the existing flag at runtime — the flag and --data still work, with precedence --flag > positional > --data.

  • Selection: required *_id/*_ids, array-wins, with a per-op override map (incident merge → target_incident_id; war-room detail/add-member → chat_id).
  • Suppressed where a positional would mislead: create verbs (the required id is a parent ref like team_id, not the resource identity) and rule-move (its rule-ids field is ids, not *_ids).
  • Arity: scalar → exactly one (requireExactArg); array → >=1 (requireArgs). Friendly errors mirror curated (missing X / expects exactly one X / invalid X: must be an integer).
  • Types: genFoldPositional handles string scalar, string slice, int scalar (schedule_id), and intslice for []uint64 id fields (team_ids/person_ids/role_ids/…) — a naive string fold breaks genBindBody for these.

123 positionals emitted across 250 generated commands (96 scalar + 27 array, post-suppression).

Verify

  • go build -tags=jsoniter ./... clean; go test -tags=jsoniter ./... all pass (incl. structural flag_consistency_test.go).
  • New tests: TestSelectPositional (override / array-wins / scalar / ambiguous→none / create-suppress / empty-override) + runtime fold tests (string/slice/int/intslice/flag-overrides-positional).
  • Live on testback: team infos <team-id> ([]uint64 fold) returns real data; incident info a bexpects exactly one incident_id; schedule info abcinvalid schedule_id: must be an integer; channel create --help has no positional.
  • Non-breakage: only the generator, regenerated zz_generated_*, the args.go/gen_support.go shared helpers, a mechanical monit_agent.go callback-signature update, and tests — no curated command behavior changed.

Quality gates

/simplify --uncommitted (3 refactors: unused param, intermediate map, error-through-callback) + /review-to-main --uncommitted (no critical bugs; all 4 warnings + the unit-test gap folded in here).

Generated commands were flag/--data-only, which blocked removing the curated
ID-based shadows (incident/alert verbs) without ergonomic regression. Add
positional-argument support in the generator: a generated command whose request
has a required *_id (scalar) or *_ids (array) body field now accepts that id
positionally (folded onto the existing flag at runtime; the flag and --data
still work and take precedence).

- Selection: required *_id/*_ids, array-wins, with a per-op override map
  (incident merge -> target_incident_id; war-room detail/add-member -> chat_id).
- Suppress positional on `create` verbs (the required id is a parent ref) and on
  rule-move (its rule-ids field is `ids`, not `*_ids`).
- Scalar positionals require exactly one arg; arrays require >=1; friendly errors
  mirror curated requireArgs (new requireExactArg sibling).
- intslice fold for []uint64 id fields (team_ids/person_ids/role_ids/...).
- gen_support.go genFoldPositional helper; selectPositional unit-tested.

123 positionals across 250 generated commands; non-breaking (no curated command
behavior changed); live-verified on testback. Foundation for dropping the clean
curated ID-verb shadows in a reviewed follow-up.
@ysyneu ysyneu merged commit 37011f7 into feat/ai-sre Jun 15, 2026
12 checks passed
ysyneu added a commit that referenced this pull request Jun 15, 2026
@ysyneu ysyneu deleted the feat/cli-generated-positional branch June 15, 2026 11:18
ysyneu added a commit that referenced this pull request Jun 15, 2026
feat(cli): drop transparent curated ID-verb shadows (parity via #50)
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