akm-cli 0.8.0-rc2 → 0.8.0

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 (295) hide show
  1. package/{.github/CHANGELOG.md → CHANGELOG.md} +191 -3
  2. package/README.md +22 -6
  3. package/SECURITY.md +93 -0
  4. package/dist/cli/config-migrate.js +144 -0
  5. package/dist/cli/config-validate.js +39 -0
  6. package/dist/cli/confirm.js +73 -0
  7. package/dist/cli/parse-args.js +93 -3
  8. package/dist/cli/shared.js +129 -0
  9. package/dist/cli.js +2141 -1268
  10. package/dist/commands/add-cli.js +279 -0
  11. package/dist/commands/agent-dispatch.js +20 -12
  12. package/dist/commands/agent-support.js +11 -5
  13. package/dist/commands/completions.js +3 -0
  14. package/dist/commands/config-cli.js +129 -517
  15. package/dist/commands/consolidate.js +1533 -144
  16. package/dist/commands/curate.js +44 -3
  17. package/dist/commands/db-cli.js +23 -0
  18. package/dist/commands/distill-promotion-policy.js +5 -3
  19. package/dist/commands/distill.js +906 -100
  20. package/dist/commands/env.js +213 -0
  21. package/dist/commands/eval-cases.js +3 -0
  22. package/dist/commands/events.js +3 -0
  23. package/dist/commands/extract-cli.js +127 -0
  24. package/dist/commands/extract-prompt.js +204 -0
  25. package/dist/commands/extract.js +477 -0
  26. package/dist/commands/feedback-cli.js +331 -0
  27. package/dist/commands/graph.js +260 -5
  28. package/dist/commands/health.js +977 -51
  29. package/dist/commands/help/help-accept.md +6 -3
  30. package/dist/commands/help/help-improve.md +36 -8
  31. package/dist/commands/help/help-proposals.md +7 -4
  32. package/dist/commands/help/help-reject.md +5 -2
  33. package/dist/commands/history.js +51 -16
  34. package/dist/commands/improve-auto-accept.js +97 -0
  35. package/dist/commands/improve-cli.js +236 -0
  36. package/dist/commands/improve-profiles.js +184 -0
  37. package/dist/commands/improve-result-file.js +167 -0
  38. package/dist/commands/improve.js +1725 -332
  39. package/dist/commands/info.js +3 -0
  40. package/dist/commands/init.js +49 -1
  41. package/dist/commands/installed-stashes.js +6 -23
  42. package/dist/commands/knowledge.js +3 -0
  43. package/dist/commands/lint/agent-linter.js +3 -0
  44. package/dist/commands/lint/base-linter.js +199 -5
  45. package/dist/commands/lint/command-linter.js +3 -0
  46. package/dist/commands/lint/default-linter.js +3 -0
  47. package/dist/commands/lint/env-key-rules.js +154 -0
  48. package/dist/commands/lint/index.js +92 -3
  49. package/dist/commands/lint/knowledge-linter.js +3 -0
  50. package/dist/commands/lint/markdown-insertion.js +343 -0
  51. package/dist/commands/lint/memory-linter.js +3 -0
  52. package/dist/commands/lint/registry.js +3 -0
  53. package/dist/commands/lint/skill-linter.js +3 -0
  54. package/dist/commands/lint/task-linter.js +15 -12
  55. package/dist/commands/lint/types.js +3 -0
  56. package/dist/commands/lint/workflow-linter.js +3 -0
  57. package/dist/commands/lint.js +3 -0
  58. package/dist/commands/migration-help.js +5 -2
  59. package/dist/commands/proposal-drain-policies.js +128 -0
  60. package/dist/commands/proposal-drain.js +477 -0
  61. package/dist/commands/proposal.js +60 -6
  62. package/dist/commands/propose.js +24 -19
  63. package/dist/commands/reflect.js +1004 -94
  64. package/dist/commands/registry-cli.js +150 -0
  65. package/dist/commands/registry-search.js +3 -0
  66. package/dist/commands/remember-cli.js +257 -0
  67. package/dist/commands/remember.js +15 -6
  68. package/dist/commands/schema-repair.js +88 -15
  69. package/dist/commands/search.js +99 -14
  70. package/dist/commands/secret.js +173 -0
  71. package/dist/commands/self-update.js +3 -0
  72. package/dist/commands/show.js +32 -13
  73. package/dist/commands/source-add.js +7 -35
  74. package/dist/commands/source-clone.js +3 -0
  75. package/dist/commands/source-manage.js +3 -0
  76. package/dist/commands/tasks.js +161 -95
  77. package/dist/commands/url-checker.js +3 -0
  78. package/dist/core/action-contributors.js +3 -0
  79. package/dist/core/asset-ref.js +13 -2
  80. package/dist/core/asset-registry.js +9 -2
  81. package/dist/core/asset-serialize.js +88 -0
  82. package/dist/core/asset-spec.js +61 -5
  83. package/dist/core/common.js +93 -5
  84. package/dist/core/concurrent.js +3 -0
  85. package/dist/core/config-io.js +347 -0
  86. package/dist/core/config-migration.js +622 -0
  87. package/dist/core/config-schema.js +558 -0
  88. package/dist/core/config-sources.js +108 -0
  89. package/dist/core/config-types.js +4 -0
  90. package/dist/core/config-walker.js +337 -0
  91. package/dist/core/config.js +366 -1077
  92. package/dist/core/errors.js +42 -20
  93. package/dist/core/events.js +31 -25
  94. package/dist/core/file-lock.js +104 -0
  95. package/dist/core/frontmatter.js +75 -10
  96. package/dist/core/lesson-lint.js +3 -0
  97. package/dist/core/markdown.js +3 -0
  98. package/dist/core/memory-belief.js +62 -0
  99. package/dist/core/memory-contradiction-detect.js +274 -0
  100. package/dist/core/memory-improve.js +142 -14
  101. package/dist/core/parse.js +3 -0
  102. package/dist/core/paths.js +218 -50
  103. package/dist/core/proposal-quality-validators.js +380 -0
  104. package/dist/core/proposal-validators.js +11 -3
  105. package/dist/core/proposals.js +464 -5
  106. package/dist/core/state-db.js +349 -56
  107. package/dist/core/text-truncation.js +107 -0
  108. package/dist/core/time.js +3 -0
  109. package/dist/core/tty.js +59 -0
  110. package/dist/core/warn.js +7 -2
  111. package/dist/core/write-source.js +12 -0
  112. package/dist/indexer/db-backup.js +391 -0
  113. package/dist/indexer/db-search.js +136 -28
  114. package/dist/indexer/db.js +661 -166
  115. package/dist/indexer/ensure-index.js +3 -0
  116. package/dist/indexer/file-context.js +3 -0
  117. package/dist/indexer/graph-boost.js +162 -40
  118. package/dist/indexer/graph-db.js +241 -51
  119. package/dist/indexer/graph-dedup.js +3 -7
  120. package/dist/indexer/graph-extraction.js +242 -149
  121. package/dist/indexer/index-context.js +3 -9
  122. package/dist/indexer/indexer.js +84 -14
  123. package/dist/indexer/llm-cache.js +24 -19
  124. package/dist/indexer/manifest.js +3 -0
  125. package/dist/indexer/matchers.js +184 -11
  126. package/dist/indexer/memory-inference.js +94 -50
  127. package/dist/indexer/metadata-contributors.js +3 -0
  128. package/dist/indexer/metadata.js +110 -50
  129. package/dist/indexer/path-resolver.js +3 -0
  130. package/dist/indexer/project-context.js +192 -0
  131. package/dist/indexer/ranking-contributors.js +134 -7
  132. package/dist/indexer/ranking.js +8 -1
  133. package/dist/indexer/search-fields.js +5 -9
  134. package/dist/indexer/search-hit-enrichers.js +91 -2
  135. package/dist/indexer/search-source.js +20 -1
  136. package/dist/indexer/semantic-status.js +4 -1
  137. package/dist/indexer/staleness-detect.js +447 -0
  138. package/dist/indexer/usage-events.js +12 -9
  139. package/dist/indexer/walker.js +3 -0
  140. package/dist/integrations/agent/builders.js +135 -0
  141. package/dist/integrations/agent/config.js +121 -401
  142. package/dist/integrations/agent/detect.js +3 -0
  143. package/dist/integrations/agent/index.js +6 -14
  144. package/dist/integrations/agent/model-aliases.js +55 -0
  145. package/dist/integrations/agent/profiles.js +3 -0
  146. package/dist/integrations/agent/prompts.js +137 -8
  147. package/dist/integrations/agent/runner.js +208 -0
  148. package/dist/integrations/agent/sdk-runner.js +8 -2
  149. package/dist/integrations/agent/spawn.js +54 -14
  150. package/dist/integrations/github.js +3 -0
  151. package/dist/integrations/lockfile.js +22 -51
  152. package/dist/integrations/session-logs/index.js +4 -0
  153. package/dist/integrations/session-logs/inline-refs.js +35 -0
  154. package/dist/integrations/session-logs/pre-filter.js +152 -0
  155. package/dist/integrations/session-logs/providers/claude-code.js +226 -0
  156. package/dist/integrations/session-logs/providers/opencode.js +231 -25
  157. package/dist/integrations/session-logs/types.js +3 -0
  158. package/dist/llm/call-ai.js +14 -26
  159. package/dist/llm/client.js +16 -2
  160. package/dist/llm/embedder.js +20 -29
  161. package/dist/llm/embedders/cache.js +3 -7
  162. package/dist/llm/embedders/local.js +42 -1
  163. package/dist/llm/embedders/remote.js +20 -8
  164. package/dist/llm/embedders/types.js +3 -7
  165. package/dist/llm/feature-gate.js +92 -56
  166. package/dist/llm/graph-extract.js +401 -30
  167. package/dist/llm/index-passes.js +44 -29
  168. package/dist/llm/memory-infer.js +30 -2
  169. package/dist/llm/metadata-enhance.js +3 -7
  170. package/dist/llm/prompts/extract-session.md +80 -0
  171. package/dist/llm/prompts/graph-extract-user-prompt.md +24 -1
  172. package/dist/output/cli-hints-full.md +60 -32
  173. package/dist/output/cli-hints-short.md +10 -7
  174. package/dist/output/cli-hints.js +5 -2
  175. package/dist/output/context.js +60 -8
  176. package/dist/output/renderers.js +170 -194
  177. package/dist/output/shapes/curate.js +56 -0
  178. package/dist/output/shapes/distill.js +10 -0
  179. package/dist/output/shapes/env-list.js +19 -0
  180. package/dist/output/shapes/events.js +11 -0
  181. package/dist/output/shapes/helpers.js +424 -0
  182. package/dist/output/shapes/history.js +7 -0
  183. package/dist/output/shapes/passthrough.js +105 -0
  184. package/dist/output/shapes/proposal-accept.js +7 -0
  185. package/dist/output/shapes/proposal-diff.js +7 -0
  186. package/dist/output/shapes/proposal-list.js +7 -0
  187. package/dist/output/shapes/proposal-producer.js +11 -0
  188. package/dist/output/shapes/proposal-reject.js +7 -0
  189. package/dist/output/shapes/proposal-show.js +7 -0
  190. package/dist/output/shapes/registry-search.js +6 -0
  191. package/dist/output/shapes/registry.js +30 -0
  192. package/dist/output/shapes/search.js +6 -0
  193. package/dist/output/shapes/secret-list.js +19 -0
  194. package/dist/output/shapes/show.js +6 -0
  195. package/dist/output/shapes/vault-list.js +19 -0
  196. package/dist/output/shapes.js +51 -549
  197. package/dist/output/text/add.js +6 -0
  198. package/dist/output/text/clone.js +6 -0
  199. package/dist/output/text/config.js +6 -0
  200. package/dist/output/text/curate.js +6 -0
  201. package/dist/output/text/distill.js +7 -0
  202. package/dist/output/text/enable-disable.js +7 -0
  203. package/dist/output/text/events.js +10 -0
  204. package/dist/output/text/feedback.js +6 -0
  205. package/dist/output/text/helpers.js +1059 -0
  206. package/dist/output/text/history.js +7 -0
  207. package/dist/output/text/import.js +6 -0
  208. package/dist/output/text/index.js +6 -0
  209. package/dist/output/text/info.js +6 -0
  210. package/dist/output/text/init.js +6 -0
  211. package/dist/output/text/list.js +6 -0
  212. package/dist/output/text/proposal-producer.js +8 -0
  213. package/dist/output/text/proposal.js +12 -0
  214. package/dist/output/text/registry-commands.js +11 -0
  215. package/dist/output/text/registry.js +30 -0
  216. package/dist/output/text/remember.js +6 -0
  217. package/dist/output/text/remove.js +6 -0
  218. package/dist/output/text/save.js +6 -0
  219. package/dist/output/text/search.js +6 -0
  220. package/dist/output/text/show.js +6 -0
  221. package/dist/output/text/update.js +6 -0
  222. package/dist/output/text/upgrade.js +6 -0
  223. package/dist/output/text/vault.js +16 -0
  224. package/dist/output/text/wiki.js +15 -0
  225. package/dist/output/text/workflow.js +14 -0
  226. package/dist/output/text.js +44 -1329
  227. package/dist/registry/build-index.js +3 -0
  228. package/dist/registry/create-provider-registry.js +3 -0
  229. package/dist/registry/factory.js +4 -1
  230. package/dist/registry/origin-resolve.js +3 -0
  231. package/dist/registry/providers/index.js +3 -0
  232. package/dist/registry/providers/skills-sh.js +11 -2
  233. package/dist/registry/providers/static-index.js +10 -1
  234. package/dist/registry/providers/types.js +3 -24
  235. package/dist/registry/resolve.js +11 -16
  236. package/dist/registry/types.js +3 -0
  237. package/dist/scripts/migrate-storage.js +17767 -0
  238. package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +9031 -0
  239. package/dist/scripts/migrations/v16-to-v17.js +141 -0
  240. package/dist/setup/detect.js +3 -0
  241. package/dist/setup/ripgrep-install.js +3 -0
  242. package/dist/setup/ripgrep-resolve.js +3 -0
  243. package/dist/setup/setup.js +306 -67
  244. package/dist/setup/steps.js +3 -15
  245. package/dist/sources/include.js +3 -0
  246. package/dist/sources/provider-factory.js +3 -11
  247. package/dist/sources/provider.js +3 -20
  248. package/dist/sources/providers/filesystem.js +19 -23
  249. package/dist/sources/providers/git.js +171 -21
  250. package/dist/sources/providers/index.js +3 -0
  251. package/dist/sources/providers/install-types.js +3 -13
  252. package/dist/sources/providers/npm.js +3 -4
  253. package/dist/sources/providers/provider-utils.js +3 -0
  254. package/dist/sources/providers/sync-from-ref.js +3 -11
  255. package/dist/sources/providers/tar-utils.js +3 -0
  256. package/dist/sources/providers/website.js +18 -22
  257. package/dist/sources/resolve.js +3 -0
  258. package/dist/sources/types.js +3 -0
  259. package/dist/sources/website-ingest.js +3 -0
  260. package/dist/tasks/backends/cron.js +3 -0
  261. package/dist/tasks/backends/exec-utils.js +3 -0
  262. package/dist/tasks/backends/index.js +3 -11
  263. package/dist/tasks/backends/launchd.js +3 -0
  264. package/dist/tasks/backends/schtasks.js +3 -0
  265. package/dist/tasks/parser.js +51 -38
  266. package/dist/tasks/resolveAkmBin.js +3 -0
  267. package/dist/tasks/runner.js +35 -9
  268. package/dist/tasks/schedule.js +20 -1
  269. package/dist/tasks/schema.js +5 -3
  270. package/dist/tasks/validator.js +6 -3
  271. package/dist/version.js +3 -0
  272. package/dist/wiki/wiki-templates.js +3 -0
  273. package/dist/wiki/wiki.js +3 -0
  274. package/dist/workflows/authoring.js +3 -0
  275. package/dist/workflows/cli.js +3 -0
  276. package/dist/workflows/db.js +140 -10
  277. package/dist/workflows/document-cache.js +3 -10
  278. package/dist/workflows/parser.js +3 -0
  279. package/dist/workflows/renderer.js +3 -0
  280. package/dist/workflows/runs.js +18 -1
  281. package/dist/workflows/schema.js +3 -0
  282. package/dist/workflows/scope-key.js +3 -0
  283. package/dist/workflows/validator.js +5 -9
  284. package/docs/README.md +7 -2
  285. package/docs/data-and-telemetry.md +225 -0
  286. package/docs/migration/release-notes/0.7.5.md +2 -2
  287. package/docs/migration/release-notes/0.8.0.md +57 -5
  288. package/docs/migration/v0.7-to-v0.8.md +1378 -0
  289. package/package.json +28 -11
  290. package/.github/LICENSE +0 -374
  291. package/dist/commands/install-audit.js +0 -385
  292. package/dist/commands/vault.js +0 -310
  293. package/dist/indexer/match-contributors.js +0 -141
  294. package/dist/integrations/agent/pipeline.js +0 -39
  295. package/dist/integrations/agent/runners.js +0 -31
