@osovv/vv-opencode 0.29.0 → 0.30.1

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 (80) hide show
  1. package/README.md +106 -335
  2. package/dist/commands/completion.js +11 -8
  3. package/dist/commands/completion.js.map +1 -1
  4. package/dist/commands/doctor.js +0 -1
  5. package/dist/commands/doctor.js.map +1 -1
  6. package/dist/commands/plugin-list.js +3 -0
  7. package/dist/commands/plugin-list.js.map +1 -1
  8. package/dist/commands/status.js +0 -1
  9. package/dist/commands/status.js.map +1 -1
  10. package/dist/commands/upgrade.js +4 -0
  11. package/dist/commands/upgrade.js.map +1 -1
  12. package/dist/index.d.ts +0 -1
  13. package/dist/index.js +6 -6
  14. package/dist/index.js.map +1 -1
  15. package/dist/lib/agent-models.d.ts +1 -1
  16. package/dist/lib/agent-models.js +7 -1
  17. package/dist/lib/agent-models.js.map +1 -1
  18. package/dist/lib/managed-agents.d.ts +1 -1
  19. package/dist/lib/managed-agents.js +3 -8
  20. package/dist/lib/managed-agents.js.map +1 -1
  21. package/dist/lib/model-roles.d.ts +0 -1
  22. package/dist/lib/model-roles.js +7 -4
  23. package/dist/lib/model-roles.js.map +1 -1
  24. package/dist/lib/opencode.d.ts +1 -8
  25. package/dist/lib/opencode.js +9 -19
  26. package/dist/lib/opencode.js.map +1 -1
  27. package/dist/lib/vvoc-config.d.ts +0 -28
  28. package/dist/lib/vvoc-config.js +30 -139
  29. package/dist/lib/vvoc-config.js.map +1 -1
  30. package/dist/lib/vvoc-paths.js +1 -1
  31. package/dist/lib/vvoc-paths.js.map +1 -1
  32. package/dist/lib/vvoc-preset-registry.d.ts +50 -0
  33. package/dist/lib/vvoc-preset-registry.js +82 -0
  34. package/dist/lib/vvoc-preset-registry.js.map +1 -0
  35. package/dist/plugins/hashline-edit/autocorrect-replacement-lines.js +4 -0
  36. package/dist/plugins/hashline-edit/autocorrect-replacement-lines.js.map +1 -1
  37. package/dist/plugins/hashline-edit/edit-operation-primitives.js +4 -0
  38. package/dist/plugins/hashline-edit/edit-operation-primitives.js.map +1 -1
  39. package/dist/plugins/hashline-edit/file-text-canonicalization.js +4 -0
  40. package/dist/plugins/hashline-edit/file-text-canonicalization.js.map +1 -1
  41. package/dist/plugins/hashline-edit/normalize-edits.js +4 -0
  42. package/dist/plugins/hashline-edit/normalize-edits.js.map +1 -1
  43. package/dist/plugins/hashline-edit/types.js +4 -0
  44. package/dist/plugins/hashline-edit/types.js.map +1 -1
  45. package/dist/plugins/secrets-redaction/config.js +2 -0
  46. package/dist/plugins/secrets-redaction/config.js.map +1 -1
  47. package/dist/plugins/secrets-redaction/deep.js +4 -0
  48. package/dist/plugins/secrets-redaction/deep.js.map +1 -1
  49. package/dist/plugins/secrets-redaction/engine.js +3 -0
  50. package/dist/plugins/secrets-redaction/engine.js.map +1 -1
  51. package/dist/plugins/secrets-redaction/index.js +4 -0
  52. package/dist/plugins/secrets-redaction/index.js.map +1 -1
  53. package/dist/plugins/secrets-redaction/patterns.js +8 -0
  54. package/dist/plugins/secrets-redaction/patterns.js.map +1 -1
  55. package/dist/plugins/secrets-redaction/restore.js +4 -0
  56. package/dist/plugins/secrets-redaction/restore.js.map +1 -1
  57. package/dist/plugins/secrets-redaction/session.js +8 -0
  58. package/dist/plugins/secrets-redaction/session.js.map +1 -1
  59. package/dist/plugins/secrets-redaction.js +4 -0
  60. package/dist/plugins/secrets-redaction.js.map +1 -1
  61. package/dist/plugins/system-context-injection/index.js +32 -32
  62. package/dist/plugins/system-context-injection/index.js.map +1 -1
  63. package/dist/plugins/workflow/index.js +47 -41
  64. package/dist/plugins/workflow/index.js.map +1 -1
  65. package/dist/plugins/workflow/repair.d.ts +26 -0
  66. package/dist/plugins/workflow/repair.js +163 -0
  67. package/dist/plugins/workflow/repair.js.map +1 -0
  68. package/dist/plugins/workflow/system-instruction.md +4 -3
  69. package/package.json +4 -8
  70. package/schemas/vvoc/v3.json +2 -13
  71. package/dist/plugins/memory/index.d.ts +0 -2
  72. package/dist/plugins/memory/index.js +0 -440
  73. package/dist/plugins/memory/index.js.map +0 -1
  74. package/dist/plugins/memory/system-instruction.md +0 -8
  75. package/dist/plugins/memory-store.d.ts +0 -51
  76. package/dist/plugins/memory-store.js +0 -461
  77. package/dist/plugins/memory-store.js.map +0 -1
  78. package/schemas/vvoc/v1.json +0 -94
  79. package/schemas/vvoc/v2.json +0 -124
  80. package/templates/agents/memory-reviewer.md +0 -40
package/README.md CHANGED
@@ -1,423 +1,194 @@
1
1
  # @osovv/vv-opencode
2
2
 
