@osovv/vv-opencode 1.3.3 → 1.3.5

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
  # @osovv/vv-opencode
2
2
 
3
- **Curated, opinionated OpenCode plugin set** for spec-first, review-driven, safer agentic development — with managed agents, skills, safety plugins, and the `vvoc` CLI.
3
+ **An opinionated agentic development layer for OpenCode** — spec-first when it matters, review-driven execution, portable model roles, safer tools, and long-run safety. Under the hood it ships as a set of OpenCode plugins, managed agents, skills, and the `vvoc` CLI.
4
4
 
5
5
  <p>
6
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>
@@ -11,49 +11,87 @@
11
11
  <a href="LICENSE"><img src="https://img.shields.io/github/license/osovv/vv-opencode?style=flat&color=green" alt="MIT"></a>
12
12
  </p>
13
13
 
14
+ OpenCode owns the mechanics: streaming, model invocation, sandboxing, permissions. The development *process* — when to clarify, when to plan, when to review, how to survive long runs — it leaves up to you.
15
+
16
+ vv-opencode adds that process layer. It is a hand-picked workflow crystallized from a year and a half of daily agentic development: you run `vvoc install`, learn three skills (`vv-spec`, `vv-plan`, `vv-execute`), and get a disciplined spec-to-code pipeline with review gates, portable model roles, and long-run safety — without needing to know how any of it works inside.
17
+
18
+ The spec pipeline is the most visible part, but it is only one layer. Everything underneath runs on every session whether or not you ever write a spec: each model edits files through the tool it knows best, routine permissions are approved without interrupting your run, secrets never reach the model, and multi-agent work is held together by an explicit state machine instead of prompt luck. If you already have your own spec tooling, keep it — the runtime layers below apply anyway.
19
+
20
+ ---
21
+
22
+ ## Why vv-opencode?
23
+
24
+ OpenCode is a strong, flexible base, but it intentionally leaves the development process up to you. Left to itself, agentic work tends to drift: requirements get skipped, one agent silently implements and "reviews" itself, multi-agent loops churn through "one more final review", long runs stall on permission prompts, and model choices are hardcoded everywhere.
25
+
26
+ vv-opencode addresses each of these:
27
+
28
+ - **Formalized trajectories** — small changes stay direct, unclear bugs start with investigation, large changes go through spec and plan, risky implementation uses review loops.
29
+ - **Spec-first by default** — broad requests become explicit specs, plans, and review gates before implementation, and every artifact is saved as grep-able XML.
30
+ - **Review-driven execution** — implementation, spec review, and code review are separate steps with bounded retries, not one agent silently doing everything.
31
+ - **A state machine for multi-agent work** — explicit work items, required reviewers, round limits, and hard stops instead of free-form subagent loops.
32
+ - **Portable model choices** — agents reference roles like `vv-role:smart` and `vv-role:fast`; you map roles to concrete models per machine or project and switch stacks with one preset command.
33
+ - **Per-model editing** — each model edits through the tool it knows best: DeepSeek gets its `str_replace_editor` contract, GLM/Qwen/Kimi get exact-match replace, and GPT keeps the host editing path. Routing is resolved dynamically per session, and every edit is anchored to a fresh file read — fewer wrong-line and stale-context errors.
34
+ - **Provider-neutral web tools** — agents get one canonical `web_search` and `web_fetch` contract backed by Exa, Brave, Z.AI, native retrieval, or Spider, instead of provider-specific search and reader schemas leaking into your prompts.
35
+ - **Long-run safety** — Guardian auto-approves routine low-risk permissions (risky ones stay in OpenCode's manual approval flow), and secrets are redacted before they reach the model.
36
+ - **Reproducible setup** — `vvoc install` / `vvoc sync` recreate the same workflow on any machine or project.
37
+
38
+ ---
39
+
40
+ ## You just talk to OpenCode normally
41
+
42
+ You don't need to learn a command surface first. Ask for what you want — `vv-controller` picks the lightest appropriate trajectory, and explicit skills take over only when the work needs them:
43
+
44
+ ```text
45
+ > Rename this field and update its tests.
46
+ → handled directly
47
+
48
+ > Why does auth occasionally return 401 after a token refresh?
49
+ → root-cause investigation first → targeted fix → verification
50
+
51
+ > Add organizations with role-based access.
52
+ → vv-spec → approval → vv-plan → approval → vv-execute
53
+ ├─ implement
54
+ ├─ spec review
55
+ └─ code review
56
+ ```
57
+
58
+ Every managed skill can also be invoked explicitly when you want to drive the process yourself.
59
+
14
60
  ---
15
61
 
16
- ## Quick Start
62
+ ## Quick start
17
63
 
18
64
  ```bash
19
- bun add -g opencode-ai@1.18.2
65
+ bun add -g opencode-ai
20
66
  bun add -g @osovv/vv-opencode
21
67
  vvoc install
22
68
  ```
23
69
 
24
- That's it. `vvoc install` pins the server plugin, registers the same pinned package for OpenCode to load its `/context` TUI export, scaffolds managed agents and skills, writes canonical config, and sets `vv-controller` as your default OpenCode agent with auto-triggered spec, planning, review, reflection, and handoff skills. The TUI integration requires OpenCode `1.18.2` or newer; `vvoc status` and `vvoc doctor` report the installed host version and fail compatibility checks for older releases.
70
+ `vvoc install` does four things:
71
+
72
+ - pins `@osovv/vv-opencode` as an OpenCode runtime plugin and registers the same pinned package as the OpenCode TUI plugin;
73
+ - scaffolds the managed agents and skills;
74
+ - writes the canonical `vvoc.json` config;
75
+ - sets `vv-controller` as your default OpenCode agent, with the spec, planning, review, reflection, and handoff skills auto-triggered by request type.
25
76
 
26
- To scope everything to the current project instead of the global OpenCode config:
77
+ The TUI integration requires OpenCode `1.18.2` or newer; `vvoc status` and `vvoc doctor` report the installed host version and fail compatibility checks for older releases.
78
+
79
+ **Want to try it without touching your global setup?** Scope everything to one project:
27
80
 
28
81
  ```bash
29
82
  vvoc install --scope project
30
83
  vvoc launch --scope project
31
84
  ```
32
85
 
33
- Project scope writes only to `./.opencode/` and `./.vvoc/`. A normal `opencode` launch may still apply OpenCode's native config discovery and merge behavior; `vvoc launch --scope project` is the hard sandbox path and starts OpenCode with `OPENCODE_CONFIG`, `OPENCODE_TUI_CONFIG`, and `VVOC_CONFIG` pinned to the selected local files, so you can smoke-test vv-opencode in one repository without mutating your primary global setup.
86
+ Project scope writes only to `./.opencode/` and `./.vvoc/`. A plain `opencode` launch may still apply OpenCode's native config discovery and merge behavior; `vvoc launch --scope project` is the hard sandbox path — it starts OpenCode with `OPENCODE_CONFIG`, `OPENCODE_TUI_CONFIG`, and `VVOC_CONFIG` pinned to the selected local files, so you can smoke-test vv-opencode in one repository without mutating your primary global setup.
34
87
 
35
88
  > **Already installed?** Run `vvoc sync` anytime to refresh plugins, prompts, skills, and presets.
36
89
 
37
90
  ---
38
91
 
39
- ## 1.0 Stability Posture
40
-
41
- `vv-opencode` 1.0 marks the workflow as a daily-driver baseline: a hand-picked, curated OpenCode setup that packages the agent routing, managed skills, model-role indirection, safer editing, review loops, and release discipline used in real projects.
42
-
43
- The stable user-facing surface is intentionally practical:
92
+ ## How it works: spec → plan → execute
44
93
 
45
- - `vvoc install` / `vvoc sync` / `vvoc launch` remain the primary setup and refresh path.
46
- - `vv-spec`, `vv-plan`, and `vv-execute` remain the canonical spec-to-code path for larger work.
47
- - `vv-review`, `vv-reflect`, and `vv-handoff` remain the auxiliary review, durable-learning, and session-continuity workflows.
48
- - The published package exports, CLI command names, canonical vvoc schema v3, and date-prefixed `.vvoc/specs/YYYY-MM-DD-<slug>/` artifact layout are treated as compatibility surfaces.
49
-
50
- The project still prefers conservative, explicit changes over hidden migration magic: user-owned config is not silently clobbered, invalid current config fails loudly, and breaking workflow or config changes must be documented in release notes.
51
-
52
- ---
53
-
54
- ## Spec-to-Code Pipeline
55
-
56
- vvoc keeps larger agentic work from jumping straight into edits. The process turns a request into explicit artifacts first, then executes the approved plan with bounded implementation and review loops.
94
+ vvoc keeps larger agentic work from jumping straight into edits. A request first becomes explicit artifacts; only the approved plan gets executed, with bounded implementation and review loops. This trajectory is opt-in per request: small changes never go through it, and if you already run your own spec workflow, you can keep it — nothing else in vv-opencode depends on these skills.
57
95
 
58
96
  ```
59
97
  Request / idea
@@ -77,7 +115,7 @@ vv-execute
77
115
  Verified result
78
116
  ```
79
117
 
80
- Inside `vv-execute`:
118
+ Inside `vv-execute`, each plan task goes through a tracked loop:
81
119
 
82
120
  ```text
83
121
  Each plan task
@@ -106,84 +144,243 @@ All artifacts for one feature live together:
106
144
  plan.xml # how to implement and verify it
107
145
  ```
108
146
 
109
- New `vv-spec` packages use a date-prefixed id (`YYYY-MM-DD-<slug>`, for example `2026-06-24-cache-store`) so active packages sort by creation date. The prefix is date-only; it must not include hours, minutes, seconds, timezone, or a full ISO timestamp.
147
+ Package ids are date-prefixed (`YYYY-MM-DD-<slug>`, for example `2026-06-24-cache-store`) so active packages sort by creation date; the prefix is date-only, never a full timestamp. Spec and plan lifecycle runs through a top-level status: `draft` while being written, `approved` after explicit user approval, `applied` after successful execution. `vv-execute` archives applied packages by moving the whole directory to `.vvoc/specs/archive/YYYY-MM-DD-<slug>-<timestamp>/`.
110
148
 
111
- Specs and plans use a top-level lifecycle status: `draft` while being written, `approved` after explicit user approval, and `applied` after successful execution. `vv-execute` archives applied artifact packages by moving the entire spec package directory `.vvoc/specs/YYYY-MM-DD-<slug>/` to `.vvoc/specs/archive/YYYY-MM-DD-<slug>-<timestamp>/`.
149
+ Specs and plans are XML, so requirements, tasks, acceptance criteria, and dependencies stay grep-able. Task and wave identity lives in unique element names (`<TASK-T-001>…</TASK-T-001>`, `<WAVE-1>…</WAVE-1>`), so grep/sed extraction stays exact without a separate query language:
112
150
 
113
- ### XML grep
151
+ ```bash
152
+ grep '<TASK-T-' .vvoc/specs/*/plan.xml # task ids
153
+ grep '<criterion>' .vvoc/specs/*/plan.xml # acceptance criteria
154
+ grep '<task_id>' .vvoc/specs/*/plan.xml # dependency graph
155
+ ```
114
156
 
115
- Plans and specs are XML documents, making every element grep-able:
157
+ `vv-controller` explicitly routes `vv-spec`, `vv-plan`, and `vv-review`; `vv-execute`, `vv-reflect`, and `vv-handoff` are available as managed skills for plan execution, durable repository memory, and end-of-session handoff notes.
116
158
 
117
- ```bash
118
- # Extract tasks from plan
119
- grep '<id>T-' .vvoc/specs/*/plan.xml
159
+ ---
120
160
 
121
- # Extract all acceptance criteria
122
- grep '<criterion>' .vvoc/specs/*/plan.xml
161
+ ## What's inside
123
162
 
124
- # Extract dependency graph
125
- grep '<task_id>' .vvoc/specs/*/plan.xml
163
+ ### The ten plugins
126
164
 
127
- # Extract method signatures
128
- grep '/\*\*' .vvoc/specs/*/plan.xml
165
+ | Plugin | What it does |
166
+ |---|---|
167
+ | **WorkflowPlugin** | A state machine over multi-agent work: explicit work items, required reviewers, bounded implementation/review rounds, and hard stops when more context is needed. |
168
+ | **ModelRolesPlugin** | Semantic model roles (`vv-role:smart`, `vv-role:fast`, …) instead of hardcoded model IDs in agents, subagents, and commands — resolved per machine or project at startup. |
169
+ | **GuardianPlugin** | Keeps long or AFK runs moving by auto-approving routine low-risk permission requests; anything risky stays in OpenCode's normal manual approval flow. |
170
+ | **HashlineEditPlugin** | Routes each model to the edit tool it knows best (DeepSeek `str_replace_editor`, exact replace for GLM/Qwen/Kimi, host path for GPT) and ties every edit to a fresh `read`, reducing wrong-line and stale-context edits. |
171
+ | **SystemContextInjectionPlugin** | Injects the work policy selected by the orchestration profile into vv-controller at startup, plus skill discovery; subagents stay unpolluted. |
172
+ | **SecretsRedactionPlugin** | Redacts tokens, keys, emails, and other sensitive values before messages reach the model, restoring them only where local execution needs the originals. |
173
+ | **WebToolsPlugin** | Two provider-neutral tools — `web_search` and `web_fetch` — over Exa, Brave, Z.AI, native retrieval, or Spider, with permission checks and normalized output. |
174
+ | **ToolHistoryCompactionPlugin** | Shrinks the context replayed to the model by compacting old tool outputs non-destructively, without touching on-disk history. |
175
+ | **AnalyticsPlugin** | Local-only token and cache telemetry per model step, a live `cache NN%` indicator in the TUI, and `vvoc analytics cache-hit-rate` for retrospective comparison. |
176
+ | **ContextTuiPlugin** | The `/context` inspector: an honest, scrollable TUI dialog showing context-window usage by category, tool, and MCP server. |
177
+
178
+ ### Managed agents
129
179
 
130
- # Extract all modules from architecture
131
- grep '<name>' .vvoc/specs/*/plan.xml
132
- ```
180
+ All prompt files are scaffolded by `vvoc install` / `vvoc sync`:
133
181
 
134
- Managed skills are installed by `vvoc`. `vv-controller` explicitly routes `vv-spec`, `vv-plan`, and `vv-review`; `vv-execute`, `vv-reflect`, and `vv-handoff` are available as managed skills for plan execution, durable repository memory, and end-of-session handoff notes.
182
+ | Agent | When it helps |
183
+ |---|---|
184
+ | `vv-controller` | Primary agent that follows the concrete work policy selected for the session by the orchestration profile |
185
+ | `enhancer` | Improves rough requests before execution when a clearer prompt would help |
186
+ | `vv-implementer` | Applies a focused approved change and verifies it before reporting completion |
187
+ | `vv-spec-reviewer` | Checks whether implementation matches the requested spec and acceptance criteria |
188
+ | `vv-code-reviewer` | Looks for bugs, regressions, maintainability risks, and missing tests |
189
+ | `investigator` | Finds the root cause first when behavior is unclear or a failure needs diagnosis |
190
+ | `guardian` | Supports GuardianPlugin by reviewing permission requests and auto-approving only routine low-risk ones |
191
+
192
+ ### Managed skills
193
+
194
+ Two families: `vv-*` skills guide the work protocol, while `vvoc-*` skills operate and observe the vvoc/OpenCode tooling itself.
195
+
196
+ | Skill | When to use it | What it gives you |
197
+ |---|---|---|
198
+ | `vv-spec` | You have a feature or creative request and no agreed contract yet | A guided interview, recommended options, and a saved spec in `.vvoc/specs/YYYY-MM-DD-<slug>/spec.xml` |
199
+ | `vv-plan` | A spec is approved and ready to implement | A task-level implementation plan with file targets, contracts, dependencies, and acceptance criteria |
200
+ | `vv-execute` | A plan is approved and you want it applied step by step | Ordered execution with verification, an explicit inline-or-classic mode choice, and applied spec/plan archival |
201
+ | `vv-review` | You want findings, not fixes | A review-only workflow that reports spec/code issues and stops before implementation |
202
+ | `vv-reflect` | A long development, debugging, ops, or investigation session produced reusable knowledge | Durable notes in existing docs or `.vvoc/lessons` / `.vvoc/runbooks` for future agents |
203
+ | `vv-handoff` | You are ending a session and want the visible context preserved | A redacted XML note at `.vvoc/handoff/YYYY-MM-DD-<session-slug>/handoff.xml`, written from already-visible context only |
204
+ | `vvoc-usage-analytics` | You ask about token usage, cache hit rate, costs, or caching regressions | Read-only analysis across `vvoc analytics`, the analytics JSONL, and historical `opencode.db` data |
205
+
206
+ Skills are loaded by OpenCode at session start through `config.skills.paths` (registered by SystemContextInjectionPlugin); the `vv-controller` agent's skill-trigger rules invoke them automatically when a request matches their conditions.
135
207
 
136
208
  ---
137
209
 
138
- ## Why vv-opencode?
210
+ ## CLI at a glance
139
211
 
140
- OpenCode is a strong, flexible base for agentic coding, but it intentionally leaves the development process mostly up to you: when to clarify requirements, when to plan, when to investigate first, when to review, and how to keep longer runs safe. That flexibility is powerful, but it can also make agent work feel loose and inconsistent.
212
+ | Command | Purpose |
213
+ |---|---|
214
+ | `vvoc init` | Interactive bootstrap flow |
215
+ | `vvoc install` | Non-interactive setup and scaffolding |
216
+ | `vvoc sync` | Refresh runtime/TUI plugin entries, agents, prompts, skills, config |
217
+ | `vvoc launch` | Launch OpenCode with deterministic runtime, TUI, and vvoc config sources |
218
+ | `vvoc status` | Show current installation state, including OpenCode version compatibility and TUI registration |
219
+ | `vvoc doctor` | Diagnose OpenCode version/runtime/TUI/vvoc setup problems (exits non-zero on issues) |
220
+ | `vvoc config validate` | Validate canonical `vvoc.json` |
221
+ | `vvoc role list\|set\|unset` | Manage model role assignments |
222
+ | `vvoc preset list\|show\|<name>` | Inspect or apply named presets |
223
+ | `vvoc guardian config` | Print or write the guardian section |
224
+ | `vvoc plugin list` | List OpenCode plugin entries |
225
+ | `vvoc plugin enable\|disable` | Toggle a vvoc-managed plugin on or off |
226
+ | `vvoc orchestration show\|set` | Show or set the vv-controller orchestration profile |
227
+ | `vvoc patch-provider stepfun-ai\|codex\|deepseek\|kimi\|alibaba\|all` | Patch OpenCode providers; `codex` adds subscription-safe OpenAI aliases (also accepts `openai`), `deepseek`/`kimi`/`alibaba` add vv- reasoning-effort aliases, `all` patches every provider at once |
228
+ | `vvoc completion` | Install shell completions |
229
+ | `vvoc upgrade` | Upgrade the global package and run follow-up sync; sync failure is reported as a partial upgrade |
230
+ | `vvoc analytics cache-hit-rate` | Aggregate persisted cache hit rate by day, week, month, session, model, provider, project, vvoc version, or OpenCode version |
231
+ | `vvoc version` | Print installed version |
141
232
 
142
- **vv-opencode adds a curated process layer on top of OpenCode:**
233
+ Guardian duration overrides use positive whole milliseconds. Both `--timeout-ms` and `--review-toast-duration-ms` reject zero, negative, fractional, missing, or malformed values:
143
234
 
144
- - **Formalized trajectories** — small changes stay direct, unclear bugs start with investigation, large changes go through spec and plan, and risky implementation uses review loops
145
- - **Spec-first by default** — turn broad requests into explicit specs, plans, and review gates before implementation
146
- - **Review-driven execution** — keep implementation, spec review, and code review as separate steps instead of one agent silently doing everything
147
- - **Portable model choices** — use roles like `vv-role:smart` and `vv-role:fast` in shared agents, then map those roles per machine or project
148
- - **Long-run safety** — Guardian auto-approves routine low-risk permission requests, leaves risky ones to OpenCode's manual approval flow, and secrets redaction reduces accidental leakage
149
- - **Safer edits** — per-model edit routing gives each model its native editing tool: hashline-anchored edits, exact oldString/newString replace, or the DeepSeek `str_replace_editor`, all tied to fresh `read` output so agents rarely write against stale content
235
+ ```bash
236
+ vvoc guardian config --print --timeout-ms 30000 --review-toast-duration-ms 5000
237
+ ```
150
238
 
151
239
  ---
152
240
 
153
- ## Features
241
+ ## Configuration
154
242
 
155
- | Area | What you get |
156
- |---|---|
157
- | **Plugins** | A curated set of OpenCode plugins that make agentic work more structured, portable, and safer without hand-wiring each piece yourself |
158
- | **Agent System** | A default controller (vv-controller) that follows the concrete work policy selected by the orchestration profile |
159
- | **Skills** | Guided workflows for turning ideas into specs, specs into plans, plans into execution, reviews into findings, and long sessions into reusable memory |
160
- | **Spec-to-Code Pipeline** | A repeatable path from request → spec → plan → implementation → review, so agents do not silently skip requirements or acceptance criteria |
161
- | **One-Click Setup** | Recreate the same opinionated workflow on a new machine or project with `vvoc install` / `vvoc sync` |
162
- | **CLI Tooling** | Operate and diagnose the setup from one CLI: install, sync, launch, status, doctor, roles, presets, orchestration profiles, plugin toggles, completion, and upgrade |
163
- | **Long-Run Safety** | Guardian keeps safe long/AFK runs moving by auto-approving routine low-risk permissions, while risky actions stay in OpenCode's manual approval flow; secrets redaction reduces accidental leakage |
164
- | **Model Roles** | Put roles like `vv-role:smart` or `vv-role:fast` in shared agents and skills instead of hardcoded model IDs, then choose provider/model mappings per environment |
165
- | **Orchestration Profiles** | Select a concrete work policy — single-session, balanced, or orchestrated — to control how vv-controller delegates. Built-in presets pick a sensible default and status reports the effective profile. |
166
- | **Workflow Tracking** | Replace free-form multi-agent chaos with explicit work items, bounded review rounds, reviewer result collection, and hard stops when more context is needed |
167
- | **Unified Web Tools** | Replace provider-specific search and reader schemas with the canonical `web_search` and `web_fetch` tools, configurable for Exa, Brave, native retrieval, or Spider extraction |
168
- | **Context Inspector** | Run `/context` in an active OpenCode TUI session for Overview, Tools, and MCP tabs with provider-reported usage, approximate context-window percentages, active post-compaction tool history, and deterministic source attribution |
169
- | **Cache Analytics** | Watch a live per-session `cache NN%` indicator in the TUI and compare cache hit rates across vvoc releases, OpenCode versions, models, and projects with `vvoc analytics cache-hit-rate` |
243
+ Mutating commands default to global scope for backward compatibility; add `--scope project` to write a project-local layer. Read and diagnostic commands accept `--scope global|project|effective`, where `effective` resolves in this order:
244
+
245
+ 1. explicit env override (`VVOC_CONFIG` / `OPENCODE_CONFIG` / `OPENCODE_TUI_CONFIG`)
246
+ 2. nearest project layer
247
+ 3. global layer
248
+ 4. built-in defaults when the command/runtime permits defaults
249
+
250
+ Canonical project-local paths:
251
+
252
+ ```text
253
+ OpenCode config → ./.opencode/opencode.json(c)
254
+ OpenCode TUI config → ./.opencode/tui.json(c)
255
+ vvoc config → ./.vvoc/vvoc.json
256
+ Managed agent prompts → ./.vvoc/agents/*.md
257
+ Managed skills → ./.vvoc/skills/*/SKILL.md
258
+ Spec package directory → ./.vvoc/specs/YYYY-MM-DD-<slug>/
259
+ Handoff notes → ./.vvoc/handoff/YYYY-MM-DD-<session-slug>/handoff.xml
260
+ Repository memory → ./.vvoc/lessons/*.xml, ./.vvoc/runbooks/*.xml
261
+ ```
262
+
263
+ Legacy root-level `./opencode.json` and `./opencode.jsonc` are intentionally not used as vvoc project layers.
264
+
265
+ Global paths:
266
+
267
+ ```text
268
+ OpenCode config → $XDG_CONFIG_HOME/opencode/opencode.json
269
+ OpenCode TUI config → $XDG_CONFIG_HOME/opencode/tui.json(c)
270
+ vvoc config → $XDG_CONFIG_HOME/vvoc/vvoc.json
271
+ Managed agent prompts → $XDG_CONFIG_HOME/vvoc/agents/*.md
272
+ Managed skills → $XDG_CONFIG_HOME/vvoc/skills/*/SKILL.md
273
+ Persisted data → $XDG_DATA_HOME/vvoc/
274
+ Usage analytics → $XDG_DATA_HOME/vvoc/analytics/usage-YYYY-MM.jsonl
275
+ ```
276
+
277
+ ### Two config surfaces, one pinned package
278
+
279
+ OpenCode keeps server/runtime plugins and native TUI plugins in separate configuration surfaces. `opencode.json(c)` is loaded by the core/server plugin runtime and activates vvoc features such as model roles, Guardian, workflow, hashline edit, redaction, and web tools. `tui.json(c)` is loaded by the terminal UI process and activates the package's `./tui` module (the `/context` inspector). The same pinned package version appears in both files, but OpenCode selects a different public export for each process; headless/server launches therefore never load the UI module.
280
+
281
+ `vvoc install`, `vvoc init`, and `vvoc sync` conservatively add the pinned base package specifier (for example `@osovv/vv-opencode@X.Y.Z`) to `tui.json(c)`; sync also migrates the broken legacy `@osovv/vv-opencode/tui` form and older managed pins. Existing comments, unrelated settings, unrelated plugin entries, and `[specifier, options]` tuples are preserved; malformed plugin entries fail without rewrite.
282
+
283
+ Runtime plugins load the effective `vvoc.json` once during OpenCode startup and share one immutable config snapshot for the lifetime of the process. There is no live reload: restart OpenCode after changing `vvoc.json` or `tui.json(c)`.
284
+
285
+ ### Strict schema, loud failures
286
+
287
+ The config contract is versioned and published with the package — source of truth at `schemas/vvoc/v3.json`. `vvoc.json` must be canonical version 3 and include required sections such as `plugins`. Existing v1/v2/pre-role, incomplete, malformed, or otherwise invalid config files fail instead of being migrated or repaired. `vvoc install` and `vvoc sync` may create a fresh canonical config when no config exists, but they refuse to rewrite an invalid existing `vvoc.json`; fix the file manually and rerun `vvoc sync`.
288
+
289
+ The optional schema-v3 `web` section follows the same layer precedence and is omitted from generated defaults — see [Web tools](#web-tools) for provider selection:
290
+
291
+ ```json
292
+ "web": {
293
+ "search": { "provider": "exa", "apiKey": "optional-exa-key" },
294
+ "fetch": { "provider": "native" }
295
+ }
296
+ ```
297
+
298
+ ### Diagnostics never mutate
299
+
300
+ `vvoc status` and `vvoc doctor` report the installed OpenCode version, the `1.18.2` TUI minimum, selected runtime/TUI/vvoc config paths, and validation problems without normalizing or rewriting files. `vvoc upgrade` can still finish the package installation when the follow-up `vvoc sync` fails; it then reports a partial upgrade, leaves config unchanged, and tells you to fix the invalid config before rerunning `vvoc sync`.
301
+
302
+ Runtime compatibility is current-only: Guardian permission replies use the current OpenCode permission reply path (with the current HTTP reply fallback), hashline edit refs must use current hash/context anchors, and sync writes current managed agents without deleting old pre-rename user or command entries.
303
+
304
+ ### Stability and compatibility
305
+
306
+ Since 1.0, vv-opencode treats the daily-driver surface as stable. The compatibility surfaces are: `vvoc install` / `vvoc sync` / `vvoc launch`, the managed skill names (`vv-spec`, `vv-plan`, `vv-execute`, `vv-review`, `vv-reflect`, `vv-handoff`), the published package exports, canonical vvoc schema v3, and the date-prefixed `.vvoc/specs/YYYY-MM-DD-<slug>/` artifact layout. Breaking workflow or config changes are documented in release notes. The project still prefers conservative, explicit changes over hidden migration magic: user-owned config is never silently clobbered, and invalid current config fails loudly.
307
+
308
+ ### Deterministic local launch
309
+
310
+ Use `vvoc launch` when the vvoc-selected config files should be the only files OpenCode sees for this run:
311
+
312
+ ```bash
313
+ vvoc install --scope project
314
+ vvoc launch --scope project -- run "hello"
315
+ ```
316
+
317
+ `vvoc launch --scope project` is strict and non-mutating: if `.opencode/opencode.json` or `.vvoc/vvoc.json` is missing, it fails with a hint to run `vvoc install --scope project`. When the selected `.opencode/tui.json(c)` exists, launch also sets `OPENCODE_TUI_CONFIG`; a missing TUI file is not synthesized. `--scope effective` follows the layered lookup order, and `--scope global` uses the global config paths.
170
318
 
171
319
  ---
172
320
 
173
- ## The Ten Plugins
321
+ ## Deep dives
322
+
323
+ ### Model roles & presets
324
+
325
+ ```bash
326
+ # View current assignments
327
+ vvoc role list
328
+ vvoc role list --scope effective
329
+
330
+ # Assign models to roles
331
+ vvoc role set default deepseek/deepseek-v4-flash
332
+ vvoc role set smart openai/vv-codex-gpt-5.6-sol-xhigh
333
+ vvoc role set fast openai/vv-codex-gpt-5.6-luna-low
334
+ vvoc role set reviewer zai-coding-plan/glm-5.2 --scope project
335
+
336
+ # Switch provider presets
337
+ vvoc preset vv-codex
338
+ vvoc preset vv-zai
339
+ vvoc preset vv-deepseek
340
+ vvoc preset vv-kimi
341
+ vvoc preset vv-alibaba
342
+ vvoc preset vv-osovv-sol
343
+ vvoc preset vv-osovv-flash
344
+ vvoc preset vv-osovv-kimi
345
+ vvoc preset vv-osovv-qwen
346
+ ```
347
+
348
+ Built-in role IDs: `default`, `smart`, `fast`, `reviewer`, plus any custom lowercase-hyphenated IDs. 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.
349
+
350
+ ### Orchestration profiles
351
+
352
+ Three concrete policies control how vv-controller delegates work at runtime:
353
+
354
+ - `single-session` — vv-controller performs exploration, investigation, planning, implementation, and verification directly. Independent reviewer subagents remain available when the user explicitly requests review or when a materially risky completed change benefits from independent cross-model evaluation.
355
+ - `balanced` — vv-controller keeps architecture, critical reading, and final synthesis in the primary session and may selectively delegate bounded search, investigation, mechanical implementation, or review when that is the lightest safe route. Delegation is optional, not mechanically mandatory.
356
+ - `orchestrated` — vv-controller uses the full tracked implementer/reviewer workflow with explicit work items, required reviewers, bounded rounds, and hard stops.
357
+
358
+ Pick a profile explicitly or let a built-in preset select one:
359
+
360
+ ```bash
361
+ vvoc orchestration show --scope effective
362
+ vvoc orchestration set single-session --scope project
363
+ ```
174
364
 
175
- | Plugin | What it helps you do |
365
+ Built-in presets declare an orchestration mapping:
366
+
367
+ | Preset | Profile |
176
368
  |---|---|
177
- | **WorkflowPlugin** | Keep multi-agent work structured with explicit work items, bounded implementation/review loops, reviewer result collection, and safe stops when more context is needed. |
178
- | **ModelRolesPlugin** | Use semantic model roles instead of hardcoded model IDs in OpenCode agents, subagents, and command configs — e.g. `vv-role:smart`, `vv-role:fast` — then map those roles per machine or project. |
179
- | **GuardianPlugin** | Keep long or AFK agent runs moving by auto-approving routine low-risk permission requests. If something looks risky, Guardian does not auto-approve it and leaves the decision to OpenCode's normal manual approval flow. |
180
- | **HashlineEditPlugin** | Route each model to its native editing tool (hashline anchors, exact replace, or DeepSeek `str_replace_editor`), tying changes to fresh `read` output to reduce wrong-line and stale-context edits. |
181
- | **SystemContextInjectionPlugin** | Inject universal primary guidance plus one startup-resolved orchestration policy into vv-controller, with skill discovery and subagent-only explore worker prompts. |
182
- | **SecretsRedactionPlugin** | Reduce accidental secret leakage by redacting tokens, keys, emails, and other sensitive values before messages are sent to the model. |
183
- | **WebToolsPlugin** | Register the provider-neutral `web_search` and `web_fetch` tools, return direct image/PDF attachments, and hide OpenCode's built-in web tools at runtime unless the user explicitly configured their permissions. |
184
- | **ContextTuiPlugin** | Add a native scrollable `/context` dialog with measured usage plus detailed observable per-tool and per-MCP schema/history estimates, explicitly marking data that OpenCode does not expose. |
185
- | **ToolHistoryCompactionPlugin** | Shrink the replayed conversation context non-destructively by compacting old tool outputs in the model replay (old reads to `[Read <file>, lines X-Y]`, over-budget ephemeral outputs pruned), while retaining web/search/skill knowledge results. |
186
- | **AnalyticsPlugin** | Persist per-step token and cache telemetry with vvoc/OpenCode version attribution, show a live `cache NN%` indicator next to the session prompt plus a combined OpenCode/vvoc version line in the sidebar footer, and answer "did my cache optimizations help?" via `vvoc analytics cache-hit-rate`. |
369
+ | `vv-codex` | single-session |
370
+ | `vv-kimi` | single-session |
371
+ | `vv-alibaba` | single-session |
372
+ | `vv-osovv-sol` | single-session |
373
+ | `vv-osovv-flash` | single-session |
374
+ | `vv-osovv-kimi` | single-session |
375
+ | `vv-osovv-qwen` | single-session |
376
+ | `vv-zai` | balanced |
377
+ | `vv-deepseek` | balanced |
378
+
379
+ Applying a built-in preset changes both model roles and the root orchestration profile atomically. A custom user-defined preset without an orchestration section preserves the current root profile. `vvoc status` reports the profile resolved from the selected vvoc source; effective status with no config files reports `balanced`.
380
+
381
+ Profiles are enforced through the concrete policy injected into vv-controller at startup — the model only receives its active work instructions and never sees inactive profile alternatives. The first version does not disable tools, change permissions, or block subagent types; the policy is prompt-driven, and asynchronous vv-execute classic mode remains available through that skill's explicit inline/classic selection. Profile changes take effect after an OpenCode restart, like all vvoc config changes.
382
+
383
+ ### Workflow work items
187
384
 
188
385
  Workflow work items are opened with explicit intent. For implementation loops, controllers use:
189
386
 
@@ -202,7 +399,7 @@ Workflow work items are opened with explicit intent. For implementation loops, c
202
399
 
203
400
  For review-only reports, use `"mode": "review_only"`. In review-only mode, reviewer `FAIL` is a completed finding result: required reviewers are collected independently, parallel `spec` and `code` reviewers may both return `FAIL`, and the item does not route to `vv-implementer` unless the user explicitly requests fixes.
204
401
 
205
- ### Edit Format Routing
402
+ ### Edit format routing
206
403
 
207
404
  `HashlineEditPlugin` resolves an edit mode per session model and exposes only the matching edit tool to that model:
208
405
 
@@ -213,9 +410,7 @@ For review-only reports, use `"mode": "review_only"`. In review-only mode, revie
213
410
 
214
411
  The default routing table sends `deepseek` to `str_replace_editor`, `kimi`, `qwen`, and `glm` to `replace`, and `gpt`/`codex` to `passthrough`; everything else stays on `hashline`. Patterns match case-insensitively against the session `providerID` first, then `modelID`; the first matching rule wins.
215
412
 
216
- `vvoc sync` and `vvoc init` write this default table into `vvoc.json` so it is visible and editable. Materialization is conservative: a routing value you have changed is never overwritten; the table is only filled in where it is missing.
217
-
218
- Override routing in `vvoc.json` (schema v3). The `plugins["hashline-edit"]` entry accepts a boolean or an object:
413
+ `vvoc sync` and `vvoc init` write this default table into `vvoc.json` so it is visible and editable. Materialization is conservative: a routing value you have changed is never overwritten; the table is only filled in where it is missing. Override routing in `vvoc.json` (schema v3) — the `plugins["hashline-edit"]` entry accepts a boolean or an object:
219
414
 
220
415
  ```json
221
416
  "plugins": {
@@ -228,19 +423,22 @@ Override routing in `vvoc.json` (schema v3). The `plugins["hashline-edit"]` entr
228
423
  }
229
424
  }
230
425
  ```
426
+
231
427
  Routing changes require an OpenCode restart, like other runtime plugin settings.
232
428
 
233
- ### Tool History Compaction
429
+ ### Tool history compaction
234
430
 
235
431
  `ToolHistoryCompactionPlugin` shrinks the context replayed to the model on every turn without touching on-disk storage. It rewrites only the in-memory message copy through the `experimental.chat.messages.transform` hook, and only the `output` of old completed tool parts — `input` and part structure (callID/type/order) are never changed, so provider tool_use/tool_result stitching stays intact.
236
432
 
433
+ The recent working context is never touched: the newest message and the last `protectRecentMessages` messages (default 8, measured by message recency time with array-order fallback) are always replayed verbatim, regardless of call count, output size, tool class, or parallel batching. Compaction only applies to messages older than that window.
434
+
237
435
  Compaction is tool-classified, not blanket:
238
436
 
239
- - **Retained (never compacted):** results that stay relevant for the whole session — `webfetch`/`web_fetch`/web readers, web/search tools, `skill`, and subagent (`task`/`agent`) outputs.
437
+ - **Retained (never compacted):** results that stay relevant for the whole session — `webfetch`/`web_fetch`/web readers, web/search tools, `skill`, and subagent (`task`/`agent`) outputs. Retained tools also never consume the per-call protection budget.
240
438
  - **Old reads** collapse to `[Read <file>, lines X-Y]` (range recovered from the line-numbered output; missing file or range falls back to head/tail pruning, never a fabricated summary).
241
- - **Other ephemeral outputs** (`bash`, `grep`, `glob`, …) past `outputMaxChars` are pruned to `headChars` + a fixed marker + `tailChars`, DeepSeek-Harness style.
439
+ - **Other ephemeral outputs** (`bash`, `grep`, `glob`, …) past `outputMaxChars` are pruned to `headChars` + a fixed marker + `tailChars`. With `savePrunedOutput` (default on), the full output is written once to `$XDG_DATA_HOME/vvoc/tool-output/tool-<callID>.txt` and the marker embeds `Full output saved to: <path>`, so the model can re-read the full content instead of reconstructing it from fragments.
242
440
 
243
- A protected tail never rewrites the last assistant message or the last `protectLastCalls` completed calls; error parts and parts already compacted by OpenCode are skipped. Rewrites are deterministic and idempotent (each part is rewritten at most once), and a `minSavingsChars` guard skips rewrites that would churn the prompt cache for a tiny gain.
441
+ Outside the recent window, the last `protectLastCalls` completed calls are also protected; error parts and parts already compacted by OpenCode are skipped. Rewrites are deterministic and idempotent (each part is rewritten at most once, and the saved path is deterministic per callID), and a `minSavingsChars` guard skips rewrites that would churn the prompt cache for a tiny gain.
244
442
 
245
443
  Config lives in `vvoc.json` under `plugins["tool-history-compaction"]` (boolean or object) and is conservatively materialized by `vvoc sync`/`init`:
246
444
 
@@ -249,6 +447,8 @@ Config lives in `vvoc.json` under `plugins["tool-history-compaction"]` (boolean
249
447
  "tool-history-compaction": {
250
448
  "enabled": true,
251
449
  "protectLastCalls": 3,
450
+ "protectRecentMessages": 8,
451
+ "savePrunedOutput": true,
252
452
  "minSavingsChars": 2000,
253
453
  "outputMaxChars": 2048,
254
454
  "headChars": 1200,
@@ -259,13 +459,13 @@ Config lives in `vvoc.json` under `plugins["tool-history-compaction"]` (boolean
259
459
  }
260
460
  ```
261
461
 
262
- Set `outputMaxChars` to `0` to disable pruning, or `"enabled": false` to disable the plugin entirely. Changes require an OpenCode restart.
462
+ Set `outputMaxChars` to `0` to disable pruning, `protectRecentMessages` to `0` to disable the message window (only the newest message stays protected), `savePrunedOutput` to `false` to skip disk persistence, or `"enabled": false` to disable the plugin entirely. Changes require an OpenCode restart.
263
463
 
264
- ### Cache Hit Rate Analytics
464
+ ### Cache hit rate analytics
265
465
 
266
466
  `AnalyticsPlugin` records one line per completed model step — fresh input, cache read, cache write, output, reasoning, recorded cost — to `$XDG_DATA_HOME/vvoc/analytics/usage-YYYY-MM.jsonl`, attributed with the vvoc version, the OpenCode version (from session telemetry), project, provider, model, and agent. Telemetry never leaves the machine; disable collection with `"plugins": { "analytics": false }` and delete old monthly files freely.
267
467
 
268
- In the TUI you get a live `cache NN%` indicator next to the session prompt (green at 80%+, yellow at 50%+, red below, muted `n/a` before the first cache-eligible step) and a combined footer line `• OpenCode <version> · vvoc vX.Y.Z` in the sidebar (the stock version line, extended with the vvoc version). The indicator is per-session and computed in memory.
468
+ In the TUI you get a live `cache NN%` indicator next to the session prompt (green at 80%+, yellow at 50%+, red below, muted `n/a` before the first cache-eligible step) and a combined footer line `• OpenCode <version> · vvoc vX.Y.Z` in the sidebar. The indicator is per-session and computed in memory.
269
469
 
270
470
  Retrospective analysis lives in the CLI:
271
471
 
@@ -277,20 +477,18 @@ vvoc analytics cache-hit-rate --group-by session|model|provider|project|week|mon
277
477
  vvoc analytics cache-hit-rate --project my-repo --order hit-rate --limit 10 --json
278
478
  ```
279
479
 
280
- The hit rate is token-weighted: `cacheRead / (cacheRead + cacheWrite + input)` over cache-eligible steps; `COVERAGE` shows the share of steps whose provider reported cache tokens at all, so providers without prompt caching read as `n/a` instead of a misleading `0%`. `--since`/`--until` accept `Nd`/`Nw`/`Nm` or `YYYY-MM-DD`.
480
+ The hit rate is token-weighted: `cacheRead / (cacheRead + cacheWrite + input)` over cache-eligible steps; `COVERAGE` shows the share of steps whose provider reported cache tokens at all, so providers without prompt caching read as `n/a` instead of a misleading `0%`. `--since`/`--until` accept `Nd`/`Nw`/`Nm` or `YYYY-MM-DD`; `--order` accepts `date`, `steps`, or `hit-rate`.
281
481
 
282
- Agents can run this analysis conversationally too: the managed `vvoc-usage-analytics` skill answers usage, cache, and cost questions inside a session — including historical comparisons from `opencode.db` that predate the analytics plugin (see Managed Skills).
482
+ Agents can run this analysis conversationally too: the managed `vvoc-usage-analytics` skill answers usage, cache, and cost questions inside a session — including historical comparisons from `opencode.db` that predate the analytics plugin.
283
483
 
284
- ### Web Tools
484
+ ### Web tools
285
485
 
286
486
  `WebToolsPlugin` exposes exactly two canonical model-facing tools:
287
487
 
288
488
  - `web_search` requests the `web_search` permission and returns ranked titles, URLs, snippets, and publication dates. Search uses Exa by default, Brave when configured, or the direct Z.AI/Zhipu Tool API for an explicitly selected region.
289
489
  - `web_fetch` requests the `web_fetch` permission and retrieves a known HTTP or HTTPS URL as Markdown, text, raw HTML, or a direct JPEG, PNG, GIF, WebP, or PDF attachment. Fetch uses local native retrieval by default, Spider for configured textual extraction, or the direct Z.AI/Zhipu Reader Tool API.
290
490
 
291
- The `web-tools` vvoc plugin toggle is enabled by default.
292
-
293
- Provider selection belongs to `vvoc.json`, not to individual model calls. Add this optional property fragment to an otherwise valid canonical schema-v3 config:
491
+ The `web-tools` vvoc plugin toggle is enabled by default. Provider selection belongs to `vvoc.json`, not to individual model calls:
294
492
 
295
493
  ```json
296
494
  "web": {
@@ -301,7 +499,7 @@ Provider selection belongs to `vvoc.json`, not to individual model calls. Add th
301
499
 
302
500
  Supported search providers are `exa` (default), `brave`, and `zai`. Supported fetch providers are `native` (default, no credential required), `spider`, and `zai`. A `zai` section must set `region` to either `international` or `china`; the plugin never guesses or falls back to another region.
303
501
 
304
- Direct Z.AI endpoint routing is:
502
+ Direct Z.AI endpoint routing:
305
503
 
306
504
  | Region | Search | Reader | Search engine |
307
505
  |---|---|---|---|
@@ -315,7 +513,7 @@ Credentials resolve in this order:
315
513
  1. `EXA_API_KEY`, `BRAVE_API_KEY`, `SPIDER_API_KEY`, or `ZAI_API_KEY` for the selected provider
316
514
  2. `web.search.apiKey` or `web.fetch.apiKey` in the effective `vvoc.json`
317
515
 
318
- Environment variables win when both sources exist. Config changes take effect after restarting OpenCode. Configured `apiKey` values become exact-match SecretsRedactionPlugin rules for provider-bound message flows, and WebToolsPlugin diagnostics report only the credential source (`env` or `config`), never the value. If a project-layer `.vvoc/vvoc.json` containing an `apiKey` is tracked by Git, startup logs warn with the file name only. Prefer environment variables or the global vvoc layer; do not commit credentials.
516
+ Environment variables win when both sources exist; config changes take effect after restarting OpenCode. Configured `apiKey` values become exact-match SecretsRedactionPlugin rules for provider-bound message flows, and WebToolsPlugin diagnostics report only the credential source (`env` or `config`), never the value. If a project-layer `.vvoc/vvoc.json` containing an `apiKey` is tracked by Git, startup logs warn with the file name only. Prefer environment variables or the global vvoc layer; do not commit credentials.
319
517
 
320
518
  While `web-tools` is enabled, its runtime config hook denies the built-in `webfetch` and `websearch` permission ids in memory, leaving only `web_fetch` and `web_search` in the normal tool surface. It does not rewrite OpenCode files or remove MCP servers. An explicit user permission entry for `webfetch` or `websearch` is respected and may intentionally keep that built-in visible. Disable the plugin and restart to restore stock behavior:
321
519
 
@@ -325,15 +523,15 @@ vvoc plugin disable web-tools
325
523
 
326
524
  Unrelated MCP search or reader tools are not removed automatically; disable those separately if you want only the two canonical tools visible.
327
525
 
328
- ### `/context` accuracy
526
+ ### `/context` inspector
329
527
 
330
- Run `/context` inside an active session. Its bounded host-owned dialog has three tabs: **Overview**, **Tools**, and **MCP**. Use left/right arrows or `1`, `2`, and `3` to switch tabs and up/down to scroll long detail. The measured header remains visible on every tab. Top-line used/remaining values come from the latest assistant turn's provider-reported input, cache-read, and output token counts when OpenCode exposes them.
528
+ Run `/context` inside an active session. Its bounded host-owned dialog has three tabs: **Overview**, **Tools**, and **MCP**. Use left/right arrows or `1`, `2`, and `3` to switch tabs and up/down to scroll long detail; the measured header remains visible on every tab. Top-line used/remaining values come from the latest assistant turn's provider-reported input, cache-read, and output token counts when OpenCode exposes them.
331
529
 
332
- Overview category rows remain provider-neutral estimates derived from observable TUI/SDK state: system instructions, skill catalog, loaded skills, tool schemas, user and assistant messages, tool calls and results, files, and the latest compaction summary. Percentages are always `estimated tokens / current model contextLimit`; if OpenCode does not expose a positive current limit, the percentage is shown as an em dash rather than using another denominator. Numeric percentages may exceed 100% when estimates drift, while visual bars clamp only their fill at 100%.
530
+ Overview category rows are provider-neutral estimates derived from observable TUI/SDK state: system instructions, skill catalog, loaded skills, tool schemas, user and assistant messages, tool calls and results, files, and the latest compaction summary. Percentages are always `estimated tokens / current model contextLimit`; if OpenCode does not expose a positive current limit, the percentage is shown as an em dash rather than using another denominator. Numeric percentages may exceed 100% when estimates drift, while visual bars clamp only their fill at 100%.
333
531
 
334
- The Tools tab separates each observable current tool's persistent **schema** estimate from its active **history** estimate, call count, combined total, source, and percentages. When a schema catalog is unavailable, the row says `schema unavailable` and labels the history-only subtotal as `known total` rather than presenting a false zero. History includes only tool parts in the active context: the latest compaction summary and subsequent turns. Pending and running calls include observable input; completed calls include output and failed calls include errors. The `skill` tool remains visible in detail, but its history continues to belong to Overview's `Loaded skill results` category so it is not double-counted as `Tool calls and results`.
532
+ The Tools tab separates each observable current tool's persistent **schema** estimate from its active **history** estimate, call count, combined total, source, and percentages. When a schema catalog is unavailable, the row says `schema unavailable` and labels the history-only subtotal as `known total` rather than presenting a false zero. History includes only tool parts in the active context: the latest compaction summary and subsequent turns. The `skill` tool remains visible in detail, but its history belongs to Overview's `Loaded skill results` category so it is not double-counted.
335
533
 
336
- The MCP tab aggregates observable current schema and retained active history by server and nests the attributed tools. OpenCode 1.18.x does not expose connected MCP tool definitions through its public TUI/SDK tool catalog, so connected servers show `current tools unavailable` and `schema unavailable`; their `known total` includes retained history only, while the unexposed schema overhead remains in `Unknown/provider-only`. `disabled`, `failed`, `needs_auth`, and `needs_client_registration` servers have a known zero current schema, while matching call history can remain visible until compaction removes it. Attribution follows OpenCode's sanitized `<server>_<tool>` naming contract with unique longest-prefix matching. Sanitized collisions or other ambiguous ownership fail closed under **Other external/plugin** with a bounded warning instead of being guessed.
534
+ The MCP tab aggregates observable current schema and retained active history by server and nests the attributed tools. OpenCode 1.18.x does not expose connected MCP tool definitions through its public TUI/SDK tool catalog, so connected servers show `current tools unavailable` and `schema unavailable`; their `known total` includes retained history only, while the unexposed schema overhead remains in `Unknown/provider-only`. Attribution follows OpenCode's sanitized `<server>_<tool>` naming contract with unique longest-prefix matching; sanitized collisions or other ambiguous ownership fail closed under **Other external/plugin** with a bounded warning instead of being guessed.
337
535
 
338
536
  The plugin does **not** claim to reconstruct the exact final provider request or provide provider-exact tokenization. Hidden provider transformations, plugin-added data, or otherwise unattributable content appears as `Unknown/provider-only`; when visible estimates exceed provider usage, the dialog reports estimation drift instead of forcing totals to match. Collection reuses OpenCode's existing tool catalog, active parts, model metadata, and MCP status snapshot without issuing extra MCP requests.
339
537
 
@@ -341,206 +539,27 @@ The `context` vvoc plugin toggle defaults to enabled. Disable it with `vvoc plug
341
539
 
342
540
  ---
343
541
 
344
- ## CLI at a Glance
345
-
346
- | Command | Purpose |
347
- |---|---|
348
- | `vvoc init` | Interactive bootstrap flow |
349
- | `vvoc install` | Non-interactive setup and scaffolding |
350
- | `vvoc sync` | Refresh runtime/TUI plugin entries, agents, prompts, skills, config |
351
- | `vvoc launch` | Launch OpenCode with deterministic runtime, TUI, and vvoc config sources |
352
- | `vvoc status` | Show current installation state, including OpenCode version compatibility and TUI registration |
353
- | `vvoc doctor` | Diagnose OpenCode version/runtime/TUI/vvoc setup problems (exits non-zero on issues) |
354
- | `vvoc config validate` | Validate canonical `vvoc.json` |
355
- | `vvoc role list\|set\|unset` | Manage model role assignments |
356
- | `vvoc preset list\|show\|<name>` | Inspect or apply named presets |
357
- | `vvoc guardian config` | Print or write guardian section |
358
- | `vvoc plugin list` | List OpenCode plugin entries |
359
- | `vvoc plugin enable\|disable` | Toggle a vvoc-managed plugin on or off |
360
- | `vvoc orchestration show\|set` | Show or set the vv-controller orchestration profile |
361
- | `vvoc patch-provider stepfun-ai\|codex\|deepseek\|kimi\|alibaba\|all` | Patch OpenCode providers; `codex` adds subscription-safe OpenAI aliases (also accepts `openai`), `deepseek`/`kimi`/`alibaba` add vv- reasoning-effort aliases, `all` patches every provider at once |
362
- | `vvoc completion` | Install shell completions |
363
- | `vvoc upgrade` | Upgrade global package and run follow-up sync; sync failure is reported as a partial upgrade |
364
- | `vvoc analytics cache-hit-rate` | Aggregate persisted cache hit rate by day, week, month, session, model, provider, project, vvoc version, or OpenCode version |
365
- | `vvoc version` | Print installed version |
366
-
367
- Guardian duration overrides use positive whole milliseconds. Both `--timeout-ms` and
368
- `--review-toast-duration-ms` reject zero, negative, fractional, missing, or malformed values:
369
-
370
- ```bash
371
- vvoc guardian config --print --timeout-ms 30000 --review-toast-duration-ms 5000
372
- ```
373
-
374
- ---
375
- ---
376
-
377
- ## Orchestration Profiles
378
-
379
- Three concrete policies control how vv-controller delegates work at runtime:
380
-
381
- - `single-session`: vv-controller performs exploration, investigation, planning, implementation,
382
- and verification directly. Independent reviewer subagents remain available when the user
383
- explicitly requests review or when a materially risky completed change benefits from independent
384
- cross-model evaluation.
385
- - `balanced`: vv-controller keeps architecture, critical reading, and final synthesis in the
386
- primary session and may selectively delegate bounded search, investigation, mechanical
387
- implementation, or review when that is the lightest safe route. Delegation is optional, not
388
- mechanically mandatory.
389
- - `orchestrated`: vv-controller uses the full tracked implementer/reviewer workflow with
390
- explicit work items, required reviewers, bounded rounds, and hard stops.
391
-
392
- Pick a profile explicitly or let a built-in preset select one:
542
+ ## Local development
393
543
 
394
544
  ```bash
395
- vvoc orchestration show --scope effective
396
- vvoc orchestration set single-session --scope project
397
- ```
398
-
399
- Built-in presets declare an orchestration mapping:
400
-
401
- | Preset | Profile |
402
- |---|---|
403
- | `vv-codex` | single-session |
404
- | `vv-kimi` | single-session |
405
- | `vv-alibaba` | single-session |
406
- | `vv-osovv-sol` | single-session |
407
- | `vv-osovv-flash` | single-session |
408
- | `vv-osovv-kimi` | single-session |
409
- | `vv-osovv-qwen` | single-session |
410
- | `vv-zai` | balanced |
411
- | `vv-deepseek` | balanced |
412
-
413
- Applying a built-in preset changes both model roles and the root orchestration profile
414
- atomically. A custom user-defined preset without an orchestration section preserves the current
415
- root profile. `vvoc status` reports the profile resolved from the selected vvoc source; effective
416
- status with no config files reports `balanced`.
417
-
418
- ### Prompt-only first version
419
-
420
- Profiles are enforced through the concrete policy injected into vv-controller at startup —
421
- the model only receives its active work instructions and does not see inactive profile alternatives.
422
- The first version does not disable tools, change permissions, or block subagent types; the policy
423
- is prompt-driven and asynchronous vv-execute classic mode remains available through that skill's
424
- explicit inline/classic selection.
425
-
426
- ### Restart requirement
427
-
428
- Config changes to the orchestration profile take effect after an OpenCode restart. Runtime plugins
429
- resolve the profile once from the startup vvoc config snapshot and do not live-reload.
430
-
431
- ## Model Roles & Presets
432
-
433
- ```bash
434
- # View current assignments
435
- vvoc role list
436
- vvoc role list --scope effective
437
-
438
- # Assign models to roles
439
- vvoc role set default openai/gpt-5.6-terra
440
- vvoc role set team-review anthropic/claude-sonnet-4-5 --scope project
441
- vvoc role set smart openai/vv-codex-gpt-5.6-sol-xhigh
442
- vvoc role set fast openai/gpt-5.6-luna
443
-
444
- # Switch provider presets
445
- vvoc preset vv-codex
446
- vvoc preset vv-zai
447
- vvoc preset vv-deepseek
448
- vvoc preset vv-kimi
449
- vvoc preset vv-alibaba
450
- vvoc preset vv-osovv-sol
451
- vvoc preset vv-osovv-flash
452
- vvoc preset vv-osovv-kimi
453
- vvoc preset vv-osovv-qwen
454
- ```
455
-
456
- Built-in role IDs: `default`, `smart`, `fast`, `reviewer` + any custom lowercase-hyphenated IDs.
457
-
458
- 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.
459
-
460
- ---
461
-
462
- ## Config & Data Layout
463
-
464
- Mutating commands default to global for backward compatibility. Add `--scope project` to write a project-local layer. Read/diagnostic commands accept `--scope global|project|effective`, where `effective` resolves in this order:
465
-
466
- 1. explicit env override (`VVOC_CONFIG` / `OPENCODE_CONFIG` / `OPENCODE_TUI_CONFIG`)
467
- 2. nearest project layer
468
- 3. global layer
469
- 4. built-in defaults when the command/runtime permits defaults
470
-
471
- Canonical project-local paths:
472
-
473
- ```text
474
- OpenCode config → ./.opencode/opencode.json(c)
475
- OpenCode TUI config → ./.opencode/tui.json(c)
476
- vvoc config → ./.vvoc/vvoc.json
477
- Managed agent prompts → ./.vvoc/agents/*.md
478
- Managed skills → ./.vvoc/skills/*/SKILL.md
479
- Spec package directory → ./.vvoc/specs/YYYY-MM-DD-<slug>/
480
- spec.xml # normative spec document (required)
481
- design-context.xml # curated design memory (optional)
482
- plan.xml # implementation plan (created by vv-plan)
483
- Handoff notes → ./.vvoc/handoff/YYYY-MM-DD-<session-slug>/handoff.xml
484
-
485
- ```
486
-
487
- Legacy root-level `./opencode.json` and `./opencode.jsonc` are intentionally not used as vvoc project layers.
488
-
489
- ```
490
- Global OpenCode config → $XDG_CONFIG_HOME/opencode/opencode.json
491
- Global OpenCode TUI → $XDG_CONFIG_HOME/opencode/tui.json(c)
492
- Global vvoc config → $XDG_CONFIG_HOME/vvoc/vvoc.json
493
- Managed agent prompts → $XDG_CONFIG_HOME/vvoc/agents/*.md (global)
494
- ./.vvoc/agents/*.md (project)
495
- Managed skills → $XDG_CONFIG_HOME/vvoc/skills/*/SKILL.md (global)
496
- ./.vvoc/skills/*/SKILL.md (project)
497
- Spec documents → ./.vvoc/specs/YYYY-MM-DD-<slug>/spec.xml
498
- Optional design context → ./.vvoc/specs/YYYY-MM-DD-<slug>/design-context.xml
499
- Implementation plans → ./.vvoc/specs/YYYY-MM-DD-<slug>/plan.xml
500
- Persisted data → $XDG_DATA_HOME/vvoc/
501
- Usage analytics → $XDG_DATA_HOME/vvoc/analytics/usage-YYYY-MM.jsonl (local-only cache telemetry)
502
- Repository memory → ./.vvoc/lessons/*.xml (lazy vv-reflect fallback)
503
- ./.vvoc/runbooks/*.xml (lazy vv-reflect fallback)
504
- Session handoff notes → ./.vvoc/handoff/YYYY-MM-DD-<session-slug>/handoff.xml
505
- ```
506
-
507
- Schema is versioned and published with the package — source of truth at `schemas/vvoc/v3.json`. The current config contract is strict: `vvoc.json` must be canonical version 3 and include required sections such as `plugins`. Existing v1/v2/pre-role, incomplete, malformed, or otherwise invalid config files fail instead of being migrated or repaired. `vvoc install` and `vvoc sync` may create a fresh canonical config when no config exists, but they refuse to rewrite an invalid existing `vvoc.json`; fix the file manually and rerun `vvoc sync`.
508
-
509
- The optional schema-v3 `web` section follows the same layer precedence as the rest of `vvoc.json` and is omitted from generated defaults:
510
-
511
- ```json
512
- "web": {
513
- "search": { "provider": "exa", "apiKey": "optional-exa-key" },
514
- "fetch": { "provider": "native" }
515
- }
545
+ bun install # Install dependencies
546
+ bun run check # Typecheck + lint + format check + GRACE markup check + test
547
+ bun run fmt # Auto-format source files
548
+ bun run release:check # Verify package/schema release consistency
516
549
  ```
517
550
 
518
- Use `brave` instead of `exa` for Brave Web Search, or `spider` instead of `native` for Spider textual extraction. The matching environment variable takes precedence over `apiKey` fields.
519
-
520
- OpenCode intentionally keeps server/runtime plugins and native terminal UI plugins in separate configuration surfaces. `opencode.json(c)` is loaded by the core/server plugin runtime and activates vvoc features such as model roles, Guardian, workflow, hashline edit, redaction, and web tools. `tui.json(c)` is loaded by the terminal UI process and activates the package's `./tui` module, currently the `/context` inspector. The same pinned package version appears in both files, but OpenCode selects a different public export for each process; headless/server launches therefore do not need to load the Solid/OpenTUI UI module.
521
-
522
- `vvoc install`, `vvoc init`, and `vvoc sync` conservatively add the pinned base package specifier (for example `@osovv/vv-opencode@X.Y.Z`) to dedicated `tui.json(c)`; OpenCode then selects the package's public `./tui` export. Sync migrates the broken legacy `@osovv/vv-opencode/tui` form and older managed pins. Existing comments, unrelated settings, unrelated plugin entries, and `[specifier, options]` tuples are preserved; malformed plugin entries fail without rewrite.
523
-
524
- `vvoc status` and `vvoc doctor` are diagnostic exceptions: they report the installed OpenCode version, the `1.18.2` TUI minimum, selected runtime/TUI/vvoc config paths, and validation problems without normalizing or rewriting the files. `vvoc upgrade` can still finish the package installation when the follow-up `vvoc sync` fails; in that case it reports a partial upgrade, leaves config unchanged, and tells you to fix the invalid config manually before rerunning `vvoc sync`.
551
+ Git hooks are managed via `lefthook`.
525
552
 
526
- Runtime compatibility is current-only. Guardian permission replies use the current OpenCode permission reply path (with the current HTTP reply fallback), Hashline edit refs must use current hash/context anchors, and sync writes current managed agents without deleting old pre-rename user or command entries.
527
-
528
- Runtime plugins load the effective `vvoc.json` once during OpenCode startup and share the same immutable config snapshot for the lifetime of the process. There is no live reload; restart OpenCode after changing `vvoc.json` or `tui.json(c)`.
529
-
530
- ### Deterministic local launch
531
-
532
- Use `vvoc launch` when you want the vvoc-selected config files to be the only files OpenCode sees for this run:
553
+ Smoke-test the built CLI against an isolated config home:
533
554
 
534
555
  ```bash
535
- vvoc install --scope project
536
- vvoc launch --scope project -- run "hello"
556
+ tmpdir="$(mktemp -d)"
557
+ bun run build
558
+ bun dist/cli.js install --config-dir "$tmpdir"
559
+ bun dist/cli.js status --config-dir "$tmpdir"
537
560
  ```
538
561
 
539
- `vvoc launch --scope project` is strict and non-mutating: if `.opencode/opencode.json` or `.vvoc/vvoc.json` is missing, it fails with a hint to run `vvoc install --scope project`. When the selected `.opencode/tui.json(c)` exists, launch also sets `OPENCODE_TUI_CONFIG`; a missing TUI file is not synthesized during launch. `--scope effective` follows the layered lookup order, and `--scope global` uses the global config paths.
540
-
541
- ### Test the local TUI before release
542
-
543
- From this repository, launch OpenCode against the freshly built local `dist/tui.js` without publishing or rewriting your selected configs:
562
+ Test the local TUI against a freshly built `dist/tui.js` without publishing or rewriting your selected configs:
544
563
 
545
564
  ```bash
546
565
  bun run tui:local
@@ -550,69 +569,7 @@ bun run tui:local -- --scope project
550
569
 
551
570
  The command defaults to `effective` config resolution. It builds the package, copies the selected `tui.json(c)` into a temporary isolated config home, replaces only the managed vv-opencode TUI entry with a local `file://` URL, preserves unrelated TUI settings and tuple options, and forwards remaining arguments to OpenCode. The original OpenCode, TUI, and vvoc config files are not modified, and the temporary config is removed after OpenCode exits. Restart the command after source changes because runtime plugins do not live reload.
552
571
 
553
- ---
554
-
555
- ## Managed Agents
556
-
557
- All prompt files are scaffolded by `vvoc install` / `vvoc sync`:
558
-
559
- | Agent | When it helps |
560
- |---|---|
561
- | `vv-controller` | Primary agent that follows the concrete work policy selected for the session by the orchestration profile |
562
- | `enhancer` | Improves rough requests before execution when a clearer prompt would help |
563
- | `vv-implementer` | Applies a focused approved change and verifies it before reporting completion |
564
- | `vv-spec-reviewer` | Checks whether implementation matches the requested spec and acceptance criteria |
565
- | `vv-code-reviewer` | Looks for bugs, regressions, maintainability risks, and missing tests |
566
- | `investigator` | Finds the root cause first when behavior is unclear or a failure needs diagnosis |
567
- | `guardian` | Supports GuardianPlugin by auto-approving routine low-risk permission requests and leaving risky ones for manual approval |
568
-
569
- ---
570
-
571
- ## Managed Skills
572
-
573
- Managed skills come in two families: `vv-*` skills guide the work protocol (spec, plan, execute, review, reflect, handoff), while `vvoc-*` skills operate and observe the vvoc/OpenCode tooling itself. Seven skills are scaffolded alongside agents:
574
-
575
- | Skill | When to use it | What it gives you |
576
- |---|---|---|
577
- | `vv-spec` | You have a feature or creative request and no agreed contract yet | A guided interview, recommended options, and a saved spec in `.vvoc/specs/YYYY-MM-DD-<slug>/spec.xml` |
578
- | `vv-plan` | A spec is approved and ready to implement | A task-level implementation plan with file targets, contracts, dependencies, and acceptance criteria |
579
- | `vv-execute` | A plan is approved and you want it applied step by step | Ordered execution with verification, explicit inline-or-classic mode choice, and applied spec/plan archival |
580
- | `vv-review` | You want findings, not fixes | A review-only workflow that reports spec/code issues and stops before implementation |
581
- | `vv-reflect` | A long development, debugging, ops, or investigation session produced reusable knowledge | Durable notes in existing docs or `.vvoc/lessons` / `.vvoc/runbooks` for future agents |
582
- | `vv-handoff` | You are ending a session and want the visible context preserved for a future session | A redacted XML note at `.vvoc/handoff/YYYY-MM-DD-<session-slug>/handoff.xml`, without running new checks or collecting fresh context |
583
- | `vvoc-usage-analytics` | You ask about token usage, cache hit rate, costs, or whether a vvoc/OpenCode upgrade changed caching | An agent-run read-only analysis across `vvoc analytics`, the analytics JSONL, and historical `opencode.db` data (validated SQL snippets included) |
584
-
585
- Spec and plan artifacts stay XML so requirements, tasks, acceptance criteria, and dependencies remain easy to grep and review.
586
-
587
- `vv-reflect` creates `.vvoc/lessons` and `.vvoc/runbooks` lazily only after approved fallback writes. It prefers an existing repository documentation convention when there is a high-confidence match.
588
-
589
- `vv-handoff` writes only the project-local XML handoff artifact from context already visible in the session. It records missing git, diff, or verification evidence as not collected in the current session instead of running commands.
590
-
591
- Skills are loaded by OpenCode at session start through `config.skills.paths` (registered by the SystemContextInjectionPlugin). The `vv-controller` agent's `<skill_trigger_rule>` ensures they are invoked automatically when the user's request matches their trigger conditions.
592
-
593
- ---
594
-
595
- ## Local Development
596
-
597
- ```bash
598
- bun install # Install dependencies
599
- bun run check # Typecheck + lint + format check + test
600
- bun run fmt # Auto-format source files
601
- bun run release:check # Verify package/schema release consistency
602
- ```
603
-
604
- Git hooks managed via `lefthook`.
605
-
606
- ### Smoke-test the built CLI
607
-
608
- ```bash
609
- tmpdir="$(mktemp -d)"
610
- bun run build
611
- bun dist/cli.js install --config-dir "$tmpdir"
612
- bun dist/cli.js status --config-dir "$tmpdir"
613
- ```
614
-
615
- ### Full release verification
572
+ Full release verification:
616
573
 
617
574
  ```bash
618
575
  bun run release:check
@@ -621,17 +578,17 @@ bun run pack:check
621
578
  ```
622
579
 
623
580
  ---
581
+
624
582
  ## Publishing
625
583
 
626
584
  The release flow is automated via a local wrapper and an exact-commit, CI-gated GitHub Actions workflow.
627
585
 
628
- ### Local bump
629
-
630
586
  ```bash
631
587
  bun run release:bump patch # or minor, major, prerelease, or explicit semver
632
588
  ```
633
589
 
634
590
  This will:
591
+
635
592
  1. Reject if the worktree is dirty
636
593
  2. Bump `package.json` via `npm version --no-git-tag-version`
637
594
  3. Generate a required AI release summary with `opencode --pure run`
@@ -645,38 +602,19 @@ This will:
645
602
  11. Retry npm metadata propagation, then verify that npm reports the exact release commit as the published `gitHead`
646
603
  12. Create and push the annotated tag locally, then create the GitHub Release through `gh`
647
604
 
648
- Required local release prerequisite:
649
- - `opencode` must be available from `PATH`.
650
- - `gh` must be installed and authenticated with permission to dispatch/watch workflows and create releases in the repository.
651
- - `gh run watch` does not support fine-grained PAT authentication; use a supported `gh` login such as OAuth or a classic token.
652
- - The summary model defaults to `deepseek/deepseek-v4-flash`.
653
- - Override with `VVOC_RELEASE_SUMMARY_MODEL=provider/model`.
654
- - Override the per-attempt timeout with `VVOC_RELEASE_SUMMARY_TIMEOUT_MS=120000`.
655
- Run `release:bump` from a checked-out branch with branch and tag push access to `origin`. A normal branch push never publishes by itself; the wrapper explicitly dispatches the workflow for the exact pushed commit.
656
-
657
- The GitHub Actions workflow checks out the requested commit SHA, verifies that its
658
- `package.json` version matches the dispatch input, and runs full validation
659
- (typecheck, lint, fmt check, tests, build, pack check, and `release:check`). Only
660
- after every gate passes does it publish to npm with provenance. The local wrapper
661
- waits for that CI result, retries registry metadata propagation, verifies npm
662
- `gitHead`, and only then uses the maintainer's authenticated `git` and `gh` clients
663
- to create the annotated `vX.Y.Z` tag and GitHub Release. This avoids GitHub App
664
- token restrictions on tagging commits that contain workflow changes while preserving
665
- verification-before-tagging.
666
-
667
- ### Checking consistency manually
605
+ Local prerequisites:
668
606
 
669
- ```bash
670
- bun run release:check
671
- ```
672
-
673
- This verifies that `package.json` name, version, and `schemas/vvoc/v3.json` `$id` and
674
- config format version are all consistent. Run it independently anytime.
607
+ - `opencode` must be available from `PATH`.
608
+ - `gh` must be installed and authenticated with permission to dispatch/watch workflows and create releases in the repository. `gh run watch` does not support fine-grained PAT authentication; use a supported `gh` login such as OAuth or a classic token.
609
+ - The summary model defaults to `deepseek/deepseek-v4-flash`; override with `VVOC_RELEASE_SUMMARY_MODEL=provider/model` and the per-attempt timeout with `VVOC_RELEASE_SUMMARY_TIMEOUT_MS=120000`.
610
+ - Run `release:bump` from a checked-out branch with branch and tag push access to `origin`. A normal branch push never publishes by itself; the wrapper explicitly dispatches the workflow for the exact pushed commit.
675
611
 
676
- ### CI publish workflow
612
+ The GitHub Actions workflow checks out the requested commit SHA, verifies that its `package.json` version matches the dispatch input, and runs full validation (typecheck, lint, fmt check, tests, build, pack check, and `release:check`). Only after every gate passes does it publish to npm with provenance. The local wrapper waits for that CI result, retries registry metadata propagation, verifies npm `gitHead`, and only then uses the maintainer's authenticated `git` and `gh` clients to create the annotated `vX.Y.Z` tag and GitHub Release. This avoids GitHub App token restrictions on tagging commits that contain workflow changes while preserving verification-before-tagging.
677
613
 
678
614
  The workflow uses npm provenance/trusted publishing (`id-token: write`) and read-only repository contents access. It can only publish through an explicit `workflow_dispatch` request; normal branch and tag pushes do not publish. Tag and GitHub Release creation happen locally only after the workflow succeeds. Configure npm trusted publishing for this GitHub repository/package, or adapt the publish step to use an `NPM_TOKEN` secret if token-based publishing is required.
679
615
 
616
+ `bun run release:check` verifies independently that `package.json` name, version, and `schemas/vvoc/v3.json` `$id` and config format version are all consistent; run it anytime.
617
+
680
618
  ---
681
619
 
682
620
  ## License