@@ -1,3 +1,6 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
1
4
  /**
2
5
  * LLM helper for the `akm index` memory-inference pass (#201).
3
6
  *
@@ -24,11 +27,35 @@ const MAX_BODY_CHARS = 4000;
24
27
  const SYSTEM_PROMPT = "You compress a developer memory into one high-signal derived memory for later retrieval. " +
25
28
  "Return only valid JSON. No prose outside the JSON object. No markdown fences.";
26
29
  const USER_PROMPT_PREFIX = `Compress the memory below into one derived memory. Output ONLY JSON:
27
- {"title":"string","description":"string","tags":["string"],"searchHints":["string"],"content":"string"}
28
- Rules: be specific, no vague generalizations, preserve key facts (names/versions/paths/config keys verbatim), merge related points, max 3 sentences body, 3-8 tags, 3-6 searchHints.
30
+ {"title":"short title string","description":"one sentence summary string","tags":["tag1","tag2"],"searchHints":["search phrase 1","search phrase 2"],"content":"2-3 sentence compressed body preserving key facts verbatim"}
31
+ Rules: be specific, no vague generalizations, preserve key facts (names/versions/paths/config keys verbatim), merge related points, 3-8 tags, 3-6 searchHints. The content field must be a plain string with 2-3 sentences.
29
32
 
30
33
  Memory:
31
34
  `;
35
+ /**
36
+ * Strict JSON Schema for the derived-memory payload. Sent to providers that
37
+ * opt in via `LlmConnectionConfig.supportsJsonSchema = true`; the client
38
+ * silently drops the schema for providers that don't.
39
+ *
40
+ * Extends the responseSchema lift (PR 1, asset-writers-investigation §5) to
41
+ * the memory-inference path. Mirrors the validation gate below
42
+ * (title/description/content + non-empty tags/searchHints) so a
43
+ * schema-compliant response is guaranteed to pass the downstream check
44
+ * — no more "incomplete derived memory payload from LLM; skipping memory"
45
+ * for shape-only failures.
46
+ */
47
+ const DERIVED_MEMORY_JSON_SCHEMA = {
48
+ type: "object",
49
+ properties: {
50
+ title: { type: "string", minLength: 1 },
51
+ description: { type: "string", minLength: 1 },
52
+ content: { type: "string", minLength: 1 },
53
+ tags: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 8 },
54
+ searchHints: { type: "array", items: { type: "string" }, minItems: 1, maxItems: 6 },
55
+ },
56
+ required: ["title", "description", "content", "tags", "searchHints"],
57
+ additionalProperties: false,
58
+ };
32
59
  /**
33
60
  * Compress a single memory body into one derived memory via the configured LLM.
34
61
  *
@@ -53,6 +80,7 @@ export async function compressMemoryToDerivedMemory(llmConfig, body, signal, akm
53
80
  temperature: 0.1,
54
81
  timeoutMs: llmConfig.timeoutMs,
55
82
  signal,
83
+ responseSchema: DERIVED_MEMORY_JSON_SCHEMA,
56
84
  });
57
85
  if (!raw)
58
86
  return undefined;
@@ -1,10 +1,6 @@
1
- /**
2
- * LLM-driven metadata enhancement for stash entries.
3
- *
4
- * Split out of `llm.ts` so the higher-level workflow (prompting the LLM to
5
- * improve descriptions/tags/searchHints) lives separately from the low-level
6
- * transport client in `client.ts`.
7
- */
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
4
  import { chatCompletion, parseJsonResponse } from "./client";