3
- Portable OpenCode workflow package with a Bun CLI that installs and maintains OpenCode plugins, managed agent prompts, and a canonical `vvoc.json` config.
3
+ **Portable OpenCode workflow toolkit** one command bootstraps a managed agent ecosystem, security-and-productivity plugins, and a unified CLI.
4
4
 
5
- ## What This Package Does
5
+ <p>
6
+ <a href="https://www.npmjs.com/package/@osovv/vv-opencode"><img src="https://img.shields.io/npm/v/%40osovv%2Fvv-opencode?style=flat&label=npm&color=blue" alt="npm"></a>
7
+ <a href="https://bun.sh"><img src="https://img.shields.io/badge/runtime-bun-%23f9f9f9?style=flat&logo=bun" alt="bun"></a>
8
+ <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-green?style=flat" alt="MIT"></a>
9
+ </p>
6
10
 
7
- - installs one pinned `@osovv/vv-opencode@<version>` entry into OpenCode
8
- - that package entry exports seven plugins: `GuardianPlugin`, `HashlineEditPlugin`, `MemoryPlugin`, `ModelRolesPlugin`, `SystemContextInjectionPlugin`, `WorkflowPlugin`, `SecretsRedactionPlugin`
9
- - creates and maintains canonical `vvoc` config at `$XDG_CONFIG_HOME/vvoc/vvoc.json`
10
- - scaffolds managed prompt files under `vvoc/agents/`
11
- - registers `vv-controller` as the default OpenCode primary agent plus managed OpenCode agents: `enhancer`, `vv-analyst`, `vv-architect`, `vv-implementer`, `vv-spec-reviewer`, `vv-code-reviewer`, `investigator`
12
- - registers OpenCode slash commands: `/vv-plan`, `/vv-review`
13
- - installs plugin-managed agents: `guardian`, `memory-reviewer`
14
- - ships role presets, diagnostics, and shell completion through the `vvoc` CLI
11
+ ---
15
12
 
16
13
  ## Quick Start
17
14
 
18
- If the package is installed as a project dependency, run it via `bun x vvoc` or `bun run vvoc`.
19
-
20
- Install globally:
21
-
22
15
  ```bash
23
16
  bun add -g @osovv/vv-opencode
24
- ```
25
-
26
- Bootstrap the default global setup:
27
-
28
- ```bash
29
17
  vvoc install
30
- vvoc status
31
18
  ```
32
19
 
33
- Write OpenCode config and managed prompts into the current repository instead of the global OpenCode config:
20
+ That's it. `vvoc install` pins the package, scaffolds managed agents, registers slash commands, writes canonical config, and sets `vv-controller` as your default OpenCode agent.
21
+
22
+ To scope everything to the current project instead of the global OpenCode config:
34
23
 
35
24
  ```bash
36
25
  vvoc install --scope project
37
26
  ```
38
27
 
39
- ## What `install` And `sync` Do
40
-
41
- `vvoc install` and `vvoc sync`:
42
-
43
- - ensure OpenCode has a pinned `@osovv/vv-opencode@<version>` package entry
44
- - register managed agents and scaffold their prompt files
45
- - set OpenCode `default_agent` to `vv-controller`
46
- - seed OpenCode `model`, `small_model`, `agent.explore`, and managed agent model refs with `vv-role:*` values
47
- - register managed OpenCode commands `vv-plan` and `vv-review`
48
- - disable global OpenCode `tools.apply_patch` in managed config so editing stays on the hashline-backed `edit` override
49
- - create or refresh canonical `vvoc.json`
50
- - refresh managed built-in presets: `vv-openai`, `vv-zai`, `vv-minimax`, `vv-deepseek`
51
-
52
- That package entry exports seven plugins:
53
-
54
- - `GuardianPlugin`
55
- - `HashlineEditPlugin`
56
- - `MemoryPlugin`
57
- - `ModelRolesPlugin`
58
- - `SystemContextInjectionPlugin`
59
- - `WorkflowPlugin`
60
- - `SecretsRedactionPlugin`
61
-
62
- ## Config And Data Layout
63
-
64
- OpenCode config stays in OpenCode-managed paths:
65
-
66
- - global: `$XDG_CONFIG_HOME/opencode/opencode.json` or `~/.config/opencode/opencode.json`
67
- - project: `./opencode.json` or `./opencode.jsonc`
28
+ > **Already installed?** Run `vvoc sync` anytime to refresh plugins, prompts, and presets.
68
29
 
69
- vvoc-owned config stays separate from OpenCode config:
30
+ ---
70
31
 
71
- - canonical config: `$XDG_CONFIG_HOME/vvoc/vvoc.json` or `~/.config/vvoc/vvoc.json`
32
+ ## Why vv-opencode?
72
33
 
73
- Managed prompt files live here:
34
+ Setting up OpenCode for serious daily work means juggling config files, agent prompts, plugin wiring, model role assignments, and permission rules — every time, on every machine.
74
35
 
75
- - global: `$XDG_CONFIG_HOME/vvoc/agents/*.md`
76
- - project: `./.vvoc/agents/*.md`
36
+ **vv-opencode collapses that into a single `vvoc install`.** It owns the wiring so you don't have to:
77
37
 
78
- Durable planning artifacts written by the managed planning agents live here:
38
+ - **Seven plugins, one entry** all plugins are exported from a single pinned package entry
39
+ - **Managed agent system** — a routed `vv-controller` primary agent with domain-specialized subagents
40
+ - **Model roles & presets** — assign models to roles (`smart`, `fast`, `vision`, …) and switch provider presets with one command
41
+ - **Security-first** — a `guardian` agent reviews permission requests, secrets are redacted from LLM-bound chat
42
+ - **Stale-line-number defense** — hashline-backed `edit` prevents write-against-wrong-snapshot bugs
79
43
 
