akm-cli 0.9.0 → 0.9.1-beta.2

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 (140) hide show
  1. package/CHANGELOG.md +724 -0
  2. package/README.md +28 -63
  3. package/STABILITY.md +4 -2
  4. package/dist/cli/parse-args.js +7 -1
  5. package/dist/commands/agent/contribute-cli.js +1 -1
  6. package/dist/commands/env/child-env.js +14 -0
  7. package/dist/commands/feedback-cli.js +7 -1
  8. package/dist/commands/health/llm-usage.js +2 -1
  9. package/dist/commands/health/surfaces.js +4 -77
  10. package/dist/commands/health.js +65 -11
  11. package/dist/commands/improve/distill/quality-gate.js +6 -1
  12. package/dist/commands/improve/eligibility.js +7 -1
  13. package/dist/commands/improve/eval-cases.js +2 -0
  14. package/dist/commands/improve/improve.js +126 -10
  15. package/dist/commands/improve/locks.js +7 -0
  16. package/dist/commands/improve/memory/memory-improve.js +9 -0
  17. package/dist/commands/improve/run-context.js +5 -0
  18. package/dist/commands/improve/session-asset.js +4 -0
  19. package/dist/commands/lint/base-linter.js +31 -7
  20. package/dist/commands/lint/index.js +205 -51
  21. package/dist/commands/lint/types.js +22 -1
  22. package/dist/commands/proposal/repository.js +17 -1
  23. package/dist/commands/sources/add-cli.js +8 -2
  24. package/dist/commands/sources/info.js +12 -2
  25. package/dist/commands/sources/installed-stashes.js +6 -1
  26. package/dist/commands/sources/migration-help.js +12 -3
  27. package/dist/commands/sources/self-update.js +9 -1
  28. package/dist/commands/tasks/tasks.js +8 -2
  29. package/dist/commands/workflow-cli.js +17 -11
  30. package/dist/core/abort-deadline.js +28 -0
  31. package/dist/core/adapter/adapters/agent-skills-adapter.js +83 -5
  32. package/dist/core/adapter/adapters/akm-adapter.js +13 -10
  33. package/dist/core/adapter/adapters/akm-lint.js +78 -22
  34. package/dist/core/adapter/adapters/akm-task-adapter.js +43 -20
  35. package/dist/core/adapter/adapters/dotenv-adapter.js +21 -0
  36. package/dist/core/adapter/adapters/tool-dir-shared.js +5 -3
  37. package/dist/core/asset/frontmatter.js +10 -1
  38. package/dist/core/common.js +147 -9
  39. package/dist/core/concurrent.js +32 -0
  40. package/dist/core/config/config-io.js +5 -45
  41. package/dist/core/config/schema/engines.js +14 -3
  42. package/dist/core/config/schema/workflow.js +11 -0
  43. package/dist/core/errors.js +25 -0
  44. package/dist/core/events.js +30 -24
  45. package/dist/core/extra-params.js +11 -0
  46. package/dist/core/file-lock.js +7 -1
  47. package/dist/core/fs-txn.js +15 -2
  48. package/dist/core/improve-result.js +5 -0
  49. package/dist/core/json-schema.js +344 -9
  50. package/dist/core/loopback.js +89 -0
  51. package/dist/core/migration-operation.js +17 -2
  52. package/dist/core/path-access.js +107 -0
  53. package/dist/core/paths.js +16 -2
  54. package/dist/core/redaction.js +86 -18
  55. package/dist/core/spawn-env.js +234 -0
  56. package/dist/core/state-db-scope.js +134 -0
  57. package/dist/core/state-db.js +1 -0
  58. package/dist/core/subprocess.js +181 -37
  59. package/dist/core/write-provenance.js +85 -0
  60. package/dist/core/write-source.js +33 -2
  61. package/dist/indexer/db/graph-db.js +17 -6
  62. package/dist/indexer/ensure-index.js +10 -3
  63. package/dist/indexer/index-written-assets.js +17 -2
  64. package/dist/indexer/indexer.js +86 -21
  65. package/dist/indexer/passes/memory-inference.js +4 -0
  66. package/dist/indexer/search/db-search.js +25 -17
  67. package/dist/indexer/walk/walker.js +6 -1
  68. package/dist/integrations/agent/detect.js +13 -1
  69. package/dist/integrations/agent/engine-resolution.js +24 -11
  70. package/dist/integrations/agent/model-aliases.js +1 -1
  71. package/dist/integrations/agent/profiles.js +9 -1
  72. package/dist/integrations/agent/spawn.js +15 -87
  73. package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +21 -0
  74. package/dist/integrations/lockfile.js +55 -2
  75. package/dist/llm/client.js +14 -19
  76. package/dist/llm/embedder.js +23 -3
  77. package/dist/llm/embedders/remote.js +27 -2
  78. package/dist/output/html-render.js +40 -1
  79. package/dist/output/text/lint-format.js +17 -4
  80. package/dist/runtime.js +23 -1
  81. package/dist/scripts/akm-migrate-node.js +1714 -836
  82. package/dist/scripts/akm-migrate.js +1682 -804
  83. package/dist/setup/setup.js +22 -7
  84. package/dist/sources/providers/git-install.js +25 -2
  85. package/dist/sources/providers/git-stash.js +19 -0
  86. package/dist/sources/providers/git.js +1 -1
  87. package/dist/sources/snapshot-fetchers/content-extract.js +63 -1
  88. package/dist/sources/snapshot-fetchers/website-ingest.js +126 -20
  89. package/dist/storage/database.js +71 -7
  90. package/dist/storage/engines/sqlite-migrations.js +61 -2
  91. package/dist/storage/managed-db.js +19 -0
  92. package/dist/storage/repositories/index-connection.js +39 -4
  93. package/dist/storage/repositories/index-entries-repository.js +6 -1
  94. package/dist/storage/repositories/index-meta-repository.js +11 -0
  95. package/dist/storage/repositories/index-schema.js +17 -2
  96. package/dist/storage/repositories/index-vec-repository.js +43 -5
  97. package/dist/storage/repositories/workflow-runs-repository.js +66 -13
  98. package/dist/storage/sqlite-pragmas.js +12 -1
  99. package/dist/tasks/log-redaction.js +156 -0
  100. package/dist/tasks/parser.js +82 -5
  101. package/dist/tasks/runner.js +222 -17
  102. package/dist/tasks/scheduler-invocation.js +19 -0
  103. package/dist/tasks/schema.js +86 -1
  104. package/dist/text-import-hook.mjs +1 -1
  105. package/dist/workflows/concurrency-policy.js +95 -1
  106. package/dist/workflows/exec/dispatch-redaction.js +114 -0
  107. package/dist/workflows/exec/exec-unit.js +542 -0
  108. package/dist/workflows/exec/frozen-judge.js +114 -42
  109. package/dist/workflows/exec/native-executor.js +465 -238
  110. package/dist/workflows/exec/param-secrets.js +4 -3
  111. package/dist/workflows/exec/run-workflow.js +424 -219
  112. package/dist/workflows/exec/step-work.js +506 -167
  113. package/dist/workflows/exec/unit-dispatch.js +31 -1
  114. package/dist/workflows/exec/unit-writer.js +53 -13
  115. package/dist/workflows/exec/worktree.js +454 -41
  116. package/dist/workflows/ir/compile.js +26 -2
  117. package/dist/workflows/ir/freeze.js +82 -15
  118. package/dist/workflows/ir/schema.js +105 -20
  119. package/dist/workflows/parser.js +242 -19
  120. package/dist/workflows/program/schema.js +24 -0
  121. package/dist/workflows/renderer.js +32 -4
  122. package/dist/workflows/resource-limits.js +182 -0
  123. package/dist/workflows/runtime/runs.js +146 -6
  124. package/dist/workflows/validate-summary.js +17 -2
  125. package/docs/README.md +74 -32
  126. package/docs/migration/release-notes/0.9.0.md +2 -1
  127. package/docs/migration/v0.7-to-v0.8.md +2 -1
  128. package/docs/migration/v0.8-to-v0.9.md +3 -1
  129. package/docs/reference/README.md +11 -4
  130. package/docs/reference/bundle-types.md +19 -0
  131. package/docs/reference/cli.md +105 -16
  132. package/docs/reference/configuration.md +15 -2
  133. package/docs/reference/data-and-telemetry.md +30 -10
  134. package/docs/reference/supported-formats.md +50 -0
  135. package/docs/reference/workflow-schema.md +1014 -0
  136. package/docs/reference/workflows.md +37 -633
  137. package/package.json +13 -6
  138. package/schemas/akm-config.json +18 -5
  139. package/schemas/akm-task.json +27 -5
  140. package/schemas/akm-workflow.json +92 -13