9
5
  import { tryLlmFeature } from "./feature-gate";
10
6
  const SYSTEM_PROMPT = `You are a metadata generator for a developer asset registry. Given a script/skill/command/agent entry, generate improved metadata. Respond with ONLY valid JSON, no markdown fencing.`;
@@ -0,0 +1,80 @@
1
+ You are extracting durable engineering insights from a software session transcript. Most sessions produce zero new durable insights — the agent already captures what's worth keeping via explicit `akm remember` / `akm feedback` calls during the session. Your job is to identify learnings that slipped through.
2
+
3
+ ## What counts as "durable insight"
4
+
5
+ Things worth extracting:
6
+ - Recovery patterns ("X fails when Y; the fix is Z")
7
+ - Hidden constraints discovered mid-task ("this codebase requires X before deploy")
8
+ - Architecture observations ("module A is consumed by B and C via the D bus")
9
+ - Non-obvious workarounds for real defects
10
+ - Domain knowledge the agent learned and would benefit a future session
11
+
12
+ Things NOT to extract:
13
+ - Successful command sequences (already in git history / shell history)
14
+ - Tool counts / aggregates
15
+ - The agent's own narrative about what it was doing
16
+ - Restatements of what the user asked for
17
+ - Generic platitudes ("test your code", "be careful with X")
18
+ - Anything already preserved via the agent's explicit calls (see below)
19
+
20
+ ## Already preserved by the agent — DO NOT re-extract
21
+
22
+ {{ALREADY_PRESERVED}}
23
+
24
+ ## Session metadata
25
+
26
+ - Harness: {{HARNESS}}
27
+ - Title: {{TITLE}}
28
+ - Started: {{STARTED_AT}}
29
+ - Ended: {{ENDED_AT}}
30
+ - Project hint: {{PROJECT_HINT}}
31
+
32
+ ## Filtered session transcript
33
+
34
+ The transcript below has already had read-only `akm` meta-ops and platform boilerplate stripped. Only content that might carry signal remains.
35
+
36
+ {{TRANSCRIPT}}
37
+
38
+ ## Output contract
39
+
40
+ Respond with EXACTLY one JSON object matching this shape:
41
+
42
+ ```
43
+ {
44
+ "candidates": [
45
+ {
46
+ "type": "memory" | "lesson" | "knowledge",
47
+ "name": "<kebab-case-slug>",
48
+ "description": "<one sentence 20-400 chars>",
49
+ "when_to_use": "<one sentence 15-400 chars; REQUIRED only when type=lesson>",
50
+ "body": "<markdown body, 200-3000 chars typical>",
51
+ "confidence": <number 0.0-1.0>,
52
+ "evidence": "<one-line pointer to the moment in the session>"
53
+ }
54
+ ],
55
+ "rationale_if_empty": "<one sentence; REQUIRED when candidates is empty>"
56
+ }
57
+ ```
58
+
59
+ ## Rules
60
+
61
+ 1. **Zero candidates is a valid and frequent answer.** Most sessions yield no new durable insight. When that's the case, return `{"candidates": [], "rationale_if_empty": "..."}` explaining what you saw and why it didn't rise to durable-knowledge level. Do not fabricate.
62
+
63
+ 2. **Pick the right type per candidate:**
64
+ - `memory` — a fact or short observation. Use for "X works on this codebase", "auth uses Y library version Z".
65
+ - `lesson` — a "do X / avoid Y" pattern, ALWAYS with `when_to_use`. Use for hard-won learnings about pitfalls, recovery patterns, or non-obvious gotchas.
66
+ - `knowledge` — substantive multi-section reference doc. Rare from one session.
67
+
68
+ 3. **Calibrate `confidence` honestly:**
69
+ - `0.9+` — high certainty this is a real durable insight a reviewer would clearly accept
70
+ - `0.7-0.89` — clear improvement, but a reviewer might prefer different framing or scope
71
+ - `0.5-0.69` — marginal / judgment call
72
+ - `<0.5` — don't include; prefer fewer-but-better candidates
73
+
74
+ 4. **`evidence` must reference the session** — a brief pointer like "agent's tool failure at ts=...", "user's correction at ...", "after the recovery in the Bash sequence around ...". Without evidence the candidate is hard to validate; default to lower confidence when evidence is vague.
75
+
76
+ 5. **Do not duplicate already-preserved content.** If a candidate substantively overlaps with anything in the "Already preserved" list above, skip it.
77
+
78
+ 6. **No speculation.** Only extract things the session genuinely demonstrates. If the agent struggled and didn't resolve, that may itself be a lesson (`when_to_use: "When attempting X, expect Y to fail"`) — but only if the failure mode is concrete enough to be useful next time.
79
+
80
+ 7. Respond with the JSON object only. No prose before or after. No code fences.
@@ -8,5 +8,28 @@ Rules:
8
8
  - Drop pleasantries, meta-commentary, and timestamps.