80
- - project: `./.vvoc/plans/*.md`
44
+ ---
81
45
 
82
- For CLI commands that accept `--scope project`, only the OpenCode config target and managed prompt directory become project-local. Canonical `vvoc.json` stays global.
46
+ ## Features
83
47
 
84
- Persisted vvoc data lives here:
48
+ | Area | What you get |
49
+ |---|---|
50
+ | **Plugins** | 6 plugins in one pinned package entry — workflow orchestration, model roles, guardian, hashline edit, system context injection, secrets redaction |
51
+ | **Agent System** | `vv-controller` routes work: direct for small changes, `investigator` for bugs, implementer+reviewer loop for risky work, analyst+architect for large features |
52
+ | **One-Click Setup** | `vvoc install` or `vvoc sync` bootstraps everything — config, agents, prompts, commands, presets |
53
+ | **CLI Tooling** | 15+ commands: install, sync, status, doctor, role management, presets, guardian config, shell completion, upgrade |
54
+ | **Security** | GuardianPlugin reviews shell-permission requests; SecretsRedactionPlugin strips tokens before LLM requests; both configurable via `vvoc.json` |
55
+ | **Model Roles** | Assign provider/model/variant to roles (`default`, `smart`, `fast`, `vision`, custom); switch between `vv-openai`, `vv-zai`, `vv-deepseek`, `vv-minimax` presets |
56
+ | **Workflow Tracking** | Work items with open/list/close for tracked implementation-to-review pipelines |
57
+ | **Slash Commands** | `/vv-plan` routes through planning mode, `/vv-review` routes through review-only mode |
85
58
 
86
- - global data root: `$XDG_DATA_HOME/vvoc/` or `~/.local/share/vvoc/`
87
- - project-local memory: `$XDG_DATA_HOME/vvoc/projects/<project-id>/memory/`
88
- - shared memory: `$XDG_DATA_HOME/vvoc/memory/shared/<namespace>/`
59
+ ---
89
60
 
90
- `vvoc.json` currently contains these top-level sections:
61
+ ## The Six Plugins
91
62
 
92
- - `roles`
93
- - `guardian`
94
- - `memory`
95
- - `secretsRedaction`
96
- - `presets`
63
+ | Plugin | What it does |
64
+ |---|---|
65
+ | **WorkflowPlugin** | Tracked orchestration around `task` for subagents; registers `work_item_open/list/close` tools; routes `/vv-plan` and `/vv-review` commands |
66
+ | **ModelRolesPlugin** | Resolves `vv-role:*` references in OpenCode config at startup; translates `:variant` suffixes into native model+variant fields |
67
+ | **GuardianPlugin** | Reviews OpenCode permission requests with a constrained guardian agent and safe-deny defaults; configurable model, timeout, risk threshold |
68
+ | **HashlineEditPlugin** | Replaces OpenCode's `edit` with hash-anchored variant; rewrites `read` output to `line#hash` format; rejects stale snapshots to prevent drift bugs |
69
+ | **SystemContextInjectionPlugin** | Injects reusable system guidance into primary sessions without polluting subagent prompts; encourages proactive `explore` usage |
70
+ | **SecretsRedactionPlugin** | Redacts secrets (tokens, keys, emails, UUIDs, IPs) before LLM requests; restores placeholders afterward; configurable patterns |
97
71
 
98
- The current schema is versioned and published with the package:
72
+ ---
99
73
 
100
- ```json
101
- {
102
- "$schema": "https://cdn.jsdelivr.net/npm/@osovv/vv-opencode@<installed-version>/schemas/vvoc/v3.json",
103
- "version": 3
104
- }
105
- ```
106
-
107
- Schema source of truth lives in this repository at `schemas/vvoc/v3.json`.
108
-
109
- ## CLI Overview
74
+ ## CLI at a Glance
110
75
 
111
76
  | Command | Purpose |
112
- | --- | --- |
77
+ |---|---|
113
78
  | `vvoc init` | Interactive bootstrap flow |
114
79
  | `vvoc install` | Non-interactive setup and scaffolding |
115
- | `vvoc sync` | Refresh plugin entry, managed agents, prompts, and `vvoc.json` |
80
+ | `vvoc sync` | Refresh plugin entry, agents, prompts, config |
116
81
  | `vvoc status` | Show current installation state |
117
- | `vvoc doctor` | Diagnose setup problems and exit non-zero if problems are found |
82
+ | `vvoc doctor` | Diagnose setup problems (exits non-zero on issues) |
118
83
  | `vvoc config validate` | Validate canonical `vvoc.json` |
119
- | `vvoc role list/set/unset` | Manage canonical role assignments |
120
- | `vvoc preset list`, `vvoc preset show <name>`, `vvoc preset <name>` | Inspect or apply named presets |
121
- | `vvoc guardian config` | Print or write the `guardian` section of `vvoc.json` |
122
- | `vvoc plugin list` | List plugin entries from OpenCode config |
123
- | `vvoc patch-provider stepfun-ai|zai|openai` | Patch a global OpenCode config preset |
84
+ | `vvoc role list\|set\|unset` | Manage model role assignments |
85
+ | `vvoc preset list\|show\|<name>` | Inspect or apply named presets |
86
+ | `vvoc guardian config` | Print or write guardian section |
87
+ | `vvoc plugin list` | List OpenCode plugin entries |
88
+ | `vvoc patch-provider stepfun-ai\|zai\|openai` | Patch a global OpenCode config preset |
124
89
  | `vvoc completion` | Install shell completions |
