akm-cli 0.7.4 → 0.8.0-rc.3

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.
Files changed (162) hide show
  1. package/{CHANGELOG.md → .github/CHANGELOG.md} +34 -1
  2. package/.github/LICENSE +374 -0
  3. package/dist/cli/parse-args.js +86 -0
  4. package/dist/cli.js +1223 -650
  5. package/dist/commands/agent-dispatch.js +107 -0
  6. package/dist/commands/agent-support.js +62 -0
  7. package/dist/commands/config-cli.js +68 -84
  8. package/dist/commands/consolidate.js +812 -0
  9. package/dist/commands/curate.js +1 -0
  10. package/dist/commands/distill-promotion-policy.js +658 -0
  11. package/dist/commands/distill.js +224 -39
  12. package/dist/commands/eval-cases.js +40 -0
  13. package/dist/commands/events.js +12 -24
  14. package/dist/commands/graph.js +222 -0
  15. package/dist/commands/health.js +376 -0
  16. package/dist/commands/help/help-accept.md +9 -0
  17. package/dist/commands/help/help-improve.md +53 -0
  18. package/dist/commands/help/help-proposals.md +15 -0
  19. package/dist/commands/help/help-propose.md +17 -0
  20. package/dist/commands/help/help-reject.md +8 -0
  21. package/dist/commands/history.js +3 -30
  22. package/dist/commands/improve.js +1161 -0
  23. package/dist/commands/info.js +2 -2
  24. package/dist/commands/init.js +2 -2
  25. package/dist/commands/install-audit.js +5 -1
  26. package/dist/commands/installed-stashes.js +118 -138
  27. package/dist/commands/knowledge.js +133 -0
  28. package/dist/commands/lint/agent-linter.js +46 -0
  29. package/dist/commands/lint/base-linter.js +291 -0
  30. package/dist/commands/lint/command-linter.js +46 -0
  31. package/dist/commands/lint/default-linter.js +13 -0
  32. package/dist/commands/lint/index.js +145 -0
  33. package/dist/commands/lint/knowledge-linter.js +13 -0
  34. package/dist/commands/lint/memory-linter.js +58 -0
  35. package/dist/commands/lint/registry.js +33 -0
  36. package/dist/commands/lint/skill-linter.js +42 -0
  37. package/dist/commands/lint/task-linter.js +47 -0
  38. package/dist/commands/lint/types.js +1 -0
  39. package/dist/commands/lint/vault-key-rules.js +67 -0
  40. package/dist/commands/lint/workflow-linter.js +53 -0
  41. package/dist/commands/lint.js +1 -0
  42. package/dist/commands/migration-help.js +2 -2
  43. package/dist/commands/proposal.js +8 -7
  44. package/dist/commands/propose.js +106 -43
  45. package/dist/commands/reflect.js +167 -41
  46. package/dist/commands/registry-search.js +2 -2
  47. package/dist/commands/remember.js +55 -1
  48. package/dist/commands/schema-repair.js +130 -0
  49. package/dist/commands/search.js +21 -5
  50. package/dist/commands/show.js +135 -55
  51. package/dist/commands/source-add.js +10 -10
  52. package/dist/commands/source-manage.js +11 -19
  53. package/dist/commands/tasks.js +385 -0
  54. package/dist/commands/url-checker.js +39 -0
  55. package/dist/commands/vault.js +173 -87
  56. package/dist/core/action-contributors.js +25 -0
  57. package/dist/core/asset-ref.js +4 -0
  58. package/dist/core/asset-registry.js +5 -17
  59. package/dist/core/asset-spec.js +11 -1
  60. package/dist/core/common.js +100 -0
  61. package/dist/core/concurrent.js +22 -0
  62. package/dist/core/config.js +240 -127
  63. package/dist/core/events.js +87 -123
  64. package/dist/core/frontmatter.js +0 -6
  65. package/dist/core/markdown.js +17 -0
  66. package/dist/core/memory-improve.js +678 -0
  67. package/dist/core/parse.js +155 -0
  68. package/dist/core/paths.js +101 -3
  69. package/dist/core/proposal-validators.js +61 -0
  70. package/dist/core/proposals.js +49 -38
  71. package/dist/core/state-db.js +731 -0
  72. package/dist/core/time.js +51 -0
  73. package/dist/core/warn.js +59 -1
  74. package/dist/indexer/db-search.js +86 -472
  75. package/dist/indexer/db.js +418 -59
  76. package/dist/indexer/ensure-index.js +133 -0
  77. package/dist/indexer/graph-boost.js +247 -94
  78. package/dist/indexer/graph-db.js +201 -0
  79. package/dist/indexer/graph-dedup.js +99 -0
  80. package/dist/indexer/graph-extraction.js +417 -74
  81. package/dist/indexer/index-context.js +10 -0
  82. package/dist/indexer/indexer.js +480 -298
  83. package/dist/indexer/llm-cache.js +47 -0
  84. package/dist/indexer/matchers.js +124 -160
  85. package/dist/indexer/memory-inference.js +63 -29
  86. package/dist/indexer/metadata-contributors.js +26 -0
  87. package/dist/indexer/metadata.js +196 -197
  88. package/dist/indexer/path-resolver.js +89 -0
  89. package/dist/indexer/ranking-contributors.js +204 -0
  90. package/dist/indexer/ranking.js +74 -0
  91. package/dist/indexer/search-hit-enrichers.js +22 -0
  92. package/dist/indexer/search-source.js +24 -9
  93. package/dist/indexer/semantic-status.js +2 -16
  94. package/dist/indexer/walker.js +25 -0
  95. package/dist/integrations/agent/builders.js +109 -0
  96. package/dist/integrations/agent/config.js +203 -3
  97. package/dist/integrations/agent/index.js +5 -2
  98. package/dist/integrations/agent/model-aliases.js +63 -0
  99. package/dist/integrations/agent/profiles.js +67 -5
  100. package/dist/integrations/agent/prompts.js +114 -29
  101. package/dist/integrations/agent/sdk-runner.js +120 -0
  102. package/dist/integrations/agent/spawn.js +158 -34
  103. package/dist/integrations/lockfile.js +10 -18
  104. package/dist/integrations/session-logs/index.js +65 -0
  105. package/dist/integrations/session-logs/providers/claude-code.js +56 -0
  106. package/dist/integrations/session-logs/providers/opencode.js +52 -0
  107. package/dist/integrations/session-logs/types.js +1 -0
  108. package/dist/llm/call-ai.js +74 -0
  109. package/dist/llm/client.js +63 -86
  110. package/dist/llm/feature-gate.js +27 -16
  111. package/dist/llm/graph-extract.js +297 -64
  112. package/dist/llm/memory-infer.js +52 -71
  113. package/dist/llm/metadata-enhance.js +39 -22
  114. package/dist/llm/prompts/graph-extract-user-prompt.md +12 -0
  115. package/dist/output/cli-hints-full.md +277 -0
  116. package/dist/output/cli-hints-short.md +65 -0
  117. package/dist/output/cli-hints.js +2 -309
  118. package/dist/output/renderers.js +226 -257
  119. package/dist/output/shapes.js +109 -96
  120. package/dist/output/text.js +274 -36
  121. package/dist/registry/providers/skills-sh.js +61 -49
  122. package/dist/registry/providers/static-index.js +44 -48
  123. package/dist/registry/resolve.js +8 -16
  124. package/dist/setup/setup.js +510 -11
  125. package/dist/sources/provider-factory.js +2 -1
  126. package/dist/sources/providers/filesystem.js +16 -23
  127. package/dist/sources/providers/git.js +45 -4
  128. package/dist/sources/providers/website.js +15 -22
  129. package/dist/sources/website-ingest.js +4 -0
  130. package/dist/tasks/backends/cron.js +200 -0
  131. package/dist/tasks/backends/exec-utils.js +25 -0
  132. package/dist/tasks/backends/index.js +32 -0
  133. package/dist/tasks/backends/launchd-template.xml +19 -0
  134. package/dist/tasks/backends/launchd.js +184 -0
  135. package/dist/tasks/backends/schtasks-template.xml +29 -0
  136. package/dist/tasks/backends/schtasks.js +212 -0
  137. package/dist/tasks/parser.js +198 -0
  138. package/dist/tasks/resolveAkmBin.js +84 -0
  139. package/dist/tasks/runner.js +432 -0
  140. package/dist/tasks/schedule.js +208 -0
  141. package/dist/tasks/schema.js +13 -0
  142. package/dist/tasks/validator.js +59 -0
  143. package/dist/wiki/index-template.md +12 -0
  144. package/dist/wiki/ingest-workflow-template.md +54 -0
  145. package/dist/wiki/log-template.md +8 -0
  146. package/dist/wiki/schema-template.md +61 -0
  147. package/dist/wiki/wiki-templates.js +12 -0
  148. package/dist/wiki/wiki.js +10 -61
  149. package/dist/workflows/authoring.js +5 -25
  150. package/dist/workflows/db.js +9 -0
  151. package/dist/workflows/renderer.js +8 -3
  152. package/dist/workflows/runs.js +73 -88
  153. package/dist/workflows/scope-key.js +76 -0
  154. package/dist/workflows/validator.js +1 -1
  155. package/dist/workflows/workflow-template.md +24 -0
  156. package/docs/README.md +5 -2
  157. package/docs/migration/release-notes/0.7.0.md +1 -1
  158. package/docs/migration/release-notes/0.7.4.md +1 -1
  159. package/docs/migration/release-notes/0.7.5.md +20 -0
  160. package/docs/migration/release-notes/0.8.0.md +43 -0
  161. package/package.json +4 -3
  162. package/dist/templates/wiki-templates.js +0 -100
