@osovv/vv-opencode 0.1.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +244 -20
  2. package/dist/commands/doctor.d.ts +1 -7
  3. package/dist/commands/doctor.js +6 -20
  4. package/dist/commands/doctor.js.map +1 -1
  5. package/dist/commands/guardian.js +1 -1
  6. package/dist/commands/guardian.js.map +1 -1
  7. package/dist/commands/install.d.ts +6 -7
  8. package/dist/commands/install.js +17 -17
  9. package/dist/commands/install.js.map +1 -1
  10. package/dist/commands/status.d.ts +1 -1
  11. package/dist/commands/status.js +5 -5
  12. package/dist/commands/status.js.map +1 -1
  13. package/dist/commands/sync.d.ts +2 -8
  14. package/dist/commands/sync.js +7 -16
  15. package/dist/commands/sync.js.map +1 -1
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +1 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/lib/opencode.d.ts +15 -13
  20. package/dist/lib/opencode.js +105 -110
  21. package/dist/lib/opencode.js.map +1 -1
  22. package/dist/lib/vvoc-paths.d.ts +9 -0
  23. package/dist/lib/vvoc-paths.js +48 -0
  24. package/dist/lib/vvoc-paths.js.map +1 -0
  25. package/dist/plugins/guardian.js +20 -21
  26. package/dist/plugins/guardian.js.map +1 -1
  27. package/dist/plugins/memory-store.d.ts +55 -0
  28. package/dist/plugins/memory-store.js +472 -0
  29. package/dist/plugins/memory-store.js.map +1 -0
  30. package/dist/plugins/memory.d.ts +2 -0
  31. package/dist/plugins/memory.js +323 -0
  32. package/dist/plugins/memory.js.map +1 -0
  33. package/package.json +16 -6
  34. package/AGENTS.md +0 -164
  35. package/dist/lib/opencode.test.d.ts +0 -1
  36. package/dist/lib/opencode.test.js +0 -47
  37. package/dist/lib/opencode.test.js.map +0 -1
  38. package/docs/development-plan.xml +0 -155
  39. package/docs/knowledge-graph.xml +0 -42
  40. package/docs/operational-packets.xml +0 -106
  41. package/docs/requirements.xml +0 -66
  42. package/docs/technology.xml +0 -51
  43. package/docs/verification-plan.xml +0 -145