125
- | `vvoc upgrade` | Upgrade the global package and run a follow-up sync |
126
- | `vvoc version` | Print the installed package version |
90
+ | `vvoc upgrade` | Upgrade global package and run follow-up sync |
91
+ | `vvoc version` | Print installed version |
127
92
 
128
- ## Model Roles And Presets
93
+ ---
129
94
 
130
- Inspect current role assignments:
95
+ ## Model Roles & Presets
131
96
 
132
97
  ```bash
98
+ # View current assignments
133
99
  vvoc role list
134
- ```
135
100
 
136
- Set role assignments (`provider/model[:variant]`):
137
-
138
- ```bash
101
+ # Assign models to roles
139
102
  vvoc role set default openai/gpt-5.4
140
103
  vvoc role set smart openai/vv-gpt-5.5-xhigh
141
104
  vvoc role set fast openai/gpt-5.4-mini
142
- vvoc role set team-review anthropic/claude-sonnet-4-5:high
143
- ```
144
-
145
- Remove custom role assignments:
146
-
147
- ```bash
148
- vvoc role unset team-review
149
- ```
150
-
151
- Built-in role IDs:
152
-
153
- - `default`
154
- - `smart`
155
- - `fast`
156
- - `vision`
157
-
158
- Role notes:
159
105
 
160
- - `vvoc role` mutates only canonical global `vvoc.json` (`roles` map)
161
- - built-in roles cannot be removed with `vvoc role unset`
162
- - custom role IDs must use lowercase letters, digits, and hyphens
163
-
164
- Presets are stored in canonical `vvoc.json` and are useful when you want to switch several role assignments together:
165
-
166
- ```bash
167
- vvoc preset list
168
- vvoc preset show vv-openai
106
+ # Switch provider presets
169
107
  vvoc preset vv-openai
170
108
  vvoc preset vv-zai
109
+ vvoc preset vv-deepseek
110
+ vvoc preset vv-minimax
111
+ vvoc preset vv-osovv
171
112
  ```
172
113
 
173
- Preset rules:
174
-
175
- - managed built-in presets are `vv-openai`, `vv-zai`, `vv-minimax`, and `vv-deepseek`
176
- - `vvoc install` and `vvoc sync` always refresh those managed `vv-*` presets back to vvoc defaults
177
- - `vv-openai` uses normal `openai/gpt-5.4` for `default`, keeps `smart` on the vv-managed xhigh alias `openai/vv-gpt-5.5-xhigh`, and keeps `fast`/`vision` on the conservative OpenAI defaults
178
- - run `vvoc patch-provider openai` before using the `vv-openai` smart role if the alias model is not already present in your global OpenCode config
179
- - user-defined presets with other names are preserved as-is, including legacy names such as `openai`, `zai`, and `minimax`
180
- - presets may be partial
181
- - applying a preset only changes the roles listed in that preset
182
- - `vvoc preset list/show/apply` reads the current canonical `vvoc.json` as-is and only bootstraps defaults when the file is missing
183
- - on existing `vvoc.json`, preset commands do not reseed or refresh managed preset definitions as a side effect
184
- - preset application updates only canonical global `vvoc.json` role assignments and does not rewrite OpenCode config directly
185
-
186
- ## Plugins Included
187
-
188
- ### ModelRolesPlugin
189
-
190
- `ModelRolesPlugin` resolves `vv-role:*` model references at startup for supported OpenCode config fields (`model`, `small_model`, `agent.*.model`, and `command.*.model`).
114
+ Built-in role IDs: `default`, `smart`, `fast`, `vision` + any custom lowercase-hyphenated IDs.
191
115
 
192
- Agent role assignments that include `:variant` are translated into native `model` plus `variant` fields.
116
+ Presets are partial applying one only changes the roles it defines. Managed built-in presets (`vv-*`) are refreshed on every `vvoc install`/`vvoc sync`; user-defined presets are preserved as-is.
193
117
 
194
- ### GuardianPlugin
118
+ ---
195
119
 
196
- `GuardianPlugin` reviews OpenCode permission requests with a constrained `guardian` agent and safe deny behavior.
120
+ ## Config & Data Layout
197
121
 
198
- Runtime settings live in the `guardian` section of canonical `vvoc.json`.
199
-
200
- Supported `guardian` fields:
201
-
202
- - `model`
203
- - `variant`
204
- - `timeoutMs`
205
- - `approvalRiskThreshold`
206
- - `reviewToastDurationMs`
207
-
208
- Print or update the `guardian` section:
209
-
210
- ```bash
211
- vvoc guardian config --print
212
- vvoc guardian config --model "anthropic/claude-sonnet-4-5" --variant high
213
122
  ```
