akm-cli 0.9.31 → 0.10.26101001-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +253 -0
- package/STABILITY.md +79 -53
- package/dist/api-node.mjs +20 -0
- package/dist/api.d.ts +23 -0
- package/dist/api.js +45 -0
- package/dist/assets/hints/cli-hints-full.md +13 -27
- package/dist/assets/hints/cli-hints-short.md +1 -1
- package/dist/assets/improve-strategies/default.json +3 -3
- package/dist/assets/prompts/consolidate-pair.md +9 -7
- package/dist/cli/shared.js +31 -48
- package/dist/cli/unknown-flags.js +6 -43
- package/dist/cli.js +8 -34
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/completions.js +1 -2
- package/dist/commands/config-cli.js +5 -28
- package/dist/commands/env/env-cli.js +5 -5
- package/dist/commands/env/secret-cli.js +2 -2
- package/dist/commands/health/checks.js +41 -16
- package/dist/commands/health/plugin-staleness.js +52 -22
- package/dist/commands/improve/autonomy-gate.js +5 -3
- package/dist/commands/improve/consolidate/pair-pass.js +7 -1
- package/dist/commands/improve/consolidate.js +6 -35
- package/dist/commands/improve/distill/lesson-update.js +91 -0
- package/dist/commands/improve/distill-guards.js +1 -43
- package/dist/commands/improve/distill.js +140 -20
- package/dist/commands/improve/extract-cli.js +1 -1
- package/dist/commands/improve/improve-cli.js +87 -102
- package/dist/commands/improve/improve-strategies.js +8 -12
- package/dist/commands/improve/loop-stages.js +0 -1
- package/dist/commands/improve/planner.js +0 -1
- package/dist/commands/improve/preparation.js +40 -99
- package/dist/commands/improve/proactive-maintenance.js +2 -2
- package/dist/commands/improve/reflect-noise.js +3 -55
- package/dist/commands/improve/reflect.js +3 -8
- package/dist/commands/improve/retrieval-scope.js +2 -2
- package/dist/commands/improve/salience.js +2 -9
- package/dist/commands/improve/stage.js +14 -9
- package/dist/commands/lint/index.js +5 -20
- package/dist/commands/observability-cli.js +3 -9
- package/dist/commands/proposal/drain.js +39 -6
- package/dist/commands/proposal/proposal-cli.js +10 -30
- package/dist/commands/proposal/repository.js +3 -3
- package/dist/commands/read/knowledge.js +3 -3
- package/dist/commands/read/remember-cli.js +0 -13
- package/dist/commands/read/search-cli.js +29 -97
- package/dist/commands/read/search.js +0 -11
- package/dist/commands/read/show.js +0 -19
- package/dist/commands/sources/plugin-upgrade.js +164 -101
- package/dist/commands/sources/sources-cli.js +1 -15
- package/dist/commands/sources/stash-cli.js +4 -12
- package/dist/commands/tasks/tasks-cli.js +4 -115
- package/dist/commands/workflow/plan.js +11 -33
- package/dist/commands/workflow-cli.js +2 -7
- package/dist/core/adapter/adapter-ids.js +1 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
- package/dist/core/adapter/adapters/akm-adapter.js +9 -48
- package/dist/core/adapter/adapters/akm-lint.js +10 -26
- package/dist/core/adapter/adapters/akm-metadata.js +2 -72
- package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
- package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
- package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
- package/dist/core/adapter/recognize-match.js +3 -4
- package/dist/core/common.js +18 -2
- package/dist/core/config/config-schema.js +12 -15
- package/dist/core/config/config-types.js +6 -15
- package/dist/core/config/config-walker.js +6 -23
- package/dist/core/config/config.js +17 -80
- package/dist/core/config/engine-semantics.js +7 -3
- package/dist/core/config/schema/engines.js +7 -7
- package/dist/core/config/schema/improve-processes.js +8 -61
- package/dist/core/config/schema/improve.js +2 -21
- package/dist/core/config/schema/index-config.js +6 -39
- package/dist/core/env-secret-ref.js +2 -45
- package/dist/core/errors.js +1 -2
- package/dist/core/extra-params.js +2 -86
- package/dist/core/improve-result.js +11 -1
- package/dist/core/mutation-target.js +2 -2
- package/dist/core/recognition-util.js +4 -5
- package/dist/core/warn.js +21 -4
- package/dist/core/write-source.js +3 -3
- package/dist/execution/target-ref.js +1 -2
- package/dist/indexer/search/db-search.js +4 -19
- package/dist/indexer/search/fts-query.js +0 -19
- package/dist/integrations/agent/engine-resolution.js +5 -2
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +41 -98
- package/dist/integrations/agent/request-lowering.js +3 -3
- package/dist/integrations/harnesses/aider/index.js +5 -0
- package/dist/integrations/harnesses/amazonq/index.js +1 -0
- package/dist/integrations/harnesses/claude/config-import.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +5 -0
- package/dist/integrations/harnesses/codex/index.js +1 -0
- package/dist/integrations/harnesses/copilot/index.js +1 -0
- package/dist/integrations/harnesses/gemini/index.js +1 -0
- package/dist/integrations/harnesses/index.js +18 -39
- package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
- package/dist/integrations/harnesses/opencode/config-import.js +121 -52
- package/dist/integrations/harnesses/opencode/index.js +22 -0
- package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
- package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
- package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
- package/dist/integrations/harnesses/opencode/session-log.js +104 -115
- package/dist/integrations/harnesses/opencode/version.js +98 -0
- package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +228 -0
- package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
- package/dist/integrations/harnesses/openhands/index.js +1 -0
- package/dist/integrations/harnesses/pi/index.js +1 -0
- package/dist/integrations/harnesses/shared.js +2 -0
- package/dist/integrations/harnesses/types.js +2 -0
- package/dist/llm/client.js +41 -11
- package/dist/output/cli-hints.js +1 -1
- package/dist/output/context.js +10 -19
- package/dist/output/format-exempt.js +5 -8
- package/dist/output/shapes/helpers.js +1 -22
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/shapes.js +3 -31
- package/dist/output/stdout.js +5 -1
- package/dist/output/text/command-format.js +6 -1
- package/dist/output/text/workflow-format.js +4 -22
- package/dist/scripts/akm-migrate-node.js +13049 -14013
- package/dist/scripts/akm-migrate.js +16316 -17276
- package/dist/setup/detect.js +10 -4
- package/dist/setup/harness-config-import.js +5 -14
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +12 -13
- package/dist/storage/repositories/task-history-repository.js +0 -5
- package/dist/storage/repositories/workflow-runs-repository.js +5 -15
- package/dist/tasks/embedded.js +2 -1
- package/dist/tasks/run/task-history.js +0 -2
- package/dist/tasks/schedule-gates.js +39 -0
- package/dist/tasks/scheduler-binding.js +0 -16
- package/dist/tasks/scheduler-sync.js +3 -97
- package/dist/tasks/source/bounded-document.js +1 -1
- package/dist/tasks/source/task-source-v4.js +2 -12
- package/dist/tasks/task-run-reserved-flags.js +2 -31
- package/dist/workflows/authoring/authoring.js +6 -6
- package/dist/workflows/compile.js +8 -65
- package/dist/workflows/exec/child-workflow.js +22 -3
- package/dist/workflows/exec/native-executor.js +12 -147
- package/dist/workflows/exec/run-workflow.js +31 -103
- package/dist/workflows/exec/step-work.js +9 -178
- package/dist/workflows/exec/unit-dispatch.js +0 -10
- package/dist/workflows/freeze/environment.js +3 -44
- package/dist/workflows/freeze/freeze.js +8 -41
- package/dist/workflows/freeze/targets/child-workflow.js +27 -63
- package/dist/workflows/freeze/targets/command.js +2 -16
- package/dist/workflows/freeze/targets/shell.js +0 -2
- package/dist/workflows/freeze/task-bindings.js +2 -28
- package/dist/workflows/ir/params.js +12 -2
- package/dist/workflows/parser.js +82 -232
- package/dist/workflows/plan.js +1 -1
- package/dist/workflows/renderer.js +10 -19
- package/dist/workflows/runtime/run-plan.js +11 -53
- package/dist/workflows/runtime/runs.js +4 -27
- package/dist/workflows/source-files.js +12 -16
- package/dist/workflows/source-semantics.js +1 -93
- package/docs/README.md +1 -1
- package/docs/agents/README.md +3 -3
- package/docs/agents/agent-install.md +1 -1
- package/docs/architecture/adapters.md +17 -31
- package/docs/architecture/architecture.md +4 -5
- package/docs/architecture/improvement.md +52 -21
- package/docs/architecture/internals/improve-workflow.md +15 -8
- package/docs/architecture/internals/indexing.md +1 -1
- package/docs/architecture/internals/search.md +1 -2
- package/docs/architecture/internals/storage-locations.md +5 -5
- package/docs/architecture/persisted-data-compat.md +13 -4
- package/docs/architecture/specs/0.9.0-decisions.md +6 -2
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +2 -2
- package/docs/architecture/specs/workflow-format-unification.md +1 -6
- package/docs/architecture/testing/manual-testing-checklist.md +20 -29
- package/docs/architecture/testing/task-workflow-manual-tests.md +106 -203
- package/docs/architecture/testing/testing-workflow.md +1 -1
- package/docs/architecture/workflow-engine.md +5 -56
- package/docs/guides/author-workflows.md +39 -69
- package/docs/guides/capture-knowledge.md +1 -1
- package/docs/guides/claude-code-vs-akm-workflows.md +1 -2
- package/docs/guides/discover-and-load.md +4 -4
- package/docs/guides/getting-started.md +1 -1
- package/docs/guides/improve-the-library.md +7 -7
- package/docs/guides/recipes/headless-install.md +2 -2
- package/docs/guides/run-workflows.md +1 -1
- package/docs/guides/use-with-any-agent.md +49 -4
- package/docs/integration/bundling-akm.md +7 -6
- package/docs/maintainers/curate-workmap.md +1 -2
- package/docs/maintainers/release-checklist.md +30 -1
- package/docs/posts/akm-command-tour.md +3 -3
- package/docs/product-surface.md +1 -1
- package/docs/reference/README.md +1 -0
- package/docs/reference/api.md +65 -0
- package/docs/reference/asset-types.md +3 -5
- package/docs/reference/bundle-types.md +2 -4
- package/docs/reference/cli.md +126 -171
- package/docs/reference/configuration.md +84 -19
- package/docs/reference/data-and-telemetry.md +1 -1
- package/docs/reference/env-and-secrets.md +2 -2
- package/docs/reference/supported-formats.md +3 -4
- package/docs/reference/tasks.md +12 -19
- package/docs/reference/website-sources.md +1 -1
- package/docs/reference/workflow-schema.md +89 -317
- package/docs/reference/workflows.md +20 -48
- package/package.json +12 -2
- package/schemas/akm-config.json +2 -243
- package/schemas/akm-task.json +2 -3
- package/schemas/akm-workflow.json +47 -84
- package/dist/assets/improve-strategies/catchup.json +0 -41
- package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
- package/dist/assets/improve-strategies/quick.json +0 -17
- package/dist/assets/improve-strategies/reflect-distill.json +0 -29
- package/dist/assets/improve-strategies/thorough.json +0 -49
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
- package/dist/cli/retired-commands.js +0 -118
- package/dist/commands/tasks/validate.js +0 -176
- package/dist/core/config/legacy-source-shape-shim.js +0 -117
- package/dist/integrations/harnesses/ids.js +0 -28
- package/dist/tasks/source/task-source-v3-frozen.js +0 -424
- package/dist/tasks/source/task-to-v4.js +0 -863
- package/dist/workflows/exec/worktree.js +0 -372
- package/dist/workflows/freeze/child-output-references.js +0 -83
- package/dist/workflows/freeze/identity.js +0 -22
- package/dist/workflows/freeze/targets/script.js +0 -50
- package/dist/workflows/freeze/targets/task.js +0 -124
- package/dist/workflows/github-yaml.js +0 -506
- package/dist/workflows/runtime/run-outputs.js +0 -80
|
@@ -23,8 +23,7 @@ akm search "team-catalog//" # List every item in one bundle
|
|
|
23
23
|
| `--from` | `local`, `registry`, `all`, or a configured bundle name | `local` |
|
|
24
24
|
| `--limit` | number | `20` |
|
|
25
25
|
| `--format` | `json`, `jsonl`, `text`, `yaml`, `md`, `html` | `json` |
|
|
26
|
-
| `--detail` | `brief`, `normal`, `full` | `brief` |
|
|
27
|
-
| `--shape` | `human`, `agent`, `summary` (`summary` only on `show`) | `human` |
|
|
26
|
+
| `--detail` | `brief`, `normal`, `full`, `agent` (`agent`: search, curate and show only) | `brief` |
|
|
28
27
|
|
|
29
28
|
Ref-prefix queries (a conceptId prefix ending in `/`, optionally bundle-qualified)
|
|
30
29
|
return a deterministic listing, not a relevance ranking. Drop the trailing slash
|
|
@@ -90,9 +89,9 @@ akm import ./doc.md --xref knowledge/auth-flow # Merge provenance xrefs into the
|
|
|
90
89
|
akm import ./new.md --supersedes knowledge/old # Import a correction AND demote the doc it replaces
|
|
91
90
|
akm import - --name scratch-notes < notes.md # Import stdin as a knowledge doc
|
|
92
91
|
akm import https://example.com/docs/auth # Fetch one URL and import it as knowledge
|
|
93
|
-
akm import ./doc.md --
|
|
92
|
+
akm import ./doc.md --bundle my-other-bundle # Route import to a named writable bundle source
|
|
94
93
|
akm workflow create ship-release # Create a workflow asset in the bundle
|
|
95
|
-
akm lint --type workflows # Parse and compile every
|
|
94
|
+
akm lint --type workflows # Parse and compile every workflow source; list every error
|
|
96
95
|
akm workflow run workflows/ship-release # Start or resume and execute the workflow
|
|
97
96
|
akm feedback skills/code-review --positive # Record that an asset helped (ranks it higher; no rewrite)
|
|
98
97
|
akm feedback agents/reviewer --negative --reason "says to run jest; the suite runs on vitest" # Content wrong or stale: lowers its ranking; improve may repair its frontmatter
|
|
@@ -176,9 +175,8 @@ akm secret run secrets/deploy-token GITHUB_TOKEN -- gh release create v1.0.0 #
|
|
|
176
175
|
|
|
177
176
|
## Workflows
|
|
178
177
|
|
|
179
|
-
Workflows live under `<bundle>/workflows/` as
|
|
180
|
-
|
|
181
|
-
the bounded GitHub-shaped YAML subset.
|
|
178
|
+
Workflows live under `<bundle>/workflows/` as `.md` sources; see
|
|
179
|
+
`docs/reference/workflow-schema.md` for the frontmatter and body syntax.
|
|
182
180
|
|
|
183
181
|
Ref-based workflow commands are scoped to the current project/worktree/directory,
|
|
184
182
|
so one active run does not block unrelated directories from starting the same
|
|
@@ -235,7 +233,6 @@ rename instead of starting fresh, run `bun scripts/rekey-asset-ref.ts <old-ref>
|
|
|
235
233
|
## Sync
|
|
236
234
|
|
|
237
235
|
Commit local changes in a git-backed bundle. Behaviour adapts automatically.
|
|
238
|
-
(`akm save` was the pre-0.8 spelling; it was removed in 0.9.0 — use `akm sync`.)
|
|
239
236
|
|
|
240
237
|
- **No `.git` directory** — no-op (silent skip)
|
|
241
238
|
- **Git repo, no remote** — stage and commit only (the default bundle always falls here)
|
|
@@ -255,15 +252,13 @@ akm sync my-skills -m "Update patterns" # Sync named bundle with message
|
|
|
255
252
|
The `--sync` / `--no-sync` and `--push` / `--no-push` flags control this:
|
|
256
253
|
|
|
257
254
|
```sh
|
|
258
|
-
akm improve # auto-sync per strategy default (
|
|
255
|
+
akm improve # auto-sync per strategy default (both strategies: on)
|
|
259
256
|
akm improve --no-sync # skip the end-of-run commit
|
|
260
257
|
akm improve --no-push # commit but skip push for this run
|
|
261
258
|
akm improve --sync # force sync even on strategies that disable it
|
|
262
259
|
```
|
|
263
260
|
|
|
264
|
-
Strategy sync defaults: `
|
|
265
|
-
`thorough` auto-commit + push; `proactive-maintenance` and `reflect-distill`
|
|
266
|
-
skip sync entirely. Override with `--sync` / `--no-sync` flags.
|
|
261
|
+
Strategy sync defaults: `consolidate` and `default` auto-commit + push. Override with `--sync` / `--no-sync` flags.
|
|
267
262
|
|
|
268
263
|
The `--writable` flag on `akm bundle add` opts a remote git bundle into push-on-sync:
|
|
269
264
|
|
|
@@ -313,7 +308,6 @@ akm config list # Show current config
|
|
|
313
308
|
akm config get <key> # Read a value
|
|
314
309
|
akm config set <key> <value> # Set a value
|
|
315
310
|
akm config unset <key> # Remove a key
|
|
316
|
-
akm config path --all # Show all config paths
|
|
317
311
|
```
|
|
318
312
|
|
|
319
313
|
## Other Commands
|
|
@@ -331,11 +325,10 @@ akm lint --fix # Auto-fix Tier 1 issues
|
|
|
331
325
|
akm lint --fail-on-flagged # Exit non-zero when summary.flagged > 0 (CI-friendly)
|
|
332
326
|
akm upgrade # Upgrade akm using its install method, then update installed harness plugins
|
|
333
327
|
akm upgrade --check # Report pending CLI and plugin updates, changing nothing
|
|
334
|
-
akm upgrade --next # Follow prereleases (@next); OpenCode needs "akm-opencode@next" in its plugin list
|
|
328
|
+
akm upgrade --next # Follow prereleases (@next); OpenCode needs "akm-opencode@next" (or "akm-opencode-v2@next" on OpenCode 2) in its plugin list
|
|
335
329
|
akm help migrate 0.6.0 # Print migration notes for a release (or: latest)
|
|
336
330
|
akm help bundle # Print options and subcommands for one command
|
|
337
|
-
akm
|
|
338
|
-
akm hints # Print this complete agent guide
|
|
331
|
+
akm hints # Print this complete agent guide (--detail brief for the short one)
|
|
339
332
|
akm completions # Print bash completion script
|
|
340
333
|
akm completions --install # Install completions
|
|
341
334
|
```
|
|
@@ -354,7 +347,7 @@ akm proposal show <id> # Render the proposal bo
|
|
|
354
347
|
akm proposal diff <ref-or-id> # Diff by ref, UUID, or 8-char prefix
|
|
355
348
|
akm proposal diff skills/akm-dream # Diff by asset ref
|
|
356
349
|
akm proposal accept 7c115132 # Accept by UUID prefix
|
|
357
|
-
akm proposal accept <id> --
|
|
350
|
+
akm proposal accept <id> --bundle team-bundle # Accept to a named writable bundle source
|
|
358
351
|
akm proposal reject skills/my-skill --reason "not ready" # Reject by asset ref
|
|
359
352
|
akm proposal reject <id> --reason "..." # Archive with a reason
|
|
360
353
|
akm proposal reopen <id> --reason "..." # Undo a rejection: back to pending (refused if the target changed)
|
|
@@ -364,11 +357,6 @@ akm proposal extract --auto # Mine native session fi
|
|
|
364
357
|
akm proposal extract --type claude # Restrict extraction to one harness
|
|
365
358
|
```
|
|
366
359
|
|
|
367
|
-
The flat verbs `akm proposals` / `akm show proposal` / `akm accept` /
|
|
368
|
-
`akm reject` / `akm diff` / `akm revert` were removed in 0.9.0 — use the
|
|
369
|
-
`akm proposal <verb>` forms above. `akm extract` and `akm propose` moved
|
|
370
|
-
here as `proposal extract` / `proposal new`.
|
|
371
|
-
|
|
372
360
|
## Scheduled Tasks
|
|
373
361
|
|
|
374
362
|
Tasks are pure-YAML assets at `<bundle>/tasks/<id>.yml`, bound to the OS
|
|
@@ -387,7 +375,7 @@ akm task doctor # Scheduler binding + runtime eli
|
|
|
387
375
|
akm task history # Recent run rows (status, timing)
|
|
388
376
|
akm task run <id> # Run one task immediately (works when disabled)
|
|
389
377
|
akm task explain <ref> # Read-only: declared inputs, target, schedule — spawns nothing
|
|
390
|
-
akm search --type task # Enumerate task assets
|
|
378
|
+
akm search --type task # Enumerate task assets
|
|
391
379
|
```
|
|
392
380
|
|
|
393
381
|
Task files use task source v4 (`version: 4`). There is no `akm:` options bag
|
|
@@ -428,7 +416,7 @@ akm log --run <run-id> # Events for one workflow-engine
|
|
|
428
416
|
|
|
429
417
|
## Output Control
|
|
430
418
|
|
|
431
|
-
Result-envelope commands accept `--format
|
|
419
|
+
Result-envelope commands accept `--format` and `--detail` flags:
|
|
432
420
|
|
|
433
421
|
- `--format json` (default) — structured JSON
|
|
434
422
|
- `--format jsonl` — one JSON object per line (streaming-friendly)
|
|
@@ -439,9 +427,7 @@ Result-envelope commands accept `--format`, `--detail`, and `--shape` flags:
|
|
|
439
427
|
- `--detail brief` (default) — compact output
|
|
440
428
|
- `--detail normal` — adds tags, refs, origins
|
|
441
429
|
- `--detail full` — includes scores, paths, timing, debug info
|
|
442
|
-
- `--
|
|
443
|
-
- `--shape agent` — agent-optimized output: strips non-actionable fields
|
|
444
|
-
- `--shape summary` — metadata only (no content/template/prompt), under 200 tokens; only `akm show` has a dedicated summary projection — elsewhere it falls back to `agent` with a warning
|
|
430
|
+
- `--detail agent` — agent-optimized output on `search`, `curate` and `show`: strips non-actionable fields (other commands ignore it)
|
|
445
431
|
|
|
446
432
|
Run `akm help <command>` or `akm <command> -h` for per-command help. Run
|
|
447
433
|
`akm --help` for the sectioned command overview.
|
|
@@ -35,7 +35,7 @@ akm remember "note" --bundle my-bundle # Route write to a named writable
|
|
|
35
35
|
akm remember "note" --xref knowledge/auth-flow # Cite provenance in frontmatter xrefs (repeatable)
|
|
36
36
|
akm remember "fix" --supersedes memories/old-note # Write a correction AND demote the superseded asset
|
|
37
37
|
akm import ./notes/release-checklist.md # Import a knowledge doc into your bundle
|
|
38
|
-
akm import ./doc.md --
|
|
38
|
+
akm import ./doc.md --bundle my-bundle # Route import to a named writable bundle source
|
|
39
39
|
akm proposal diff skills/akm-dream # Diff proposal by ref, UUID, or 8-char prefix
|
|
40
40
|
akm proposal accept 7c115132 # Accept by UUID prefix
|
|
41
41
|
akm proposal reject skills/my-skill --reason "..." # Reject by ref
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Standard improve pass — reflect (rewrites only from negative feedback), distill, consolidation (promotion plus the reviewed pair-pass retire/supersede proposals), and validation. Memory inference is listed below but only runs when experimental.improveAutonomy is set; improve-stage extract
|
|
2
|
+
"description": "Standard improve pass — reflect (rewrites only from negative feedback), distill, consolidation (promotion plus the reviewed pair-pass retire/supersede proposals), and validation. Memory inference is listed below but only runs when experimental.improveAutonomy is set; improve-stage extract off. Proactive maintenance plans up to 15 assets not reflected or distilled for 30 days.",
|
|
3
3
|
"processes": {
|
|
4
4
|
"reflect": {
|
|
5
5
|
"enabled": true,
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
"memoryInference": { "enabled": true },
|
|
12
12
|
"extract": { "enabled": false, "triage": { "enabled": true, "minScore": 2 } },
|
|
13
13
|
"validation": { "enabled": true },
|
|
14
|
-
"proactiveMaintenance": { "enabled":
|
|
15
|
-
"triage": { "enabled":
|
|
14
|
+
"proactiveMaintenance": { "enabled": true, "dueDays": 30, "maxPerRun": 15 },
|
|
15
|
+
"triage": { "enabled": true, "applyMode": "promote", "maxAcceptsPerRun": 25 }
|
|
16
16
|
},
|
|
17
17
|
"sync": { "enabled": true, "push": true }
|
|
18
18
|
}
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
You compare two assets from one person's agent-memory library (memories and knowledge notes an AI coding agent reads). Asset A is the OLDER one and asset B the NEWER one, by the dates shown. akm deletes one of them only when the other keeps every claim a reader would need, so your two lists decide what is safe to delete.
|
|
1
|
+
You compare two assets from one person's agent-memory library (memories and knowledge notes an AI coding agent reads). Asset A is the OLDER one and asset B the NEWER one, by the dates shown, unless both carry the same date and are labelled "same age". akm deletes one of them only when the other keeps every claim a reader would need, so your two lists decide what is safe to delete.
|
|
2
2
|
|
|
3
3
|
First list what each asset has that the other lacks:
|
|
4
|
-
- "onlyInA": every durable claim of A that B
|
|
5
|
-
- "onlyInB": every durable claim of B that A
|
|
4
|
+
- "onlyInA": every durable claim of A that B does not state or replace.
|
|
5
|
+
- "onlyInB": every durable claim of B that A does not state or replace.
|
|
6
6
|
|
|
7
7
|
A durable claim is a fact, decision, value, command, flag, path, file name, URL, number, version, name, error message, condition or rule someone would act on. Ignore wording, headings, dates of writing, tags and boilerplate. A claim is stated when the other asset says it in any wording or format. It is not stated when the other asset is vaguer (a config file instead of the specific path) or drops a number, command, step or condition. Write each item as a short phrase that quotes its identifier. Use [] when there is nothing.
|
|
8
8
|
|
|
9
|
+
B replaces a claim of A only when both are about the same named thing (the same service, integration, partner, component, region or file) and B gives a new value for it that is current: B says so (now, instead of, since, renamed, corrected, no longer) or B is created later than A. Notes about different named things never replace each other, whatever their dates: list each one's own name, value and path as its claims. A different value for the same thing with neither sign is a conflict, not a replacement: list A's value in "onlyInA" and B's value in "onlyInB".
|
|
10
|
+
|
|
9
11
|
Then classify the relation as exactly one of:
|
|
10
12
|
- "duplicate": both lists are empty.
|
|
11
13
|
- "subsumed": exactly one list is empty. The asset with the empty list is redundant.
|
|
12
|
-
- "supersedes": B
|
|
13
|
-
- "contradicts": they make logically exclusive claims about the same thing and nothing shows which one is current.
|
|
14
|
+
- "supersedes": B replaces a claim in A as defined above (a newer version, a changed decision, a fixed bug, a new value), and onlyInA is empty.
|
|
15
|
+
- "contradicts": they make logically exclusive claims about the same thing and nothing shows which one is current: B does not say it replaces the claim and was not created later.
|
|
14
16
|
- "overlap": same subject, and both lists have items.
|
|
15
|
-
- "unrelated": different subjects or different facts that happen to share words.
|
|
17
|
+
- "unrelated": different subjects, or different named things written to one layout (two services, partners or regions), or different facts that happen to share words.
|
|
16
18
|
|
|
17
19
|
Set "redundant" to the asset that could be deleted with no loss: "A" for "duplicate", the asset with the empty list for "subsumed", "A" for "supersedes"; else null. Set "stale" to "A" when the relation is "supersedes", else null.
|
|
18
20
|
|
|
19
|
-
Answer ONLY with JSON: {"onlyInA": ["..."], "onlyInB": ["..."], "relation": "...", "redundant": "A"|"B"|null, "stale": "A"|null, "confidence": 0.0-1.0, "reason": "<at most 25 words: name the asset that can be deleted and what the other asset still holds>"}
|
|
21
|
+
Answer ONLY with JSON: {"onlyInA": ["..."], "onlyInB": ["..."], "relation": "...", "redundant": "A"|"B"|null, "stale": "A"|null, "confidence": 0.0-1.0, "reason": "<at most 25 words: name the asset that can be deleted and what the other asset still holds; for supersedes, quote the words of B that replace the claim or say B is created later>"}
|
package/dist/cli/shared.js
CHANGED
|
@@ -156,19 +156,8 @@ export const GLOBAL_OUTPUT_ARGS = {
|
|
|
156
156
|
format: { type: "string", description: "Output format: json|jsonl|yaml|text|md|html (global flag)" },
|
|
157
157
|
detail: {
|
|
158
158
|
type: "string",
|
|
159
|
-
description: "Detail level
|
|
160
|
-
|
|
161
|
-
// R-050(c): single-sourced with the root command's own `--shape` help
|
|
162
|
-
// (`main.args.shape` in src/cli.ts, which spreads this object) so the
|
|
163
|
-
// caveat is visible from every leaf's own `--help`, not only the top-level
|
|
164
|
-
// one. `summary` outside `show` falls back to `agent` with a warning
|
|
165
|
-
// (shapeForCommand in src/output/shapes.ts) — `--shape` is a global flag,
|
|
166
|
-
// so a script that passes it to a mixed batch of commands still works.
|
|
167
|
-
shape: {
|
|
168
|
-
type: "string",
|
|
169
|
-
description: "Output projection: human|agent|summary (global flag). 'agent' trims to agent-essential fields; " +
|
|
170
|
-
"'summary' only has a dedicated projection on 'akm show' — elsewhere it falls back to 'agent' with a " +
|
|
171
|
-
"warning. Default: human.",
|
|
159
|
+
description: "Detail level: brief|normal|full (verbosity), or agent (trims search, curate and show to agent-essential " +
|
|
160
|
+
"fields; other commands ignore it) (global flag).",
|
|
172
161
|
},
|
|
173
162
|
output: {
|
|
174
163
|
type: "string",
|
|
@@ -294,51 +283,45 @@ export function outputWithExitCode(command, result, exitCode) {
|
|
|
294
283
|
}
|
|
295
284
|
export function output(command, result) {
|
|
296
285
|
const mode = getOutputMode();
|
|
297
|
-
const
|
|
298
|
-
if (
|
|
299
|
-
outputJsonl(command,
|
|
286
|
+
const { format } = mode;
|
|
287
|
+
if (format === "jsonl") {
|
|
288
|
+
outputJsonl(command, shapeForCommand(command, result, mode.detail, mode.shape));
|
|
300
289
|
return;
|
|
301
290
|
}
|
|
291
|
+
deliverRendered(renderOutput(command, result, { ...mode, format }), mode.outputPath);
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Shape and render a command result into the document `output()` delivers.
|
|
295
|
+
* Pure: reads no process-level output mode and writes nothing, so in-process
|
|
296
|
+
* callers (`src/api.ts`) get text byte-identical to the CLI's stdout from an
|
|
297
|
+
* explicit `mode`.
|
|
298
|
+
*/
|
|
299
|
+
export function renderOutput(command, result, mode) {
|
|
300
|
+
const shaped = shapeForCommand(command, result, mode.detail, mode.shape);
|
|
302
301
|
switch (mode.format) {
|
|
303
302
|
case "json":
|
|
304
|
-
|
|
305
|
-
return;
|
|
303
|
+
return JSON.stringify(shaped, null, 2);
|
|
306
304
|
case "yaml":
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
case "text": {
|
|
305
|
+
return yamlStringify(shaped);
|
|
306
|
+
case "text":
|
|
310
307
|
// D7 — registry first, generic rendering of the shaped envelope second.
|
|
311
|
-
//
|
|
312
|
-
// registered text formatter used to fall through to
|
|
308
|
+
// A command with no registered text formatter used to fall through to
|
|
313
309
|
// `JSON.stringify(shaped, null, 2)`, i.e. silently hand back JSON while
|
|
314
|
-
// claiming `--format text`
|
|
315
|
-
//
|
|
316
|
-
//
|
|
317
|
-
//
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
//
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
}
|
|
325
|
-
case "md": {
|
|
326
|
-
// D7 — registry first, generic rendering of the shaped envelope second.
|
|
327
|
-
// No command emits JSON under `--format md` any more: silently handing
|
|
328
|
-
// back the wrong format was the worst of the three behaviours this
|
|
329
|
-
// replaced.
|
|
330
|
-
const rendered = getMdRendererHandler(command)?.(shaped, mode.detail);
|
|
331
|
-
deliverRendered(rendered ?? renderGenericMarkdown(command, shaped), mode.outputPath);
|
|
332
|
-
return;
|
|
333
|
-
}
|
|
334
|
-
case "html": {
|
|
310
|
+
// claiming `--format text`. `renderGenericText` renders flat
|
|
311
|
+
// `key=value` text matching the house style of registered formatters
|
|
312
|
+
// like `config list`; it is a DISTINCT function from
|
|
313
|
+
// `renderGenericMarkdown` (see src/output/generic-render.ts).
|
|
314
|
+
return formatPlain(command, shaped, mode.detail) ?? renderGenericText(command, shaped);
|
|
315
|
+
case "md":
|
|
316
|
+
// D7 — registry first, generic rendering second; no command emits JSON
|
|
317
|
+
// under `--format md`.
|
|
318
|
+
return getMdRendererHandler(command)?.(shaped, mode.detail) ?? renderGenericMarkdown(command, shaped);
|
|
319
|
+
case "html":
|
|
335
320
|
// `akm health` and `akm metrics` are the only commands with a bespoke
|
|
336
321
|
// HTML report, so they are called directly rather than through a
|
|
337
322
|
// registry with two possible registrants (see `output/render-registry.ts`).
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
return;
|
|
341
|
-
}
|
|
323
|
+
return ((command === "health" ? renderHealthHtml(shaped) : command === "metrics" ? renderMetricsHtml(shaped) : null) ??
|
|
324
|
+
renderGenericHtml(command, shaped));
|
|
342
325
|
}
|
|
343
326
|
}
|
|
344
327
|
// parseAllFlagValues moved to ./invocation (chunk-9 WI-9.9 argv-normalization
|
|
@@ -28,7 +28,6 @@
|
|
|
28
28
|
import { UsageError } from "../core/errors.js";
|
|
29
29
|
import { warn } from "../core/warn.js";
|
|
30
30
|
import { cittyComparableName, findCittyTopLevelCommandIndex, toAliasArray, } from "./invocation.js";
|
|
31
|
-
import { retiredFlagHint } from "./retired-commands.js";
|
|
32
31
|
/**
|
|
33
32
|
* Commands that must never refuse on an unrecognized flag — `akm info` warns
|
|
34
33
|
* and continues instead of exiting 2, the same tolerance a bare `akm help
|
|
@@ -39,36 +38,6 @@ import { retiredFlagHint } from "./retired-commands.js";
|
|
|
39
38
|
const UNKNOWN_FLAG_TOLERANT_COMMANDS = new Set(["info"]);
|
|
40
39
|
/** Flags citty implements itself, which no command declares. */
|
|
41
40
|
const IMPLICIT_FLAGS = ["help", "h", "version", "v"];
|
|
42
|
-
/**
|
|
43
|
-
* Retired flags whose commands still diagnose them THEMSELVES, with a message
|
|
44
|
-
* that names the replacement ("`--scope` was removed, use `--filter`",
|
|
45
|
-
* "`--source` was renamed to `--generator`"). A generic "unknown flag" would
|
|
46
|
-
* preempt the better diagnosis, so these are passed through — but ONLY on the
|
|
47
|
-
* command path that owns the diagnostic, keyed by the resolved path. On every
|
|
48
|
-
* other command the same spelling is a genuine typo and still fails fast
|
|
49
|
-
* A retired flag is rejected everywhere else, where silently dropping it could
|
|
50
|
-
* run a real mutation.
|
|
51
|
-
*
|
|
52
|
-
* Shrink-only: when a command drops its bespoke diagnostic, drop the entry and
|
|
53
|
-
* the generic error takes over.
|
|
54
|
-
*/
|
|
55
|
-
const SELF_DIAGNOSED_FLAGS = new Map(Object.entries({
|
|
56
|
-
show: ["akmView", "scope"], // removed view grammar; --scope points at --filter
|
|
57
|
-
index: ["enrich", "re-enrich"], // removed index-time enrichment flags
|
|
58
|
-
"proposal accept": ["source"], // renamed to --generator
|
|
59
|
-
"proposal reject": ["source"], // renamed to --generator
|
|
60
|
-
"proposal drain": ["profile"], // retired, points at --strategy
|
|
61
|
-
search: ["source"], // renamed to --from
|
|
62
|
-
curate: ["source"], // renamed to --from
|
|
63
|
-
"task list": ["source"], // renamed to --from (alias of `search --type task`, #951)
|
|
64
|
-
remember: ["target"], // renamed to --bundle
|
|
65
|
-
clone: ["target"], // renamed to --bundle
|
|
66
|
-
improve: ["auto-accept", "target"], // retired in 0.9.0 / renamed to --bundle
|
|
67
|
-
"task add": ["target"], // renamed to --bundle
|
|
68
|
-
"task run": ["target"], // renamed to --bundle
|
|
69
|
-
"task history": ["target"], // renamed to --bundle
|
|
70
|
-
"task sync": ["target"], // renamed to --bundle
|
|
71
|
-
}).map(([path, flags]) => [path, new Set(flags.map(cittyComparableName))]));
|
|
72
41
|
/**
|
|
73
42
|
* Union the arg definitions declared along the resolved command path. The
|
|
74
43
|
* subcommand walk delegates to {@link findCittyTopLevelCommandIndex} — the
|
|
@@ -111,6 +80,12 @@ function collectKnownArgs(root, rawArgs) {
|
|
|
111
80
|
break;
|
|
112
81
|
const idx = findCittyTopLevelCommandIndex(args, (cmd.args ?? {}));
|
|
113
82
|
const token = idx >= 0 ? args[idx] : undefined;
|
|
83
|
+
// A command that takes a positional AND has subcommands (`improve [scope]`
|
|
84
|
+
// beside `improve report`) is itself the target when the token is absent
|
|
85
|
+
// or names none of them.
|
|
86
|
+
const takesPositional = Object.values(cmd.args ?? {}).some((def) => def.type === "positional");
|
|
87
|
+
if (takesPositional && (token === undefined || !subCommands[token]))
|
|
88
|
+
break;
|
|
114
89
|
// A group with no subcommand token: citty reports "no command specified".
|
|
115
90
|
if (token === undefined)
|
|
116
91
|
return { names, valueFlags, booleanFlags, displayNames, path, resolved: false };
|
|
@@ -166,15 +141,6 @@ export function closestMatch(attempted, candidates, threshold) {
|
|
|
166
141
|
* @param attempted The spelling to edit-distance against `--long` candidates.
|
|
167
142
|
*/
|
|
168
143
|
function throwUnknownFlag(shown, attempted, known) {
|
|
169
|
-
// Flags the 0.9 overhaul removed outright get their retirement note, not a
|
|
170
|
-
// did-you-mean — same reasoning as `retiredCommandHint` in src/cli.ts:
|
|
171
|
-
// edit distance can point at an unrelated survivor rather than the real
|
|
172
|
-
// replacement procedure (e.g. `index --background` is closer to no other
|
|
173
|
-
// `index` flag than it is to any useful suggestion).
|
|
174
|
-
const retired = retiredFlagHint(known.path, attempted);
|
|
175
|
-
if (retired) {
|
|
176
|
-
throw new UsageError(`Unknown flag "${shown}".`, "UNKNOWN_FLAG", retired);
|
|
177
|
-
}
|
|
178
144
|
const threshold = Math.max(2, Math.ceil(attempted.length / 3));
|
|
179
145
|
const suggestion = closestMatch(attempted, known.displayNames, threshold);
|
|
180
146
|
throw new UsageError(`Unknown flag "${shown}".`, "UNKNOWN_FLAG", suggestion
|
|
@@ -207,7 +173,6 @@ export function assertKnownFlags(root, rawArgs) {
|
|
|
207
173
|
// scanner, so it needs the identical exemption).
|
|
208
174
|
const dynamicNamedFlagCommands = new Set(["workflow run", "task run", "task explain"]);
|
|
209
175
|
const dynamicWorkflowParams = dynamicNamedFlagCommands.has(known.path.join(" "));
|
|
210
|
-
const selfDiagnosed = SELF_DIAGNOSED_FLAGS.get(known.path.join(" "));
|
|
211
176
|
const tolerant = UNKNOWN_FLAG_TOLERANT_COMMANDS.has(known.path.join(" "));
|
|
212
177
|
for (let i = 0; i < ownArgs.length; i += 1) {
|
|
213
178
|
const token = ownArgs[i];
|
|
@@ -250,8 +215,6 @@ export function assertKnownFlags(root, rawArgs) {
|
|
|
250
215
|
? rawName.slice(3)
|
|
251
216
|
: undefined;
|
|
252
217
|
const candidates = [cittyComparableName(rawName), ...(negated ? [cittyComparableName(negated)] : [])];
|
|
253
|
-
if (selfDiagnosed !== undefined && candidates.some((name) => selfDiagnosed.has(name)))
|
|
254
|
-
continue;
|
|
255
218
|
if (!candidates.some((name) => known.names.has(name))) {
|
|
256
219
|
// `workflow run` owns one deliberately dynamic namespace: long options
|
|
257
220
|
// become exact-name workflow parameters and are checked against the
|
package/dist/cli.js
CHANGED
|
@@ -58,7 +58,6 @@ process.on("uncaughtException", (err) => {
|
|
|
58
58
|
import fs from "node:fs";
|
|
59
59
|
import { defineCommand, parseArgs, renderUsage, runCommand, showUsage } from "citty";
|
|
60
60
|
import { findCittyTopLevelCommandIndex, getParsedInvocation, parseAllFlagValues, resolveHelpMigrateVersionArg, setParsedInvocation, } from "./cli/invocation.js";
|
|
61
|
-
import { retiredCommandHint } from "./cli/retired-commands.js";
|
|
62
61
|
import { defineGroupCommand, EXIT_CODES, emitJsonError, GLOBAL_OUTPUT_ARGS, output, runWithJsonErrors, } from "./cli/shared.js";
|
|
63
62
|
import { assertKnownFlags, closestMatch } from "./cli/unknown-flags.js";
|
|
64
63
|
import { agentCommand, lintCommand } from "./commands/agent/contribute-cli.js";
|
|
@@ -137,7 +136,7 @@ function printSetupTtyHint(result) {
|
|
|
137
136
|
if (!result?.bundleDir)
|
|
138
137
|
return;
|
|
139
138
|
console.error(plainize(`\n✓ Bundle created at ${result.bundleDir}\n` +
|
|
140
|
-
' Next: `akm bundle add <source>`, `akm index`, `akm search "<query>"`, `akm
|
|
139
|
+
' Next: `akm bundle add <source>`, `akm index`, `akm search "<query>"`, `akm hints`'));
|
|
141
140
|
}
|
|
142
141
|
/**
|
|
143
142
|
* Module Naming:
|
|
@@ -264,7 +263,7 @@ const healthCommand = defineCommand({
|
|
|
264
263
|
args: {
|
|
265
264
|
// R-051: `health` is a raw `defineCommand` (not `defineJsonCommand`), so
|
|
266
265
|
// it does not get `GLOBAL_OUTPUT_ARGS` for free. `--format`/`--detail`/
|
|
267
|
-
// `--
|
|
266
|
+
// `--output` already parsed correctly here (this command has
|
|
268
267
|
// no positional for a stray value to fall into), so this is purely a
|
|
269
268
|
// `--help` visibility / consistency fix, not a behavior change.
|
|
270
269
|
...GLOBAL_OUTPUT_ARGS,
|
|
@@ -383,9 +382,6 @@ const healthCommand = defineCommand({
|
|
|
383
382
|
}
|
|
384
383
|
},
|
|
385
384
|
});
|
|
386
|
-
function loadAgentHints(full) {
|
|
387
|
-
return full ? EMBEDDED_HINTS_FULL : EMBEDDED_HINTS;
|
|
388
|
-
}
|
|
389
385
|
const hintsCommand = defineCommand({
|
|
390
386
|
meta: {
|
|
391
387
|
name: "hints",
|
|
@@ -401,7 +397,7 @@ const hintsCommand = defineCommand({
|
|
|
401
397
|
run({ args }) {
|
|
402
398
|
return runWithJsonErrors(() => {
|
|
403
399
|
const detail = parseDetailLevel(args.detail) ?? "normal";
|
|
404
|
-
process.stdout.write(
|
|
400
|
+
process.stdout.write(detail === "brief" ? EMBEDDED_HINTS : EMBEDDED_HINTS_FULL);
|
|
405
401
|
});
|
|
406
402
|
},
|
|
407
403
|
});
|
|
@@ -504,24 +500,6 @@ const helpCommand = defineGroupCommand({
|
|
|
504
500
|
},
|
|
505
501
|
subCommands: {
|
|
506
502
|
...commandHelpTopics,
|
|
507
|
-
agents: defineCommand({
|
|
508
|
-
meta: {
|
|
509
|
-
name: "agents",
|
|
510
|
-
description: "Print agent instructions on how to use akm — the short guide by default; pass --full for the complete guide",
|
|
511
|
-
},
|
|
512
|
-
args: {
|
|
513
|
-
full: {
|
|
514
|
-
type: "boolean",
|
|
515
|
-
default: false,
|
|
516
|
-
description: "Print the complete guide instead of the short one.",
|
|
517
|
-
},
|
|
518
|
-
},
|
|
519
|
-
run({ args }) {
|
|
520
|
-
return runWithJsonErrors(() => {
|
|
521
|
-
process.stdout.write(loadAgentHints(args.full === true));
|
|
522
|
-
});
|
|
523
|
-
},
|
|
524
|
-
}),
|
|
525
503
|
migrate: defineCommand({
|
|
526
504
|
meta: {
|
|
527
505
|
name: "migrate",
|
|
@@ -855,7 +833,7 @@ function renderCommandSections() {
|
|
|
855
833
|
* USAGE line + global OPTIONS, then cuts the string before citty's own
|
|
856
834
|
* "COMMANDS" heading (present because `main` has `subCommands`) and appends
|
|
857
835
|
* the grouped sections plus a one-line bundle/ref-grammar tagline and the
|
|
858
|
-
* `akm
|
|
836
|
+
* `akm hints` pointer.
|
|
859
837
|
*/
|
|
860
838
|
async function renderSectionedRootHelp() {
|
|
861
839
|
const base = await renderUsage(main, undefined);
|
|
@@ -872,7 +850,7 @@ async function renderSectionedRootHelp() {
|
|
|
872
850
|
"`akm search` output rather than synthesizing them.",
|
|
873
851
|
"",
|
|
874
852
|
"Run `akm help <command>` or `akm <command> --help` for details on any command.",
|
|
875
|
-
"Agents: run `akm hints` for the complete guide or `akm
|
|
853
|
+
"Agents: run `akm hints` for the complete guide, or `akm hints --detail brief` for the short one.",
|
|
876
854
|
].join("\n");
|
|
877
855
|
return [head, "", renderCommandSections(), "", epilogue].join("\n");
|
|
878
856
|
}
|
|
@@ -910,7 +888,7 @@ function findUnknownCommandAttempt(rawArgs) {
|
|
|
910
888
|
}
|
|
911
889
|
/** Closest command within a length-scaled distance threshold (shared DP in cli/unknown-flags.ts). */
|
|
912
890
|
function closestCommandMatch(attempted, candidates) {
|
|
913
|
-
return closestMatch(attempted, candidates, Math.
|
|
891
|
+
return closestMatch(attempted, candidates, Math.floor(attempted.length / 3));
|
|
914
892
|
}
|
|
915
893
|
const CLI_HELP_POINTER = "Run `akm --help` for usage.";
|
|
916
894
|
/**
|
|
@@ -944,12 +922,8 @@ function cittyCliErrorUsageCode(error) {
|
|
|
944
922
|
function toUsageErrorFromCliError(error, rawArgs) {
|
|
945
923
|
const code = cittyCliErrorUsageCode(error);
|
|
946
924
|
const attempt = code === "UNKNOWN_COMMAND" ? findUnknownCommandAttempt(rawArgs) : undefined;
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
// (`init`→`info`, `update`→`upgrade`), and agents follow suggestions.
|
|
950
|
-
const retired = attempt ? retiredCommandHint(attempt.parentPath, attempt.attempted) : undefined;
|
|
951
|
-
const suggestion = retired === undefined && attempt ? closestCommandMatch(attempt.attempted, attempt.candidates) : undefined;
|
|
952
|
-
const hint = retired ?? (suggestion ? `Did you mean \`${suggestion}\`? ${CLI_HELP_POINTER}` : CLI_HELP_POINTER);
|
|
925
|
+
const suggestion = attempt ? closestCommandMatch(attempt.attempted, attempt.candidates) : undefined;
|
|
926
|
+
const hint = suggestion ? `Did you mean \`${suggestion}\`? ${CLI_HELP_POINTER}` : CLI_HELP_POINTER;
|
|
953
927
|
// citty colorizes error.message with ANSI escapes even when stdout/stderr
|
|
954
928
|
// is not a TTY. Strip them so the JSON envelope's `error` field is plain
|
|
955
929
|
// text instead of embedding raw escape sequences.
|
|
@@ -112,7 +112,7 @@ export const lintCommand = defineCommand({
|
|
|
112
112
|
args: {
|
|
113
113
|
// R-051: `lint` is a raw `defineCommand` (not `defineJsonCommand`), so it
|
|
114
114
|
// does not get `GLOBAL_OUTPUT_ARGS` for free. `--format`/`--detail`/
|
|
115
|
-
// `--
|
|
115
|
+
// `--output` already parsed correctly here (this command has no
|
|
116
116
|
// positional for a stray value to fall into), so this is purely a
|
|
117
117
|
// `--help` visibility / consistency fix, not a behavior change.
|
|
118
118
|
...GLOBAL_OUTPUT_ARGS,
|
|
@@ -7,8 +7,7 @@ import path from "node:path";
|
|
|
7
7
|
import { placementTypes } from "../core/asset/asset-placement.js";
|
|
8
8
|
const FLAG_VALUES = {
|
|
9
9
|
"--format": [{ values: ["json", "jsonl", "yaml", "text", "md", "html"] }],
|
|
10
|
-
"--detail": [{ values: ["brief", "normal", "full"] }],
|
|
11
|
-
"--shape": [{ values: ["human", "agent", "summary"] }],
|
|
10
|
+
"--detail": [{ values: ["brief", "normal", "full", "agent"] }],
|
|
12
11
|
"--type": [{ values: () => [...placementTypes(), "any"] }],
|
|
13
12
|
"--shell": [{ values: ["bash"] }],
|
|
14
13
|
"--from": [{ paths: ["akm search", "akm curate"], values: ["local", "registry", "all"] }],
|
|
@@ -14,11 +14,11 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { isDeepStrictEqual } from "node:util";
|
|
16
16
|
import { defineGroupCommand, defineJsonCommand, output } from "../cli/shared.js";
|
|
17
|
-
import { isRecord
|
|
17
|
+
import { isRecord } from "../core/common.js";
|
|
18
18
|
import { DEFAULT_CONFIG, getConfigValueSource, loadConfig, mutateConfig, parseAndValidateConfigText, resolveConfigRefSource, } from "../core/config/config.js";
|
|
19
19
|
import { configGet, configSet, configUnset, unknownKeyHint } from "../core/config/config-walker.js";
|
|
20
20
|
import { UsageError } from "../core/errors.js";
|
|
21
|
-
import {
|
|
21
|
+
import { getConfigPath } from "../core/paths.js";
|
|
22
22
|
import { formatRegistryUrl } from "../core/registry-url.js";
|
|
23
23
|
// ── Public API ──────────────────────────────────────────────────────────────
|
|
24
24
|
export function getConfigValue(config, key) {
|
|
@@ -118,32 +118,9 @@ export const configCommand = defineGroupCommand({
|
|
|
118
118
|
meta: { name: "config", description: "Show and manage configuration" },
|
|
119
119
|
subCommands: {
|
|
120
120
|
path: defineJsonCommand({
|
|
121
|
-
meta: { name: "path", description: "
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
},
|
|
125
|
-
run({ args }) {
|
|
126
|
-
const configPath = getConfigPath();
|
|
127
|
-
if (args.all) {
|
|
128
|
-
let stashDir;
|
|
129
|
-
try {
|
|
130
|
-
stashDir = resolveStashDir();
|
|
131
|
-
}
|
|
132
|
-
catch {
|
|
133
|
-
stashDir = `${getDefaultStashDir()} (not initialized)`;
|
|
134
|
-
}
|
|
135
|
-
const cacheDir = getCacheDir();
|
|
136
|
-
const result = {
|
|
137
|
-
config: configPath,
|
|
138
|
-
bundle: stashDir,
|
|
139
|
-
cache: cacheDir,
|
|
140
|
-
index: getDbPath(),
|
|
141
|
-
};
|
|
142
|
-
output("config", result);
|
|
143
|
-
}
|
|
144
|
-
else {
|
|
145
|
-
console.log(configPath);
|
|
146
|
-
}
|
|
121
|
+
meta: { name: "path", description: "Print the path to the config file" },
|
|
122
|
+
run() {
|
|
123
|
+
console.log(getConfigPath());
|
|
147
124
|
},
|
|
148
125
|
}),
|
|
149
126
|
list: defineJsonCommand({
|
|
@@ -56,7 +56,7 @@ const envCreateCommand = defineJsonCommand({
|
|
|
56
56
|
description: "Exclude this env file from env list output and the search index",
|
|
57
57
|
default: false,
|
|
58
58
|
},
|
|
59
|
-
|
|
59
|
+
bundle: {
|
|
60
60
|
type: "string",
|
|
61
61
|
description: "Override the write destination. Accepts a source name from your config; falls back to defaultWriteTarget then the working bundle.",
|
|
62
62
|
},
|
|
@@ -64,8 +64,8 @@ const envCreateCommand = defineJsonCommand({
|
|
|
64
64
|
async run({ args }) {
|
|
65
65
|
const { createEnv, writeEnv } = await import("./env.js");
|
|
66
66
|
// `create` always targets env/, never the frozen vaults/ copy. `--path` is
|
|
67
|
-
// the subdirectory; `--
|
|
68
|
-
const { name, absPath, target, ref } = resolveEnvWriteTarget(args.name, args.
|
|
67
|
+
// the subdirectory; `--bundle` selects the writable destination source.
|
|
68
|
+
const { name, absPath, target, ref } = resolveEnvWriteTarget(args.name, args.bundle, {
|
|
69
69
|
subPath: getStringArg(args, "path"),
|
|
70
70
|
});
|
|
71
71
|
const fromFile = args["from-file"];
|
|
@@ -304,13 +304,13 @@ const envRemoveCommand = defineJsonCommand({
|
|
|
304
304
|
args: {
|
|
305
305
|
ref: { type: "positional", description: "Env ref", required: true },
|
|
306
306
|
yes: { type: "boolean", alias: "y", description: "Skip confirmation prompt", default: false },
|
|
307
|
-
|
|
307
|
+
bundle: {
|
|
308
308
|
type: "string",
|
|
309
309
|
description: "Override the write destination. Accepts a source name from your config; falls back to defaultWriteTarget then the working bundle.",
|
|
310
310
|
},
|
|
311
311
|
},
|
|
312
312
|
async run({ args }) {
|
|
313
|
-
const { name, absPath, target, ref } = resolveEnvWriteTarget(args.ref, args.
|
|
313
|
+
const { name, absPath, target, ref } = resolveEnvWriteTarget(args.ref, args.bundle);
|
|
314
314
|
const { confirmDestructive } = await import("../../cli/confirm.js");
|
|
315
315
|
const confirmed = await confirmDestructive(`Remove env "${args.ref}"? This cannot be undone.`, {
|
|
316
316
|
yes: args.yes === true,
|
|
@@ -108,14 +108,14 @@ const secretSetCommand = defineJsonCommand({
|
|
|
108
108
|
},
|
|
109
109
|
"from-file": { type: "string", description: "Read the value from this file (stored byte-exact)" },
|
|
110
110
|
"from-env": { type: "string", description: "Read the value from the named environment variable" },
|
|
111
|
-
|
|
111
|
+
bundle: {
|
|
112
112
|
type: "string",
|
|
113
113
|
description: "Override the write destination. Accepts a source name from your config; falls back to defaultWriteTarget then the working bundle.",
|
|
114
114
|
},
|
|
115
115
|
},
|
|
116
116
|
async run({ args }) {
|
|
117
117
|
const { setSecret } = await import("./secret.js");
|
|
118
|
-
const { name, absPath, target, ref } = resolveSecretWriteTarget(args.ref, args.
|
|
118
|
+
const { name, absPath, target, ref } = resolveSecretWriteTarget(args.ref, args.bundle, {
|
|
119
119
|
subPath: getStringArg(args, "path"),
|
|
120
120
|
});
|
|
121
121
|
const fromEnv = args["from-env"];
|