@osovv/vv-opencode 1.7.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/README.md +22 -2
- package/dist/commands/preset.js +1 -1
- package/dist/commands/preset.js.map +1 -1
- package/dist/index.d.ts +7 -11
- package/dist/index.js +53 -20
- package/dist/index.js.map +1 -1
- package/dist/plugins/analytics/index.d.ts +2 -0
- package/dist/plugins/analytics/index.js +13 -2
- package/dist/plugins/analytics/index.js.map +1 -1
- package/dist/plugins/analytics/v2.d.ts +21 -0
- package/dist/plugins/analytics/v2.js +133 -0
- package/dist/plugins/analytics/v2.js.map +1 -0
- package/dist/plugins/guardian/index.d.ts +46 -0
- package/dist/plugins/guardian/index.js +21 -6
- package/dist/plugins/guardian/index.js.map +1 -1
- package/dist/plugins/guardian/v2.d.ts +13 -0
- package/dist/plugins/guardian/v2.js +161 -0
- package/dist/plugins/guardian/v2.js.map +1 -0
- package/dist/plugins/hashline-edit/index.d.ts +33 -1
- package/dist/plugins/hashline-edit/index.js +38 -14
- package/dist/plugins/hashline-edit/index.js.map +1 -1
- package/dist/plugins/hashline-edit/schemas.d.ts +7 -7
- package/dist/plugins/hashline-edit/v2.d.ts +12 -0
- package/dist/plugins/hashline-edit/v2.js +145 -0
- package/dist/plugins/hashline-edit/v2.js.map +1 -0
- package/dist/plugins/model-roles/index.d.ts +2 -0
- package/dist/plugins/model-roles/index.js +13 -2
- package/dist/plugins/model-roles/index.js.map +1 -1
- package/dist/plugins/model-roles/v2.d.ts +24 -0
- package/dist/plugins/model-roles/v2.js +274 -0
- package/dist/plugins/model-roles/v2.js.map +1 -0
- package/dist/plugins/peak-hours/index.d.ts +2 -0
- package/dist/plugins/peak-hours/index.js +13 -2
- package/dist/plugins/peak-hours/index.js.map +1 -1
- package/dist/plugins/peak-hours/v2.d.ts +12 -0
- package/dist/plugins/peak-hours/v2.js +95 -0
- package/dist/plugins/peak-hours/v2.js.map +1 -0
- package/dist/plugins/secrets-redaction/index.d.ts +7 -0
- package/dist/plugins/secrets-redaction/index.js +17 -4
- package/dist/plugins/secrets-redaction/index.js.map +1 -1
- package/dist/plugins/secrets-redaction/v2.d.ts +14 -0
- package/dist/plugins/secrets-redaction/v2.js +100 -0
- package/dist/plugins/secrets-redaction/v2.js.map +1 -0
- package/dist/plugins/spec-guard/index.d.ts +2 -0
- package/dist/plugins/spec-guard/index.js +13 -2
- package/dist/plugins/spec-guard/index.js.map +1 -1
- package/dist/plugins/spec-guard/v2.d.ts +12 -0
- package/dist/plugins/spec-guard/v2.js +139 -0
- package/dist/plugins/spec-guard/v2.js.map +1 -0
- package/dist/plugins/system-context-injection/agent-contexts.d.ts +5 -0
- package/dist/plugins/system-context-injection/agent-contexts.js +164 -0
- package/dist/plugins/system-context-injection/agent-contexts.js.map +1 -0
- package/dist/plugins/system-context-injection/index.d.ts +2 -0
- package/dist/plugins/system-context-injection/index.js +16 -146
- package/dist/plugins/system-context-injection/index.js.map +1 -1
- package/dist/plugins/system-context-injection/v2.d.ts +13 -0
- package/dist/plugins/system-context-injection/v2.js +60 -0
- package/dist/plugins/system-context-injection/v2.js.map +1 -0
- package/dist/plugins/tool-history-compaction/index.d.ts +2 -0
- package/dist/plugins/tool-history-compaction/index.js +13 -2
- package/dist/plugins/tool-history-compaction/index.js.map +1 -1
- package/dist/plugins/tool-history-compaction/v2.d.ts +11 -0
- package/dist/plugins/tool-history-compaction/v2.js +56 -0
- package/dist/plugins/tool-history-compaction/v2.js.map +1 -0
- package/dist/plugins/v2-runtime/config-watcher.d.ts +26 -0
- package/dist/plugins/v2-runtime/config-watcher.js +111 -0
- package/dist/plugins/v2-runtime/config-watcher.js.map +1 -0
- package/dist/plugins/v2-runtime/index.d.ts +50 -0
- package/dist/plugins/v2-runtime/index.js +114 -0
- package/dist/plugins/v2-runtime/index.js.map +1 -0
- package/dist/plugins/v2-runtime/location-config.d.ts +51 -0
- package/dist/plugins/v2-runtime/location-config.js +91 -0
- package/dist/plugins/v2-runtime/location-config.js.map +1 -0
- package/dist/plugins/v2-runtime/setup.d.ts +48 -0
- package/dist/plugins/v2-runtime/setup.js +174 -0
- package/dist/plugins/v2-runtime/setup.js.map +1 -0
- package/dist/plugins/web-tools/index.d.ts +2 -0
- package/dist/plugins/web-tools/index.js +13 -2
- package/dist/plugins/web-tools/index.js.map +1 -1
- package/dist/plugins/web-tools/v2.d.ts +11 -0
- package/dist/plugins/web-tools/v2.js +99 -0
- package/dist/plugins/web-tools/v2.js.map +1 -0
- package/dist/plugins/workflow/index.d.ts +2 -0
- package/dist/plugins/workflow/index.js +13 -2
- package/dist/plugins/workflow/index.js.map +1 -1
- package/dist/plugins/workflow/results.d.ts +16 -16
- package/dist/plugins/workflow/v2.d.ts +58 -0
- package/dist/plugins/workflow/v2.js +181 -0
- package/dist/plugins/workflow/v2.js.map +1 -0
- package/dist/tui.d.ts +1 -0
- package/dist/tui.js +41 -6
- package/dist/tui.js.map +1 -1
- package/package.json +13 -5
- package/schemas/vvoc/v3.json +1 -1
- package/server.js +7 -0
- package/templates/skills/vv-execute/references/tool-contracts.md +1 -1
- package/tui.js +7 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// START_MODULE_CONTRACT
|
|
4
4
|
// PURPOSE: Inject universal primary guidance, including correctness obligations and evidence discipline for behavior changes, and one startup-resolved concrete orchestration policy into vv-controller without polluting subagent prompts.
|
|
5
5
|
// SCOPE: Universal instructions with correctness obligations, material-assumption discipline, settled-conclusion reopen triggers, false-premise handling, and pressure-versus-evidence distinction; vv-controller policy selection; explore-worker guidance; known subagent filtering; startup vvoc snapshot use; custom subagent tracking; and chat.message injection.
|
|
6
|
-
// DEPENDS: [@opencode-ai/plugin, src/lib/config-layers.ts, src/lib/managed-agents.ts, src/lib/orchestration.ts, src/lib/vvoc-paths.ts]
|
|
6
|
+
// DEPENDS: [@opencode-ai/plugin, src/lib/config-layers.ts, src/lib/managed-agents.ts, src/lib/orchestration.ts, src/lib/vvoc-paths.ts, src/plugins/v2-runtime/index.ts]
|
|
7
7
|
// LINKS: [M-PLUGIN-SYSTEM-CONTEXT-INJECTION, M-ORCHESTRATION-PROFILES, M-CLI-MANAGED-AGENTS]
|
|
8
8
|
// ROLE: RUNTIME
|
|
9
9
|
// MAP_MODE: EXPORTS
|
|
@@ -11,133 +11,18 @@
|
|
|
11
11
|
//
|
|
12
12
|
// START_MODULE_MAP
|
|
13
13
|
// SystemContextInjectionPlugin - Injects reusable system guidance into primary sessions while skipping known subagents.
|
|
14
|
+
// default - Dual subpath entrypoint: v2 setup() seam plus v1 server() delegating to the named factory.
|
|
14
15
|
// END_MODULE_MAP
|
|
15
16
|
//
|
|
16
17
|
// START_CHANGE_SUMMARY
|
|
17
|
-
// LAST_CHANGE: [DIRECT-FIX refine-thinking-discipline - Added settled-evidence reopen triggers, false-premise handling, pressure-versus-evidence distinction, and test-results-as-evidence wording, while preserving material-assumption discipline, repository-answerable question resolution, and honest uncertainty.]
|
|
18
|
+
// LAST_CHANGE: [C-OPENCODE-V2-MIGRATION T-001 - Added the dual subpath entrypoint so the plugin loads under OpenCode v1 via server() and v2 via setup(). Prior: DIRECT-FIX refine-thinking-discipline - Added settled-evidence reopen triggers, false-premise handling, pressure-versus-evidence distinction, and test-results-as-evidence wording, while preserving material-assumption discipline, repository-answerable question resolution, and honest uncertainty.]
|
|
18
19
|
// END_CHANGE_SUMMARY
|
|
19
20
|
import { loadVvocConfig } from "../../lib/config-layers.js";
|
|
20
|
-
import {
|
|
21
|
-
import { resolveOrchestrationPolicy, } from "../../lib/orchestration.js";
|
|
21
|
+
import { resolveOrchestrationPolicy } from "../../lib/orchestration.js";
|
|
22
22
|
import { isVvocPluginEnabled } from "../../lib/plugin-toggle-config.js";
|
|
23
23
|
import { existsSync } from "node:fs";
|
|
24
|
+
import { createKnownSubagentSet, getSystemContextsForAgent, shouldInjectForAgent, } from "./agent-contexts.js";
|
|
24
25
|
import { getGlobalOpencodeSkillsDir, getProjectVvocDir, getVvocSkillsDir, } from "../../lib/vvoc-paths.js";
|
|
25
|
-
const BUILT_IN_SUBAGENTS = ["general"];
|
|
26
|
-
const PLUGIN_MANAGED_SUBAGENTS = ["guardian"];
|
|
27
|
-
const INTERNAL_PRIMARY_AGENTS = ["compaction", "title", "summary"];
|
|
28
|
-
const SELF_SUFFICIENT_PRIMARY_AGENTS = [];
|
|
29
|
-
const EXPLORE_SUBAGENT = "explore";
|
|
30
|
-
const VV_CONTROLLER_AGENT = "vv-controller";
|
|
31
|
-
const UNIVERSAL_PRIMARY_SYSTEM_CONTEXTS = [
|
|
32
|
-
[
|
|
33
|
-
"<semantic_continuity>",
|
|
34
|
-
"Reuse stable domain terms from the user request and the repository.",
|
|
35
|
-
"When the repository already has a canonical name for a concept, keep that name.",
|
|
36
|
-
"If the user's wording conflicts with repository terminology, map it once and continue with the repository's canonical term.",
|
|
37
|
-
"Keep stable domain terms across planning, implementation, review, and reporting.",
|
|
38
|
-
"</semantic_continuity>",
|
|
39
|
-
].join("\n"),
|
|
40
|
-
[
|
|
41
|
-
"<assumption_discipline>",
|
|
42
|
-
"Do not make silent material assumptions.",
|
|
43
|
-
"A material assumption is one that affects behavior, scope, API shape, schema, UX, data meaning, or verification.",
|
|
44
|
-
"If a material assumption is necessary, state it explicitly and carry its effect into the result report.",
|
|
45
|
-
"If a material assumption later becomes false, stop and reroute.",
|
|
46
|
-
"Resolve repository-answerable technical questions from the established code, contracts, and tests yourself; only a genuine business-semantics fork needs a user decision.",
|
|
47
|
-
"When a request assumes something that does not exist (a library, file, or behavior), surface the false premise and investigate the actual mechanism; continue only if the original goal stays unambiguous and within the approved scope, and never silently substitute a different goal or add an unnecessary dependency to make the premise true.",
|
|
48
|
-
"Report honest residual uncertainty: an unverified material condition is named as unverified, never presented as a passed check.",
|
|
49
|
-
"</assumption_discipline>",
|
|
50
|
-
].join("\n"),
|
|
51
|
-
[
|
|
52
|
-
"<execution_source_and_authority>",
|
|
53
|
-
"Execution ownership, requirement source, and authority are distinct: a native spec/plan package, a provided plan, and the current conversation are all valid sources, and none of them by itself implies a different ownership model.",
|
|
54
|
-
"Required reviews are exactly those declared by the selected source, explicitly requested by the user, or explicitly registered by the controller; do not invent a universal final-review pair.",
|
|
55
|
-
"When the user explicitly authorizes autonomous completion, record it as a bounded advance authority with a finite shared reserve. Use it only after ordinary allowances are exhausted, disclose material decisions without turning each into a blocking question, and still respect reserved stops, host permissions, and destructive, publication, or credential operations.",
|
|
56
|
-
"Report completion honestly as controller-accepted when no independent review was assigned, and as independently reviewed only when every registered obligation actually passed for the current result.",
|
|
57
|
-
"</execution_source_and_authority>",
|
|
58
|
-
].join("\n"),
|
|
59
|
-
[
|
|
60
|
-
"<correctness_obligations>",
|
|
61
|
-
"For behavior changes, run a compact correctness cycle before reporting done: state the target effect, derive the material properties that must be preserved from the request and established contracts, identify the directly affected consumers, challenge at least one material assumption with a diagnostic counterexample, choose verification proportionate to the risk, report the observed result, and name the remaining uncertainty.",
|
|
62
|
-
"Separate write scope (what you may edit), impact scope (behavior that could change), and verification scope (what you actually check). Investigating directly affected consumers to understand impact is required; broadening writes beyond the approved scope is not — request a scope decision instead.",
|
|
63
|
-
"Choose verification at the level where the risk arises. Derive test expectations from the contract and the request, not from the implementation's current output, and ground mocks in the dependency's established contract rather than in whatever makes the change pass.",
|
|
64
|
-
"Report honestly what was inspected, what was reasoned about, and what was executed as a check. The absence of a discovered defect is not proof of correctness: a substantive completion claim needs observed evidence, and an unverified material condition is reported as remaining uncertainty, never presented as a passed check.",
|
|
65
|
-
"Once required checks substantiate the material claims for the current files and inputs, move forward; recheck for changed inputs, uncovered material properties, conflicting evidence, or a mandatory gate, not for reassurance alone.",
|
|
66
|
-
"Interpret test results as evidence against the request and established contracts, not as the authoritative specification: a failing test that contradicts the agreed contract is a discrepancy to surface, not an automatic reason to rewrite code or tests.",
|
|
67
|
-
"Unrelated informational or trivial documentation work needs none of this ceremony.",
|
|
68
|
-
"</correctness_obligations>",
|
|
69
|
-
].join("\n"),
|
|
70
|
-
[
|
|
71
|
-
"<working_state>",
|
|
72
|
-
"For non-trivial work, stabilize a compact working state before acting: goal, current route, constraints, non-goals when relevant, assumptions, verification target, current unknown, and reroute if.",
|
|
73
|
-
"Check that state against the original request before and while acting; a constraint dropped early wastes the downstream chain.",
|
|
74
|
-
"Keep it compact and revise it when evidence changes.",
|
|
75
|
-
"Surface it explicitly when blocked, rerouting, or handing off to the user.",
|
|
76
|
-
"</working_state>",
|
|
77
|
-
].join("\n"),
|
|
78
|
-
[
|
|
79
|
-
"<editing_workflow>",
|
|
80
|
-
"When editing files, prefer the `edit` tool over shell-based rewrites when it is available.",
|
|
81
|
-
"Read the file first, then use exact `line#hash#anchor` refs from the latest `read` output when present.",
|
|
82
|
-
"Reserve `bash` for tests, builds, git, and other non-file-edit commands.",
|
|
83
|
-
"</editing_workflow>",
|
|
84
|
-
].join("\n"),
|
|
85
|
-
[
|
|
86
|
-
"<reroute_on_evidence>",
|
|
87
|
-
"When new evidence invalidates the current route, stop and reroute.",
|
|
88
|
-
"Reroute when root cause or expected behavior remains unclear, scope crosses an unexpected boundary, or requirement ambiguity blocks safe progress.",
|
|
89
|
-
"When rerouting, state the current route, the trigger, the next route, and why the previous route is no longer safe.",
|
|
90
|
-
"A retry must carry a named diagnosis of the prior failure; a blank retry is the same attempt again.",
|
|
91
|
-
"A reopen or reroute trigger is concrete — contradictory evidence, a specific error or counterexample, changed requirements, or changed relevant inputs. Vague doubt or unsupported pressure is not itself a trigger: retain a supported conclusion with a brief justification and ask for a specific discrepancy only when needed, while an explicit user change in requirements follows the existing scope and approval process rather than a factual debate.",
|
|
92
|
-
"An unchecked claim is not settled: run the required checks before treating a conclusion as final.",
|
|
93
|
-
"</reroute_on_evidence>",
|
|
94
|
-
].join("\n"),
|
|
95
|
-
[
|
|
96
|
-
"<anti_drift_budget>",
|
|
97
|
-
"When repeated attempts do not converge, stop and summarize.",
|
|
98
|
-
"Drift signals include repeated file reading without a stable path, repeated speculative fixes without stronger evidence, 2 major strategy changes for the same task, 2 review rounds without convergence, or requirement interpretation changing repeatedly during execution.",
|
|
99
|
-
"When drift signals accumulate, report what was learned, what remains unknown, and which route is now safest.",
|
|
100
|
-
"</anti_drift_budget>",
|
|
101
|
-
].join("\n"),
|
|
102
|
-
[
|
|
103
|
-
"<project_overlays>",
|
|
104
|
-
"If the task context or repository provides project-specific vocabulary, preferred patterns, boundaries, verification commands, architecture notes, or examples, treat them as project-owned overlays.",
|
|
105
|
-
"Prefer those overlays over generic vvoc defaults when they do not conflict with the user's request.",
|
|
106
|
-
"Use only overlays provided in the task context or repository.",
|
|
107
|
-
"</project_overlays>",
|
|
108
|
-
].join("\n"),
|
|
109
|
-
[
|
|
110
|
-
"<repository_memory>",
|
|
111
|
-
"If `.vvoc/lessons/index.xml` or `.vvoc/runbooks/index.xml` exists, inspect relevant index entries before debugging, fixing, changing behavior, operating on, architecting, or investigating repository-specific issues.",
|
|
112
|
-
"Load only entry files whose slug, summary, or applicability signal appears relevant to the current task.",
|
|
113
|
-
"Treat `.vvoc/lessons` and `.vvoc/runbooks` as advisory agent-facing repository memory, not as stronger authority than explicit user instructions, code, tests, or repository-owned instructions.",
|
|
114
|
-
"After a long development, debugging, bugfix, ops, or investigation session with reusable findings, consider using the vv-reflect skill to propose durable lessons or runbooks.",
|
|
115
|
-
"</repository_memory>",
|
|
116
|
-
].join("\n"),
|
|
117
|
-
[
|
|
118
|
-
"<delivery_discipline>",
|
|
119
|
-
"Keep internal and scratch reasoning compact; anything user- or tool-facing must be clean, complete language with no half-compressed notation or stray markers.",
|
|
120
|
-
"</delivery_discipline>",
|
|
121
|
-
].join("\n"),
|
|
122
|
-
];
|
|
123
|
-
const EXPLORE_SYSTEM_CONTEXTS = [
|
|
124
|
-
[
|
|
125
|
-
"<explore_role>",
|
|
126
|
-
"You are a repository search-and-discovery worker.",
|
|
127
|
-
"Behave like grep/glob/fuzzy-search over the repo: locate relevant files, symbols, call sites, config entries, tests, and line ranges.",
|
|
128
|
-
"Do not act like a file-dumping reader and never act like an editor.",
|
|
129
|
-
"Do not return exact file contents, large pasted excerpts, or rewrite proposals unless the parent explicitly asks for them.",
|
|
130
|
-
"Default output: a short summary plus a compact, prioritized list of relevant paths with why they matter and line references or anchors when useful.",
|
|
131
|
-
"Use short quoted snippets only when needed to disambiguate a match or prove a finding.",
|
|
132
|
-
"If full contents seem necessary, return the path and the most relevant line ranges or anchors so the parent session can read the file directly.",
|
|
133
|
-
"Keep results capped and focused. Prefer the smallest useful set of references over broad dumps.",
|
|
134
|
-
"</explore_role>",
|
|
135
|
-
].join("\n"),
|
|
136
|
-
];
|
|
137
|
-
// START_BLOCK_AGENT_FILTERS
|
|
138
|
-
function createKnownSubagentSet() {
|
|
139
|
-
return new Set([...BUILT_IN_SUBAGENTS, ...PLUGIN_MANAGED_SUBAGENTS, ...MANAGED_SUBAGENT_NAMES]);
|
|
140
|
-
}
|
|
141
26
|
function syncConfiguredSubagents(config, knownSubagents) {
|
|
142
27
|
for (const [name, definition] of Object.entries(config.agent ?? {})) {
|
|
143
28
|
if (definition?.mode === "subagent") {
|
|
@@ -145,32 +30,6 @@ function syncConfiguredSubagents(config, knownSubagents) {
|
|
|
145
30
|
}
|
|
146
31
|
}
|
|
147
32
|
}
|
|
148
|
-
function shouldInjectForAgent(agentName, knownSubagents) {
|
|
149
|
-
if (!agentName) {
|
|
150
|
-
return false;
|
|
151
|
-
}
|
|
152
|
-
if (knownSubagents.has(agentName)) {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
if (INTERNAL_PRIMARY_AGENTS.includes(agentName)) {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
if (SELF_SUFFICIENT_PRIMARY_AGENTS.includes(agentName)) {
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
/** Returns universal primary guidance and, only for vv-controller, one concrete policy. */
|
|
164
|
-
function getSystemContextsForAgent(agentName, policy) {
|
|
165
|
-
if (agentName === EXPLORE_SUBAGENT) {
|
|
166
|
-
return EXPLORE_SYSTEM_CONTEXTS;
|
|
167
|
-
}
|
|
168
|
-
if (agentName === VV_CONTROLLER_AGENT) {
|
|
169
|
-
return [...UNIVERSAL_PRIMARY_SYSTEM_CONTEXTS, policy.controllerSystemContext];
|
|
170
|
-
}
|
|
171
|
-
return UNIVERSAL_PRIMARY_SYSTEM_CONTEXTS;
|
|
172
|
-
}
|
|
173
|
-
// END_BLOCK_AGENT_FILTERS
|
|
174
33
|
// START_BLOCK_SYSTEM_CONTEXT_FORMATTING
|
|
175
34
|
function hasInjectedContext(existingSystem, context) {
|
|
176
35
|
return typeof existingSystem === "string" && existingSystem.includes(context);
|
|
@@ -188,6 +47,7 @@ function appendSystemContexts(existingSystem, contexts) {
|
|
|
188
47
|
return parts.join("\n\n");
|
|
189
48
|
}
|
|
190
49
|
// END_BLOCK_SYSTEM_CONTEXT_FORMATTING
|
|
50
|
+
// END_BLOCK_V1_ONLY_HELPERS
|
|
191
51
|
// START_BLOCK_PLUGIN_ENTRY
|
|
192
52
|
export const SystemContextInjectionPlugin = async ({ directory }) => {
|
|
193
53
|
const vvoc = await loadVvocConfig({ cwd: directory });
|
|
@@ -230,4 +90,14 @@ export const SystemContextInjectionPlugin = async ({ directory }) => {
|
|
|
230
90
|
};
|
|
231
91
|
};
|
|
232
92
|
// END_BLOCK_PLUGIN_ENTRY
|
|
93
|
+
// START_BLOCK_DUAL_SUBPATH_ENTRY
|
|
94
|
+
import { defineDualPlugin } from "../v2-runtime/index.js";
|
|
95
|
+
import { createV2Adapter } from "../v2-runtime/setup.js";
|
|
96
|
+
import { setupSystemContextInjectionV2 } from "./v2.js";
|
|
97
|
+
export default defineDualPlugin({
|
|
98
|
+
id: "vvoc.system-context-injection",
|
|
99
|
+
v1: SystemContextInjectionPlugin,
|
|
100
|
+
v2: (ctx) => setupSystemContextInjectionV2(createV2Adapter(ctx)),
|
|
101
|
+
});
|
|
102
|
+
// END_BLOCK_DUAL_SUBPATH_ENTRY
|
|
233
103
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/system-context-injection/index.ts"],"names":[],"mappings":"AAAA,sDAAsD;AACtD,iBAAiB;AACjB,wBAAwB;AACxB,8OAA8O;AAC9O,0WAA0W;AAC1W,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/system-context-injection/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Plugin as V2Plugin } from "@opencode/plugin";
|
|
2
|
+
import type { V2AdapterContext } from "../v2-runtime/setup.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register the system-context injection hook on the v2 runtime.
|
|
5
|
+
*
|
|
6
|
+
* The v1 chat.message mutation of output.message.system becomes the v2
|
|
7
|
+
* session context hook appending text SystemParts to event.system, which runs
|
|
8
|
+
* immediately before each agent-loop model request and therefore covers tool
|
|
9
|
+
* continuations as well. Enablement and policy resolve per session through
|
|
10
|
+
* the shared location resolver so one server can host projects with different
|
|
11
|
+
* orchestration policies.
|
|
12
|
+
*/
|
|
13
|
+
export declare function setupSystemContextInjectionV2(adapter: V2AdapterContext): Promise<V2Plugin.Cleanup | void>;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
// FILE: src/plugins/system-context-injection/v2.ts
|
|
2
|
+
// VERSION: 1.0.0
|
|
3
|
+
// START_MODULE_CONTRACT
|
|
4
|
+
// PURPOSE: Inject the vvoc system guidance into OpenCode v2 model requests with per-session location resolution and agent filtering.
|
|
5
|
+
// SCOPE: v2 setup only: register the session context hook, resolve the injection policy from the session's effective config, skip known subagents and internal request kinds, and append the same system context blocks the v1 chat.message hook produced; v1 config-hook skills-path registration moves to vvoc sync config writes under v2.
|
|
6
|
+
// DEPENDS: [@opencode/plugin, src/lib/orchestration.ts, src/plugins/system-context-injection/index.ts, src/plugins/v2-runtime/setup.ts]
|
|
7
|
+
// LINKS: [M-PLUGIN-SYSTEM-CONTEXT-INJECTION, V-M-PLUGIN-SYSTEM-CONTEXT-INJECTION, M-PLUGIN-V2-RUNTIME]
|
|
8
|
+
// ROLE: RUNTIME
|
|
9
|
+
// MAP_MODE: EXPORTS
|
|
10
|
+
// END_MODULE_CONTRACT
|
|
11
|
+
//
|
|
12
|
+
// START_MODULE_MAP
|
|
13
|
+
// setupSystemContextInjectionV2 - Register the per-request system context injection hook for one OpenCode v2 plugin context.
|
|
14
|
+
// END_MODULE_MAP
|
|
15
|
+
//
|
|
16
|
+
// START_CHANGE_SUMMARY
|
|
17
|
+
// LAST_CHANGE: [C-OPENCODE-V2-MIGRATION T-004 - Ported system guidance injection onto the v2 session context hook.]
|
|
18
|
+
// END_CHANGE_SUMMARY
|
|
19
|
+
import { resolveOrchestrationPolicy } from "../../lib/orchestration.js";
|
|
20
|
+
import { isVvocPluginEnabled } from "../../lib/plugin-toggle-config.js";
|
|
21
|
+
import { createKnownSubagentSet, getSystemContextsForAgent, shouldInjectForAgent, } from "./agent-contexts.js";
|
|
22
|
+
// START_BLOCK_SETUP_SYSTEM_CONTEXT_INJECTION_V2
|
|
23
|
+
/**
|
|
24
|
+
* Register the system-context injection hook on the v2 runtime.
|
|
25
|
+
*
|
|
26
|
+
* The v1 chat.message mutation of output.message.system becomes the v2
|
|
27
|
+
* session context hook appending text SystemParts to event.system, which runs
|
|
28
|
+
* immediately before each agent-loop model request and therefore covers tool
|
|
29
|
+
* continuations as well. Enablement and policy resolve per session through
|
|
30
|
+
* the shared location resolver so one server can host projects with different
|
|
31
|
+
* orchestration policies.
|
|
32
|
+
*/
|
|
33
|
+
export async function setupSystemContextInjectionV2(adapter) {
|
|
34
|
+
const knownSubagents = createKnownSubagentSet();
|
|
35
|
+
const registration = await adapter.ctx.session.hook("context", async (event) => {
|
|
36
|
+
try {
|
|
37
|
+
const snapshot = await adapter.resolver.forSession(event.sessionID, (input) => adapter.ctx.session.get(input));
|
|
38
|
+
if (!snapshot || !isVvocPluginEnabled(snapshot.config, "system-context-injection")) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
if (!shouldInjectForAgent(event.agent, knownSubagents)) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const policy = resolveOrchestrationPolicy(snapshot.config);
|
|
45
|
+
const contexts = getSystemContextsForAgent(event.agent, policy);
|
|
46
|
+
for (const context of contexts) {
|
|
47
|
+
const alreadyInjected = event.system.some((part) => part.type === "text" && typeof part.text === "string" && part.text.includes(context));
|
|
48
|
+
if (!alreadyInjected) {
|
|
49
|
+
event.system.push({ type: "text", text: context });
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
console.warn(`[vvoc][system-context-injection] context hook failed: ${String(error)}`);
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
return () => registration.dispose();
|
|
58
|
+
}
|
|
59
|
+
// END_BLOCK_SETUP_SYSTEM_CONTEXT_INJECTION_V2
|
|
60
|
+
//# sourceMappingURL=v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.js","sourceRoot":"","sources":["../../../src/plugins/system-context-injection/v2.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,iBAAiB;AACjB,wBAAwB;AACxB,uIAAuI;AACvI,gVAAgV;AAChV,0IAA0I;AAC1I,yGAAyG;AACzG,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,+HAA+H;AAC/H,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,sHAAsH;AACtH,qBAAqB;AAIrB,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,oBAAoB,GACrB,MAAM,qBAAqB,CAAC;AAE7B,gDAAgD;AAChD;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,6BAA6B,CACjD,OAAyB;IAEzB,MAAM,cAAc,GAAG,sBAAsB,EAAE,CAAC;IAChD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,SAAmB,EAAE,CAAC,KAAK,EAAE,EAAE,CACtF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAC/B,CAAC;YACF,IAAI,CAAC,QAAQ,IAAI,CAAC,mBAAmB,CAAC,QAAQ,CAAC,MAAM,EAAE,0BAA0B,CAAC,EAAE,CAAC;gBACnF,OAAO;YACT,CAAC;YAED,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,KAA2B,EAAE,cAAc,CAAC,EAAE,CAAC;gBAC7E,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,0BAA0B,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YAC3D,MAAM,QAAQ,GAAG,yBAAyB,CAAC,KAAK,CAAC,KAA2B,EAAE,MAAM,CAAC,CAAC;YACtF,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,MAAM,eAAe,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CACvC,CAAC,IAAI,EAAE,EAAE,CACP,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,CACvF,CAAC;gBACF,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;gBACrD,CAAC;YACH,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,yDAAyD,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;AACtC,CAAC;AACD,8CAA8C"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// START_MODULE_CONTRACT
|
|
4
4
|
// PURPOSE: Register the tool-history-compaction plugin: load vvoc config, gate on the enabled toggle, and rewrite only the in-memory message copy the model is about to receive via experimental.chat.messages.transform.
|
|
5
5
|
// SCOPE: Plugin entry point, config loading, transform hook registration, and disabled no-op.
|
|
6
|
-
// DEPENDS: [@opencode-ai/plugin, src/lib/config-layers.ts, src/plugins/tool-history-compaction/config.ts, src/plugins/tool-history-compaction/transform.ts]
|
|
6
|
+
// DEPENDS: [@opencode-ai/plugin, src/lib/config-layers.ts, src/plugins/tool-history-compaction/config.ts, src/plugins/tool-history-compaction/transform.ts, src/plugins/v2-runtime/index.ts]
|
|
7
7
|
// LINKS: [M-PLUGIN-TOOL-HISTORY-COMPACTION]
|
|
8
8
|
// ROLE: RUNTIME
|
|
9
9
|
// MAP_MODE: EXPORTS
|
|
@@ -11,10 +11,11 @@
|
|
|
11
11
|
//
|
|
12
12
|
// START_MODULE_MAP
|
|
13
13
|
// ToolHistoryCompactionPlugin - OpenCode plugin that compacts old tool outputs in the replay without touching storage or inputs.
|
|
14
|
+
// default - Dual subpath entrypoint: v2 setup() seam plus v1 server() delegating to the named factory.
|
|
14
15
|
// END_MODULE_MAP
|
|
15
16
|
//
|
|
16
17
|
// START_CHANGE_SUMMARY
|
|
17
|
-
// LAST_CHANGE: [v0.2.0 - Recent-message window, retained-budget fix, and recoverable pruning.]
|
|
18
|
+
// LAST_CHANGE: [C-OPENCODE-V2-MIGRATION T-001 - Added the dual subpath entrypoint so the plugin loads under OpenCode v1 via server() and v2 via setup(). Prior: v0.2.0 - Recent-message window, retained-budget fix, and recoverable pruning.]
|
|
18
19
|
// END_CHANGE_SUMMARY
|
|
19
20
|
import { loadVvocConfig } from "../../lib/config-layers.js";
|
|
20
21
|
import { parseToolHistoryCompactionEntry } from "./config.js";
|
|
@@ -32,4 +33,14 @@ export const ToolHistoryCompactionPlugin = async ({ directory }) => {
|
|
|
32
33
|
};
|
|
33
34
|
};
|
|
34
35
|
// END_BLOCK_PLUGIN
|
|
36
|
+
// START_BLOCK_DUAL_SUBPATH_ENTRY
|
|
37
|
+
import { defineDualPlugin } from "../v2-runtime/index.js";
|
|
38
|
+
import { createV2Adapter } from "../v2-runtime/setup.js";
|
|
39
|
+
import { setupToolHistoryCompactionV2 } from "./v2.js";
|
|
40
|
+
export default defineDualPlugin({
|
|
41
|
+
id: "vvoc.tool-history-compaction",
|
|
42
|
+
v1: ToolHistoryCompactionPlugin,
|
|
43
|
+
v2: (ctx) => setupToolHistoryCompactionV2(createV2Adapter(ctx)),
|
|
44
|
+
});
|
|
45
|
+
// END_BLOCK_DUAL_SUBPATH_ENTRY
|
|
35
46
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,iBAAiB;AACjB,wBAAwB;AACxB,4NAA4N;AAC5N,gGAAgG;AAChG
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/index.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,iBAAiB;AACjB,wBAAwB;AACxB,4NAA4N;AAC5N,gGAAgG;AAChG,+LAA+L;AAC/L,8CAA8C;AAC9C,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,mIAAmI;AACnI,yGAAyG;AACzG,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,iPAAiP;AACjP,qBAAqB;AAGrB,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAEjD,qBAAqB;AACrB,MAAM,CAAC,MAAM,2BAA2B,GAAW,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;IACzE,MAAM,IAAI,GAAG,MAAM,cAAc,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC;IACtD,MAAM,KAAK,GAAG,+BAA+B,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,yBAAyB,CAAC,CAAC,CAAC;IAChG,IAAI,CAAC,KAAK,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IAE9B,OAAO;QACL,sCAAsC,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE;YAC/D,eAAe,CAAC,MAAM,CAAC,QAAQ,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC;KACF,CAAC;AACJ,CAAC,CAAC;AACF,mBAAmB;AAEnB,iCAAiC;AACjC,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,4BAA4B,EAAE,MAAM,SAAS,CAAC;AAEvD,eAAe,gBAAgB,CAAC;IAC9B,EAAE,EAAE,8BAA8B;IAClC,EAAE,EAAE,2BAA2B;IAC/B,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,4BAA4B,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;CAChE,CAAC,CAAC;AACH,+BAA+B"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Plugin as V2Plugin } from "@opencode/plugin";
|
|
2
|
+
import type { V2AdapterContext } from "../v2-runtime/setup.js";
|
|
3
|
+
/**
|
|
4
|
+
* Register the compaction hook on the v2 runtime.
|
|
5
|
+
*
|
|
6
|
+
* The v1 experimental.chat.messages.transform becomes the v2 session context
|
|
7
|
+
* hook, which owns the mutable message copy for the outgoing model request.
|
|
8
|
+
* Enablement resolves per session location so one shared server can host
|
|
9
|
+
* projects with different compaction settings.
|
|
10
|
+
*/
|
|
11
|
+
export declare function setupToolHistoryCompactionV2(adapter: V2AdapterContext): Promise<V2Plugin.Cleanup | void>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
// FILE: src/plugins/tool-history-compaction/v2.ts
|
|
2
|
+
// VERSION: 1.0.0
|
|
3
|
+
// START_MODULE_CONTRACT
|
|
4
|
+
// PURPOSE: Register tool-history compaction on the OpenCode v2 session context hook with per-session location resolution.
|
|
5
|
+
// SCOPE: v2 setup only: gate on the per-location plugin toggle, rewrite only the in-memory message copy the model is about to receive through the shared pure compactMessages transform, and stay fail-soft on handler errors.
|
|
6
|
+
// DEPENDS: [@opencode/plugin, src/lib/config-layers.ts, src/plugins/tool-history-compaction/config.ts, src/plugins/tool-history-compaction/transform.ts, src/plugins/v2-runtime/setup.ts]
|
|
7
|
+
// LINKS: [M-PLUGIN-TOOL-HISTORY-COMPACTION, V-M-PLUGIN-TOOL-HISTORY-COMPACTION, M-PLUGIN-V2-RUNTIME]
|
|
8
|
+
// ROLE: RUNTIME
|
|
9
|
+
// MAP_MODE: EXPORTS
|
|
10
|
+
// END_MODULE_CONTRACT
|
|
11
|
+
//
|
|
12
|
+
// START_MODULE_MAP
|
|
13
|
+
// setupToolHistoryCompactionV2 - Register the compaction context hook for one OpenCode v2 plugin context.
|
|
14
|
+
// END_MODULE_MAP
|
|
15
|
+
//
|
|
16
|
+
// START_CHANGE_SUMMARY
|
|
17
|
+
// LAST_CHANGE: [C-OPENCODE-V2-MIGRATION T-004 - Ported tool-history compaction onto the v2 session context hook.]
|
|
18
|
+
// END_CHANGE_SUMMARY
|
|
19
|
+
import { parseToolHistoryCompactionEntry } from "./config.js";
|
|
20
|
+
import { compactMessages } from "./transform.js";
|
|
21
|
+
// START_BLOCK_SETUP_TOOL_HISTORY_COMPACTION_V2
|
|
22
|
+
/**
|
|
23
|
+
* Register the compaction hook on the v2 runtime.
|
|
24
|
+
*
|
|
25
|
+
* The v1 experimental.chat.messages.transform becomes the v2 session context
|
|
26
|
+
* hook, which owns the mutable message copy for the outgoing model request.
|
|
27
|
+
* Enablement resolves per session location so one shared server can host
|
|
28
|
+
* projects with different compaction settings.
|
|
29
|
+
*/
|
|
30
|
+
export async function setupToolHistoryCompactionV2(adapter) {
|
|
31
|
+
const registration = await adapter.ctx.session.hook("context", async (event) => {
|
|
32
|
+
try {
|
|
33
|
+
const snapshot = await adapter.resolver.forSession(event.sessionID, (input) => adapter.ctx.session.get(input));
|
|
34
|
+
if (!snapshot)
|
|
35
|
+
return;
|
|
36
|
+
const entry = parseToolHistoryCompactionEntry(snapshot.config.plugins?.["tool-history-compaction"]);
|
|
37
|
+
if (!entry.enabled)
|
|
38
|
+
return;
|
|
39
|
+
const messages = event.messages;
|
|
40
|
+
const adapted = messages.map((message) => ({
|
|
41
|
+
info: message,
|
|
42
|
+
parts: (message.parts ?? []),
|
|
43
|
+
}));
|
|
44
|
+
compactMessages(adapted, entry.config);
|
|
45
|
+
for (const [index, message] of messages.entries()) {
|
|
46
|
+
message.parts = adapted[index]?.parts;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
console.warn(`[vvoc][tool-history-compaction] context hook failed: ${String(error)}`);
|
|
51
|
+
}
|
|
52
|
+
});
|
|
53
|
+
return () => registration.dispose();
|
|
54
|
+
}
|
|
55
|
+
// END_BLOCK_SETUP_TOOL_HISTORY_COMPACTION_V2
|
|
56
|
+
//# sourceMappingURL=v2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"v2.js","sourceRoot":"","sources":["../../../src/plugins/tool-history-compaction/v2.ts"],"names":[],"mappings":"AAAA,kDAAkD;AAClD,iBAAiB;AACjB,wBAAwB;AACxB,4HAA4H;AAC5H,iOAAiO;AACjO,4LAA4L;AAC5L,uGAAuG;AACvG,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,4GAA4G;AAC5G,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,oHAAoH;AACpH,qBAAqB;AAIrB,OAAO,EAAE,+BAA+B,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAyB,MAAM,gBAAgB,CAAC;AAExE,+CAA+C;AAC/C;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,4BAA4B,CAChD,OAAyB;IAEzB,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE;QAC7E,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,KAAK,CAAC,SAAmB,EAAE,CAAC,KAAK,EAAE,EAAE,CACtF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAC/B,CAAC;YACF,IAAI,CAAC,QAAQ;gBAAE,OAAO;YACtB,MAAM,KAAK,GAAG,+BAA+B,CAC1C,QAAQ,CAAC,MAAM,CAAC,OAA+C,EAAE,CAChE,yBAAyB,CAC1B,CACF,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,OAAO;gBAAE,OAAO;YAE3B,MAAM,QAAQ,GAAG,KAAK,CAAC,QAErB,CAAC;YACH,MAAM,OAAO,GAAuB,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAC7D,IAAI,EAAE,OAAO;gBACb,KAAK,EAAE,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAA8B;aAC1D,CAAC,CAAC,CAAC;YACJ,eAAe,CAAC,OAAO,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;YACvC,KAAK,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,IAAI,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;gBAClD,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,EAAE,KAAwC,CAAC;YAC3E,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,wDAAwD,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,CAAC;AACtC,CAAC;AACD,6CAA6C"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface WatcherRegistrationOptions {
|
|
2
|
+
/** Injectable nearest-project config-path resolver for deterministic tests. */
|
|
3
|
+
resolveProjectConfigPath?: (directory: string) => Promise<string | undefined>;
|
|
4
|
+
/** Debounce window in milliseconds; defaults to 200. */
|
|
5
|
+
debounceMs?: number;
|
|
6
|
+
/** Injectable logger for non-fatal watcher diagnostics. */
|
|
7
|
+
warn?: (message: string) => void;
|
|
8
|
+
/** Injectable filesystem watch factory for deterministic tests. */
|
|
9
|
+
createWatch?: (filePath: string, onEvent: () => void, onError: (error: unknown) => void) => {
|
|
10
|
+
close: () => void;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Watch the project vvoc config effective for one directory.
|
|
15
|
+
*
|
|
16
|
+
* Resolves the nearest project config root the same way the layer engine
|
|
17
|
+
* does, watches the config file's directory so atomic replace writes are
|
|
18
|
+
* observed, debounces bursts, and invokes every callback with the resolved
|
|
19
|
+
* config path. Callback errors are isolated per callback; watcher errors
|
|
20
|
+
* degrade to a logged warning and stop notification for that directory.
|
|
21
|
+
*
|
|
22
|
+
* Returns a stop function that is safe to call multiple times. The function
|
|
23
|
+
* itself never throws: a directory without a project config resolves to a
|
|
24
|
+
* no-op watcher with the provided warn hook informed.
|
|
25
|
+
*/
|
|
26
|
+
export declare function watchProjectVvocConfig(directory: string, onChange: (configPath: string) => void, options?: WatcherRegistrationOptions): Promise<() => void>;
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
// FILE: src/plugins/v2-runtime/config-watcher.ts
|
|
2
|
+
// VERSION: 1.0.0
|
|
3
|
+
// START_MODULE_CONTRACT
|
|
4
|
+
// PURPOSE: Watch a project's effective vvoc config file for changes and notify registered reload callbacks without restarting the OpenCode v2 server.
|
|
5
|
+
// SCOPE: Watcher registration per directory with debounced change notification, callback error isolation, multiplexed subscriptions over one filesystem watch, and a returned stop function; never throws to the caller.
|
|
6
|
+
// DEPENDS: [node:fs/promises, node:fs, src/lib/config-layers.ts]
|
|
7
|
+
// LINKS: [M-PLUGIN-V2-RUNTIME, V-M-PLUGIN-V2-RUNTIME, M-CONFIG-LAYERS]
|
|
8
|
+
// ROLE: RUNTIME
|
|
9
|
+
// MAP_MODE: EXPORTS
|
|
10
|
+
// END_MODULE_CONTRACT
|
|
11
|
+
//
|
|
12
|
+
// START_MODULE_MAP
|
|
13
|
+
// WatcherRegistrationOptions - Injectable project-path resolution, debounce window, and logger for deterministic tests.
|
|
14
|
+
// watchProjectVvocConfig - Watch one directory's project vvoc config and invoke callbacks on debounced changes until stopped.
|
|
15
|
+
// END_MODULE_MAP
|
|
16
|
+
//
|
|
17
|
+
// START_CHANGE_SUMMARY
|
|
18
|
+
// LAST_CHANGE: [C-OPENCODE-V2-MIGRATION T-002 - Created the debounced config watcher powering restart-free preset switching.]
|
|
19
|
+
// END_CHANGE_SUMMARY
|
|
20
|
+
import { watch } from "node:fs";
|
|
21
|
+
import { basename, dirname } from "node:path";
|
|
22
|
+
import { access } from "node:fs/promises";
|
|
23
|
+
import { findNearestProjectConfigRoot } from "../../lib/config-layers.js";
|
|
24
|
+
import { getProjectVvocConfigPath } from "../../lib/vvoc-paths.js";
|
|
25
|
+
// END_BLOCK_WATCHER_OPTIONS
|
|
26
|
+
// START_BLOCK_WATCH_PROJECT_VVOC_CONFIG
|
|
27
|
+
/**
|
|
28
|
+
* Watch the project vvoc config effective for one directory.
|
|
29
|
+
*
|
|
30
|
+
* Resolves the nearest project config root the same way the layer engine
|
|
31
|
+
* does, watches the config file's directory so atomic replace writes are
|
|
32
|
+
* observed, debounces bursts, and invokes every callback with the resolved
|
|
33
|
+
* config path. Callback errors are isolated per callback; watcher errors
|
|
34
|
+
* degrade to a logged warning and stop notification for that directory.
|
|
35
|
+
*
|
|
36
|
+
* Returns a stop function that is safe to call multiple times. The function
|
|
37
|
+
* itself never throws: a directory without a project config resolves to a
|
|
38
|
+
* no-op watcher with the provided warn hook informed.
|
|
39
|
+
*/
|
|
40
|
+
export async function watchProjectVvocConfig(directory, onChange, options = {}) {
|
|
41
|
+
const debounceMs = options.debounceMs ?? 200;
|
|
42
|
+
const warn = options.warn ?? ((message) => console.warn(message));
|
|
43
|
+
const resolveProjectConfigPath = options.resolveProjectConfigPath ??
|
|
44
|
+
(async (dir) => {
|
|
45
|
+
const root = await findNearestProjectConfigRoot(dir);
|
|
46
|
+
if (root?.vvocConfigPath)
|
|
47
|
+
return root.vvocConfigPath;
|
|
48
|
+
// Watch the canonical project path even when absent so a later file
|
|
49
|
+
// creation is observed.
|
|
50
|
+
const canonical = getProjectVvocConfigPath(dir);
|
|
51
|
+
try {
|
|
52
|
+
await access(canonical);
|
|
53
|
+
return canonical;
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
const createWatch = options.createWatch ??
|
|
60
|
+
((filePath, onEvent, onError) => {
|
|
61
|
+
const watcher = watch(dirname(filePath), { persistent: false }, (_event, filename) => {
|
|
62
|
+
if (!filename || filename === basename(filePath)) {
|
|
63
|
+
onEvent();
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
watcher.on("error", onError);
|
|
67
|
+
return watcher;
|
|
68
|
+
});
|
|
69
|
+
const configPath = await resolveProjectConfigPath(directory);
|
|
70
|
+
if (!configPath) {
|
|
71
|
+
warn(`[vvoc][v2-runtime] no project vvoc config found for ${directory}; config watching disabled`);
|
|
72
|
+
return () => { };
|
|
73
|
+
}
|
|
74
|
+
let stopped = false;
|
|
75
|
+
let timer;
|
|
76
|
+
const watcher = createWatch(configPath, () => {
|
|
77
|
+
if (stopped)
|
|
78
|
+
return;
|
|
79
|
+
if (timer)
|
|
80
|
+
clearTimeout(timer);
|
|
81
|
+
timer = setTimeout(() => {
|
|
82
|
+
timer = undefined;
|
|
83
|
+
if (stopped)
|
|
84
|
+
return;
|
|
85
|
+
try {
|
|
86
|
+
onChange(configPath);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
warn(`[vvoc][v2-runtime] config change callback failed for ${configPath}: ${String(error)}`);
|
|
90
|
+
}
|
|
91
|
+
}, debounceMs);
|
|
92
|
+
}, (error) => {
|
|
93
|
+
warn(`[vvoc][v2-runtime] config watcher error for ${configPath}: ${String(error)}`);
|
|
94
|
+
});
|
|
95
|
+
return () => {
|
|
96
|
+
if (stopped)
|
|
97
|
+
return;
|
|
98
|
+
stopped = true;
|
|
99
|
+
if (timer)
|
|
100
|
+
clearTimeout(timer);
|
|
101
|
+
timer = undefined;
|
|
102
|
+
try {
|
|
103
|
+
watcher.close();
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// Closing a dead watcher is not an error.
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
// END_BLOCK_WATCH_PROJECT_VVOC_CONFIG
|
|
111
|
+
//# sourceMappingURL=config-watcher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-watcher.js","sourceRoot":"","sources":["../../../src/plugins/v2-runtime/config-watcher.ts"],"names":[],"mappings":"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"}
|