akm-opencode 0.9.1202608250804 → 0.9.14202609050148

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # akm-opencode
2
2
 
3
- OpenCode plugin for [AKM](https://github.com/itlackey/akm) `^0.9.0`. It exposes exactly five public tools and uses lifecycle hooks to bring relevant AKM context into a session.
3
+ OpenCode plugin for [AKM](https://github.com/itlackey/akm) `0.9.14`. It exposes exactly five public tools and uses lifecycle hooks to bring relevant AKM context into a session. The dependency is exact-pinned because the plugin calls AKM's in-process `dist/` APIs.
4
4
 
5
5
  ## Installation
6
6
 
@@ -18,13 +18,13 @@ Add the plugin to `opencode.json`:
18
18
  | --- | --- |
19
19
  | `akm_search` | Search configured bundles or registries. `source` accepts `local`, `registry`, `all`, or a configured bundle name. |
20
20
  | `akm_show` | Show a concept by `[bundle//]conceptId[#fragment]`. A fragment selects a Markdown section. |
21
- | `akm_curate` | Return ranked concepts for a task or topic. |
21
+ | `akm_curate` | Return ranked concepts for a task or topic. Optional `pack` is a token budget that returns the selected local assets' full content in one response; registry hits are omitted from packed items. |
22
22
  | `akm_feedback` | Record positive or negative feedback for a concept. |
23
23
  | `akm_remember` | Save durable knowledge as a searchable memory. |
24
24
 
25
25
  `akm_search`, `akm_show`, and `akm_curate` call the bundled AKM read APIs in process. `akm_feedback` and `akm_remember` use the compatible AKM CLI because they mutate AKM state. Failures return structured results and are logged through OpenCode app logging.
26
26
 
27
- Use the `ref` returned by search or curate directly with show or feedback. Concept IDs look like `skills/code-review`, `memories/release-retro`, or `team-playbook//knowledge/deploy#Rollback`.
27
+ Use the `ref` returned by search or curate directly with show or feedback. When `akm_curate.pack` is set, the response already includes packed local content, so a separate show call is only needed for omitted or registry-only hits. Concept IDs look like `skills/code-review`, `memories/release-retro`, or `team-playbook//knowledge/deploy#Rollback`.
28
28
 
29
29
  ## Lifecycle Hooks
30
30
 
@@ -32,12 +32,12 @@ The plugin subscribes to OpenCode lifecycle events. Hook failures are logged thr
32
32
 
33
33
  | Event | Behavior |
34
34
  | --- | --- |
35
- | `session.created` | Resolves AKM, warms local data in the background, and prepares hints, an active-workflow summary, and curated context for the session. |
35
+ | `session.created` | Warms local data in the background, and prepares hints, an active-workflow summary, and curated context for the session. |
36
36
  | `session.updated` | Backfills hints and the workflow summary for a session the plugin has not prepared yet. It does not re-run session-created work. |
37
37
  | `chat.message` | Records feedback or memory intent and can schedule non-blocking curation for a substantive prompt. The curate is fire-and-forget: its result is injected on a later turn rather than delaying this one. |
38
38
  | `experimental.chat.system.transform` | Injects the AKM guidance and cached curated context into the system prompt. The host rebuilds the system prompt on every request, so these blocks are re-injected each turn — including after a compaction — rather than once per session. |
39
- | `tool.execute.before` | The format-declaration write gate (`AKM_WRITE_GATE`, `observe` by default). Blocks the first `edit`/`write` to an existing file that declares a format your stash documents and hands the model the ref to read. Once per file per session, released unconditionally on the retry. |
40
- | `tool.execute.after` | Tracks concepts used by AKM tools, records deduplicated feedback, and checkpoints session observations. It also records what a file the session `read` declares about its own format, which is what the write gate above keys on. `write` is deliberately not a source: a file the session created is not one it needs the stash to explain. The create itself is recorded on the write's `tool.execute.before` pass, so a later read-back of that file cannot re-arm the gate. |
39
+ | `tool.execute.before` | The format-declaration write gate (`AKM_WRITE_GATE`, `observe` by default). Blocks the first `edit`/`write` to an existing file that declares a format your bundle documents and hands the model the ref to read. Once per file per session, released unconditionally on the retry. |
40
+ | `tool.execute.after` | Tracks concepts used by AKM tools, records deduplicated feedback, and checkpoints session observations. It also records what a file the session `read` declares about its own format, which is what the write gate above keys on. `write` is deliberately not a source: a file the session created is not one it needs the bundle to explain. The create itself is recorded on the write's `tool.execute.before` pass, so a later read-back of that file cannot re-arm the gate. |
41
41
  | `shell.env` | Exposes `AKM_PROJECT`, `AKM_PLUGIN_VERSION`, and the resolved `AKM_BUNDLE_DIR` to shell tools. |
42
42
  | `session.idle` | Runs interval-gated memory extraction (`AKM_AUTO_MEMORY=0` disables it). Fires after every turn, so it is rate-limited. |
43
43
  | `session.compacted` | Records a post-compaction event. |
@@ -64,14 +64,13 @@ Every kill switch below is opt-out and reads the same way: only the literal `0`
64
64
  | Variable | Default | Purpose |
65
65
  | --- | --- | --- |
66
66
  | `AKM_BUNDLE_DIR` | unset | Absolute path to the AKM bundle root. When unset the plugin discovers it once per process by running `akm info`. The resolved value is re-exported to shell tools through the `shell.env` hook. |
67
- | `AKM_LOCAL_BUILD_CLI` | unset | Absolute path to a locally built AKM CLI entry point. |
68
- | `AKM_OPENCODE_IGNORE_BUNDLED_CLI` | unset (off) | Set to `1` to drop the bundled AKM CLI from resolution so only an `akm` on `PATH` is considered. Used by the eval harness; also an escape hatch when the bundled dependency is broken. |
67
+ | `AKM_OPENCODE_CLI` | unset | Absolute path to an `akm` executable to run instead of the `akm-cli` dependency, exec'd as-is. Used by the eval harness to substitute a deterministic shim. |
69
68
  | `AKM_AUTO_CURATE` | `1` | Set to `0` to disable automatic prompt curation. |
70
69
  | `AKM_AUTO_FEEDBACK` | `1` | Set to `0` to disable automatic outcome feedback. |
71
- | `AKM_AUTO_HINTS` | `1` | Set to `0` to skip the per-session `akm hints` call. The missing-bundle warning is deliberately not gated on this: it explains why the stash is empty in the first place. |
70
+ | `AKM_AUTO_HINTS` | `1` | Set to `0` to skip the per-session `akm hints` call. The missing-bundle warning is deliberately not gated on this: it explains why the bundle is empty in the first place. |
72
71
  | `AKM_AUTO_MEMORY` | `1` | Set to `0` to disable automatic memory harvesting — the interval-gated `akm proposal extract` on `session.idle`, which is the whole of that harvest here. The Claude plugin honours the same variable for its `SessionEnd` extract, so one setting covers both harnesses. |
73
72
  | `AKM_INDEX_ON_SESSION_END` | `1` | Set to `0` to skip the `akm index` refresh. It runs only on `session.deleted` — never on `session.idle`, which fires after every turn. |
74
- | `AKM_WRITE_GATE` | `observe` | The format-declaration write gate (#99). When a file the session **read** declares a format your stash documents — an `apiVersion:` namespace, a `yaml-language-server` pragma, a `$schema` key, an XML root namespace — and that asset has not been opened this session, the FIRST `edit`/`write` to that file is blocked once and the model is told which ref to read. It ships in `observe`: everything runs and the would-fire count lands in the ledger, but nothing is blocked. Set `enforce` to block, or `off`/`0` to disable it entirely. An unrecognized value is a configuration error — it logs one error per process and the gate refuses to run rather than guessing a default. It never fires on a file this session created: the create is recorded when it happens — a `write` to a path this session has not read, or an `edit` with an empty `oldString` — and that path stays insulated for the rest of the session, so reading back the model's own output does not re-arm it (ledger reason `session-created`). It self-disables when the AKM CLI does not resolve, and it is inert on `apply_patch` (which carries no file path) — that case logs one warning per process rather than failing quietly. |
73
+ | `AKM_WRITE_GATE` | `observe` | The format-declaration write gate (#99). When a file the session **read** declares a format your bundle documents — an `apiVersion:` namespace, a `yaml-language-server` pragma, a `$schema` key, an XML root namespace — and that asset has not been opened this session, the FIRST `edit`/`write` to that file is blocked once and the model is told which ref to read. It ships in `observe`: everything runs and the would-fire count lands in the ledger, but nothing is blocked. Set `enforce` to block, or `off`/`0` to disable it entirely. An unrecognized value is a configuration error — it logs one error per process and the gate refuses to run rather than guessing a default. It never fires on a file this session created: the create is recorded when it happens — a `write` to a path this session has not read, or an `edit` with an empty `oldString` — and that path stays insulated for the rest of the session, so reading back the model's own output does not re-arm it (ledger reason `session-created`). It is inert on `apply_patch` (which carries no file path) — that case logs one warning per process rather than failing quietly. |
75
74
 
76
75
  ### Scope
77
76
 
@@ -92,6 +91,8 @@ The `agent`, `run`, and `project` dimensions come from OpenCode itself (the acti
92
91
  | `AKM_CURATE_LIMIT` | `5` | Maximum curated results injected per prompt. |
93
92
  | `AKM_CURATE_MIN_CHARS` | `16` | Minimum prompt length for automatic curation. |
94
93
  | `AKM_CURATE_TIMEOUT` | `8` | Timeout in seconds for AKM calls made by hooks. |
94
+ | `AKM_CURATE_MIN_SCORE` | `0` (disabled) | Minimum per-item relevance score to keep a curated result. `0` preserves the long-standing behavior. Set it above `0` and items below the floor are dropped (no curated block at all when none survive), and the survivors are reordered so locally authored assets (lesson, memory, knowledge, skill, command, agent, instruction, fact, workflow, task, env, secret) come before imported website/wiki snapshots. Same contract as the Claude plugin's `AKM_CURATE_MIN_SCORE` — see `claude/README.md` for the full explanation, including why there is no universal default value. |
95
+ | `AKM_CURATE_TYPE` | unset | Passthrough for `akm curate --type`. |
95
96
  | `AKM_CONTEXT_BUDGET_CHARS` | `4000` | Maximum length of the AKM text injected into the system prompt on one turn. Past it the block is truncated with a marker. |
96
97
  | `AKM_PENDING_PROPOSAL_TIMEOUT` | `2` | Timeout in seconds for the pending-proposal count. Floored at 0.5s. |
97
98
  | `AKM_SESSION_BUFFER_MAX_ENTRIES` | `200` | Per-session cap on buffered observations. Oldest entries are dropped first. |
@@ -113,7 +114,7 @@ These three are read once, when the plugin module is imported, so they must be s
113
114
 
114
115
  ## Usage
115
116
 
116
- 1. Start with `akm_curate` for task-oriented discovery.
117
+ 1. Start with `akm_curate` for task-oriented discovery; set `pack` when you want the selected local content immediately.
117
118
  2. Use `akm_search` when you know the concept name and need its exact ID.
118
119
  3. Fetch the full concept with `akm_show` before relying on it.
119
120
  4. Record the outcome with `akm_feedback`.