@@ -7,7 +7,9 @@ different presentation. Errors include `error` and `hint` fields.
7
7
 
8
8
  This page is authoritative for the current CLI. For per-release behavior
9
9
  changes, see [`CHANGELOG.md`](../../CHANGELOG.md) and
10
- [`docs/migration/`](../migration/).
10
+ [`docs/migration/`](../migration/). For the bundle formats akm recognizes
11
+ (detection, ref shapes, indexing, validation, read/write), see
12
+ [Bundle Types](bundle-types.md).
11
13
 
12
14
  ## Global Flags
13
15
 
@@ -356,7 +358,7 @@ tip names the conceptId spelling that replaces it.
356
358
 
357
359
  | Flag | Values | Default | Description |
358
360
  | --- | --- | --- | --- |
359
- | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter by asset type. Free-form and unvalidated — an unknown type returns no hits. Also accepts any adapter-defined type (e.g. `website`). |
361
+ | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter by asset type. Free-form and unvalidated — an unknown type returns no hits. Also accepts any adapter-defined type (e.g. `website`) — see [Bundle Types](bundle-types.md) for the open types each adapter emits. |
360
362
  | `--limit` | number | `20` | Maximum results |
361
363
  | `--from` | `local`, `registry`, `all` | `local` | Where to search |
362
364
  | `--assets` | flag | `false` | Include asset-level registry results (only meaningful with `--from registry\|all`; folds in the retired `akm registry search --assets`) |
@@ -525,7 +527,7 @@ Returns type-specific payloads:
525
527
  | command | `template`, `description` |
526
528
  | agent | `prompt`, `description`, `modelHint` |
527
529
  | knowledge | `content` — the whole document, or one section via `#fragment` |