9
9
  - Limit to at most {{MAX_ENTITIES}} entities and {{MAX_RELATIONS}} relations per asset.
10
10
  - Return {"entities": [], "relations": []} if the body has no extractable graph content.
11
+ - DO NOT return markdown code blocks, ONLY valid JSON objects.
12
+
13
+ Examples:
14
+
15
+ Input:
16
+ ## Deployment Notes
17
+ The auth-service uses PostgreSQL for user sessions. It depends on the redis-cache
18
+ for rate limiting. The terraform-provisioner deploys everything to the prod cluster.
19
+ Owner: @alice.
20
+
21
+ Output:
22
+ {"entities":["auth-service","PostgreSQL","redis-cache","terraform-provisioner","prod cluster","@alice"],"relations":[{"from":"auth-service","to":"PostgreSQL","type":"uses"},{"from":"auth-service","to":"redis-cache","type":"depends on"},{"from":"terraform-provisioner","to":"prod cluster","type":"deploys"},{"from":"terraform-provisioner","to":"auth-service","type":"deploys"},{"from":"@alice","to":"auth-service","type":"owns"}]}
23
+
24
+ Input:
25
+ ## Meeting: API Redesign
26
+ Discussed moving from REST to GraphQL. The frontend team will use Apollo Client.
27
+ Backend needs to implement resolvers. Timeline: Q2.
28
+
29
+ Output:
30
+ {"entities":["REST","GraphQL","Apollo Client","frontend team","backend","resolvers","Q2"],"relations":[{"from":"frontend team","to":"Apollo Client","type":"uses"},{"from":"backend","to":"resolvers","type":"implements"},{"from":"frontend team","to":"GraphQL","type":"migrates to"}]}
31
+
32
+ ===============
33
+
34
+ Request:
11
35
 
