akm-opencode 0.8.2 → 0.9.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.
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # akm-opencode
2
2
 
3
- OpenCode plugin for the [AKM](https://github.com/itlackey/akm) CLI (v0.8.0+). Registers tools that let your AI agent **search**, **show**, and **manage** stash assets — skills, commands, agents, knowledge, memories, lessons, tasks, scripts, workflows, vaults, secrets, and wikis — **operate the v0.8.0 proposal queue** and **improve assets** through dedicated tools, plus **agentic hooks** that auto-load relevant assets into each turn, record feedback when assets are used (skipping proposed-quality drafts), and harvest session memories so the stash improves with every session.
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.
4
4
 
5
5
  ## Installation
6
6
 
7
- Add to your OpenCode config (`opencode.json`):
7
+ Add the plugin to `opencode.json`:
8
8
 
9
9
  ```json
10
10
  {
@@ -14,255 +14,55 @@ Add to your OpenCode config (`opencode.json`):
14
14
 
15
15
  ## Tools
16
16
 
17
- The plugin exposes **21 high-value tools**. Long-tail verbs (`add`, `save`, `import`, `clone`, `update`, `remove`, `list`-sources, `registry-search`, `index`-reindex, `config`, `upgrade`, `tasks`, ad-hoc `run`, raw `agent`, vault writes, secret writes/run) are reachable via `akm_help` plus the raw `akm` CLI through the `bash` tool.
18
-
19
17
  | Tool | Description |
20
- |------|-------------|
21
- | `akm_info` | Show `akm info` output together with the installed `akm-opencode` plugin version and install location |
22
- | `akm_search` | Search the local stash, the registry, or both. Type filter accepts `skill`, `command`, `agent`, `knowledge`, `lesson`, `memory`, `script`, `task`, `workflow`, `vault`, `secret`, `wiki`, `any`; proposed hits can be included explicitly |
23
- | `akm_show` | Show a stash asset by its ref |
24
- | `akm_agent` | Dispatch a stash `agent:*` into OpenCode using the stash prompt and metadata |
25
- | `akm_cmd` | Execute a stash `command:*` template in OpenCode via SDK session prompting |
26
- | `akm_remember` | Record a memory in the default stash |
27
- | `akm_feedback` | Record positive or negative feedback for a stash asset (skipped automatically for `memory:`, `vault:`, `secret:`, `lesson:`, and proposed-quality refs) |
28
- | `akm_curate` | Curate the stash for a task or topic and return ranked matches the agent can use |
29
- | `akm_evolve` | Dispatch the AKM curator subagent into a child session, capture the report as a memory, and seed the curator-context cache so it survives compaction |
30
- | `akm_parent_messages` | Summarize the parent OpenCode session so dispatched stash subagents can inherit upstream context |
31
- | `akm_session_messages` | Summarize a specific OpenCode session (arbitrary IDs restricted to `akm-curator`) |
32
- | `akm_vault` | Vault `list` / `show` (key names) / `load` (writes the shell snippet to a temp file path without surfacing values inline). **Values never surface** through tool output |
33
- | `akm_secret` | Secret `list` / `path` only. Returns refs or the absolute file path for `_FILE`-style consumers without reading contents |
34
- | `akm_wiki` | Manage wikis (`create`, `register`, `list`, `show`, `pages`, `search`, `stash`, `lint`, `ingest`, `remove`) |
35
- | `akm_workflow` | Drive workflow runs (`start`, `next`, `complete`, `status`, `list`, `create`, `template`, `resume`) |
36
- | `akm_proposal` | Operate the v0.8.0 proposal queue (`list` / `show` / `diff` / `accept` / `reject`). Always confirm with the user before `accept`/`reject` — those operations require explicit approval |
37
- | `akm_improve` | Generate improvement proposals for an existing ref, a whole asset type, or the current stash scope; output lands in the proposal queue only |
38
- | `akm_propose` | Generate a new-asset proposal via the configured agent CLI; the result is `quality:"proposed"` until accepted |
39
- | `akm_init` | Initialize AKM's working stash directory and persist `stashDir` in config. This is the agent-safe initialization path; interactive `akm setup` is human-facing |
40
- | `akm_help` | Discover the right `akm` CLI invocation for non-first-class verbs. Returns a curated quick-reference table plus live `akm <subcommand> --help` output |
41
-
42
- ## Compound-engineering hooks
43
-
44
- The plugin subscribes to OpenCode lifecycle events so AKM participates in the
45
- session loop instead of waiting to be called. Every hook is non-blocking and
46
- fails silently when a compatible `akm` is not resolvable — the TUI is never affected.
47
-
48
- | Event | What happens |
49
18
  | --- | --- |
50
- | **`session.created`** (event hook) | Sets the AKM default agent in `~/.config/akm/config.json` to `opencode` when missing, warms the stash index in the background, caches `akm hints` plus active workflow status, and runs a scoped `akm curate --run <sessionID>` so fresh sessions start with relevant stash context. |
51
- | **`chat.message`** | Records user feedback/memory intent and appends a short reminder to use `akm_search` / `akm_curate` when more stash context is needed. It does not auto-run AKM CLI lookups on every message. |
52
- | **`experimental.chat.system.transform`** | Appends cached hints, active workflow state, pending proposal summaries, the last curator report, and the current prompt's curated context to the model's system prompt. Hints and workflow state are re-injected after transcript compaction. |
53
- | **`tool.execute.before`** (`akm_*` tools) | Blocks destructive or sensitive operations on the plugin's own typed tools (`akm_vault show/load`, `akm_secret path`, `akm_proposal accept`, etc.) until `confirm:true` is provided. This contract is per-tool, not a generic shell-command gate. |
54
- | **`tool.execute.after`** (`akm_*` tools) | Logs asset usage, accumulates refs into the session buffer, records `akm feedback <ref> --positive` / `--negative` asynchronously with per-call dedupe, checkpoints memories every `AKM_MEMORY_CHECKPOINT_EVERY` successful asset-touching tool calls, and scans child-agent free text for additional refs. |
55
- | **`experimental.session.compacting`** | Pushes hints, curated context, active workflows, and the last curator report into the compaction prompt so they survive transcript shrinking. |
56
- | **`shell.env`** | Exposes `AKM_PROJECT`, `AKM_PLUGIN_VERSION`, and the resolved `AKM_STASH_DIR` to shell tools so raw shell checks and plain `akm` invocations see the same stash path as the plugin. |
57
- | **`stop`** / **`session.idle`** / **`session.compacted`** / **`session.deleted`** | Flushes the per-session buffer into a `memory:opencode-session-YYYYMMDD-<sid>` memory so every meaningful session contributes durable context for future searches. The persisted memory now includes compact event/candidate summaries plus explicit file paths to the full-detail plugin state and OpenCode host logs so `akm improve` can inspect deeper evidence when needed. Requires at least two observations before persisting. When `AKM_INDEX_ON_SESSION_END=1`, the hook follows a successful flush with `akm index` so upstream inference/graph passes run immediately. |
58
-
59
- ### Locking down destructive commands
60
-
61
- Earlier versions of this plugin shipped `permission.ask` and
62
- `command.execute.before` hooks that tokenized each raw `akm` CLI invocation
63
- and **denied** a hard-coded list of risky subcommands (vault writes,
64
- `save --push`, `accept` / `reject` / `revert`, `tasks add` / `tasks run`,
65
- `upgrade`, `update --all`, etc.) until the user re-approved them inline.
66
- That gate has been removed in 0.8.0. The tokenized matcher was brittle — it
67
- produced false positives on commit messages, heredoc bodies, and other
68
- prose that happened to contain `akm <verb>` substrings — and gating
69
- destructive shell calls is fundamentally the host platform's job, not a
70
- plugin's.
19
+ | `akm_search` | Search configured bundles or registries. `source` accepts `local`, `registry`, `all`, or a configured bundle name. |
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. |
22
+ | `akm_feedback` | Record positive or negative feedback for a concept. |
23
+ | `akm_remember` | Save durable knowledge as a searchable memory. |
71
24
 
72
- OpenCode does not currently expose a first-class declarative permission
73
- DSL equivalent to Claude Code's `permissions.ask` / `permissions.deny`.
74
- For the verbs that historically tripped the plugin's gate, lock things
75
- down at the OS level instead:
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.
76
26
 
77
- - **Run `akm` under a wrapper script** that prompts (or denies) on the
78
- destructive subcommands you care about. Put the wrapper earlier on
79
- `PATH` than the real `akm`. For example:
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`.
80
28
 
81
- ```sh
82
- #!/usr/bin/env bash
83
- # ~/bin/akm — wraps the real akm to confirm destructive verbs
84
- case "$1 $2 $3" in
85
- "vault set "*|"vault unset "*|"vault load "*|"vault create "*|\
86
- "save --push"*|"sync "*|"sync"|"remove "*|\
87
- "accept "*|"reject "*|"revert "*|\
88
- "proposal accept "*|"proposal reject "*|"proposal revert "*|"proposal drain "*|\
89
- "tasks add "*|"tasks remove "*|"tasks enable "*|"tasks disable "*|\
90
- "tasks run "*|"upgrade"*|"update --all"*|"config set "*)
91
- read -rp "Run 'akm $*' ? [y/N] " ans
92
- [[ "$ans" == "y" || "$ans" == "Y" ]] || { echo "aborted"; exit 1; } ;;
93
- esac
94
- exec /usr/local/bin/akm-real "$@"
95
- ```
29
+ ## Lifecycle Hooks
96
30
 
97
- - **Use OS-level access controls** (`sudo`, `chmod`, mount restrictions,
98
- AppArmor / SELinux profiles) when running OpenCode in shared or
99
- sandboxed environments.
100
- - **Vault and secret writes still bypass the chat turn entirely.** Use the typed
101
- `akm_vault` tool only for read paths (`list`, `show` of key names,
102
- `load` when you need a temporary shell-file path without surfacing
103
- values inline), and the typed `akm_secret` tool only for `list` / `path`.
104
- To create vaults or set/unset values, or to set/run/remove whole-file
105
- secrets, run `akm env …` / `akm secret …` directly in the shell so
106
- secret material never passes through the chat turn.
31
+ The plugin subscribes to OpenCode lifecycle events. Hook failures are logged through OpenCode app logging and do not interrupt the TUI.
107
32
 
108
- The plugin's typed `akm_*` tools (`akm_vault show`, `akm_proposal accept`,
109
- etc.) still apply their per-tool `confirm:true` contracts at
110
- `tool.execute.before`. Only the raw-shell tokenized gate has been removed.
33
+ | Event | Behavior |
34
+ | --- | --- |
35
+ | `session.created` | Resolves AKM, warms local data in the background, and prepares scoped context for the session. |
36
+ | `chat.message` | Records feedback or memory intent and can schedule non-blocking curation for a substantive prompt. |
37
+ | `experimental.chat.system.transform` | Injects cached AKM guidance and curated context into the system prompt. |
38
+ | `tool.execute.after` | Tracks concepts used by AKM tools, records deduplicated feedback, and checkpoints session observations. |
39
+ | `shell.env` | Exposes `AKM_PROJECT`, `AKM_PLUGIN_VERSION`, and the resolved `AKM_BUNDLE_DIR` to shell tools. |
40
+ | Session idle, compacted, or deleted | Flushes sufficiently meaningful session observations through the memory lifecycle. |
111
41
 