528
- | workflow | `workflowTitle`, `workflowParameters`, `steps` |
530
+ | workflow | `workflowTitle`, `workflowParameters`, `steps` (each step's `orchestration` summary names its engine/model, or — for an [exec step](https://github.com/itlackey/akm/blob/main/docs/reference/workflow-schema.md#what-akm-show-reports-for-an-exec-step) — its `exec.command` and no engine at all) |
529
531
  | memory | `content` |
530
532
  | env | `keys` (key names only — values and comment text never returned) |
531
533
  | lesson | `content` plus `when_to_use` surfaced from frontmatter |
@@ -607,15 +609,34 @@ The old `--params <json>` bag is removed.
607
609
 
608
610
  | Flag | Description |
609
611
  | --- | --- |
610
- | `--max-steps <n>` | Stop after executing at most this many steps, leaving a partial run active. Must be at least 1. |
612
+ | `--max-steps <n>` | Stop once this many steps have finished, leaving a partial run active. Must be at least 1. |
611
613
  | `--max-retries <n>` | When a step fails, reopen the same run and retry the failed step up to this many additional times. Range: 0 through 100; default 0. Gate rejection and interruption are not retried. |
612
614
  | `--timeout <duration>` | Abort the whole invocation after `N`, `Nms`, `Ns`, or `Nm`; bare `N` is milliseconds. The active step remains resumable. |
613
615
 
614
- The result includes the current `run`, an `executed` step report list, and
615
- optional `done`, `gateRejection`, `aborted`, or `timedOut` markers. A failed
616
- run, rejected verification gate, timeout, or interrupt exits nonzero. `SIGINT`
617
- and `SIGTERM` map to 130 and 143; a timeout maps to exit 1. Reaching
618
- `--max-steps` with an active resumable run is successful.
616
+ The result includes the current `run`, an `executed` step report list, a
617
+ `stepsProcessed` count of the steps that finished, and optional `done`,
618
+ `gateRejection`, `aborted`, or `timedOut` markers. A failed run, rejected
619
+ verification gate, timeout, or interrupt exits nonzero. `SIGINT` and `SIGTERM`
620
+ map to 130 and 143; a timeout maps to exit 1. Reaching `--max-steps` with an
621
+ active resumable run is successful. A `--timeout` that lands during the run's
622
+ final bookkeeping is not reported as a timeout: a run that reached `completed`
623
+ has nothing left to abort and nothing left to resume.
624
+
625
+ **What `--max-steps` counts.** The budget is spent by the **steps that
626
+ finish** — completed, failed, or gate-rejected with the loop budget spent — not
627
+ by entries in the `executed` report, which gains one per gate-loop iteration
628
+ and one per route-skip. So a step's whole bounded `gate.max_loops` loop costs
629
+ one, a route-skipped step costs nothing (no work was dispatched for it), and a
630
+ step the invocation left unfinished — an abort, a verification-judge outage —
631
+ costs nothing either, because the next invocation still owes that work.
632
+ `--max-retries` subtracts the same way: a reopened run's remaining budget is
633
+ not shrunk by loops or skips.
634
+
635
+ The budget is checked **between** steps, so it does not bound what any single
636
+ step dispatches — a step's gate loop runs to its own limit no matter how little
637
+ budget is left. `gate.max_loops` (1–100) is the per-step ceiling;
638
+ `budget.max_units` and `budget.max_tokens` are the whole-run ceilings, seeded
639
+ from the unit journal so they hold across resumes.
619
640
 
620
641
  `run` is Stable and does not consult `experimental.workflowEngine`. Every
621
642
  non-empty `### gate` requires `workflow.judgeEngine` to name a configured LLM
@@ -716,6 +737,10 @@ sources. Other HTTP(S) URLs are crawled as website sources.
716
737
  ### bundle add
717
738
 
718
739
  Add a source — a local directory, npm package, GitHub repo, git URL, or website.
740
+ akm detects the bundle's **format** automatically (its own native workspace,
741
+ a Claude Code or OpenCode tool directory, an OKF or LLM-wiki knowledge base,
742
+ …) — see [Bundle Types](bundle-types.md) for how detection works and what
743
+ each format gives you.
719
744
 
720
745
  ```sh
721
746
  akm bundle add ~/.claude/skills # Local directory
@@ -775,7 +800,7 @@ akm bundle add github:owner/repo-with-sensitive-env
775
800
  akm bundle add github:owner/repo-with-sensitive-env --allow-insecure
776
801
  ```
777
802
 