12
- Asset body:
@@ -16,12 +16,13 @@ akm search "<query>" --detail full # Include scores, paths, timing
16
16
 
17
17
  | Flag | Values | Default |
18
18
  | --- | --- | --- |
19
- | `--type` | `skill`, `command`, `agent`, `knowledge`, `workflow`, `script`, `memory`, `vault`, `wiki`, `any` | `any` |
19
+ | `--type` | `skill`, `command`, `agent`, `knowledge`, `workflow`, `script`, `memory`, `env`, `secret`, `wiki`, `any` | `any` |
20
20
  | `--source` | `stash`, `registry`, `both` | `stash` |
21
21
  | `--limit` | number | `20` |
22
22
  | `--format` | `json`, `jsonl`, `text`, `yaml` | `json` |
23
- | `--detail` | `brief`, `normal`, `full`, `summary`, `agent` | `brief` |
24
- | `--for-agent` | boolean (deprecated use `--detail agent`) | `false` |
23
+ | `--detail` | `brief`, `normal`, `full` | `brief` |
24
+ | `--shape` | `human`, `agent`, `summary` (`summary` only on `show`) | `human` |
25
+ | `--for-agent` | boolean (deprecated — use `--shape agent`) | `false` |
25
26
 
26
27
  ## Curate
27
28
 
@@ -59,7 +60,7 @@ akm show knowledge:my-doc # Show content (local or remote)
59
60
  | workflow | `workflowTitle`, `workflowParameters`, `steps` |
60
61
  | memory | `content` (recalled context) |
61
62
  | vault | `keys`, `comments` |
62
- | wiki | `content` (same view modes as knowledge). For any wiki task, run `akm wiki list` then `akm wiki ingest <name>` for the workflow. |
63
+ | wiki | `content` (same view modes as knowledge). For any wiki task, run `akm wiki list`. To ingest sources, `akm wiki ingest <name>` dispatches the configured agent (defaults.agent or `--profile`) to execute the ingest workflow. |
63
64
 
64
65
  ## Capture Knowledge While You Work
65
66
 
@@ -102,13 +103,17 @@ akm wiki stash research https://example.com/paper # Fetch one URL into raw/<slug
102
103
  akm wiki stash research ./paper.md --target my-stash # Route write to a named writable stash source
103
104
  echo "..." | akm wiki stash research - # stdin form
104
105
  akm wiki lint research # Structural checks: orphans, broken xrefs, uncited raws, stale index