@@ -6,6 +6,70 @@
6
6
  * `Record<string, unknown>` shapes, which makes them trivial to unit test.
7
7
  */
8
8
  const NORMAL_DESCRIPTION_LIMIT = 250;
9
+ const PASSTHROUGH_COMMANDS = new Set([
10
+ "add",
11
+ "agent-result",
12
+ "clone",
13
+ "config",
14
+ "consolidate",
15
+ "curate",
16
+ "disable",
17
+ "enable",
18
+ "feedback",
19
+ "graph-entities",
20
+ "graph-export",
21
+ "graph-related",
22
+ "graph-relations",
23
+ "graph-summary",
24
+ "health",
25
+ "import",
26
+ "improve",
27
+ "index",
28
+ "info",
29
+ "init",
30
+ "lint",
31
+ "list",
32
+ "registry-add",
33
+ "registry-build-index",
34
+ "registry-list",
35
+ "registry-remove",
36
+ "remember",
37
+ "remove",
38
+ "save",
39
+ "setup",
40
+ "tasks-add",
41
+ "tasks-disable",
42
+ "tasks-doctor",
43
+ "tasks-enable",
44
+ "tasks-history",
45
+ "tasks-list",
46
+ "tasks-remove",
47
+ "tasks-run",
48
+ "tasks-show",
49
+ "tasks-sync",
50
+ "update",
51
+ "upgrade",
52
+ "vault-create",
53
+ "vault-set",
54
+ "vault-unset",
55
+ "wiki-create",
56
+ "wiki-ingest",
57
+ "wiki-lint",
58
+ "wiki-list",
59
+ "wiki-pages",
60
+ "wiki-register",
61
+ "wiki-remove",
62
+ "wiki-show",
63
+ "wiki-stash",
64
+ "workflow-complete",
65
+ "workflow-create",
66
+ "workflow-list",
67
+ "workflow-next",
68
+ "workflow-resume",
69
+ "workflow-start",
70
+ "workflow-status",
71
+ "workflow-validate",
72
+ ]);
9
73
  export function shapeForCommand(command, result, detail, forAgent = false) {
10
74
  switch (command) {
11
75
  case "search":
@@ -45,66 +109,31 @@ export function shapeForCommand(command, result, detail, forAgent = false) {
45
109
  case "reflect":
46
110
  case "propose":
47
111
  return shapeProposalProducerOutput(result, detail);
48
- // Output shape registration for `akm distill <ref>` (#228). The shape is
49
- // simple — outcome + ids + optional payload — so `brief` strips the full
50
- // proposal blob, `normal` keeps the headline fields, and `full` projects
51
- // everything for downstream automation.
52
112
  case "distill":
53
113
  return shapeDistillOutput(result, detail);
54
- // Identity-passthrough commands — registered here so the registry stays
55
- // exhaustive (v1 spec §9). Each result object is already shaped at the
56
- // command boundary; the registry just confirms there's no surprise
57
- // command name slipping through.
58
- case "add":
59
- case "clone":
60
- case "config":
61
- case "curate":
62
- case "disable":
63
- case "enable":
64
- case "feedback":
65
- case "import":
66
- case "index":
67
- case "info":
68
- case "init":
69
- case "list":
70
- case "registry-add":
71
- case "registry-build-index":
72
- case "registry-list":
73
- case "registry-remove":
74
- case "remember":
75
- case "remove":
76
- case "save":
77
- case "update":
78
- case "upgrade":
79
- case "vault-create":
80
- case "vault-list":
81
- case "vault-set":
82
- case "vault-unset":
83
- case "wiki-create":
84
- case "wiki-ingest":
85
- case "wiki-lint":
86
- case "wiki-list":
87
- case "wiki-pages":
88
- case "wiki-register":
89
- case "wiki-remove":
90
- case "wiki-show":
91
- case "wiki-stash":
92
- case "workflow-complete":
93
- case "workflow-create":
94
- case "workflow-list":
95
- case "workflow-next":
96
- case "workflow-resume":
97
- case "workflow-start":
98
- case "workflow-status":
99
- case "workflow-validate":
100
- return result;
114
+ case "vault-list": {
115
+ const r = result;
116
+ const vaults = Array.isArray(r.vaults) ? r.vaults : [];
117
+ return {
118
+ ...r,
119
+ vaults: vaults.map((v) => {
120
+ const { path: _path, ...rest } = v;
121
+ return rest;
122
+ }),
123
+ };
124
+ }
101
125
  default:
102
- // v1 spec §9 (output-shape registry exhaustive): no silent JSON.stringify
103
- // fallback. A missing case here is a registration bug — fail loudly so
104
- // the caller (or its tests) sees the missing command name.
126
+ // v1 spec §9 (output-shape registry exhaustive): identity-passthrough
127
+ // commands are listed in PASSTHROUGH_COMMANDS; anything not in that set
128
+ // is a registration bug fail loudly.
129
+ if (PASSTHROUGH_COMMANDS.has(command))
130
+ return result;
105
131
  throw new Error(`output shape not registered for command: ${command}`);
106
132
  }
107
133
  }
134
+ function maybeAddSchema(base, detail, version) {
135
+ return detail === "full" ? { schemaVersion: version ?? 1, ...base } : base;
136
+ }
108
137
  /**
109
138
  * Shape the result of `akm reflect` / `akm propose`. On success we surface
110
139
  * the queued proposal entry (using the standard proposal-entry shaper so
@@ -141,10 +170,7 @@ export function shapeProposalProducerOutput(result, detail) {
141
170
  ...(typeof result.durationMs === "number" ? { durationMs: result.durationMs } : {}),
142
171
  proposal: shapeProposalEntry(proposal, detail === "brief" ? "normal" : detail),
143
172
  };
144
- if (detail === "full") {
145
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
146
- }
147
- return base;
173
+ return maybeAddSchema(base, detail, result.schemaVersion);
148
174
  }
149
175
  export function shapeProposalEntry(entry, detail) {
150
176
  if (detail === "brief") {
@@ -173,10 +199,7 @@ export function shapeProposalListOutput(result, detail) {
173
199
  totalCount: result.totalCount ?? shaped.length,
174
200
  proposals: shaped,
175
201
  };
176
- if (detail === "full") {
177
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
178
- }
179
- return base;
202
+ return maybeAddSchema(base, detail, result.schemaVersion);
180
203
  }
181
204
  export function shapeProposalShowOutput(result, detail) {
182
205
  const proposal = result.proposal ?? {};
@@ -185,10 +208,7 @@ export function shapeProposalShowOutput(result, detail) {
185
208
  proposal: shapeProposalEntry(proposal, detail === "brief" ? "normal" : detail),
186
209
  ...(validation ? { validation } : {}),
187
210
  };
188
- if (detail === "full") {
189
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
190
- }
191
- return base;
211
+ return maybeAddSchema(base, detail, result.schemaVersion);
192
212
  }
193
213
  export function shapeProposalAcceptOutput(result, detail) {
194
214
  const proposal = result.proposal ?? {};
@@ -199,10 +219,7 @@ export function shapeProposalAcceptOutput(result, detail) {
199
219
  assetPath: result.assetPath,
200
220
  proposal: shapeProposalEntry(proposal, detail === "brief" ? "normal" : detail),
201
221
  };
202
- if (detail === "full") {
203
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
204
- }
205
- return base;
222
+ return maybeAddSchema(base, detail, result.schemaVersion);
206
223
  }
207
224
  export function shapeProposalRejectOutput(result, detail) {
208
225
  const proposal = result.proposal ?? {};
@@ -213,10 +230,7 @@ export function shapeProposalRejectOutput(result, detail) {
213
230
  ...(result.reason !== undefined ? { reason: result.reason } : {}),
214
231
  proposal: shapeProposalEntry(proposal, detail === "brief" ? "normal" : detail),
215
232
  };
216
- if (detail === "full") {
217
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
218
- }
219
- return base;
233
+ return maybeAddSchema(base, detail, result.schemaVersion);
220
234
  }
221
235
  export function shapeDistillOutput(result, detail) {
222
236
  const proposal = result.proposal;
@@ -233,10 +247,7 @@ export function shapeDistillOutput(result, detail) {
233
247
  ...(Array.isArray(result.findings) && result.findings.length > 0 ? { findings: result.findings } : {}),
234
248
  ...(proposal ? { proposal: shapeProposalEntry(proposal, detail === "summary" ? "normal" : detail) } : {}),
235
249
  };
236
- if (detail === "full") {
237
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
238
- }
239
- return base;
250
+ return maybeAddSchema(base, detail, result.schemaVersion);
240
251
  }
241
252
  export function shapeProposalDiffOutput(result, detail) {
242
253
  const base = {
@@ -246,10 +257,7 @@ export function shapeProposalDiffOutput(result, detail) {
246
257
  unified: result.unified,
247
258
  ...(result.targetPath !== undefined ? { targetPath: result.targetPath } : {}),
248
259
  };
249
- if (detail === "full") {
250
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
251
- }
252
- return base;
260
+ return maybeAddSchema(base, detail, result.schemaVersion);
253
261
  }
254
262
  export function shapeEventsOutput(result, detail) {
255
263
  const events = Array.isArray(result.events) ? result.events : [];
@@ -268,16 +276,10 @@ export function shapeEventsOutput(result, detail) {
268
276
  if (typeof result.reason === "string") {
269
277
  base.reason = result.reason;
270
278
  }
271
- if (detail === "full") {
272
- return { schemaVersion: result.schemaVersion ?? 1, ...base };
273
- }
274
- return base;
279
+ return maybeAddSchema(base, detail, result.schemaVersion);
275
280
  }
276
281
  export function shapeEventEntry(entry, detail) {
277
- if (detail === "brief") {
278
- return pickFields(entry, ["eventType", "ref", "ts"]);
279
- }
280
- if (detail === "normal" || detail === "summary") {
282
+ if (detail === "brief" || detail === "normal" || detail === "summary") {
281
283
  return pickFields(entry, ["eventType", "ref", "ts"]);
282
284
  }
283
285
  // full / agent: project everything the reader emits.
@@ -407,19 +409,22 @@ export function shapeSearchHit(hit, detail) {
407
409
  // `ref` is included at `brief` so agents can run `akm show <ref>` without
408
410
  // needing --detail full or --for-agent (REC-03).
409
411
  if (detail === "brief")
410
- return pickFields(hit, ["type", "name", "ref", "action", "estimatedTokens"]);
412
+ return pickFields(hit, ["type", "name", "ref", "action", "estimatedTokens", "keys"]);
411
413
  if (detail === "normal") {
412
414
  // `warnings` is projected at `normal` so non-fatal hit-level issues are
413
415
  // visible without forcing callers up to `--detail full`. Optional
414
416
  // `quality` (v1 spec §4.2) is also surfaced when present so callers
415
417
  // can see why a `proposed` entry showed up under `--include-proposed`.
416
- return capDescription(pickFields(hit, ["type", "name", "description", "action", "score", "estimatedTokens", "warnings", "quality"]), NORMAL_DESCRIPTION_LIMIT);
418
+ const shaped = capDescription(pickFields(hit, ["type", "name", "description", "action", "score", "estimatedTokens", "warnings", "quality"]), NORMAL_DESCRIPTION_LIMIT);
419
+ if (Array.isArray(hit.keys) && hit.keys.length > 0)
420
+ shaped.keys = hit.keys;
421
+ return shaped;
417
422
  }
418
423
  return hit;
419
424
  }
420
425
  /** Agent-optimized search hit: only fields an LLM agent needs to decide and act */
421
426
  export function shapeSearchHitForAgent(hit) {
422
- const picked = pickFields(hit, ["name", "ref", "type", "description", "action", "score", "estimatedTokens"]);
427
+ const picked = pickFields(hit, ["name", "ref", "type", "description", "action", "score", "estimatedTokens", "keys"]);
423
428
  return capDescription(picked, NORMAL_DESCRIPTION_LIMIT);
424
429
  }
425
430
  export function capDescription(hit, limit) {
@@ -449,6 +454,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
449
454
  "run",
450
455
  "setup",
451
456
  "cwd",
457
+ "activeRun",
452
458
  "toolPolicy",
453
459
  "modelHint",
454
460
  "agent",
@@ -458,6 +464,7 @@ export function shapeShowOutput(result, detail, forAgent = false) {
458
464
  "steps",
459
465
  "keys",
460
466
  "comments",
467
+ "related",
461
468
  ]);
462
469
  }
463
470
  if (detail === "summary") {
@@ -473,9 +480,10 @@ export function shapeShowOutput(result, detail, forAgent = false) {
473
480
  "origin",
474
481
  "keys",
475
482
  "comments",
483
+ "related",
476
484
  ]);
477
485
  }
478
- const base = pickFields(result, [
486
+ const baseFields = [
479
487
  "type",
480
488
  "name",
481
489
  "origin",
@@ -495,13 +503,18 @@ export function shapeShowOutput(result, detail, forAgent = false) {
495
503
  "run",
496
504
  "setup",
497
505
  "cwd",
506
+ "activeRun",
498
507
  "keys",
499
508
  "comments",
509
+ "related",
500
510
  // path and editable are always projected so JSON consumers can locate and
501
511
  // edit the asset without needing --detail full (QA #7).
502
- "path",
512
+ // Exception: vault assets omit path to avoid leaking absolute disk paths
513
+ // into structured JSON output (security fix M3).
514
+ ...(result.type === "vault" ? [] : ["path"]),
503
515
  "editable",
504
- ]);
516
+ ];
517
+ const base = pickFields(result, baseFields);
505
518
  if (detail !== "full") {
506
519
  return base;
507
520
  }