778
- Bundle publishers: see the [Stash Maker's Guide](https://github.com/itlackey/akm/blob/main/docs/guides/stash-makers.md#env-security)
803
+ Bundle publishers: see the [Author Bundles guide](https://github.com/itlackey/akm/blob/main/docs/guides/author-bundles.md#env-security)
779
804
  for guidance on env files that legitimately need these keys.
780
805
 
781
806
  #### Website sources
@@ -1827,15 +1852,25 @@ akm lint --fail-on-flagged # CI-friendly: exit non-zero when summary.flagge
1827
1852
 
1828
1853
  | Flag | Description |
1829
1854
  | --- | --- |
1830
- | `--fix` (alias `--auto-fix`) | Apply auto-fixes in place |
1855
+ | `--fix` (alias `--auto-fix`) | Apply auto-fixes in place. Refused with a usage error when the target bundle is configured `writable: false`. |
1831
1856
  | `--dir` | Override the bundle root directory (default: from config) |
1832
- | `--type` | Only lint assets of this type (e.g. `workflows`, `tasks`, `memories`) |
1857
+ | `--type` | Only lint assets of this type (e.g. `workflows`, `tasks`, `memories`). **akm bundles only** — every other adapter validates the whole bundle and warns on stderr that the flag had no effect. |
1833
1858
  | `--fail-on-flagged` | Exit non-zero when `summary.flagged > 0`. Default: exit 0 regardless of findings. |
1834
1859
 
1835
1860
  Returns `fixed[]` and `flagged[]` arrays plus a `summary: { fixed, flagged }`
1836
1861
  count. Each entry carries `file`, `issue`, `detail`, and whether it was
1837
1862
  `fixed`.
1838
1863
 
1864
+ Task files are checked for more than their fields: a `tasks/*.yml` whose YAML
1865
+ does not parse is reported as `invalid-task-yaml` (it used to fall through as an
1866
+ empty mapping and lint clean), and a `tasks/*.yaml` file — a spelling akm never
1867
+ indexes or schedules — is flagged for the extension rather than skipped.
1868
+
1869
+ `--fix` is transactional per file: a fix that cannot be written (read-only file,
1870
+ full disk) is reported as `fixed: "failed"` on that file and the sweep continues,
1871
+ so a mid-run write failure can no longer abort the command and hide the fixes
1872
+ that already landed.
1873
+
1839
1874
  ### improve
1840
1875
 
1841
1876
  Improve existing assets and write the results to the proposal queue.
@@ -2241,13 +2276,67 @@ Each task targets exactly one of `--workflow <ref>`, `--prompt <text-or-ref>`,
2241
2276
  or `--command <shell>`. Task YAML is strict and begins with `version: 2`.
2242
2277
  Prompt targets dispatch through `--engine` or `defaults.engine` and may set
2243
2278
  `model`, `timeoutMs`, and LLM request overrides; command tasks may set only
2244
- `timeoutMs`; workflow tasks may set only `params`. `task add` accepts
2245
- `--engine`, `--model`, `--timeout-ms`, `--params`, `--name`, `--when-to-use`,
2246
- `--description`, and `--tags`. A v1 task is diagnosed by sync and doctor
2247
- but is never rewritten or executed.
2279
+ `timeoutMs`; workflow tasks may set `params`, `timeoutMs`, `maxSteps`, and
2280
+ `maxRetries`. `task add` accepts `--engine`, `--model`, `--timeout-ms`,
2281
+ `--params`, `--name`, `--when-to-use`, `--description`, and `--tags`
2282
+ (`maxSteps` / `maxRetries` are YAML-only — set them in the file and run `akm
2283
+ task sync`). A v1 task is diagnosed by sync and doctor but is never rewritten
2284
+ or executed.
2285
+
2286
+ **Task-log redaction and `redact:`.** A task's persisted output — the run `.log`
2287
+ file and its `logs.db` rows — is scrubbed before it is written. Two passes run:
2288
+ credential *shapes* (`Bearer …`, `sk-…`, webhook URLs) are matched by pattern,
2289
+ and exact secret values are matched by value. akm knows a value is secret when
2290
+ the config declares it (`engines.<name>.apiKey`, `embedding.apiKey`, and the
2291
+ `AKM_ENGINE_<NAME>_API_KEY` / `AKM_LLM_API_KEY` / `AKM_EMBED_API_KEY` recipes),
2292
+ and it infers others from the variable name (`*_TOKEN`, `*_SECRET`, `*_API_KEY`,
2293
+ `*_PASSWORD`, …) provided the value is at least 8 characters — a short one is
2294
+ far more likely to be a flag than a credential, and redaction replaces
2295
+ substrings, so guessing wrong mangles the log.
2296
+
2297
+ Any task kind may add `redact:` for a secret exported under a name none of those
2298
+ rules recognise:
2299
+
2300
+ ```yaml
2301
+ version: 2
2302
+ schedule: "0 3 * * *"
2303
+ command: ./deploy.sh
2304
+ redact: [ACME_DEPLOY_TOKEN] # NAMES, never values — max 32
2305
+ ```
2306
+
2307
+ akm looks each name up in the environment the run is given; a name that is unset
2308
+ contributes nothing. **Names only.** A literal secret in a task file would leak
2309
+ far more widely than the redaction closes: task files are indexed into the search
2310
+ database, can be sent to an embedding provider, are printed verbatim by `akm
2311
+ show`, and ship inside bundles over git and npm. This is the same rule exec
2312
+ units' `pass_env:` follows.
2248
2313
 
2249
2314
  A workflow-target task executes the same native orchestration as `akm workflow
2250
2315
  run`; it does not stop after creating a run. Completion maps to task
2251
2316
  `completed`, while workflow failure or verifier rejection maps to task
2252
2317
  `failed`. The task schema's `params` mapping remains the non-CLI way a scheduled
2253
2318
  definition supplies its new-run parameter snapshot.
2319
+
2320
+ **Workflow-task run bounds.** `timeoutMs`, `maxSteps`, and `maxRetries` are the
2321
+ task-file spellings of `akm workflow run --timeout`, `--max-steps`, and
2322
+ `--max-retries`. Unlike the interactive command, a scheduled workflow task gets
2323
+ a **default whole-run timeout of 6 hours**
2324
+ (`DEFAULT_WORKFLOW_TASK_TIMEOUT_MS`): nobody is at the terminal to Ctrl-C an
2325
+ unattended run, so without one a single wedged unit hangs the task forever. An
2326
+ explicit `timeoutMs` always wins, and `timeoutMs: null` opts out entirely. On
2327
+ expiry the runner aborts the run's signal, which the engine treats as a
2328
+ graceful break at the next step boundary — the journal is kept and the run
2329
+ stays resumable with `akm workflow resume <run-id>` (the run id is in the task
2330
+ run's `detail.error` and log). The attempt itself is recorded as `failed`, so
2331
+ the OS scheduler sees a non-zero exit.
2332
+
2333
+ ```yaml
2334
+ version: 2
2335
+ schedule: "@daily"
2336
+ workflow: workflows/nightly-report
2337
+ params:
2338
+ region: us-east-1
2339
+ timeoutMs: 3600000 # 1h whole-run bound (omit for the 6h default, null for none)
2340
+ maxSteps: 20 # optional
2341
+ maxRetries: 1 # optional
2342
+ ```
@@ -113,6 +113,16 @@ value is clamped to `1..64`. When absent, AKM derives the cap once from the CPU
113
113
  count (`min(16, max(1, cores - 2))`) and freezes it into the run plan, so resume
114
114
  does not change policy on a different host or after config edits.
115
115
 
116
+ `workflow.defaultMapConcurrency` is the width a `map` step freezes when it
117
+ declares no `concurrency:` of its own. Unset means **4** — map steps are
118
+ parallel by default as of 0.9.1. An explicit value is clamped to `1..64`; set
119
+ it to `1` to restore the pre-0.9.1 serial-by-default fan-out for every workflow
120
+ on this machine. It is only a default: an authored `map.concurrency` always
121
+ wins, and it never raises a step past `workflow.maxConcurrency`, the selected
122
+ engine's `concurrency`, or the host CPU cap. An LLM engine that declares no
123
+ `engines.<name>.concurrency` gets **1** on a loopback endpoint (a local model
124
+ server holds one loaded model) and **4** on a remote one.
125
+
116
126
  `workflow.judgeEngine` names the LLM or agent engine used to verify every
117
127
  non-empty workflow `### gate` rubric. It is required when a workflow declares
118
128
  completion criteria and is frozen into each new run, so later config edits do
@@ -228,7 +238,10 @@ reference, same rules as engine `apiKey`), `dimension`, `localModel`,
228
238
  and `defaultBundle` are the 0.9 source configuration shape — see
229
239
  [Concepts](https://github.com/itlackey/akm/blob/main/docs/guides/concepts.md) and the [CLI reference](cli.md) for the
230
240
  full bundle model (`path`, `git`, `website`, `npm`, `writable`, `registryId`,
231
- `components`). `defaultBundle` must name a key in `bundles` when set.
241
+ `components`). `defaultBundle` must name a key in `bundles` when set. A
242
+ bundle's `components.<id>.adapter` key pins it to a specific format adapter
243
+ instead of relying on auto-detection — see [Bundle Types](bundle-types.md)
244
+ for the full adapter list and what each one reads/writes.
232
245
 
233
246
  ### defaultWriteTarget
234
247
 
@@ -333,7 +346,7 @@ generic walker.
333
346
  | `AKM_ENGINE_<NAME>_API_KEY` | Fallback credential for LLM engine `<name>` |
334
347
  | `AKM_LLM_API_KEY` | Fallback only for the selected `defaults.llmEngine` |
335
348
  | `AKM_EMBED_API_KEY` | Embedding credential |
336
- | `AKM_BUNDLE_DIR` | Override the stash directory |
349
+ | `AKM_BUNDLE_DIR` | Override the bundle directory |
337
350
  | `AKM_DATA_DIR` | Override the data directory — durable `index.db`/`workflow.db`/`state.db`, `akm.lock`, config backups (or set `XDG_DATA_HOME`) |
338
351
  | `AKM_CACHE_DIR` | Override the cache directory — regenerable caches (or set `XDG_CACHE_HOME`) |
339
352
  | `AKM_STATE_DIR` | Override the state directory — task-scheduler invocation state (or set `XDG_STATE_HOME`) |
@@ -13,7 +13,7 @@ AKM does not:
13
13
  AKM adds no network destinations of its own. The requests it *does* make all go to endpoints you chose or invoked, and those third parties receive whatever the request contains:
14
14
 
15
15
  1. **Your configured LLM/embedding provider** (e.g. Anthropic, OpenAI, a local Ollama, or any OpenAI-compatible endpoint) receives the prompts and asset content sent for reflect/propose/distill/embedding when you enable those features. If you point AKM at Anthropic, Anthropic receives those requests.
16
- 2. **Registry metadata and stash packages** from sources you explicitly configure (GitHub, npm, git remotes, websites) — those hosts receive the fetch/clone/crawl requests, and website sources receive requests for the pages you crawl.
16
+ 2. **Registry metadata and bundle packages** from sources you explicitly configure (GitHub, npm, git remotes, websites) — those hosts receive the fetch/clone/crawl requests, and website sources receive requests for the pages you crawl.
17
17
  3. **`akm upgrade`** — fetches the latest release from GitHub releases (GitHub sees the request).
18
18
  4. **`akm setup`** — a single DNS lookup for `github.com` to decide whether to skip network-dependent steps (Ollama detection, remote embedding probes) when offline. No HTTP request is made by this probe; if it succeeds, akm proceeds with the network-dependent steps you already configured.
19
19
  5. **`akm improve` dead-link checks** — a full-scope improve run (the default for a bare `akm improve`) sends best-effort `HEAD` requests (following redirects, with a short timeout and a hard cap on URL count) to URLs found in the bodies of the knowledge assets it is improving, to flag dead links. The hosts of those URLs see a `HEAD` request; no asset content is sent. Keep URLs you don't want probed out of knowledge-asset bodies, or run improve with an explicit narrower scope.
@@ -30,7 +30,7 @@ AKM writes to these locations on your machine. All paths follow [XDG Base Direct
30
30
 
31
31
  | Path | Contents | Safe to delete? |
32
32
  |---|---|---|
33
- | `config.json` | Your AKM configuration: engines, improve strategies, bundles (stash sources), and experimental opt-ins — see [Configuration](configuration.md) | **No** — deleting resets all settings |
33
+ | `config.json` | Your AKM configuration: engines, improve strategies, bundles (bundle sources), and experimental opt-ins — see [Configuration](configuration.md) | **No** — deleting resets all settings |
34
34
 
35
35
  Override: set `AKM_CONFIG_DIR` or `XDG_CONFIG_HOME`.
36
36
 
@@ -38,7 +38,7 @@ Override: set `AKM_CONFIG_DIR` or `XDG_CONFIG_HOME`.
38
38
 
39
39
  | Path | Contents | Safe to delete? |
40
40
  |---|---|---|
41
- | `index.db` | Search index for all your stash assets (FTS5 + metadata) | Yes — rebuilds via `akm index --full` |
41
+ | `index.db` | Search index for all your bundle assets (FTS5 + metadata) | Yes — rebuilds via `akm index --full` |
42
42
  | `state.db` | Events, local usage telemetry, proposals, task history, improve run results, and workflow run state/history (the former `workflow.db` was folded in during the 0.9.0 cutover) | **No** — deletes event/usage logs, proposal queue, improve history, and workflow run history |
43
43
  | `logs.db` | Structured, high-volume task/run log lines (`{ts, task_id, run_id, stream, level, line}`), joined to `state.db`'s `task_history` rows by `task_id@started_at`. Kept separate from `state.db` because log lines are append-only and freely purgeable, unlike durable state | Yes — log lines are regenerable per run; deleting loses historical run output only |
44
44
  | `akm.lock` | Inter-process write lock | Yes — recreated automatically |
@@ -46,6 +46,26 @@ Override: set `AKM_CONFIG_DIR` or `XDG_CONFIG_HOME`.
46
46
 
47
47
  Override: set `AKM_DATA_DIR` or `XDG_DATA_HOME`.
48
48
 
49
+ These files take your **process umask** — akm does not set or change their
50
+ permissions. They hold task history, captured command output, and indexed
51
+ content, so on a shared machine you probably do not want them world-readable;
52
+ set a tighter umask, or `chmod` the directory yourself. akm will not do it for
53
+ you, and `akm health` will not nag about it either — `0644` under a default
54
+ `022` umask is simply the expected state.
55
+
56
+ If akm **cannot read** this directory — a uid/ownership mismatch, for instance
57
+ when two accounts share one `$XDG_DATA_HOME` — commands fail loudly with a
58
+ `DATA_DIR_UNREADABLE` config error (exit 78) naming the path, the errno, the
59
+ mode and owner, and the uid you are running as. They do **not** report an empty
60
+ index. `akm health` stays runnable in that state and reports it as a failing
61
+ `state-db-readable` check, so it remains the command to reach for.
62
+
63
+ > **0.9.1 note.** A pre-release build briefly chmodded this directory to `0700`
64
+ > and the databases to `0600` on every open. That was reverted: it silently
65
+ > changed the permissions of directories akm did not create, which broke installs
66
+ > sharing `$XDG_DATA_HOME` between two uids. If a 0.9.1 pre-release tightened
67
+ > your data directory and you need it shared again, `chmod` it back.
68
+
49
69
  ### Cache Directory (`$XDG_CACHE_HOME/akm` or `~/.cache/akm/`)
50
70
 
51
71
  Everything in the cache is regenerable. It is safe to delete the entire cache directory; AKM will recreate what it needs on next use.
@@ -54,16 +74,16 @@ Everything in the cache is regenerable. It is safe to delete the entire cache di
54
74
  |---|---|---|
55
75
  | `config-backups/config-<timestamp>.json` | Pre-save config snapshots (5 retained; owner-only permissions — file `0600`, dir `0700`, since 08-F4) | Yes |
56
76
  | `config-backups/config.latest.json` | Latest backup alias (owner-only `0600`) | Yes |
57
- | `registry/` | Downloaded registry tarballs (stash packages from npm, GitHub, etc.) | Yes — re-downloaded on next `akm bundle add` or `akm bundle update` |
77
+ | `registry/` | Downloaded registry tarballs (bundle packages from npm, GitHub, etc.) | Yes — re-downloaded on next `akm bundle add` or `akm bundle update` |
58
78
  | `registry-index/` | Legacy per-URL JSON cache (v0.7 artifact) | Yes — fully replaced by `index.db` in 0.8.0 |
59
79
  | `semantic-status.json` | Semantic index build status marker | Yes |
60
80
  | `bin/` | Downloaded AKM binary cache (used by `akm upgrade`) | Yes |
61
- | `tasks/logs/` | Scheduled task log files | Yes — ephemeral logs |
81
+ | `tasks/logs/` | Scheduled task log files. Written at your umask; they hold captured command/agent output, so tighten the directory yourself if the machine is shared | Yes — ephemeral logs |
62
82
  | `tasks/history/` | Legacy task history JSONL (v0.7 migration artifact) | Yes |
63
83
 
64
84
  Override: set `AKM_CACHE_DIR` or `XDG_CACHE_HOME`.
65
85
 
66
- ### Stash Directory (`~/akm/` by default, or user-configured)
86
+ ### Bundle Directory (`~/akm/` by default, or user-configured)
67
87
 
68
88
  | Path | Contents | Safe to delete? |
69
89
  |---|---|---|
@@ -122,7 +142,7 @@ the set of types the code actually emits at HEAD (verified against every
122
142
  | `select` | `akm show` after a search returning the same ref | `ref`, `entryId` |
123
143
  | `feedback` | `akm feedback <ref>` | `signal` (positive/negative) |
124
144
  | `sync` | `akm sync` (renamed from `save` in 0.9.0; historical rows keep `save`, and `akm log --type save`/`--type sync` are synonyms on read) | `ref` |
125
- | `stash_synced` | `akm improve`'s internal auto-sync pass (the `sync.push` feature), **distinct from** the `akm sync` command above | `committed`, `pushed`, `skipped`, `reason` |
145
+ | `stash_synced` | `akm improve`'s internal auto-sync pass (the `sync.push` feature), **distinct from** the `akm sync` command above | `committed`, `pushed`, `skipped`, `reason`, `attributed` (paths the run wrote and staged), `unattributed` (in-scope paths that went dirty during the run without the run writing them — left for their author) |
126
146
  | `env_access` | `akm env run <name> -- <command>` (audit trail: key **names** only, values never recorded) | `ref`, `keys` |
127
147
  | `secret_access` | `akm secret run <ref> <VAR> -- <command>` (audit trail: var **name** only, value never recorded) | `ref`, `var` |
128
148
 
@@ -162,7 +182,7 @@ the set of types the code actually emits at HEAD (verified against every
162
182
  | `proactive_selected` | The proactive-maintenance selector runs (once per `akm improve` run) | `count`, `dueTotal`, `neverReflected` (aggregated) |
163
183
  | `improve_replay_selected` | Bounded replay-budget selection ran | `count`, `budget`, `convergedSkipped`, `candidatePool` (aggregated) |
164
184
  | `improve_salience_first_run` | First improve run with no pre-existing salience baseline to compare against | `candidateCount`, `note` |
165
- | `improve_salience_rank_change` | Stash-wide rank-change report, from the second improve run onward | `stashSize`, `totalChanged`, `forgettingCandidates`, `topDrops` |
185
+ | `improve_salience_rank_change` | Bundle-wide rank-change report, from the second improve run onward | `stashSize`, `totalChanged`, `forgettingCandidates`, `topDrops` |
166
186
  | `outcome_proxy_inverted` | Proxy-adequacy tripwire: `outcome_score` correlates *negatively* with accepted-change rate (corr < −0.3) | `correlation`, `n` |
167
187
  | `outcome_proxy_dead` | Proxy-adequacy tripwire: `outcome_score` is statistically unrelated to accepted-change rate (\|corr\| < 0.1, n ≥ 500) | `correlation`, `n` |
168
188
  | `collapse_detector_alert` | The collapse/churn detector trips an alert rule during an improve cycle | `kind` (collapse-recall\|collapse-entropy\|collapse-shrink\|churn\|merge-floor), `detail`, `metrics`, `canarySetId`, `runId` |
@@ -241,7 +261,7 @@ an identity that production indexing omitted.
241
261
 
242
262
  ### 3. Proposals Table
243
263
 
244
- The proposal queue: pending, accepted, and rejected improvement proposals for your stash assets. Generated by `akm improve`, `akm proposal new`, and related proposal-producing flows.
264
+ The proposal queue: pending, accepted, and rejected improvement proposals for your bundle assets. Generated by `akm improve`, `akm proposal new`, and related proposal-producing flows.
245
265
 
246
266
  Contents:
247
267
  - Proposal UUID (primary key)
@@ -327,7 +347,7 @@ You can redirect any AKM directory to a custom path:
327
347
  | `AKM_SQLITE_JOURNAL_MODE` | SQLite journal mode: `WAL` (default), `DELETE`, or `TRUNCATE`. Use `DELETE`/`TRUNCATE` on network filesystems (NFS/SMB) where WAL is impossible. When left at the `WAL` default, akm auto-detects a network FS for the data dir and falls back to `DELETE`. |
328
348
  | `AKM_STATE_DIR` | State directory (`~/.local/state/akm/`) |
329
349
  | `AKM_CACHE_DIR` | Cache directory (`~/.cache/akm/`) |
330
- | `AKM_BUNDLE_DIR` | Default stash directory (`~/akm/`) |
350
+ | `AKM_BUNDLE_DIR` | Default bundle directory (`~/akm/`) |
331
351
  | `XDG_CONFIG_HOME` | XDG base — akm appends `/akm` |
332
352
  | `XDG_DATA_HOME` | XDG base — akm appends `/akm` |
333
353
  | `XDG_STATE_HOME` | XDG base — akm appends `/akm` |
@@ -0,0 +1,50 @@
1
+ # Supported Formats
2
+
3
+ AKM is a portable capability library for AI agents: one library for every
4
+ agent. Interoperability is the point — AKM doesn't only manage its own asset
5
+ library, it can point at a directory that already follows a *different*
6
+ convention (a Claude Code project, an OKF knowledge base, a Karpathy-style LLM
7
+ wiki, a crawled website, …) and index, search, and validate it in place,
8
+ without you converting anything first.
9
+
10
+ A directory AKM indexes this way is a **bundle**. AKM auto-detects which
11
+ format a bundle uses — you never declare it yourself unless you want to pin
12
+ one explicitly. 0.9.0 recognizes 11 formats.
13
+
14
+ ## Format compatibility
15
+
16
+ | Format | What AKM indexes | Auto-detection marker | Current read/write support | Typical use |
17
+ | --- | --- | --- | --- | --- |
18
+ | `website-snapshot` | Crawled pages tagged `website` (name, description, full body, original crawl URL) | Root `manifest.json` with `url` + `fetchedAt` | Read-only | A website materialized locally via `akm bundle add <url>` |
19
+ | `agent-skills` | Standalone Agent Skills packages as type `skill` (name, description, tags, body) | A direct child directory containing `SKILL.md` | Read-only | The [github.com/anthropics/skills](https://github.com/anthropics/skills) layout — one `<name>/SKILL.md` per package at the bundle root |
20
+ | `claude` | `CLAUDE.md` as `instruction`; `commands/`, `agents/`, `skills/<name>/SKILL.md` as their matching types | Root `CLAUDE.md` plus at least one of `commands/`, `agents/`, `skills/` | Read-only | Point AKM at an existing Claude Code `.claude` tool directory |
21
+ | `opencode` | Same shape as `claude`, rooted on `AGENTS.md` | `opencode.json`/`opencode.jsonc`, or root `AGENTS.md` plus a tool directory (plural or singular alias) | Read-only | Point AKM at an existing OpenCode `.opencode` tool directory |
22
+ | `dotenv` | `env` entries as key names only (never values); `secret` entries as file names only (never content) | Every top-level directory is `env/` and/or `secrets/`, with at least one present | Writable, narrowly — `akm env create`/`env remove`/`secret set` only | A standalone env/secrets-only bundle |
23
+ | `akm-workflow` | Workflow steps, name, description, tags | A top-level `.md` file with explicit `type: workflow` frontmatter | Writable — `akm workflow create` only | A standalone workflow bundle, one workflow per file |
24
+ | `akm-task` | Tasks as type `task`, name, full raw YAML | A top-level `.yml` file that parses with a non-empty `schedule` key | Read-only | A standalone scheduled-task bundle |
25
+ | `llm-wiki` | `raw/` sources as `wiki-source`; `pages/` as their `pageKind` (default `note`), with resolved cross-reference links | Root `schema.md` plus a `pages/` directory | Read-only (author by writing directly into `pages/`; AKM indexes and serves the result) | [Karpathy's LLM-wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) — agent-authored reference wikis |
26
+ | `akm` (native) | AKM's own 14 native asset types — see [Asset Types](https://github.com/itlackey/akm/blob/main/docs/reference/asset-types.md) | A `.stash` marker directory, or two-plus native subdirectories, or the fallback when nothing else matches | Fully writable — every AKM-native write command | Your working bundle, and any bundle authored as AKM's own format |
27
+ | `okf` | Frontmatter `type` (defaults to `knowledge`); name, description, tags, links, body | A root `index.md`, or any `.md` file anywhere carrying a non-empty frontmatter `type` | Read-only | The [Open Knowledge Format](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md) — the portable baseline every markdown-based format here is a superset of |
28
+ | `generic-files` | Files classified by extension: scripts, markdown/text as `document`, everything else as `file` | None — only claimed via an explicit `components.<id>.adapter: "generic-files"` config override | Read-only | A catch-all for a directory that doesn't match any other format |
29
+
30
+ **Read-only** here means AKM's own write commands (`akm remember`, `akm
31
+ import`, `proposal accept`, and similar) won't create or edit files in a
32
+ bundle of that format. Reading, searching, and `akm lint` validation work
33
+ against every format in the table above regardless of write support.
34
+
35
+ ## Why this matters
36
+
37
+ This table is the proof of the first pillar: **one library for every agent**.
38
+ You don't migrate a Claude Code project, an OpenCode project, or an OKF
39
+ knowledge base into AKM's own layout to get search, curation, and validation
40
+ over it — AKM meets each format where it already lives. Writing new
41
+ capabilities back into a foreign-format bundle is a separate, narrower
42
+ guarantee; see [Adapters](https://github.com/itlackey/akm/blob/main/docs/architecture/adapters.md) for exactly which
43
+ formats are writable today and why.
44
+
45
+ ## See also
46
+
47
+ - [Asset Types](https://github.com/itlackey/akm/blob/main/docs/reference/asset-types.md) — the 14 native asset types AKM's own format recognizes
48
+ - [Adapters](https://github.com/itlackey/akm/blob/main/docs/architecture/adapters.md) — how AKM picks a format, the write-path internals, and current caveats
49
+ - [Concepts](https://github.com/itlackey/akm/blob/main/docs/guides/concepts.md) — the retrieval loop these formats feed
50
+ - [Wikis](https://github.com/itlackey/akm/blob/main/docs/guides/wikis.md) — the `llm-wiki` authoring workflow