105
- akm wiki ingest research # Print the ingest workflow for this wiki (no action)
106
- akm wiki remove research --force # Delete pages/schema/index/log; preserves raw/
107
- akm wiki remove research --force --with-sources # Full nuke, including raw/
106
+ akm wiki ingest research # Dispatch defaults.agent to run the ingest workflow on this wiki
107
+ akm wiki ingest research --profile claude --model sonnet # Override profile and model
108
+ akm wiki ingest research --timeout-ms 600000 # Override agent CLI timeout (default: profile setting)
109
+ akm wiki remove research -y # Delete pages/schema/index/log; preserves raw/ (--force is a deprecated alias for -y)
110
+ akm wiki remove research -y --with-sources # Full nuke, including raw/
108
111
  ```
109
112
 
110
- **For any wiki task, start with `akm wiki list`, then `akm wiki ingest <name>`
111
- to get the step-by-step workflow.** Wiki pages are also addressable as
113
+ **For any wiki task, start with `akm wiki list`. Then `akm wiki ingest <name>`
114
+ dispatches the configured agent (defaults.agent or `--profile`) to execute
115
+ the wiki's ingest workflow end-to-end — schema read, source dedup, search,
116
+ page create/update, log entry, lint, reindex.** Wiki pages are also addressable as
112
117
  `wiki:<name>/<page-path>` and show up in stash-wide `akm search` as
113
118
  `type: wiki`. Files under `raw/` and the wiki root infrastructure files
114
119
  `schema.md`, `index.md`, and `log.md` are not indexed and do not appear in
@@ -163,23 +168,40 @@ akm clone "npm:@scope/pkg//script:deploy.sh" # Clone from remote package
163
168
 
164
169
  When `--dest` is provided, `akm init` is not required first.
165
170
 
166
- ## Save
171
+ ## Sync
167
172
 
168
- Commit local changes in a git-backed stash. Behaviour adapts automatically:
173
+ Commit local changes in a git-backed stash. Behaviour adapts automatically.
174
+ (`akm save` is the deprecated 0.7 spelling — it still works but warns; removed
175
+ in 0.9.0.)
169
176
 
170
- - **Not a git repo** — no-op (silent skip)
177
+ - **No `.git` directory** — no-op (silent skip)
171
178
  - **Git repo, no remote** — stage and commit only (the default stash always falls here)
172
179
  - **Git repo, has remote, not writable** — stage and commit only
173
180
  - **Git repo, has remote, `writable: true`** — stage, commit, and push
181
+ - **Any writable repo with `--no-push`** — stage and commit only
174
182
 
175
183
  ```sh
176
- akm save # Save primary stash (timestamp message)
177
- akm save -m "Add deploy skill" # Save with explicit message
178
- akm save my-skills # Save a named writable git stash
179
- akm save my-skills -m "Update patterns" # Save named stash with message
184
+ akm sync # Sync primary stash (timestamp message)
185
+ akm sync -m "Add deploy skill" # Sync with explicit message
186
+ akm sync --no-push # Commit only; never push
187
+ akm sync my-skills # Sync a named writable git stash
188
+ akm sync my-skills -m "Update patterns" # Sync named stash with message
180
189
  ```
181
190
 
182
- The `--writable` flag on `akm add` opts a remote git stash into push-on-save:
191
+ `akm improve` also performs an end-of-run batch commit for git-backed stashes.
192
+ The `--sync` / `--no-sync` and `--push` / `--no-push` flags control this:
193
+
194
+ ```sh
195
+ akm improve # auto-sync per profile default (default/thorough: on; quick/memory-focus: off)
196
+ akm improve --no-sync # skip the end-of-run commit
197
+ akm improve --no-push # commit but skip push for this run
198
+ akm improve --sync # force sync even on profiles that disable it
199
+ ```
200
+
201
+ Profile sync defaults: `default` and `thorough` auto-commit + push; `quick` and
202
+ `memory-focus` skip sync entirely. Override with `--sync` / `--no-sync` flags.
203
+
204
+ The `--writable` flag on `akm add` opts a remote git stash into push-on-sync:
183
205
 
184
206
  ```sh
185
207
  akm add git@github.com:org/skills.git --provider git --name my-skills --writable
@@ -193,8 +215,8 @@ akm add @scope/stash # From npm (managed)
193
215
  akm add owner/repo # From GitHub (managed)
194
216
  akm add ./path/to/local/stash # Local directory
195
217
  akm add git@github.com:org/repo.git --provider git --name my-skills --writable
196
- akm enable skills.sh # Enable the skills.sh registry
197
- akm disable skills.sh # Disable the skills.sh registry
218
+ akm config enable skills.sh # Enable the skills.sh registry
219
+ akm config disable skills.sh # Disable the skills.sh registry
198
220
  akm list # List all sources
199
221
  akm list --kind managed # List managed sources only
200
222
  akm remove <target> # Remove by id, ref, path, or name
@@ -244,24 +266,29 @@ akm completions --install # Install completions
244
266
  ## Proposals & Improvement (0.8.0+)
245
267
 
246
268
  ```sh
247
- akm improve <ref> # Propose improvement for an asset
248
- akm proposals # List pending proposals
249
- akm show proposal <id> # Render the proposal body
250
- akm diff <ref-or-id> # Diff by ref, UUID, or 8-char prefix (proposal positional optional)
251
- akm diff skill:akm-dream # Diff by asset ref
252
- akm accept 7c115132 # Accept by UUID prefix
253
- akm accept <id> --target team-stash # Accept to a named writable stash source
254
- akm reject skill:my-skill --reason "not ready" # Reject by asset ref
255
- akm reject <id> --reason "..." # Archive with a reason
269
+ akm improve <ref> # Propose improvement for an asset
270
+ akm proposal list # List pending proposals
271
+ akm proposal show <id> # Render the proposal body
272
+ akm proposal diff <ref-or-id> # Diff by ref, UUID, or 8-char prefix
273
+ akm proposal diff skill:akm-dream # Diff by asset ref
274
+ akm proposal accept 7c115132 # Accept by UUID prefix
275
+ akm proposal accept <id> --target team-stash # Accept to a named writable stash source
276
+ akm proposal reject skill:my-skill --reason "not ready" # Reject by asset ref
277
+ akm proposal reject <id> --reason "..." # Archive with a reason
278
+ akm proposal revert <id> # Restore the pre-promotion content
256
279
  ```