214
-
215
- The runtime prompt is loaded from `guardian.md`, preferring `./.vvoc/agents/guardian.md` over the global `vvoc` agents directory.
216
-
217
- ### HashlineEditPlugin
218
-
219
- `HashlineEditPlugin` is enabled by default and replaces OpenCode's `edit` tool with a hash-anchored variant.
220
-
221
- It also rewrites `read` output from plain numbered rows such as `42: const value = 1;` into hashline rows such as `42#VK#AB|const value = 1;`, where the final hash anchors the surrounding context.
222
-
223
- The overridden `edit` tool requires those exact `line#hash#anchor` anchors, still accepts legacy `line#hash` anchors, and rejects stale references when the file changed since the last read, which prevents line-number drift and accidental writes against the wrong snapshot.
224
-
225
- Managed OpenCode config written by `vvoc install`, `vvoc sync`, and `vvoc init` also sets `tools.apply_patch = false` so sessions are steered away from the global `apply_patch` tool and onto the hashline-backed `edit` override.
226
- Primary chat sessions also receive a short system reminder to prefer `read` plus the hashline-backed `edit` tool over shell-based file rewrites when an edit is needed.
227
-
228
- ### MemoryPlugin
229
-
230
- `MemoryPlugin` adds explicit persistent memory tools and installs a report-only `memory-reviewer` subagent.
231
-
232
- Memory scopes are `session`, `branch`, `project`, and `shared`. Writes default to `project`; `shared` is cross-project, the rest are repository-local.
233
-
234
- Available tools:
235
-
236
- - `memory_search`
237
- - `memory_get`
238
- - `memory_put`
239
- - `memory_update`
240
- - `memory_delete`
241
- - `memory_list`
242
-
243
- Memory is explicit-only:
244
-
245
- - stored entries are never injected into prompts automatically
246
- - the agent must call memory tools directly when durable context is useful
247
- - `memory-reviewer` can read memory but cannot modify it
248
-
249
- Supported `memory` fields:
250
-
251
- - `enabled`
252
- - `defaultSearchLimit`
253
- - `reviewerModel`
254
- - `reviewerVariant`
255
-
256
- Example:
257
-
258
- ```text
259
- @memory-reviewer review the current memory and suggest keep/update/merge/delete actions
260
- ```
261
-
262
- The runtime prompt is loaded from `memory-reviewer.md`, preferring `./.vvoc/agents/memory-reviewer.md` over the global `vvoc` agents directory.
263
-
264
- ### SystemContextInjectionPlugin
265
-
266
- `SystemContextInjectionPlugin` injects reusable system guidance into primary sessions without polluting known subagent prompts.
267
-
268
- The default injected guidance tells the main session to proactively use the `explore` subagent for read-only context gathering when the task depends on unfamiliar code, unclear scope, or multiple candidate implementation areas. The `explore` subagent must not be asked to propose solutions, suggest plans, recommend changes, make design decisions, or evaluate trade-offs.
269
-
270
- ### WorkflowPlugin
271
-
272
- `vv-controller` is the managed default primary agent. It routes routine localized work directly, uses `investigator` for unclear bugs, uses tracked implementer/reviewer loops for risky or multi-file changes, and uses `vv-analyst` plus `vv-architect` for large-feature planning before implementation approval.
273
-
274
- Managed OpenCode commands:
275
-
276
- - `/vv-plan` routes the request through planning mode and stops before implementation
277
- - `/vv-review` routes the request through review-only mode and reports findings first
278
-
279
- `WorkflowPlugin` adds tracked workflow orchestration around the `task` tool for these managed subagents:
280
-
281
- - `vv-implementer`
282
- - `vv-spec-reviewer`
283
- - `vv-code-reviewer`
284
-
285
- It also registers three workflow tools:
286
-
287
- - `work_item_open`
288
- - `work_item_list`
289
- - `work_item_close`
290
-
291
- Tracked task prompts must start with a first-line header like:
292
-
293
- ```text
294
- VVOC_WORK_ITEM_ID: wi-1
295
- <assignment>
296
- <goal>Implement the approved change.</goal>
297
- <context>Repository-specific notes.</context>
298
- <verification>bun test src/plugins/workflow.test.ts</verification>
299
- </assignment>
300
- ```
301
-
302
- The lightweight XML-like tags are for assignment prompt bodies only. Keep `VVOC_WORK_ITEM_ID` as line 1 for tracked assignments, use `<reviewer_findings>` as a container when passing normalized review findings, and do not convert tracked final result fields into tags.
303
-
304
- Tracked result blocks must return strict top-block protocol fields (`VVOC_WORK_ITEM_ID`, `VVOC_STATUS`, and `VVOC_ROUTE` for `vv-implementer`).
305
-
306
- Main-session guidance reminds agents to open work items first for tracked implementer/reviewer loops, reuse returned headers, keep the tracked header first while using tagged assignment bodies, treat `NEEDS_CONTEXT` as a hard stop, inspect `work_item_list` before retries, and avoid free-form review loops without explicit work-item identity.
307
-
308
- Review-only workflows may start a fresh work item directly with `vv-spec-reviewer` or `vv-code-reviewer`; implementation workflows still follow `vv-implementer -> vv-spec-reviewer -> vv-code-reviewer`.
309
-
310
- ### SecretsRedactionPlugin
311
-
312
- `SecretsRedactionPlugin` redacts secrets from chat content before LLM requests and restores placeholders afterward where needed.
313
-
314
- Settings live in the `secretsRedaction` section of canonical `vvoc.json`.
315
-
316
- The default seeded config uses:
317
-
318
- ```json
319
- {
320
- "secret": "${VVOC_SECRET}"
321
- }
123
+ OpenCode config → OpenCode-managed paths (global or project)
124
+ vvoc.json (canonical) → $XDG_CONFIG_HOME/vvoc/vvoc.json
125
+ Managed agent prompts → $XDG_CONFIG_HOME/vvoc/agents/*.md (global)
126
+ ./.vvoc/agents/*.md (project)
127
+ Planning artifacts → ./.vvoc/plans/*
128
+ Persisted data → $XDG_DATA_HOME/vvoc/
322
129
  ```
323
130
 
324
- Set `VVOC_SECRET` if you want placeholder restoration to stay stable across restarts.
131
+ Schema is versioned and published with the package source of truth at `schemas/vvoc/v3.json`.
325
132
 
326
- Built-in patterns cover common identifiers and tokens such as email addresses, UUIDs, IP and MAC addresses, bearer tokens, and common OpenAI, Anthropic, GitHub, AWS, and Stripe-style keys.
133
+ ---
327
134
 
328
- ## Managed Prompts And Agents
135
+ ## Managed Agents
329
136
 
330
- Managed prompt files are created for:
137
+ All prompt files are scaffolded by `vvoc install` / `vvoc sync`:
331
138
 
