akm-opencode 0.8.1 → 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 +39 -239
- package/index.ts +699 -2469
- package/package.json +10 -8
- package/shared/akm-version.ts +45 -0
- package/shared/memory-candidates.ts +19 -15
- package/shared/memory-events.ts +7 -11
- package/shared/ref-extraction.ts +75 -216
- package/shared/state-files.ts +99 -0
- package/shared/vendor-semver.ts +112 -0
- package/agent/akm-curator.md +0 -66
- package/commands/akm-evolve-session.md +0 -15
- package/commands/akm-improve-asset.md +0 -9
- package/commands/akm-propose-asset.md +0 -8
- package/commands/akm-review-proposals.md +0 -8
- package/commands/akm-workflow-status.md +0 -7
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# akm-opencode
|
|
2
2
|
|
|
3
|
-
OpenCode plugin for
|
|
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
|
|
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
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
|
54
|
-
|
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
109
|
-
|
|
110
|
-
`
|
|
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
|
-
|
|
42
|
+
## Environment
|
|
113
43
|
|
|
114
44
|
| Variable | Default | Purpose |
|
|
115
45
|
| --- | --- | --- |
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `AKM_AUTO_FEEDBACK` | `1` | Set to `0` to disable automatic
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
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
|
|
268
|
-
- [OpenCode
|
|
67
|
+
- [OpenCode plugins](https://opencode.ai/docs/plugins/)
|
|
68
|
+
- [OpenCode custom tools](https://opencode.ai/docs/custom-tools/)
|