257
280
 
281
+ The flat verbs `akm proposals` / `akm show proposal` / `akm accept` /
282
+ `akm reject` / `akm diff` / `akm revert` still work as deprecated aliases
283
+ (warn on stderr; removed in 0.9.0).
284
+
258
285
  Per-task `timeoutMs`: task markdown frontmatter may set `timeoutMs: null` to
259
286
  disable the agent kill timer for long-running local-model tasks, or a number
260
287
  (milliseconds) to override `config.agent.timeoutMs` for that task only.
261
288
 
262
289
  ## Output Control
263
290
 
264
- All commands accept `--format` and `--detail` flags:
291
+ All commands accept `--format`, `--detail`, and `--shape` flags:
265
292
 
266
293
  - `--format json` (default) — structured JSON
267
294
  - `--format jsonl` — one JSON object per line (streaming-friendly)
@@ -270,8 +297,9 @@ All commands accept `--format` and `--detail` flags:
270
297
  - `--detail brief` (default) — compact output
271
298
  - `--detail normal` — adds tags, refs, origins
272
299
  - `--detail full` — includes scores, paths, timing, debug info
273
- - `--detail summary` — metadata only (no content/template/prompt), under 200 tokens
274
- - `--detail agent` — agent-optimized output: strips non-actionable fields
275
- - `--for-agent` — deprecated alias for `--detail agent`
300
+ - `--shape human` (default) standard projection
301
+ - `--shape agent` — agent-optimized output: strips non-actionable fields
302
+ - `--shape summary` — metadata only (no content/template/prompt), under 200 tokens; only valid on `akm show`
303
+ - `--for-agent` — deprecated alias for `--shape agent` (removed 0.9.0)
276
304
 
277
305
  Run `akm -h` or `akm <command> -h` for per-command help.
@@ -33,15 +33,17 @@ akm remember "note" --target my-stash # Route write to a named writable
33
33
  akm import ./notes/release-checklist.md # Import a knowledge doc into your stash
34
34
  akm import ./doc.md --target my-stash # Route import to a named writable stash source
35
35
  akm wiki list # List available wikis
36
- akm wiki ingest <name> # Print the ingest workflow for a wiki
36
+ akm wiki ingest <name> # Dispatch an agent to run the ingest workflow (uses defaults.agent or --profile)
37
37
  akm wiki stash <name> ./paper.md --target my-stash # Route wiki stash write to a named source
38
- akm diff skill:akm-dream # Diff proposal by ref, UUID, or 8-char prefix
39
- akm accept 7c115132 # Accept by UUID prefix (proposal positional optional)
40
- akm reject skill:my-skill --reason "..." # Reject by ref (proposal positional optional)
38
+ akm proposal diff skill:akm-dream # Diff proposal by ref, UUID, or 8-char prefix
39
+ akm proposal accept 7c115132 # Accept by UUID prefix
40
+ akm proposal reject skill:my-skill --reason "..." # Reject by ref
41
41
  akm feedback <ref> --positive|--negative # Record whether an asset helped
42
42
  akm add <ref> # Add a source (npm, GitHub, git, local dir)
43
43
  akm clone <ref> # Copy an asset to the working stash (optional --dest arg to clone to specific location)
44
- akm save # Commit (and push if writable remote) changes in the primary stash
44
+ akm sync # Commit (and push if writable remote) changes in the primary stash (--no-push to commit only)
45
+ akm improve --no-sync # Run improve without the end-of-run auto-commit
46
+ akm improve --no-push # Auto-commit but skip push for this run
45
47
  akm registry search "<query>" # Search all registries