332
- - `guardian`
333
- - `memory-reviewer`
334
- - `vv-controller`
335
- - `enhancer`
336
- - `vv-analyst`
337
- - `vv-architect`
338
- - `vv-implementer`
339
- - `vv-spec-reviewer`
340
- - `vv-code-reviewer`
341
- - `investigator`
139
+ | Agent | Role |
140
+ |---|---|
141
+ | `vv-controller` | Default primary agent — routes work to the right subagent |
142
+ | `enhancer` | Prompt enhancement |
143
+ | `vv-analyst` | Requirements analysis for large features |
144
+ | `vv-architect` | Module/contract/wave design |
145
+ | `vv-implementer` | Focused implementation with verification |
146
+ | `vv-spec-reviewer` | Checks implementation against spec |
147
+ | `vv-code-reviewer` | Engineering review for bugs and maintainability |
148
+ | `investigator` | Root-cause analysis for unclear bugs |
149
+ | `guardian` | Permission request review (plugin runtime) |
342
150
 
343
- OpenCode agent registrations written by `vvoc install` and `vvoc sync` are:
151
+ ---
344
152
 
345
- - `explore`
346
- - `vv-controller`
347
- - `enhancer`
348
- - `vv-analyst`
349
- - `vv-architect`
350
- - `vv-implementer`
351
- - `vv-spec-reviewer`
352
- - `vv-code-reviewer`
353
- - `investigator`
354
-
355
- Plugin runtime agents are:
356
-
357
- - `guardian`
358
- - `memory-reviewer`
359
-
360
- `vvoc install` and `vvoc sync` also keep OpenCode `default_agent` set to `vv-controller` and keep command entries for `vv-plan` and `vv-review` registered.
361
-
362
- If a managed prompt file is missing, rerun one of these commands:
153
+ ## Local Development
363
154
 
364
155
  ```bash
365
- vvoc install
366
- vvoc sync
156
+ bun install # Install dependencies
157
+ bun run check # Typecheck + lint + format check + test
158
+ bun run fmt # Auto-format source files
367
159
  ```
368
160
 
369
- ## Local Development
161
+ Git hooks managed via `lefthook`.
370
162
 
371
- Install dependencies:
163
+ ### Smoke-test the built CLI
372
164
 
373
165
  ```bash
374
- bun install
166
+ tmpdir="$(mktemp -d)"
167
+ bun run build
168
+ bun dist/cli.js install --config-dir "$tmpdir"
169
+ bun dist/cli.js status --config-dir "$tmpdir"
375
170
  ```
376
171
 
377
- Run the local verification stack:
172
+ ### Full release verification
378
173
 
379
174
  ```bash
380
- bun run typecheck
381
- bun run lint
382
- bun run fmt:check
383
- bun test
175
+ bun run check
384
176
  bun run build
385
177
  bun run pack:check
386
178
  ```
387
179
 
388
- Format source files:
389
-
390
- ```bash
391
- bun run fmt
392
- ```
180
+ ---
393
181
 
394
- Smoke-test the built CLI against a temporary config root:
182
+ ## Publishing
395
183
 
396
184
  ```bash
397
- tmpdir="$(mktemp -d)"
398
- bun run build
399
- bun dist/cli.js install --config-dir "$tmpdir"
400
- bun dist/cli.js status --config-dir "$tmpdir"
185
+ bun run check && bun run build && npm publish
401
186
  ```
402
187
 
403
- Git hooks are managed with `lefthook`.
404
-
405
- ## Publishing
188
+ Publishing is manual from the terminal. No CI publish workflows.
406
189
 
407
- Publishing is manual from the terminal.
408
-
409
- Typical release flow:
410
-
411
- ```bash
412
- bun run typecheck
413
- bun run lint
414
- bun run fmt:check
415
- bun test
416
- bun run build
417
- bun run pack:check
418
- npm publish
419
- ```
190
+ ---
420
191
 
421
192
  ## Optional: RTK
422
193
 
