Skip to content

feat: agent-native CLI fixes round 2 (F11, F14, F18)#191

Merged
AlephNotation merged 4 commits intomainfrom
feat/agent-native-cli-fixes-2
May 8, 2026
Merged

feat: agent-native CLI fixes round 2 (F11, F14, F18)#191
AlephNotation merged 4 commits intomainfrom
feat/agent-native-cli-fixes-2

Conversation

@AlephNotation
Copy link
Copy Markdown
Contributor

Three more agent-native-CLI fixes from the audit, sourced from Trevin Chow's 10 Principles for Agent-Native CLIs. Implemented by three Opus 4.7 subagents in parallel git worktrees.

What changed

F11 — vers agent-context (principle 7: introspection)

New top-level command emitting versioned JSON describing every command, subcommand, and flag. Agents consume this instead of parsing --help text.

$ vers agent-context | jq '.schema_version, (.commands | keys | length), .commands.run.async'
"1"
30
true

Schema shape:

{
  "schema_version": "1",
  "cli": {"name", "version", "description"},
  "commands": {
    "<name>": {
      "use", "short", "long", "aliases", "args": {min, max},
      "async": <true if --wait flag exists>,
      "flags": {"--<name>": {type, default, usage, required, shorthand?, enum?}},
      "subcommands": {recursive}
    }
  },
  "available_profiles": [],
  "feedback": {"local_path", "endpoint_configured"}
}

Includes an annotation hook (cmd.Annotations["vers:enum:<flag>"] = "a,b,c") for declaring enum constraints; not pre-populated in this PR. cmd.SilenceUsage = true and cmd.SilenceErrors = true so the command never fails — it's the agent's escape hatch when --help is too noisy.

F18 Phase A — vers feedback (principle 10: two-way I/O)

New command for reporting friction back. Phase A is local journaling + opt-in upstream POST. No backend infra is being built right now — the upstream sink is whatever URL the user sets via VERS_FEEDBACK_ENDPOINT.

$ vers feedback "the --visibility flag rejects 'enterprise' but docs list it as valid"
feedback recorded locally (1 entry)

$ VERS_FEEDBACK_ENDPOINT=https://hooks.example.com/cli vers feedback "race condition in --wait"
feedback recorded locally and sent upstream (status: 200)

$ vers feedback list --json --limit 10
[ ... ]
  • Local journal at ~/.vers/feedback.jsonl (overridable via VERS_FEEDBACK_PATH for tests).
  • feedback list supports --limit, --offset, --json via the existing pagination presenter.
  • agent-context (F11) declares both the path and endpoint_configured: bool so introspecting agents can discover the channel.
  • Phase B (server-side endpoint on api.vers.sh for issue-tracker integration) is deferred until the backend question is decided.

F14 Phase 1 — durable job ledger (principle 8: async-aware execution)

vers-cli already has --wait on every async-submitting command. F14 Phase 1 adds the journaling layer: every --wait invocation writes start + completion entries to ~/.vers/jobs.jsonl, and a new vers jobs parent command exposes the ledger.

$ vers run --wait --vm-alias my-vm
... handler output ...

$ vers jobs list
JOB_ID         STATUS    KIND     STARTED              DURATION
job_8f2a3b4c5d complete  vm.run   2026-05-08T04:09:02Z 37123ms

$ vers jobs get job_8f2a3b4c5d --json
{...full latest state...}

$ vers jobs prune --older-than 7d --dry-run
would prune 3 entries (12 kept)
  • Append-only JSONL: every state change appends a new line with the same id; latest line wins on read.
  • Hooks added to cmd/run.go, cmd/branch.go, cmd/deploy.go, cmd/resume.go, cmd/run_commit.go — only journal when --wait is set; ledger writes are best-effort (a write failure must not fail the user-facing command).
  • vers jobs list reuses the F7 pagination envelope; supports --status filter.
  • Resumption (re-attaching to in-flight jobs on retry) is Phase 2 — explicitly out of scope for this PR.

Caveats and follow-ups

  1. F11 enum hook is wired but unused. Annotating bounded-input flags (--visibility, --deliver schemes, log levels) with vers:enum:* is a follow-up sweep. Once done, errors on those flags can self-enumerate via principle 3.
  2. vers jobs requires auth today because the cobra PersistentPreRunE requires an API key for any non-(login/signup/help/upgrade) command. The ledger is purely local; if we want it to work fully offline, add jobs to the skip list in cmd/root.go.
  3. agent-context does not yet enumerate vers feedback / vers jobs integrations. Each landed in parallel; a follow-up PR should add those env vars (VERS_FEEDBACK_ENDPOINT, VERS_FEEDBACK_PATH, VERS_JOBS_DIR) and the jobs ledger path to the schema.
  4. F1/F7 worker-report markdown files (F1-json-flag.md, F7-pagination.md) leaked into PR feat: agent-native CLI fixes (F1, F7, F8) #190 and are still on main. This PR happens to delete them.

Validation

  • make build — clean
  • gofmt -l cmd/ internal/ — empty
  • go test ./internal/... ./cmd/... — all pass, including new test packages:
    • internal/feedback (8 unit tests with t.TempDir())
    • internal/jobs (8 unit tests covering submit/complete/fail/collapse/prune/parseDuration)
    • cmd/agent_context_test.go (schema_version, top-level walk, async flag, enum annotation)
  • Smoke checks against an authenticated environment confirm vers agent-context, vers feedback/feedback list, and vers jobs list/get/prune all behave correctly.

Commits

0847925 style: gofmt -s -w
83127d5 feat: add durable job ledger and 'vers jobs' command (F14 Phase 1: journaling)
c274713 feat: add 'vers feedback' command (F18 Phase A: local + opt-in upstream)
812c459 feat: add 'vers agent-context' for versioned schema introspection (F11)

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