112
- ### Environment overrides
42
+ ## Environment
113
43
 
114
44
  | Variable | Default | Purpose |
115
45
  | --- | --- | --- |
116
- | `AKM_AUTO_CURATE` | `1` | Set to `0` to disable automatic `akm curate` on user messages. Session start no longer auto-curates. |
117
- | `AKM_LOCAL_BUILD_CLI` | _(unset)_ | Optional absolute path to a locally built AKM CLI entrypoint such as `/abs/path/to/akm/dist/cli.js`. When set, the OpenCode plugin runs that build through Bun before falling back to bundled or PATH-based `akm` binaries. |
118
- | `AKM_AUTO_FEEDBACK` | `1` | Set to `0` to disable automatic `akm feedback` on tool success/failure. |
119
- | `AKM_AUTO_HINTS` | `1` | Set to `0` to skip injecting `akm hints` at session start. |
120
- | `AKM_AUTO_MEMORY` | `1` | Set to `0` to disable automatic session-summary memories. |
121
- | `AKM_INDEX_ON_SESSION_END` | `0` | Set to `1` to run `akm index` after a session-end memory is captured. |
122
- | `AKM_CURATE_LIMIT` | `5` | Max curated results injected into context per prompt. |
123
- | `AKM_CURATE_MIN_CHARS` | `16` | Minimum prompt length before curation runs. |
124
- | `AKM_CURATE_TIMEOUT` | `8` | Wall-clock seconds for `akm` invocations inside hooks. |
125
- | `AKM_CONTEXT_BUDGET_CHARS` | `4000` | Max total characters injected into system/compaction context for a single turn. |
126
- | `AKM_CURATOR_CONTEXT_MAX_CHARS` | `4000` | Max cached curator-report characters re-injected into system/compaction context; the full report is still persisted as memory. |
127
- | `AKM_MEMORY_CHECKPOINT_EVERY` | `8` | Number of successful asset-touching tool calls between mid-session checkpoint memories. |
128
- | `AKM_RETROSPECTIVE_FEEDBACK_PATTERN` | `\b(thanks|perfect|worked)\b` | Case-insensitive regex used for lightweight positive retrospective feedback on the most recent refs. |
129
- | `AKM_RETROSPECTIVE_NEGATIVE_PATTERN` | `\b(wrong|failed|broken|didn't work|did not work|bad)\b` | Case-insensitive regex used for negative retrospective feedback signals. |
130
- | `AKM_SCOPE_KEYS` | `user,agent,run,channel` | Comma-separated list of scope fields to attach on every `akm_remember`, `akm_curate`, and `akm_feedback` call. Remove a key to opt out of that dimension. |
131
- | `AKM_PENDING_PROPOSAL_TIMEOUT` | `2` | Seconds allowed for lightweight pending-proposal count checks during context injection. |
132
-
133
- ### Curator agent
134
-
135
- `akm_evolve` dispatches the native `akm-curator` OpenCode subagent when it is
136
- available, falling back to `general` with the same curator prompt when needed.
137
- The curator reviews recent AKM activity (OpenCode app logs, session-summary
138
- memories, parent-session context, live stash), produces a prioritized action
139
- list, and persists its latest report as `memory:akm-curator-YYYYMMDD-<sid>` so
140
- future curator runs can build on it.
141
-
142
- ## AKM v1 workflows
143
-
144
- The plugin injects a concise AKM workflow instruction pack into context so agents:
145
-
146
- - search or curate before writing from scratch;
147
- - show an asset before relying on it;
148
- - record feedback after the result is known;
149
- - treat `lesson:*` as first-class durable assets;
150
- - treat proposed-quality assets as uncurated until accepted;
151
- - use `akm_help` to route `proposal`, `improve`, `propose`, and `tasks` CLI workflows;
152
- - require explicit user approval before proposal acceptance/rejection, push saves, source removal, CLI upgrades, update-all, vault value access, or secret-path access.
153
-
154
- The package also ships OpenCode command docs for common workflows:
155
-
156
- - `/akm-review-proposals`
157
- - `/akm-improve-asset`
158
- - `/akm-propose-asset`
159
- - `/akm-evolve-session`
160
- - `/akm-workflow-status`
161
-
162
- ### Registry discovery
163
-
164
- Search registries with `akm_search` using `source: "registry"` or `source: "both"`. Registry hits include `id`, `installRef`, and `action` fields. Use `installRef` when feeding a result into `akm add` (run via `akm_help` topic="add" or directly through bash); registry-specific IDs are not installable refs.
165
-
166
- ## Agent Dispatch
167
-
168
- Use `akm_agent` after retrieving an agent ref from `akm_search`.
169
-
170
- Inputs:
171
- - `ref` (optional): stash ref like `agent:coach.md`
172
- - `query` (optional): resolve best matching stash agent when `ref` is omitted
173
- - `task_prompt` (required): user task to run
174
- - `dispatch_agent` (optional): OpenCode agent name, or a `provider/model` override like `openai/gpt-5.3-codex` (defaults to `general`)
175
- - `as_subtask` (optional): create child session (defaults to `true`)
176
-
177
- At least one of `ref` or `query` is required.
178
-
179
- Behavior:
180
- - Loads the stash agent via `akm show`
181
- - Uses stash `prompt` verbatim as OpenCode `system`
182
- - Treats `dispatch_agent` values in `provider/model` form as model overrides and keeps a valid OpenCode agent in the `agent` field
183
- - Applies stash `modelHint` when in `provider/model` format
184
- - Applies stash `toolPolicy` when it maps to boolean tool flags
185
-
186
- ## Command Execution
187
-
188
- Use `akm_cmd` to execute stash command templates through the OpenCode SDK.
189
-
190
- Inputs:
191
- - `ref` (optional): stash ref like `command:review.md`
192
- - `query` (optional): resolve best matching stash command when `ref` is omitted
193
- - `arguments` (optional): raw command arguments for `$ARGUMENTS`, `$1`, `$2`, etc.
194
- - `dispatch_agent` (optional): OpenCode agent name, or a `provider/model` override like `openai/gpt-5.3-codex` (defaults to current agent)
195
- - `as_subtask` (optional): create child session (defaults to `false`)
196
-
197
- At least one of `ref` or `query` is required.
198
-
199
- ## Prerequisites
200
-
201
- When the plugin loads, it resolves the bundled `akm-cli` dependency installed with the plugin and requires an `akm` version that satisfies `^0.8.0`. It prefers that bundled binary first, falls back to an existing `akm` on PATH only when it also satisfies the same range, and otherwise returns a structured error telling you to reinstall or update the plugin so OpenCode/Bun installs the dependency. It does not run global installers from plugin runtime.
202
-
203
- ```sh
204
- # macOS / Linux
205
- curl -fsSL https://raw.githubusercontent.com/itlackey/akm/main/install.sh | bash
206
- # PowerShell (Windows)
207
- irm https://raw.githubusercontent.com/itlackey/akm/main/install.ps1 -OutFile install.ps1; ./install.ps1
208
- ```
209
-
210
- Reinstall or update the plugin to let OpenCode/Bun install the bundled `akm-cli`
211
- dependency automatically.
212
-
213
- ## Stash model
214
-
215
- The stash directory is resolved automatically via a three-tier fallback: `AKM_STASH_DIR` env var (optional override) → `stashDir` in `config.json` → platform default. Set it persistently with:
216
-
217
- ```sh
218
- akm config set stashDir /abs/path/to/your-stash
219
- ```
220
-
221
- Expected layout:
222
-
223
- ```
224
- stash/
225
- ├── scripts/ # executable scripts (.sh, .ts, .js, .ps1, .cmd, .bat, .py, .rb, .go, .pl, .php, .lua, .r, .swift, .kt)
226
- ├── skills/ # skill directories containing SKILL.md
227
- ├── commands/ # markdown files
228
- ├── agents/ # markdown files
229
- ├── knowledge/ # markdown files
230
- ├── memories/ # markdown memory files (akm remember)
231
- ├── lessons/ # first-class durable learnings (lesson:<name>) — often produced by akm improve, accepted via akm proposal accept
232
- ├── tasks/ # scheduled task definitions (task:<name>) managed via akm tasks ...
233
- ├── workflows/ # multi-step procedures (workflow:<name>)
234
- ├── vaults/ # .env secret stores (vault:<name>) — values never surface through structured output
235
- ├── secrets/ # whole-file secrets (secret:<name>) — contents never surface through structured output
236
- ├── wikis/ # per-wiki directories <name>/{schema,index,log}.md + raw/ + pages
237
- └── .akm/proposals/ # v0.8.0 proposal queue — drafts that never leak into search or commits
238
- ```
239
-
240
- ## Vaults And Secrets
241
-
242
- `akm_vault` is the one tool in this plugin with a hard contract on output. The
243
- AKM CLI itself guarantees vault values never appear in JSON, the search index,
244
- `.stash.json`, or any structured output channel. This plugin mirrors that:
245
-
246
- - `action: "list"` / `"show"` return key names and comments only.
247
- - `action: "set"` / `"unset"` never echo the value.
248
- - `action: "load"` wraps `akm vault load` and returns the raw shell text
249
- as-is. Treat it as opaque and hand it straight to a shell via
250
- `eval "$(…)"` — do not log it, do not pass it through another tool, and do
251
- not let the agent inspect it.
252
-
253
- Automatic feedback recording (`tool.execute.after`) skips `vault:*` and `secret:*`
254
- refs so usage signals can't leak which sensitive asset was touched.
255
-
256
- `akm_secret` mirrors the same safety boundary for whole-file secrets:
257
-
258
- - `action: "list"` returns secret refs only.
259
- - `action: "path"` returns the absolute file path without reading or surfacing contents.
260
- - `action: "set"`, `"run"`, and `"remove"` are intentionally absent from the typed tool surface. Use raw `akm secret …` through the shell only after explicit user approval.
261
-
262
- Assets are resolved from three source types: **working** (local stash), **search paths** (additional dirs via `searchPaths` config), and **installed** (registry kits via `akm add` — see `akm_help` topic="add").
46
+ | `AKM_LOCAL_BUILD_CLI` | unset | Absolute path to a locally built AKM CLI entry point. |
47
+ | `AKM_AUTO_CURATE` | `1` | Set to `0` to disable automatic prompt curation. |
48
+ | `AKM_AUTO_FEEDBACK` | `1` | Set to `0` to disable automatic outcome feedback. |
49
+ | `AKM_AUTO_MEMORY` | `1` | Set to `0` to disable automatic session memories. |
50
+ | `AKM_CURATE_LIMIT` | `5` | Maximum curated results injected per prompt. |
51
+ | `AKM_CURATE_MIN_CHARS` | `16` | Minimum prompt length for automatic curation. |
52
+ | `AKM_CURATE_TIMEOUT` | `8` | Timeout in seconds for AKM calls made by hooks. |
53
+ | `AKM_CONTEXT_BUDGET_CHARS` | `4000` | Maximum AKM context injected into one turn. |
54
+ | `AKM_SCOPE_KEYS` | `user,agent,run,channel` | Scope dimensions attached to remember calls and local lifecycle records. |
55
+
56
+ ## Usage
57
+
58
+ 1. Start with `akm_curate` for task-oriented discovery.
59
+ 2. Use `akm_search` when you know the concept name and need its exact ID.
60
+ 3. Fetch the full concept with `akm_show` before relying on it.
61
+ 4. Record the outcome with `akm_feedback`.
62
+ 5. Use `akm_remember` for durable knowledge that should be available to future sessions.
263
63
 
264
64
  ## Docs
265
65
 
266
66
  - [AKM CLI](https://github.com/itlackey/akm)
267
- - [OpenCode Plugins](https://opencode.ai/docs/plugins/)
268
- - [OpenCode Custom Tools](https://opencode.ai/docs/custom-tools/)
67
+ - [OpenCode plugins](https://opencode.ai/docs/plugins/)
68
+ - [OpenCode custom tools](https://opencode.ai/docs/custom-tools/)