@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.
- package/README.md +244 -20
- package/dist/commands/doctor.d.ts +1 -7
- package/dist/commands/doctor.js +6 -20
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/guardian.js +1 -1
- package/dist/commands/guardian.js.map +1 -1
- package/dist/commands/install.d.ts +6 -7
- package/dist/commands/install.js +17 -17
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/status.d.ts +1 -1
- package/dist/commands/status.js +5 -5
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/sync.d.ts +2 -8
- package/dist/commands/sync.js +7 -16
- package/dist/commands/sync.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/opencode.d.ts +15 -13
- package/dist/lib/opencode.js +105 -110
- package/dist/lib/opencode.js.map +1 -1
- package/dist/lib/vvoc-paths.d.ts +9 -0
- package/dist/lib/vvoc-paths.js +48 -0
- package/dist/lib/vvoc-paths.js.map +1 -0
- package/dist/plugins/guardian.js +20 -21
- package/dist/plugins/guardian.js.map +1 -1
- package/dist/plugins/memory-store.d.ts +55 -0
- package/dist/plugins/memory-store.js +472 -0
- package/dist/plugins/memory-store.js.map +1 -0
- package/dist/plugins/memory.d.ts +2 -0
- package/dist/plugins/memory.js +323 -0
- package/dist/plugins/memory.js.map +1 -0
- package/package.json +16 -6
- package/AGENTS.md +0 -164
- package/dist/lib/opencode.test.d.ts +0 -1
- package/dist/lib/opencode.test.js +0 -47
- package/dist/lib/opencode.test.js.map +0 -1
- package/docs/development-plan.xml +0 -155
- package/docs/knowledge-graph.xml +0 -42
- package/docs/operational-packets.xml +0 -106
- package/docs/requirements.xml +0 -66
- package/docs/technology.xml +0 -51
- 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.
|
|
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"}
|