46
48
  ```
47
49
 
@@ -56,8 +58,9 @@ akm registry search "<query>" # Search all registries
56
58
  | knowledge | A reference doc (use `toc` or `section "..."` to navigate) |
57
59
  | workflow | Parsed steps plus workflow-specific execution commands |
58
60
  | memory | Recalled context (read the content for background information) |
59
- | vault | Key names only; use `akm vault path` or `akm vault run` to use values safely |
60
- | wiki | A page in a multi-wiki knowledge base. For any wiki task, start with `akm wiki list`, then `akm wiki ingest <name>` for the workflow. Run `akm wiki -h` for the full surface. |
61
+ | env | A `.env` file of related CONFIGURATION (many vars; sensitive or not — all protected); key names only. Inject with `akm env run <ref> -- <cmd>` (the agent-safe path values stay on disk). `vault` is the deprecated alias. |
62
+ | secret | A single sensitive value for AUTHENTICATION (token, key, cert); name only. Use `akm secret path` / `akm secret run`. |
63
+ | wiki | A page in a multi-wiki knowledge base. For any wiki task, start with `akm wiki list`. To ingest sources, run `akm wiki ingest <name>` — it dispatches the configured agent profile to execute the ingest workflow against the wiki's `raw/` directory. Run `akm wiki -h` for the full surface. |
61
64
 
62
65
  When an asset meaningfully helps or fails, record that with `akm feedback` so
63
66
  future search ranking can learn from real usage.
@@ -1,11 +1,14 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
1
4
  /**
2
5
  * Embedded "agent CLI hints" rendered by `akm hints` when no other source
3
6
  * is available.
4
7
  *
5
8
  * Extracted from `src/cli.ts` so it does not bloat the CLI module and so
6
9
  * docs/CI tooling can re-use the same constants. Two flavors:
7
- * `EMBEDDED_HINTS` (default reference, ~40 lines) and
8
- * `EMBEDDED_HINTS_FULL` (`--detail full`, ~250 lines).
10
+ * `EMBEDDED_HINTS` (`--detail brief`, short reference, ~40 lines) and
11
+ * `EMBEDDED_HINTS_FULL` (`--detail normal|full`, ~250 lines).
9
12
  */
10
13
  import EMBEDDED_HINTS_FULL from "./cli-hints-full.md" with { type: "text" };
11
14
  import EMBEDDED_HINTS from "./cli-hints-short.md" with { type: "text" };
@@ -1,7 +1,10 @@
1
+ // This Source Code Form is subject to the terms of the Mozilla Public
2
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
3
+ // file, You can obtain one at https://mozilla.org/MPL/2.0/.
1
4
  /**
2
5
  * Process-level output mode singleton.
3
6
  *
4
- * Output mode (format + detail + forAgent) is parsed once at startup from
7
+ * Output mode (format + detail + shape) is parsed once at startup from
5
8
  * `process.argv` and the persisted user config. All subsequent `output()`
6
9
  * calls read from this in-memory singleton instead of re-scanning argv and
7
10
  * re-loading config on every call.
@@ -9,8 +12,9 @@
9
12
  * Initialized from `cli.ts` before `runMain`.
10
13
  */
11
14
  import { UsageError } from "../core/errors";
12
- export const OUTPUT_FORMATS = ["json", "yaml", "text", "jsonl"];
13
- export const DETAIL_LEVELS = ["brief", "normal", "full", "summary", "agent"];
15
+ export const OUTPUT_FORMATS = ["json", "yaml", "text", "jsonl", "md"];
16
+ export const DETAIL_LEVELS = ["brief", "normal", "full"];
17
+ export const SHAPE_MODES = ["human", "agent", "summary"];
14
18
  export function parseOutputFormat(value) {
15
19
  if (!value)
16
20
  return undefined;
@@ -25,6 +29,13 @@ export function parseDetailLevel(value) {
25
29
  return value;
26
30
  throw new UsageError(`Invalid value for --detail: ${value}. Expected one of: ${DETAIL_LEVELS.join("|")}`, "INVALID_DETAIL_VALUE");
27
31
  }
32
+ export function parseShapeMode(value) {
33
+ if (!value)
34
+ return undefined;
35
+ if (SHAPE_MODES.includes(value))
36
+ return value;
37
+ throw new UsageError(`Invalid value for --shape: ${value}. Expected one of: ${SHAPE_MODES.join("|")}`, "INVALID_SHAPE_VALUE");
38
+ }
28
39
  export function parseFlagValue(argv, flag) {
29
40
  for (let i = 0; i < argv.length; i++) {
30
41
  const arg = argv[i];
@@ -62,11 +73,52 @@ export function getHyphenatedBoolean(args, key) {
62
73
  */
63
74
  export function resolveOutputMode(argv, defaults = {}) {
64
75
  const format = parseOutputFormat(parseFlagValue(argv, "--format")) ?? defaults?.format ?? "json";
65
- const detail = parseDetailLevel(parseFlagValue(argv, "--detail")) ?? defaults?.detail ?? "brief";
66
- // `--detail=agent` is the preferred preset. `--for-agent` is kept for one
67
- // release cycle as an alias so existing scripts and docs keep working.
68
- const forAgent = detail === "agent" || hasBooleanFlag(argv, "--for-agent");
69
- return { format, detail, forAgent };
76
+ const rawDetail = parseFlagValue(argv, "--detail");
77
+ const rawShape = parseFlagValue(argv, "--shape");
78
+ const usedForAgent = hasBooleanFlag(argv, "--for-agent");
79
+ // Back-compat: the projection presets `summary`/`agent` used to live on
80
+ // `--detail`. They moved to `--shape` in 0.8 (removed from `--detail` in
81
+ // 0.9.0). Map the legacy spellings onto `--shape` + warn, and treat the
82
+ // verbosity axis as `normal` (the prior effective behaviour).
83
+ let detailForVerbosity = rawDetail;
84
+ let shapeFromLegacyDetail;
85
+ if (rawDetail === "summary" || rawDetail === "agent") {
86
+ // Only nudge toward `--shape` when the caller did not already pass an
87
+ // explicit `--shape` (which wins below). Otherwise the "use --shape <x>"
88
+ // advice would name a projection the caller did not request.
89
+ if (rawShape === undefined)
90
+ emitDetailShapeDeprecation(rawDetail);
91
+ shapeFromLegacyDetail = rawDetail;
92
+ detailForVerbosity = "normal";
93
+ }
94
+ else if (rawDetail === "per-run") {
95
+ // Legacy `akm health --detail per-run` (→ `--group-by run`). The health
96
+ // command owns the back-compat warning + mapping; the global singleton must
97
+ // not reject the value here, so fall through to the default verbosity.
98
+ detailForVerbosity = undefined;
99
+ }
100
+ if (usedForAgent) {
101
+ emitForAgentDeprecation();
102
+ }
103
+ const detail = parseDetailLevel(detailForVerbosity) ?? defaults?.detail ?? "brief";
104
+ // Precedence: explicit `--shape` wins; then legacy `--detail summary|agent`;
105
+ // then legacy `--for-agent`; default `human`.
106
+ const shape = parseShapeMode(rawShape) ?? shapeFromLegacyDetail ?? (usedForAgent ? "agent" : "human");
107
+ return { format, detail, shape, forAgent: shape === "agent" };
108
+ }
109
+ /** Suppress deprecation warnings under `--quiet` (mirrors the rest of the CLI). */
110
+ function isQuietArgv() {
111
+ return process.argv.includes("--quiet") || process.argv.includes("-q");
112
+ }
113
+ function emitDetailShapeDeprecation(value) {
114
+ if (isQuietArgv())
115
+ return;
116
+ process.stderr.write(`warning: '--detail ${value}' is deprecated; use '--shape ${value}'. Removed in 0.9.0.\n`);
117
+ }
118
+ function emitForAgentDeprecation() {
119
+ if (isQuietArgv())
120
+ return;
121
+ process.stderr.write("warning: '--for-agent' is deprecated; use '--shape agent'. Removed in 0.9.0.\n");
70
122
  }
71
123
  let _mode;
72
124
  /**