423
- [RTK](https://github.com/rtk-ai/rtk) is a CLI proxy that can reduce token usage for common developer commands. The interactive `vvoc init` flow recommends it after setup.
194
+ [RTK](https://github.com/rtk-ai/rtk) is a CLI proxy that reduces token usage for common developer commands. The interactive `vvoc init` flow recommends it after setup.
@@ -1,11 +1,11 @@
1
1
  // FILE: src/commands/completion.ts
2
- // VERSION: 0.5.14
2
+ // VERSION: 0.5.15
3
3
  // START_MODULE_CONTRACT
4
4
  // PURPOSE: Auto-detect shell and install vvoc completions idempotently.
5
5
  // SCOPE: Shell detection, completion file writing, nested command and preset completion generation for config/plugin/patch-provider/preset and the `role set|unset` flow, and rc file patching.
6
6
  // INPUTS: Current shell environment plus built-in vvoc command and preset names.
7
7
  // OUTPUTS: Shell-specific completion scripts and idempotent rc/config patches.
8
- // DEPENDS: [citty, node:fs/promises, node:path, node:os, src/lib/model-roles.ts]
8
+ // DEPENDS: [citty, node:fs/promises, node:path, node:os, src/lib/model-roles.ts, src/lib/vvoc-preset-registry.ts]
9
9
  // LINKS: [M-CLI-COMPLETION, M-CLI-COMMANDS]
10
10
  // ROLE: RUNTIME
11
11
  // MAP_MODE: EXPORTS
@@ -20,6 +20,7 @@
20
20
  // END_MODULE_MAP
21
21
  //
22
22
  // START_CHANGE_SUMMARY
23
+ // LAST_CHANGE: [v0.5.15 - Switched built-in preset completions to the shared internal preset registry so managed names stay in sync.]
23
24
  // LAST_CHANGE: [v0.5.14 - Restricted unset-role completions so shell suggestions no longer imply built-in roles are unsettable.]
24
25
  // END_CHANGE_SUMMARY
25
26
  import { defineCommand } from "citty";
@@ -27,6 +28,7 @@ import { appendFile, mkdir, readFile, writeFile } from "node:fs/promises";
27
28
  import { homedir } from "node:os";
28
29
  import { resolve } from "node:path";
29
30
  import { BUILTIN_ROLE_NAMES } from "../lib/model-roles.js";
31
+ import { BUILTIN_VVOC_PRESET_NAMES } from "../lib/vvoc-preset-registry.js";
30
32
  const VVOC_TOP_LEVEL_COMMANDS = [
31
33
  "completion",
32
34
  "config",
@@ -46,7 +48,6 @@ const VVOC_TOP_LEVEL_COMMANDS = [
46
48
  const VVOC_CONFIG_COMMANDS = ["validate"];
47
49
  const VVOC_PATCH_PROVIDER_PRESETS = ["stepfun-ai", "zai", "openai"];
48
50
  const VVOC_PRESET_COMMANDS = ["list", "show"];
49
- const VVOC_PRESET_NAMES = ["vv-openai", "vv-zai", "vv-minimax", "vv-deepseek"];
50
51
  const VVOC_PLUGIN_COMMANDS = ["list"];
51
52
  const VVOC_ROLE_COMMANDS = ["set", "unset", "list"];
52
53
  const VVOC_ROLE_IDS = [...BUILTIN_ROLE_NAMES];
@@ -148,8 +149,8 @@ export function generateBashCompletion() {
148
149
  const topLevelCommands = VVOC_TOP_LEVEL_COMMANDS.join(" ");
149
150
  const configCommands = VVOC_CONFIG_COMMANDS.join(" ");
150
151
  const patchProviderPresets = VVOC_PATCH_PROVIDER_PRESETS.join(" ");
151
- const presetCommands = [...VVOC_PRESET_COMMANDS, ...VVOC_PRESET_NAMES].join(" ");
152
- const presetNames = VVOC_PRESET_NAMES.join(" ");
152
+ const presetCommands = [...VVOC_PRESET_COMMANDS, ...BUILTIN_VVOC_PRESET_NAMES].join(" ");
153
+ const presetNames = BUILTIN_VVOC_PRESET_NAMES.join(" ");
153
154
  const pluginCommands = VVOC_PLUGIN_COMMANDS.join(" ");
154
155
  const roleCommands = VVOC_ROLE_COMMANDS.join(" ");
155
156
  const roleIds = VVOC_ROLE_IDS.join(" ");
@@ -264,16 +265,18 @@ export function generateZshCompletion() {
264
265
  for (const cmd of VVOC_TOP_LEVEL_COMMANDS) {
265
266
  lines.push(' "' + cmd + '"');
266
267
  }
267
- lines.push(" )", "", ' _arguments -C "1: :(' + VVOC_TOP_LEVEL_COMMANDS.join(" ") + ')" "*::arg:->args"', "", " case $line[1] in", " role)", " _vvoc_role_cmds", " ;;", " config)", " _vvoc_config_cmds", " ;;", " patch-provider)", " _vvoc_patch_provider_cmds", " ;;", " preset)", " _vvoc_preset_cmds", " ;;", " plugin)", " _vvoc_plugin_cmds", " ;;", " esac", "}", "", "_vvoc_config_cmds() {", " local -a config_commands", " config_commands=(" + VVOC_CONFIG_COMMANDS.join(" ") + ")", ' _arguments "1: :(' + VVOC_CONFIG_COMMANDS.join(" ") + ')"', "}", "", "_vvoc_patch_provider_cmds() {", ' _arguments "1: :(' + VVOC_PATCH_PROVIDER_PRESETS.join(" ") + ')"', "}", "", "_vvoc_preset_cmds() {", " case $words[2] in", " show)", ' _arguments "1: :(' + VVOC_PRESET_NAMES.join(" ") + ')"', " ;;", " *)", ' _arguments "1: :(' + [...VVOC_PRESET_COMMANDS, ...VVOC_PRESET_NAMES].join(" ") + ')"', " ;;", " esac", "}", "", "_vvoc_role_cmds() {", " case $words[2] in", " set)", ' _arguments "1: :(' + VVOC_ROLE_IDS.join(" ") + ')"', " ;;", " unset)", ' _arguments "1: :<custom-role-id>"', " ;;", " *)", ' _arguments "1: :(' + VVOC_ROLE_COMMANDS.join(" ") + ')"', " ;;", " esac", "}", "", "_vvoc_plugin_cmds() {", " local -a plugin_commands", " plugin_commands=(" + VVOC_PLUGIN_COMMANDS.join(" ") + ")", ' _arguments "1: :(' + VVOC_PLUGIN_COMMANDS.join(" ") + ')"', "}", "", "compdef _vvoc vvoc");
268
+ lines.push(" )", "", ' _arguments -C "1: :(' + VVOC_TOP_LEVEL_COMMANDS.join(" ") + ')" "*::arg:->args"', "", " case $line[1] in", " role)", " _vvoc_role_cmds", " ;;", " config)", " _vvoc_config_cmds", " ;;", " patch-provider)", " _vvoc_patch_provider_cmds", " ;;", " preset)", " _vvoc_preset_cmds", " ;;", " plugin)", " _vvoc_plugin_cmds", " ;;", " esac", "}", "", "_vvoc_config_cmds() {", " local -a config_commands", " config_commands=(" + VVOC_CONFIG_COMMANDS.join(" ") + ")", ' _arguments "1: :(' + VVOC_CONFIG_COMMANDS.join(" ") + ')"', "}", "", "_vvoc_patch_provider_cmds() {", ' _arguments "1: :(' + VVOC_PATCH_PROVIDER_PRESETS.join(" ") + ')"', "}", "", "_vvoc_preset_cmds() {", " case $words[2] in", " show)", ' _arguments "1: :(' + BUILTIN_VVOC_PRESET_NAMES.join(" ") + ')"', " ;;", " *)", ' _arguments "1: :(' +
269
+ [...VVOC_PRESET_COMMANDS, ...BUILTIN_VVOC_PRESET_NAMES].join(" ") +
270
+ ')"', " ;;", " esac", "}", "", "_vvoc_role_cmds() {", " case $words[2] in", " set)", ' _arguments "1: :(' + VVOC_ROLE_IDS.join(" ") + ')"', " ;;", " unset)", ' _arguments "1: :<custom-role-id>"', " ;;", " *)", ' _arguments "1: :(' + VVOC_ROLE_COMMANDS.join(" ") + ')"', " ;;", " esac", "}", "", "_vvoc_plugin_cmds() {", " local -a plugin_commands", " plugin_commands=(" + VVOC_PLUGIN_COMMANDS.join(" ") + ")", ' _arguments "1: :(' + VVOC_PLUGIN_COMMANDS.join(" ") + ')"', "}", "", "compdef _vvoc vvoc");
268
271
  return lines.join("\n") + "\n";
269
272
  }
270
273
  export function generateFishCompletion() {
271
- const presetCommands = [...VVOC_PRESET_COMMANDS, ...VVOC_PRESET_NAMES].join(" ");
274
+ const presetCommands = [...VVOC_PRESET_COMMANDS, ...BUILTIN_VVOC_PRESET_NAMES].join(" ");
272
275
  const lines = ["# fish completion for vvoc", "", "function __vvoc_commands"];
273
276
  for (const cmd of VVOC_TOP_LEVEL_COMMANDS) {
274
277
  lines.push(" echo " + cmd);
275
278
  }
276
- lines.push("end", "", "function __vvoc_config_cmds", " echo " + VVOC_CONFIG_COMMANDS.join(" "), "end", "", "function __vvoc_patch_provider_cmds", " echo " + VVOC_PATCH_PROVIDER_PRESETS.join(" "), "end", "", "function __vvoc_preset_cmds", " echo " + presetCommands, "end", "", "function __vvoc_preset_names", " echo " + VVOC_PRESET_NAMES.join(" "), "end", "", "function __vvoc_role_cmds", " echo " + VVOC_ROLE_COMMANDS.join(" "), "end", "", "function __vvoc_role_ids", " echo " + VVOC_ROLE_IDS.join(" "), "end", "", "function __vvoc_plugin_cmds", " echo " + VVOC_PLUGIN_COMMANDS.join(" "), "end", "", 'complete -c vvoc -f -a "(__vvoc_commands)"', 'complete -c vvoc -n "__fish_seen_subcommand_from role; and not __fish_seen_subcommand_from set unset list" -f -a "(__vvoc_role_cmds)"', 'complete -c vvoc -n "__fish_seen_subcommand_from role; and __fish_seen_subcommand_from set" -f -a "(__vvoc_role_ids)"', 'complete -c vvoc -n "__fish_seen_subcommand_from config" -f -a "(__vvoc_config_cmds)"', 'complete -c vvoc -n "__fish_seen_subcommand_from patch-provider" -f -a "(__vvoc_patch_provider_cmds)"', 'complete -c vvoc -n "__fish_seen_subcommand_from preset; and not __fish_seen_subcommand_from ' +
279
+ lines.push("end", "", "function __vvoc_config_cmds", " echo " + VVOC_CONFIG_COMMANDS.join(" "), "end", "", "function __vvoc_patch_provider_cmds", " echo " + VVOC_PATCH_PROVIDER_PRESETS.join(" "), "end", "", "function __vvoc_preset_cmds", " echo " + presetCommands, "end", "", "function __vvoc_preset_names", " echo " + BUILTIN_VVOC_PRESET_NAMES.join(" "), "end", "", "function __vvoc_role_cmds", " echo " + VVOC_ROLE_COMMANDS.join(" "), "end", "", "function __vvoc_role_ids", " echo " + VVOC_ROLE_IDS.join(" "), "end", "", "function __vvoc_plugin_cmds", " echo " + VVOC_PLUGIN_COMMANDS.join(" "), "end", "", 'complete -c vvoc -f -a "(__vvoc_commands)"', 'complete -c vvoc -n "__fish_seen_subcommand_from role; and not __fish_seen_subcommand_from set unset list" -f -a "(__vvoc_role_cmds)"', 'complete -c vvoc -n "__fish_seen_subcommand_from role; and __fish_seen_subcommand_from set" -f -a "(__vvoc_role_ids)"', 'complete -c vvoc -n "__fish_seen_subcommand_from config" -f -a "(__vvoc_config_cmds)"', 'complete -c vvoc -n "__fish_seen_subcommand_from patch-provider" -f -a "(__vvoc_patch_provider_cmds)"', 'complete -c vvoc -n "__fish_seen_subcommand_from preset; and not __fish_seen_subcommand_from ' +
277
280
  presetCommands +
278
281
  '" -f -a "(__vvoc_preset_cmds)"', 'complete -c vvoc -n "__fish_seen_subcommand_from preset; and __fish_seen_subcommand_from show" -f -a "(__vvoc_preset_names)"', 'complete -c vvoc -n "__fish_seen_subcommand_from plugin" -f -a "(__vvoc_plugin_cmds)"');
279
282
  return lines.join("\n") + "\n";