@@ -0,0 +1,323 @@
1
+ import { tool } from "@opencode-ai/plugin";
2
+ import { deleteMemory, getDefaultProjectScopeKey, getDefaultSearchLimit, getDefaultSharedScopeKey, getMemory, listMemories, loadMemoryRuntimeConfig, normalizeReadScopeType, normalizeWriteScopeType, putMemory, resolveBranchScopeKey, searchMemories, updateMemory, } from "./memory-store.js";
3
+ const MEMORY_REVIEW_AGENT = "memory-reviewer";
4
+ const z = tool.schema;
5
+ const MEMORY_SYSTEM_INSTRUCTION = `
6
+ vvoc explicit memory is available in this workspace.
7
+
8
+ - Stored memory is never preloaded into the prompt.
9
+ - When durable user preferences, recurring project facts, or reusable procedures may already exist, consider memory_search, memory_list, or memory_get before guessing.
10
+ - When you discover durable information that should survive across turns or sessions, consider memory_put if your current role and available tools permit it.
11
+ - Do not use memory for transient scratch notes or one-off reasoning.
12
+ `.trim();
13
+ const MEMORY_REVIEW_PROMPT = `
14
+ You review explicit persistent memory managed by vvoc.
15
+
16
+ Rules:
17
+ - Memory is explicit-only. Nothing is automatically loaded into the prompt.
18
+ - Start with memory_list for the relevant scopes.
19
+ - Use memory_get for exact ids.
20
+ - Use memory_search to confirm overlap, duplicates, or scope mistakes.
21
+ - Do not create, update, or delete memory.
22
+ - Produce a report only.
23
+
24
+ Return sections in this order:
25
+ ## Keep
26
+ ## Update
27
+ ## Merge
28
+ ## Delete
29
+ ## Questions
30
+ ## Summary
31
+ `;
32
+ function createMemoryReviewerToolsConfig() {
33
+ return {
34
+ bash: false,
35
+ edit: false,
36
+ write: false,
37
+ read: false,
38
+ list: false,
39
+ glob: false,
40
+ grep: false,
41
+ task: false,
42
+ webfetch: false,
43
+ websearch: false,
44
+ codesearch: false,
45
+ lsp: false,
46
+ skill: false,
47
+ todoread: false,
48
+ todowrite: false,
49
+ memory_search: true,
50
+ memory_get: true,
51
+ memory_list: true,
52
+ memory_put: false,
53
+ memory_update: false,
54
+ memory_delete: false,
55
+ };
56
+ }
57
+ function installMemoryReviewerAgent(config) {
58
+ config.agent ??= {};
59
+ config.agent[MEMORY_REVIEW_AGENT] = {
60
+ mode: "subagent",
61
+ description: "Reviews stored vvoc memory and suggests cleanup actions without modifying entries.",
62
+ prompt: MEMORY_REVIEW_PROMPT.trim(),
63
+ steps: 6,
64
+ permission: {
65
+ edit: "deny",
66
+ webfetch: "deny",
67
+ bash: {
68
+ "*": "deny",
69
+ },
70
+ },
71
+ tools: createMemoryReviewerToolsConfig(),
72
+ };
73
+ }
74
+ function resolveWriteScope(scopeType, scopeKey, sessionID, directory) {
75
+ const normalizedType = normalizeWriteScopeType(scopeType) ?? "project";
76
+ if (normalizedType === "project") {
77
+ return { scopeType: "project", scopeKey: getDefaultProjectScopeKey() };
78
+ }
79
+ if (normalizedType === "shared") {
80
+ return {
81
+ scopeType: "shared",
82
+ scopeKey: typeof scopeKey === "string" && scopeKey.trim()
83
+ ? scopeKey.trim()
84
+ : getDefaultSharedScopeKey(),
85
+ };
86
+ }
87
+ if (normalizedType === "session") {
88
+ return {
89
+ scopeType: "session",
90
+ scopeKey: typeof scopeKey === "string" && scopeKey.trim() ? scopeKey.trim() : sessionID,
91
+ };
92
+ }
93
+ return {
94
+ scopeType: "branch",
95
+ scopeKey: typeof scopeKey === "string" && scopeKey.trim()
96
+ ? scopeKey.trim()
97
+ : resolveBranchScopeKey(directory),
98
+ };
99
+ }
100
+ function getRelevantScopes(sessionID, directory) {
101
+ return [
102
+ resolveWriteScope("session", undefined, sessionID, directory),
103
+ resolveWriteScope("branch", undefined, sessionID, directory),
104
+ resolveWriteScope("project", undefined, sessionID, directory),
105
+ resolveWriteScope("shared", undefined, sessionID, directory),
106
+ ];
107
+ }
108
+ function resolveReadScopes(scopeType, scopeKey, sessionID, directory) {
109
+ const normalizedType = normalizeReadScopeType(scopeType);
110
+ if (!normalizedType) {
111
+ return getRelevantScopes(sessionID, directory);
112
+ }
113
+ if (normalizedType === "all") {
114
+ return undefined;
115
+ }
116
+ return [resolveWriteScope(normalizedType, scopeKey, sessionID, directory)];
117
+ }
118
+ function formatMemoryEntry(entry) {
119
+ return `- ${entry.id} [${entry.scope_type}:${entry.scope_key}] [${entry.kind}] ${entry.text}`;
120
+ }
121
+ function formatMemoryEntries(entries) {
122
+ return entries.map(formatMemoryEntry).join("\n");
123
+ }
124
+ function formatMemoryDetails(entry) {
125
+ return JSON.stringify(entry, null, 2);
126
+ }
127
+ function getMemoryMetadataTitle(action, count) {
128
+ if (typeof count === "number") {
129
+ return `${action} (${count})`;
130
+ }
131
+ return action;
132
+ }
133
+ function getMemoryConfigWarningLines(memoryConfig) {
134
+ return memoryConfig.warnings.map((warning) => `- ${warning}`);
135
+ }
136
+ function assertEnabled(memoryConfig) {
137
+ if (!memoryConfig.enabled) {
138
+ throw new Error("vvoc memory is disabled in memory.jsonc");
139
+ }
140
+ }
141
+ export const MemoryPlugin = async ({ client, directory }) => {
142
+ const memoryConfig = await loadMemoryRuntimeConfig(directory);
143
+ await client.app.log({
144
+ body: {
145
+ service: "memory",
146
+ level: "info",
147
+ message: "memory plugin initialized",
148
+ extra: {
149
+ enabled: memoryConfig.enabled,
150
+ storageRoot: memoryConfig.storageRoot,
151
+ defaultSearchLimit: memoryConfig.defaultSearchLimit,
152
+ configSources: memoryConfig.sources,
153
+ configWarnings: memoryConfig.warnings,
154
+ },
155
+ },
156
+ });
157
+ if (!memoryConfig.enabled) {
158
+ return {};
159
+ }
160
+ const metadataWarnings = getMemoryConfigWarningLines(memoryConfig);
161
+ return {
162
+ config: async (config) => {
163
+ installMemoryReviewerAgent(config);
164
+ },
165
+ "experimental.chat.system.transform": async (_input, output) => {
166
+ if (!output.system.includes(MEMORY_SYSTEM_INSTRUCTION)) {
167
+ output.system.push(MEMORY_SYSTEM_INSTRUCTION);
168
+ }
169
+ },
170
+ tool: {
171
+ memory_search: tool({
172
+ description: "Search explicit persistent memory stored in .vvoc/memory. Memory is never preloaded into the prompt.",
173
+ args: {
174
+ query: z.string(),
175
+ scopeType: z.enum(["session", "branch", "project", "shared", "all"]).optional(),
176
+ scopeKey: z.string().optional(),
177
+ kind: z.string().optional(),
178
+ limit: z.number().int().positive().optional(),
179
+ },
180
+ async execute(args, context) {
181
+ assertEnabled(memoryConfig);
182
+ const results = await searchMemories(memoryConfig, args.query, {
183
+ scopes: resolveReadScopes(args.scopeType, args.scopeKey, context.sessionID, context.worktree),
184
+ kind: args.kind,
185
+ limit: args.limit ?? getDefaultSearchLimit(memoryConfig),
186
+ });
187
+ context.metadata({
188
+ title: getMemoryMetadataTitle("Memory Search", results.length),
189
+ metadata: { count: results.length },
190
+ });
191
+ if (results.length === 0) {
192
+ return metadataWarnings.length > 0
193
+ ? [`No matching memory entries found.`, "", ...metadataWarnings].join("\n")
194
+ : "No matching memory entries found.";
195
+ }
196
+ return metadataWarnings.length > 0
197
+ ? [formatMemoryEntries(results), "", "Warnings:", ...metadataWarnings].join("\n")
198
+ : formatMemoryEntries(results);
199
+ },
200
+ }),
201
+ memory_get: tool({
202
+ description: "Load a single explicit memory entry by id from .vvoc/memory.",
203
+ args: {
204
+ id: z.string(),
205
+ },
206
+ async execute(args, context) {
207
+ assertEnabled(memoryConfig);
208
+ const entry = await getMemory(memoryConfig, args.id);
209
+ if (!entry) {
210
+ throw new Error(`Memory not found: ${args.id}`);
211
+ }
212
+ context.metadata({
213
+ title: getMemoryMetadataTitle("Memory Get"),
214
+ metadata: { id: entry.id },
215
+ });
216
+ return formatMemoryDetails(entry);
217
+ },
218
+ }),
219
+ memory_put: tool({
220
+ description: "Create a new explicit memory entry in session, branch, project, or shared scope. Use this deliberately for durable facts, preferences, or procedures.",
221
+ args: {
222
+ text: z.string(),
223
+ kind: z.string().optional(),
224
+ scopeType: z.enum(["session", "branch", "project", "shared"]).optional(),
225
+ scopeKey: z.string().optional(),
226
+ tags: z.array(z.string()).optional(),
227
+ meta: z.record(z.string(), z.unknown()).optional(),
228
+ },
229
+ async execute(args, context) {
230
+ assertEnabled(memoryConfig);
231
+ const scope = resolveWriteScope(args.scopeType, args.scopeKey, context.sessionID, context.worktree);
232
+ const entry = await putMemory(memoryConfig, {
233
+ scope_type: scope.scopeType,
234
+ scope_key: scope.scopeKey,
235
+ kind: args.kind,
236
+ text: args.text,
237
+ tags: args.tags,
238
+ meta: args.meta,
239
+ });
240
+ context.metadata({
241
+ title: getMemoryMetadataTitle("Memory Put"),
242
+ metadata: { id: entry.id, scopeType: entry.scope_type, scopeKey: entry.scope_key },
243
+ });
244
+ return `Stored memory ${entry.id}`;
245
+ },
246
+ }),
247
+ memory_update: tool({
248
+ description: "Update an existing explicit memory entry by id.",
249
+ args: {
250
+ id: z.string(),
251
+ text: z.string().optional(),
252
+ kind: z.string().optional(),
253
+ tags: z.array(z.string()).optional(),
254
+ meta: z.record(z.string(), z.unknown()).optional(),
255
+ },
256
+ async execute(args, context) {
257
+ assertEnabled(memoryConfig);
258
+ if (args.text === undefined &&
259
+ args.kind === undefined &&
260
+ args.tags === undefined &&
261
+ args.meta === undefined) {
262
+ throw new Error("memory_update requires at least one field to change");
263
+ }
264
+ const entry = await updateMemory(memoryConfig, args.id, {
265
+ text: args.text,
266
+ kind: args.kind,
267
+ tags: args.tags,
268
+ meta: args.meta,
269
+ });
270
+ if (!entry) {
271
+ throw new Error(`Memory not found: ${args.id}`);
272
+ }
273
+ context.metadata({
274
+ title: getMemoryMetadataTitle("Memory Update"),
275
+ metadata: { id: entry.id },
276
+ });
277
+ return `Updated memory ${entry.id}`;
278
+ },
279
+ }),
280
+ memory_delete: tool({
281
+ description: "Delete an explicit memory entry by id.",
282
+ args: {
283
+ id: z.string(),
284
+ },
285
+ async execute(args, context) {
286
+ assertEnabled(memoryConfig);
287
+ const entry = await deleteMemory(memoryConfig, args.id);
288
+ if (!entry) {
289
+ throw new Error(`Memory not found: ${args.id}`);
290
+ }
291
+ context.metadata({
292
+ title: getMemoryMetadataTitle("Memory Delete"),
293
+ metadata: { id: entry.id },
294
+ });
295
+ return `Deleted memory ${entry.id}`;
296
+ },
297
+ }),
298
+ memory_list: tool({
299
+ description: "List explicit persistent memory entries across session, branch, project, or shared scopes. Memory is never preloaded into the prompt.",
300
+ args: {
301
+ scopeType: z.enum(["session", "branch", "project", "shared", "all"]).optional(),
302
+ scopeKey: z.string().optional(),
303
+ kind: z.string().optional(),
304
+ limit: z.number().int().positive().optional(),
305
+ },
306
+ async execute(args, context) {
307
+ assertEnabled(memoryConfig);
308
+ const results = await listMemories(memoryConfig, {
309
+ scopes: resolveReadScopes(args.scopeType, args.scopeKey, context.sessionID, context.worktree),
310
+ kind: args.kind,
311
+ limit: args.limit ?? getDefaultSearchLimit(memoryConfig),
312
+ });
313
+ context.metadata({
314
+ title: getMemoryMetadataTitle("Memory List", results.length),
315
+ metadata: { count: results.length },
316
+ });
317
+ return results.length > 0 ? formatMemoryEntries(results) : "No memory entries found.";
318
+ },
319
+ }),
320
+ },
321
+ };
322
+ };
323
+ //# sourceMappingURL=memory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/plugins/memory.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@osovv/vv-opencode",
3
- "version": "0.1.0",
3
+ "version": "0.2.2",
4
4
  "description": "Portable OpenCode workflow plugins and CLI tooling.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -12,6 +12,7 @@
12
12
  "plugins",
13
13
  "workflow",
14
14
  "guardian",
15
+ "memory",
15
16
  "bun",
16
17
  "citty"
17
18
  ],
@@ -20,9 +21,7 @@
20
21
  },
21
22
  "files": [
22
23
  "dist",
23
- "README.md",
24
- "AGENTS.md",
25
- "docs"
24
+ "README.md"
26
25
  ],
27
26
  "exports": {
28
27
  ".": {
@@ -32,13 +31,21 @@
32
31
  "./plugins/guardian": {
33
32
  "types": "./dist/plugins/guardian.d.ts",
34
33
  "import": "./dist/plugins/guardian.js"
34
+ },
35
+ "./plugins/memory": {
36
+ "types": "./dist/plugins/memory.d.ts",
37
+ "import": "./dist/plugins/memory.js"
35
38
  }
36
39
  },
37
40
  "scripts": {
38
- "build": "tsc -p tsconfig.json",
41
+ "build": "rm -rf dist && tsc -p tsconfig.build.json",
39
42
  "typecheck": "tsc --noEmit -p tsconfig.json",
43
+ "lint": "oxlint --deny warnings src",
44
+ "fmt": "oxfmt --write src",
45
+ "fmt:check": "oxfmt --check src",
40
46
  "test": "bun test",
41
- "check": "bun run typecheck && bun test"
47
+ "check": "bun run typecheck && bun run lint && bun run fmt:check && bun test",
48
+ "prepare": "lefthook install --force"
42
49
  },
43
50
  "dependencies": {
44
51
  "@opencode-ai/plugin": "1.3.17",
@@ -49,6 +56,9 @@
49
56
  "devDependencies": {
50
57
  "@types/node": "22.13.9",
51
58
  "bun-types": "1.3.11",
59
+ "lefthook": "2.1.5",
60
+ "oxfmt": "0.43.0",
61
+ "oxlint": "1.58.0",
52
62
  "typescript": "5.8.2"
53
63
  },
54
64
  "engines": {
package/AGENTS.md DELETED
@@ -1,164 +0,0 @@
1
- # GRACE Framework - Project Engineering Protocol
2
-
3
- ## Keywords
4
- opencode, plugins, workflow
5
-
6
- ## Annotation
7
- Portable OpenCode workflow package with plugins and a Bun CLI for install, sync, and cross-device setup.
8
-
9
- ## Core Principles
10
-
11
- ### 1. Never Write Code Without a Contract
12
- Before generating or editing any module, create or update its MODULE_CONTRACT with PURPOSE, SCOPE, INPUTS, and OUTPUTS. The contract is the source of truth. Code implements the contract, not the other way around.
13
-
14
- ### 2. Semantic Markup Is Load-Bearing Structure
15
- Markers like `// START_BLOCK_<NAME>` and `// END_BLOCK_<NAME>` are navigation anchors, not documentation. They must be:
16
- - uniquely named
17
- - paired
18
- - proportionally sized so one block fits inside an LLM working window
19
-
20
- ### 3. Knowledge Graph Is Always Current
21
- `docs/knowledge-graph.xml` is the project map. When you add a module, move a module, rename exports, or add dependencies, update the graph so future agents can navigate deterministically.
22
-
23
- ### 4. Verification Is a First-Class Artifact
24
- Testing, traces, and log anchors are designed before large execution waves. `docs/verification-plan.xml` is part of the architecture, not an afterthought. Logs are evidence. Tests are executable contracts.
25
-
26
- ### 5. Top-Down Synthesis
27
- Code generation follows:
28
- `RequirementsAnalysis -> TechnologyStack -> DevelopmentPlan -> VerificationPlan -> Code + Tests`
29
-
30
- Never jump straight to code when requirements, architecture, or verification intent are still unclear.
31
-
32
- ### 6. Governed Autonomy
33
- Agents have freedom in HOW to implement, but not in WHAT to build. Contracts, plans, graph references, and verification requirements define the allowed space.
34
-
35
- ## Semantic Markup Reference
36
-
37
- ### Module Level
38
- ```
39
- // FILE: path/to/file.ext
40
- // VERSION: 1.0.0
41
- // START_MODULE_CONTRACT
42
- // PURPOSE: [What this module does - one sentence]
43
- // SCOPE: [What operations are included]
44
- // DEPENDS: [List of module dependencies]
45
- // LINKS: [Knowledge graph references]
46
- // ROLE: [Optional: RUNTIME | TEST | BARREL | CONFIG | TYPES | SCRIPT]
47
- // MAP_MODE: [Optional: EXPORTS | LOCALS | SUMMARY | NONE]
48
- // END_MODULE_CONTRACT
49
- //
50
- // START_MODULE_MAP
51
- // exportedSymbol - one-line description
52
- // END_MODULE_MAP
53
- ```
54
-
55
- ### Function or Component Level
56
- ```
57
- // START_CONTRACT: functionName
58
- // PURPOSE: [What it does]
59
- // INPUTS: { paramName: Type - description }
60
- // OUTPUTS: { ReturnType - description }
61
- // SIDE_EFFECTS: [External state changes or "none"]
62
- // LINKS: [Related modules/functions]
63
- // END_CONTRACT: functionName
64
- ```
65
-
66
- ### Code Block Level
67
- ```
68
- // START_BLOCK_VALIDATE_INPUT
69
- // ... code ...
70
- // END_BLOCK_VALIDATE_INPUT
71
- ```
72
-
73
- ### Change Tracking
74
- ```
75
- // START_CHANGE_SUMMARY
76
- // LAST_CHANGE: [v1.2.0 - What changed and why]
77
- // END_CHANGE_SUMMARY
78
- ```
79
-
80
- ### Optional Lint Semantics
81
-
82
- Use `ROLE` and `MAP_MODE` only when the file should be linted differently from a normal runtime module.
83
-
84
- - `RUNTIME` + `EXPORTS`: normal source files with public APIs
85
- - `TEST` + `LOCALS`: tests where the map should describe helpers, fixtures, and assertion surfaces
86
- - `BARREL` + `SUMMARY`: re-export aggregators and grouped entry points
87
- - `CONFIG` + `NONE`: build or tool configuration files
88
- - `TYPES` + `EXPORTS`: pure type/interface modules
89
- - `SCRIPT` + `LOCALS`: CLI/bootstrap/smoke scripts
90
-
91
- ## Logging and Trace Convention
92
-
93
- All important logs must point back to semantic blocks:
94
- ```
95
- logger.info(`[ModuleName][functionName][BLOCK_NAME] message`, {
96
- correlationId,
97
- stableField: value,
98
- });
99
- ```
100
-
101
- Rules:
102
- - prefer structured fields over prose-heavy log lines
103
- - redact secrets and high-risk payloads
104
- - treat missing log anchors on critical branches as a verification defect
105
- - update tests when log markers change intentionally
106
-
107
- ## Verification Conventions
108
-
109
- `docs/verification-plan.xml` is the project-wide verification contract. Keep it current when module scope, test files, commands, critical log markers, or gate expectations change. Use `docs/operational-packets.xml` as the canonical schema for execution packets, graph deltas, verification deltas, and failure handoff packets.
110
-
111
- Testing rules:
112
- - deterministic assertions first
113
- - trace or log assertions when trajectory matters
114
- - test files may also carry MODULE_CONTRACT, MODULE_MAP, semantic blocks, and CHANGE_SUMMARY when they are substantial
115
- - module-local tests should stay close to the module they verify
116
- - wave-level and phase-level checks should be explicit in the verification plan
117
-
118
- ## File Structure
119
- ```
120
- docs/
121
- requirements.xml - Product requirements and use cases
122
- technology.xml - Stack decisions, tooling, observability, testing
123
- development-plan.xml - Modules, phases, data flows, ownership, write scopes
124
- verification-plan.xml - Test strategy, trace expectations, module and phase gates
125
- knowledge-graph.xml - Project-wide navigation graph
126
- operational-packets.xml - Canonical packet, delta, and failure handoff templates
127
- src/
128
- ... code with GRACE markup ...
129
- tests/
130
- ... tests with GRACE-aware evidence where appropriate ...
131
- ```
132
-
133
- ## Documentation Artifacts - Unique Tag Convention
134
-
135
- In `docs/*.xml`, repeated entities must use their unique ID as the XML tag name instead of a generic tag with an `ID` attribute. This reduces closing-tag ambiguity and gives LLMs stronger anchors.
136
-
137
- ### Tag naming conventions
138
-
139
- | Entity type | Anti-pattern | Correct (unique tags) |
140
- |---|---|---|
141
- | Module | `<Module ID="M-CONFIG">...</Module>` | `<M-CONFIG NAME="Config" TYPE="UTILITY">...</M-CONFIG>` |
142
- | Verification module | `<Verification ID="V-M-AUTH">...</Verification>` | `<V-M-AUTH MODULE="M-AUTH">...</V-M-AUTH>` |
143
- | Phase | `<Phase number="1">...</Phase>` | `<Phase-1 name="Foundation">...</Phase-1>` |
144
- | Flow | `<Flow ID="DF-SEARCH">...</Flow>` | `<DF-SEARCH NAME="...">...</DF-SEARCH>` |
145
- | Use case | `<UseCase ID="UC-001">...</UseCase>` | `<UC-001>...</UC-001>` |
146
- | Step | `<step order="1">...</step>` | `<step-1>...</step-1>` |
147
- | Export | `<export name="config" .../>` | `<export-config .../>` |
148
- | Function | `<function name="search" .../>` | `<fn-search .../>` |
149
- | Type | `<type name="SearchResult" .../>` | `<type-SearchResult .../>` |
150
- | Class | `<class name="Error" .../>` | `<class-Error .../>` |
151
-
152
- ### What NOT to change
153
- - `CrossLink` tags stay self-closing
154
- - single-use structural wrappers like `<contract>`, `<inputs>`, `<outputs>`, `<annotations>`, `<test-files>`, `<module-checks>`, and `<phase-gates>` stay generic
155
- - code-level markup already uses unique names and stays as-is
156
-
157
- ## Rules for Modifications
158
-
159
- 1. Read the MODULE_CONTRACT before editing any file.
160
- 2. After editing source or test files, update MODULE_MAP in a way that matches the file's role and map mode.
161
- 3. After adding or removing modules, update `docs/knowledge-graph.xml`.
162
- 4. After changing test files, commands, critical scenarios, or log markers, update `docs/verification-plan.xml`.
163
- 5. After fixing bugs, add a CHANGE_SUMMARY entry and strengthen nearby verification if the old evidence was weak.
164
- 6. Never remove semantic markup anchors unless the structure is intentionally replaced with better anchors.
@@ -1 +0,0 @@
1
- export {};
@@ -1,47 +0,0 @@
1
- import { describe, expect, test } from "bun:test";
2
- import { parse } from "jsonc-parser";
3
- import { OPENCODE_SCHEMA_URL, PACKAGE_NAME, ensurePackageConfigText, parseGuardianConfigText, renderLocalPluginShim, renderGuardianConfig, } from "./opencode.js";
4
- describe("ensurePackageConfigText", () => {
5
- test("creates a new config when none exists", () => {
6
- const output = ensurePackageConfigText();
7
- const parsed = parse(output);
8
- expect(parsed.$schema).toBe(OPENCODE_SCHEMA_URL);
9
- expect(parsed.plugin).toEqual([PACKAGE_NAME]);
10
- });
11
- test("preserves comments while appending the plugin", () => {
12
- const input = `{
13
- // existing plugin comment
14
- "plugin": ["foo"]
15
- }\n`;
16
- const output = ensurePackageConfigText(input);
17
- const parsed = parse(output);
18
- expect(output).toContain("// existing plugin comment");
19
- expect(parsed.plugin).toEqual(["foo", PACKAGE_NAME]);
20
- });
21
- });
22
- describe("guardian config helpers", () => {
23
- test("round-trips managed guardian config values", () => {
24
- const output = renderGuardianConfig({
25
- model: "anthropic/claude-sonnet-4-5",
26
- variant: "high",
27
- timeoutMs: 12_345,
28
- approvalRiskThreshold: 55,
29
- reviewToastDurationMs: 6_789,
30
- });
31
- const parsed = parseGuardianConfigText(output, "test guardian config");
32
- expect(parsed).toEqual({
33
- model: "anthropic/claude-sonnet-4-5",
34
- variant: "high",
35
- timeoutMs: 12_345,
36
- approvalRiskThreshold: 55,
37
- reviewToastDurationMs: 6_789,
38
- });
39
- });
40
- test("renders a managed local plugin shim", async () => {
41
- const output = await renderLocalPluginShim();
42
- expect(output).toContain("Managed by vvoc");
43
- expect(output).toContain("GuardianPlugin");
44
- expect(output).toContain("file://");
45
- });
46
- });
47
- //# sourceMappingURL=opencode.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"opencode.test.js","sourceRoot":"","sources":["../../src/lib/opencode.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAClD,OAAO,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC;AACrC,OAAO,EACL,mBAAmB,EACnB,YAAY,EACZ,uBAAuB,EACvB,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,eAAe,CAAC;AAEvB,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,IAAI,CAAC,uCAAuC,EAAE,GAAG,EAAE;QACjD,MAAM,MAAM,GAAG,uBAAuB,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAA4C,CAAC;QAExE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QACjD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IAChD,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACzD,MAAM,KAAK,GAAG;;;IAGd,CAAC;QACD,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,CAAC;QAC9C,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAA0B,CAAC;QAEtD,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,4BAA4B,CAAC,CAAC;QACvD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,yBAAyB,EAAE,GAAG,EAAE;IACvC,IAAI,CAAC,4CAA4C,EAAE,GAAG,EAAE;QACtD,MAAM,MAAM,GAAG,oBAAoB,CAAC;YAClC,KAAK,EAAE,6BAA6B;YACpC,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,MAAM;YACjB,qBAAqB,EAAE,EAAE;YACzB,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAC;QACH,MAAM,MAAM,GAAG,uBAAuB,CAAC,MAAM,EAAE,sBAAsB,CAAC,CAAC;QAEvE,MAAM,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;YACrB,KAAK,EAAE,6BAA6B;YACpC,OAAO,EAAE,MAAM;YACf,SAAS,EAAE,MAAM;YACjB,qBAAqB,EAAE,EAAE;YACzB,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,MAAM,GAAG,MAAM,qBAAqB,EAAE,CAAC;QAE7C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QAC5C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}