@osovv/vv-opencode 1.4.5 → 1.5.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.
Files changed (69) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/README.md +8 -8
  3. package/dist/commands/patch-provider.d.ts +5 -5
  4. package/dist/commands/patch-provider.js +10 -6
  5. package/dist/commands/patch-provider.js.map +1 -1
  6. package/dist/lib/opencode/agent-registrations.d.ts +33 -0
  7. package/dist/lib/opencode/agent-registrations.js +469 -0
  8. package/dist/lib/opencode/agent-registrations.js.map +1 -0
  9. package/dist/lib/opencode/inspection.d.ts +84 -0
  10. package/dist/lib/opencode/inspection.js +367 -0
  11. package/dist/lib/opencode/inspection.js.map +1 -0
  12. package/dist/lib/opencode/model-overrides.d.ts +19 -0
  13. package/dist/lib/opencode/model-overrides.js +221 -0
  14. package/dist/lib/opencode/model-overrides.js.map +1 -0
  15. package/dist/lib/opencode/paths.d.ts +21 -0
  16. package/dist/lib/opencode/paths.js +62 -0
  17. package/dist/lib/opencode/paths.js.map +1 -0
  18. package/dist/lib/opencode/plugin-registration.d.ts +17 -0
  19. package/dist/lib/opencode/plugin-registration.js +210 -0
  20. package/dist/lib/opencode/plugin-registration.js.map +1 -0
  21. package/dist/lib/opencode/shared-utils.d.ts +30 -0
  22. package/dist/lib/opencode/shared-utils.js +183 -0
  23. package/dist/lib/opencode/shared-utils.js.map +1 -0
  24. package/dist/lib/opencode/vvoc-config-io.d.ts +9 -0
  25. package/dist/lib/opencode/vvoc-config-io.js +58 -0
  26. package/dist/lib/opencode/vvoc-config-io.js.map +1 -0
  27. package/dist/lib/opencode.d.ts +15 -174
  28. package/dist/lib/opencode.js +19 -1387
  29. package/dist/lib/opencode.js.map +1 -1
  30. package/dist/lib/spec-lint/cross-file-rules.d.ts +2 -0
  31. package/dist/lib/spec-lint/cross-file-rules.js +33 -0
  32. package/dist/lib/spec-lint/cross-file-rules.js.map +1 -0
  33. package/dist/lib/spec-lint/delegated-extraction.d.ts +8 -0
  34. package/dist/lib/spec-lint/delegated-extraction.js +112 -0
  35. package/dist/lib/spec-lint/delegated-extraction.js.map +1 -0
  36. package/dist/lib/spec-lint/lint.d.ts +7 -0
  37. package/dist/lib/spec-lint/lint.js +92 -0
  38. package/dist/lib/spec-lint/lint.js.map +1 -0
  39. package/dist/lib/spec-lint/parser.d.ts +101 -0
  40. package/dist/lib/spec-lint/parser.js +482 -0
  41. package/dist/lib/spec-lint/parser.js.map +1 -0
  42. package/dist/lib/spec-lint/plan-rules.d.ts +38 -0
  43. package/dist/lib/spec-lint/plan-rules.js +745 -0
  44. package/dist/lib/spec-lint/plan-rules.js.map +1 -0
  45. package/dist/lib/spec-lint/spec-rules.d.ts +8 -0
  46. package/dist/lib/spec-lint/spec-rules.js +188 -0
  47. package/dist/lib/spec-lint/spec-rules.js.map +1 -0
  48. package/dist/lib/spec-lint.d.ts +4 -63
  49. package/dist/lib/spec-lint.js +13 -1505
  50. package/dist/lib/spec-lint.js.map +1 -1
  51. package/dist/lib/vvoc-preset-registry.d.ts +7 -7
  52. package/dist/lib/vvoc-preset-registry.js +8 -8
  53. package/dist/lib/vvoc-preset-registry.js.map +1 -1
  54. package/dist/plugins/workflow/authorization.d.ts +30 -0
  55. package/dist/plugins/workflow/authorization.js +139 -0
  56. package/dist/plugins/workflow/authorization.js.map +1 -0
  57. package/dist/plugins/workflow/index.js +26 -329
  58. package/dist/plugins/workflow/index.js.map +1 -1
  59. package/dist/plugins/workflow/recovery.d.ts +17 -0
  60. package/dist/plugins/workflow/recovery.js +150 -0
  61. package/dist/plugins/workflow/recovery.js.map +1 -0
  62. package/dist/plugins/workflow/schemas.d.ts +208 -0
  63. package/dist/plugins/workflow/schemas.js +138 -0
  64. package/dist/plugins/workflow/schemas.js.map +1 -0
  65. package/dist/plugins/workflow/tooling.d.ts +10 -65
  66. package/dist/plugins/workflow/tooling.js +5 -5
  67. package/dist/plugins/workflow/tooling.js.map +1 -1
  68. package/package.json +1 -1
  69. package/schemas/vvoc/v3.json +1 -1
@@ -0,0 +1,21 @@
1
+ export type Scope = "global" | "project";
2
+ export type ResolvedPaths = {
3
+ scope: Scope;
4
+ cwd: string;
5
+ configHome: string;
6
+ projectRoot?: string;
7
+ opencodeBaseDir: string;
8
+ vvocBaseDir: string;
9
+ vvocConfigPath: string;
10
+ managedAgentsDirPath: string;
11
+ managedSkillsDirPath: string;
12
+ opencodeConfigPath: string;
13
+ opencodeAlternatePaths: string[];
14
+ opencodeTuiConfigPath: string;
15
+ opencodeTuiAlternatePaths: string[];
16
+ };
17
+ export declare function resolvePaths(options: {
18
+ scope: Scope;
19
+ cwd: string;
20
+ configDir?: string;
21
+ }): Promise<ResolvedPaths>;
@@ -0,0 +1,62 @@
1
+ // FILE: src/lib/opencode/paths.ts
2
+ // VERSION: 1.0.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Scope-aware path resolution for OpenCode runtime/TUI and vvoc config locations.
5
+ // SCOPE: Global/project write-target resolution, managed agents/skills directory derivation, alternate config file discovery for opencode.json(c) and tui.json(c), and the Scope/ResolvedPaths contract shared by every config-mutating zone.
6
+ // DEPENDS: [node:path, src/lib/config-layers.ts, src/lib/vvoc-paths.ts, src/lib/opencode/shared-utils.ts]
7
+ // LINKS: [M-CLI-CONFIG, M-CONFIG-LAYERS]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // Scope - Supported installation scopes for vvoc config writes.
14
+ // ResolvedPaths - Scope-aware path bundle for OpenCode runtime/TUI and vvoc config locations.
15
+ // resolvePaths - Resolves OpenCode runtime/TUI and vvoc config paths for global/project scopes.
16
+ // END_MODULE_MAP
17
+ //
18
+ // START_CHANGE_SUMMARY
19
+ // LAST_CHANGE: [C-OPENCODE-MODULE-SPLIT - Extracted path resolution and alternate-config discovery from the former src/lib/opencode.ts monolith into this zone module.]
20
+ // END_CHANGE_SUMMARY
21
+ import { join } from "node:path";
22
+ import { resolveConfigWriteTargets } from "../config-layers.js";
23
+ import { getConfigHome, getVvocAgentsDir, getVvocSkillsDir } from "../vvoc-paths.js";
24
+ import { readOptionalText } from "./shared-utils.js";
25
+ const OPENCODE_CONFIG_FILE_NAMES = ["opencode.json", "opencode.jsonc"];
26
+ const OPENCODE_TUI_CONFIG_FILE_NAMES = ["tui.json", "tui.jsonc"];
27
+ // START_BLOCK_RESOLVE_CONFIG_PATHS
28
+ export async function resolvePaths(options) {
29
+ const targets = await resolveConfigWriteTargets(options);
30
+ const configHome = getConfigHome(options.configDir);
31
+ const managedAgentsDirPath = getVvocAgentsDir(targets.vvocBaseDir);
32
+ const managedSkillsDirPath = getVvocSkillsDir(targets.vvocBaseDir);
33
+ return {
34
+ scope: options.scope,
35
+ cwd: options.cwd,
36
+ configHome,
37
+ projectRoot: targets.projectRoot,
38
+ opencodeBaseDir: targets.opencodeBaseDir,
39
+ vvocBaseDir: targets.vvocBaseDir,
40
+ vvocConfigPath: targets.vvocConfigPath,
41
+ managedAgentsDirPath,
42
+ managedSkillsDirPath,
43
+ opencodeConfigPath: targets.opencodeConfigPath,
44
+ opencodeAlternatePaths: await resolveOpenCodeAlternates(targets.opencodeBaseDir, targets.opencodeConfigPath),
45
+ opencodeTuiConfigPath: targets.opencodeTuiConfigPath,
46
+ opencodeTuiAlternatePaths: await resolveConfigAlternates(targets.opencodeBaseDir, targets.opencodeTuiConfigPath, OPENCODE_TUI_CONFIG_FILE_NAMES),
47
+ };
48
+ }
49
+ async function resolveOpenCodeAlternates(opencodeBaseDir, selectedPath) {
50
+ return resolveConfigAlternates(opencodeBaseDir, selectedPath, OPENCODE_CONFIG_FILE_NAMES);
51
+ }
52
+ async function resolveConfigAlternates(baseDir, selectedPath, fileNames) {
53
+ const alternates = [];
54
+ for (const candidate of fileNames.map((name) => join(baseDir, name))) {
55
+ if (candidate !== selectedPath && (await readOptionalText(candidate)) !== undefined) {
56
+ alternates.push(candidate);
57
+ }
58
+ }
59
+ return alternates;
60
+ }
61
+ // END_BLOCK_RESOLVE_CONFIG_PATHS
62
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/lib/opencode/paths.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,iBAAiB;AACjB,wBAAwB;AACxB,6FAA6F;AAC7F,gPAAgP;AAChP,4GAA4G;AAC5G,2CAA2C;AAC3C,kBAAkB;AAClB,sBAAsB;AACtB,sBAAsB;AACtB,EAAE;AACF,mBAAmB;AACnB,kEAAkE;AAClE,gGAAgG;AAChG,kGAAkG;AAClG,iBAAiB;AACjB,EAAE;AACF,uBAAuB;AACvB,0KAA0K;AAC1K,qBAAqB;AAErB,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,0BAA0B,GAAG,CAAC,eAAe,EAAE,gBAAgB,CAAU,CAAC;AAChF,MAAM,8BAA8B,GAAG,CAAC,UAAU,EAAE,WAAW,CAAU,CAAC;AAoB1E,mCAAmC;AACnC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAIlC;IACC,MAAM,OAAO,GAAG,MAAM,yBAAyB,CAAC,OAAO,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,aAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACpD,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IACnE,MAAM,oBAAoB,GAAG,gBAAgB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAEnE,OAAO;QACL,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,GAAG,EAAE,OAAO,CAAC,GAAG;QAChB,UAAU;QACV,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,eAAe,EAAE,OAAO,CAAC,eAAe;QACxC,WAAW,EAAE,OAAO,CAAC,WAAW;QAChC,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,oBAAoB;QACpB,oBAAoB;QACpB,kBAAkB,EAAE,OAAO,CAAC,kBAAkB;QAC9C,sBAAsB,EAAE,MAAM,yBAAyB,CACrD,OAAO,CAAC,eAAe,EACvB,OAAO,CAAC,kBAAkB,CAC3B;QACD,qBAAqB,EAAE,OAAO,CAAC,qBAAqB;QACpD,yBAAyB,EAAE,MAAM,uBAAuB,CACtD,OAAO,CAAC,eAAe,EACvB,OAAO,CAAC,qBAAqB,EAC7B,8BAA8B,CAC/B;KACF,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,yBAAyB,CACtC,eAAuB,EACvB,YAAoB;IAEpB,OAAO,uBAAuB,CAAC,eAAe,EAAE,YAAY,EAAE,0BAA0B,CAAC,CAAC;AAC5F,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,OAAe,EACf,YAAoB,EACpB,SAA4B;IAE5B,MAAM,UAAU,GAAa,EAAE,CAAC;IAEhC,KAAK,MAAM,SAAS,IAAI,SAAS,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC;QACrE,IAAI,SAAS,KAAK,YAAY,IAAI,CAAC,MAAM,gBAAgB,CAAC,SAAS,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACpF,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AACD,iCAAiC"}
@@ -0,0 +1,17 @@
1
+ import { type JsonObject, type WriteResult } from "./shared-utils.js";
2
+ import type { ResolvedPaths } from "./paths.js";
3
+ export declare const TUI_PACKAGE_SPECIFIER: string;
4
+ export declare const MINIMUM_TUI_OPENCODE_VERSION = "1.18.2";
5
+ export type TuiPluginEntry = string | [string, JsonObject];
6
+ export declare function ensurePackageConfigText(text: string | undefined, packageSpecifier?: string): string;
7
+ export declare function ensureTuiPackageConfigText(text: string | undefined, packageSpecifier?: string): string;
8
+ export declare function ensureTuiPackageInstalled(paths: Pick<ResolvedPaths, "opencodeTuiConfigPath">): Promise<WriteResult>;
9
+ export declare function ensurePackageInstalled(paths: ResolvedPaths): Promise<{
10
+ path: string;
11
+ changed: boolean;
12
+ }>;
13
+ export declare function readPluginList(document: JsonObject, label: string): string[];
14
+ export declare function readTuiPluginList(document: JsonObject, label: string): TuiPluginEntry[];
15
+ export declare function isPackagePluginSpecifier(value: string): boolean;
16
+ export declare function readTuiPluginName(entry: TuiPluginEntry): string;
17
+ export declare function isTuiPackageSpecifier(value: string): boolean;
@@ -0,0 +1,210 @@
1
+ // FILE: src/lib/opencode/plugin-registration.ts
2
+ // VERSION: 1.0.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Conservative pinned runtime and TUI plugin registration for OpenCode config.
5
+ // SCOPE: Pinned base-package specifier constants, plugin-list parsing and normalization with legacy /tui spec migration and tuple-option preservation, and idempotent writes of the pinned vvoc plugin into opencode.json(c) and the pinned base package into tui.json(c).
6
+ // DEPENDS: [jsonc-parser, src/lib/package.ts, src/lib/opencode/shared-utils.ts]
7
+ // LINKS: [M-CLI-CONFIG]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // TUI_PACKAGE_SPECIFIER - Pinned base package specifier registered in tui.json(c) so OpenCode selects its ./tui export.
14
+ // MINIMUM_TUI_OPENCODE_VERSION - Minimum OpenCode host version supported by the managed TUI plugin.
15
+ // TuiPluginEntry - Supported TUI plugin string or tuple entry.
16
+ // ensurePackageConfigText - Ensures OpenCode config contains the pinned vvoc plugin specifier.
17
+ // ensureTuiPackageConfigText - Ensures TUI config contains the pinned vvoc base package while preserving tuple options.
18
+ // ensureTuiPackageInstalled - Writes the pinned vvoc base package into dedicated tui.json(c).
19
+ // ensurePackageInstalled - Writes the pinned vvoc plugin specifier into OpenCode config.
20
+ // readPluginList - Reads the runtime plugin array from a parsed OpenCode config.
21
+ // readTuiPluginList - Reads the TUI plugin array accepting string and tuple entries.
22
+ // isPackagePluginSpecifier - True when a plugin entry is the vvoc base package.
23
+ // isTuiPackageSpecifier - True when a TUI entry equals the pinned base package specifier.
24
+ // readTuiPluginName - Extracts the name from a TUI plugin entry.
25
+ // END_MODULE_MAP
26
+ //
27
+ // START_CHANGE_SUMMARY
28
+ // LAST_CHANGE: [C-OPENCODE-MODULE-SPLIT - Extracted runtime/TUI plugin pinning and plugin-list normalization from the former src/lib/opencode.ts monolith into this zone module.]
29
+ // END_CHANGE_SUMMARY
30
+ import { applyEdits, format, modify } from "jsonc-parser";
31
+ import { getPinnedPackageSpecifier, PACKAGE_NAME, PACKAGE_VERSION } from "../package.js";
32
+ import { ensureTrailingNewline, isJsonObject, OPENCODE_SCHEMA_URL, OPENCODE_TUI_SCHEMA_URL, parseObjectDocument, readOptionalText, renderJson, writeText, } from "./shared-utils.js";
33
+ export const TUI_PACKAGE_SPECIFIER = `${PACKAGE_NAME}@${PACKAGE_VERSION}`;
34
+ export const MINIMUM_TUI_OPENCODE_VERSION = "1.18.2";
35
+ const JSON_FORMAT = {
36
+ insertSpaces: true,
37
+ tabSize: 2,
38
+ eol: "\n",
39
+ };
40
+ // START_BLOCK_ENSURE_OPENCODE_PLUGIN_CONFIG
41
+ export function ensurePackageConfigText(text, packageSpecifier = PACKAGE_NAME) {
42
+ if (!text?.trim()) {
43
+ return renderJson({
44
+ $schema: OPENCODE_SCHEMA_URL,
45
+ plugin: [packageSpecifier],
46
+ });
47
+ }
48
+ const document = parseObjectDocument(text, "OpenCode config");
49
+ const currentPlugins = readPluginList(document, "OpenCode config");
50
+ let nextText = text;
51
+ if (!Object.hasOwn(document, "$schema")) {
52
+ nextText = applyEdits(nextText, modify(nextText, ["$schema"], OPENCODE_SCHEMA_URL, {
53
+ formattingOptions: JSON_FORMAT,
54
+ getInsertionIndex: () => 0,
55
+ }));
56
+ }
57
+ const nextPlugins = normalizePluginList(currentPlugins, packageSpecifier);
58
+ if (JSON.stringify(nextPlugins) !== JSON.stringify(currentPlugins)) {
59
+ nextText = applyEdits(nextText, modify(nextText, ["plugin"], nextPlugins, {
60
+ formattingOptions: JSON_FORMAT,
61
+ }));
62
+ }
63
+ return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
64
+ }
65
+ // END_BLOCK_ENSURE_OPENCODE_PLUGIN_CONFIG
66
+ // START_BLOCK_ENSURE_TUI_PLUGIN_CONFIG
67
+ export function ensureTuiPackageConfigText(text, packageSpecifier = TUI_PACKAGE_SPECIFIER) {
68
+ if (!text?.trim()) {
69
+ return renderJson({
70
+ $schema: OPENCODE_TUI_SCHEMA_URL,
71
+ plugin: [packageSpecifier],
72
+ });
73
+ }
74
+ const document = parseObjectDocument(text, "OpenCode TUI config");
75
+ const currentPlugins = readTuiPluginList(document, "OpenCode TUI config");
76
+ let nextText = text;
77
+ if (!Object.hasOwn(document, "$schema")) {
78
+ nextText = applyEdits(nextText, modify(nextText, ["$schema"], OPENCODE_TUI_SCHEMA_URL, {
79
+ formattingOptions: JSON_FORMAT,
80
+ getInsertionIndex: () => 0,
81
+ }));
82
+ }
83
+ const nextPlugins = normalizeTuiPluginList(currentPlugins, packageSpecifier);
84
+ if (JSON.stringify(nextPlugins) !== JSON.stringify(currentPlugins)) {
85
+ nextText = applyEdits(nextText, modify(nextText, ["plugin"], nextPlugins, {
86
+ formattingOptions: JSON_FORMAT,
87
+ }));
88
+ }
89
+ return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
90
+ }
91
+ export async function ensureTuiPackageInstalled(paths) {
92
+ const currentText = await readOptionalText(paths.opencodeTuiConfigPath);
93
+ const nextText = ensureTuiPackageConfigText(currentText);
94
+ if ((currentText ?? "") === nextText) {
95
+ return { action: "kept", path: paths.opencodeTuiConfigPath };
96
+ }
97
+ await writeText(paths.opencodeTuiConfigPath, nextText);
98
+ return {
99
+ action: currentText ? "updated" : "created",
100
+ path: paths.opencodeTuiConfigPath,
101
+ };
102
+ }
103
+ // END_BLOCK_ENSURE_TUI_PLUGIN_CONFIG
104
+ // START_BLOCK_INSTALL_PACKAGE_AND_GUARDIAN_CONFIG
105
+ export async function ensurePackageInstalled(paths) {
106
+ const currentText = await readOptionalText(paths.opencodeConfigPath);
107
+ const nextText = ensurePackageConfigText(currentText, await getPinnedPackageSpecifier());
108
+ if (currentText === nextText) {
109
+ return { path: paths.opencodeConfigPath, changed: false };
110
+ }
111
+ await writeText(paths.opencodeConfigPath, nextText);
112
+ return { path: paths.opencodeConfigPath, changed: true };
113
+ }
114
+ // END_BLOCK_INSTALL_PACKAGE_AND_GUARDIAN_CONFIG
115
+ // START_BLOCK_PARSE_AND_NORMALIZE_CONFIG_VALUES
116
+ export function readPluginList(document, label) {
117
+ const raw = document.plugin;
118
+ if (raw === undefined)
119
+ return [];
120
+ if (!Array.isArray(raw) || raw.some((entry) => typeof entry !== "string")) {
121
+ throw new Error(`${label}: expected "plugin" to be an array of strings`);
122
+ }
123
+ return raw.slice();
124
+ }
125
+ export function readTuiPluginList(document, label) {
126
+ const raw = document.plugin;
127
+ if (raw === undefined)
128
+ return [];
129
+ if (!Array.isArray(raw)) {
130
+ throw new Error(`${label}: expected "plugin" to be an array`);
131
+ }
132
+ return raw.map((entry, index) => {
133
+ if (typeof entry === "string") {
134
+ return entry;
135
+ }
136
+ if (Array.isArray(entry) &&
137
+ entry.length === 2 &&
138
+ typeof entry[0] === "string" &&
139
+ isJsonObject(entry[1])) {
140
+ return [entry[0], entry[1]];
141
+ }
142
+ throw new Error(`${label}: expected "plugin[${index}]" to be a string or [string, options] tuple`);
143
+ });
144
+ }
145
+ function normalizePluginList(currentPlugins, packageSpecifier) {
146
+ const nextPlugins = [];
147
+ const seen = new Set();
148
+ let insertedPackage = false;
149
+ const push = (value) => {
150
+ if (!seen.has(value)) {
151
+ seen.add(value);
152
+ nextPlugins.push(value);
153
+ }
154
+ };
155
+ for (const plugin of currentPlugins) {
156
+ if (isPackagePluginSpecifier(plugin)) {
157
+ if (!insertedPackage) {
158
+ push(packageSpecifier);
159
+ insertedPackage = true;
160
+ }
161
+ continue;
162
+ }
163
+ push(plugin);
164
+ }
165
+ if (!insertedPackage) {
166
+ push(packageSpecifier);
167
+ }
168
+ return nextPlugins;
169
+ }
170
+ function normalizeTuiPluginList(currentPlugins, packageSpecifier) {
171
+ const nextPlugins = [];
172
+ let insertedPackage = false;
173
+ for (const entry of currentPlugins) {
174
+ if (!isManagedTuiPackageSpecifier(readTuiPluginName(entry))) {
175
+ nextPlugins.push(entry);
176
+ continue;
177
+ }
178
+ if (insertedPackage) {
179
+ continue;
180
+ }
181
+ nextPlugins.push(typeof entry === "string" ? packageSpecifier : [packageSpecifier, entry[1]]);
182
+ insertedPackage = true;
183
+ }
184
+ if (!insertedPackage) {
185
+ nextPlugins.push(packageSpecifier);
186
+ }
187
+ return nextPlugins;
188
+ }
189
+ export function isPackagePluginSpecifier(value) {
190
+ return value === PACKAGE_NAME || value.startsWith(`${PACKAGE_NAME}@`);
191
+ }
192
+ export function readTuiPluginName(entry) {
193
+ return typeof entry === "string" ? entry : entry[0];
194
+ }
195
+ function isManagedTuiPackageSpecifier(value) {
196
+ return (isBasePackageSpecifier(value) ||
197
+ value === `${PACKAGE_NAME}/tui` ||
198
+ (value.startsWith(`${PACKAGE_NAME}@`) && value.endsWith("/tui")));
199
+ }
200
+ export function isTuiPackageSpecifier(value) {
201
+ return value === TUI_PACKAGE_SPECIFIER;
202
+ }
203
+ function isBasePackageSpecifier(value) {
204
+ if (value === PACKAGE_NAME)
205
+ return true;
206
+ const prefix = `${PACKAGE_NAME}@`;
207
+ return value.startsWith(prefix) && !value.slice(prefix.length).includes("/");
208
+ }
209
+ // END_BLOCK_PARSE_AND_NORMALIZE_CONFIG_VALUES
210
+ //# sourceMappingURL=plugin-registration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-registration.js","sourceRoot":"","sources":["../../../src/lib/opencode/plugin-registration.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ import { type VvocConfig } from "../vvoc-config.js";
2
+ export declare const CLI_NAME = "vvoc";
3
+ export declare const OPENCODE_SCHEMA_URL = "https://opencode.ai/config.json";
4
+ export declare const OPENCODE_TUI_SCHEMA_URL = "https://opencode.ai/tui.json";
5
+ export type JsonObject = Record<string, unknown>;
6
+ export type WriteResult = {
7
+ action: "created" | "updated" | "kept" | "skipped";
8
+ path: string;
9
+ reason?: string;
10
+ };
11
+ export type OpenCodeAgentOverride = {
12
+ model?: string;
13
+ };
14
+ export declare function parseObjectDocument(text: string, label: string): JsonObject;
15
+ export declare function readStringArray(value: unknown, label: string): string[];
16
+ export declare function updateAgentEntryText(text: string, agentName: string, entry: JsonObject): string;
17
+ export declare function ensureOpenCodeConfigText(text: string | undefined): string;
18
+ export declare function readNonEmptyString(value: unknown, label: string): string;
19
+ export declare function isJsonObject(value: unknown): value is JsonObject;
20
+ export declare function mergeJsonObjects(current: JsonObject, patch: JsonObject): JsonObject;
21
+ export declare function readOptionalObject(document: JsonObject, key: string, label: string): JsonObject | undefined;
22
+ export declare function readAgentOverride(entry: JsonObject | undefined, label: string): OpenCodeAgentOverride;
23
+ export declare function isManagedFile(text: string): boolean;
24
+ export declare function hasYamlFrontmatter(text: string): boolean;
25
+ export declare function renderJson(value: unknown): string;
26
+ export declare function stripMarkdownFrontmatter(text: string): string;
27
+ export declare function ensureTrailingNewline(text: string): string;
28
+ export declare function writeResolvedVvocConfig(path: string, currentText: string | undefined, config: VvocConfig): Promise<WriteResult>;
29
+ export declare function readOptionalText(path: string): Promise<string | undefined>;
30
+ export declare function writeText(path: string, text: string): Promise<void>;
@@ -0,0 +1,183 @@
1
+ // FILE: src/lib/opencode/shared-utils.ts
2
+ // VERSION: 1.0.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Private shared JSONC document, value, text, and filesystem helpers plus cross-zone constants used by every src/lib/opencode zone module.
5
+ // SCOPE: JSONC parse/edit primitives with strict object validation, bounded string/array readers, shared role-agnostic agent value readers, managed-file markers, canonical JSON rendering, strict vvoc render-and-write, atomic-ish text IO, write-result shape, and the OpenCode schema URL constants consumed by config-producing zones.
6
+ // DEPENDS: [jsonc-parser, node:fs/promises, node:path, src/lib/vvoc-config.ts]
7
+ // LINKS: [M-CLI-CONFIG]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // CLI_NAME - Canonical vvoc CLI binary name.
14
+ // OPENCODE_SCHEMA_URL - OpenCode config schema URL.
15
+ // OPENCODE_TUI_SCHEMA_URL - OpenCode TUI config schema URL.
16
+ // JsonObject - Internal mutable JSON object shape.
17
+ // WriteResult - Result shape returned by managed config write operations.
18
+ // OpenCodeAgentOverride - Agent override config for OpenCode.
19
+ // parseObjectDocument - Strict JSONC parse returning a top-level object or throwing a labeled error.
20
+ // readStringArray - Reads a required string array with a labeled error.
21
+ // updateAgentEntryText - Rewrites one agent.<name> object with formatting.
22
+ // ensureOpenCodeConfigText - Ensures an OpenCode config document with $schema exists.
23
+ // readNonEmptyString - Reads a required non-empty trimmed string with a labeled error.
24
+ // isJsonObject - Narrows an unknown value to JsonObject.
25
+ // mergeJsonObjects - Deep-merges a patch object into a current object.
26
+ // readOptionalObject - Reads an optional object field with a labeled error.
27
+ // readAgentOverride - Reads the model override from one agent entry.
28
+ // isManagedFile - True when text carries the vvoc managed marker.
29
+ // hasYamlFrontmatter - True when text starts with a YAML frontmatter block.
30
+ // renderJson - Renders a value as canonical two-space JSON with trailing newline.
31
+ // stripMarkdownFrontmatter - Removes a leading YAML frontmatter block.
32
+ // ensureTrailingNewline - Appends a trailing newline when missing.
33
+ // writeResolvedVvocConfig - Renders and writes a vvoc config only when text changed.
34
+ // readOptionalText - Reads a file as text, returning undefined on ENOENT.
35
+ // writeText - Writes text, creating parent directories.
36
+ // END_MODULE_MAP
37
+ //
38
+ // START_CHANGE_SUMMARY
39
+ // LAST_CHANGE: [C-OPENCODE-MODULE-SPLIT - Extracted the shared JSON/value/text/filesystem helper block and cross-zone constants from the former src/lib/opencode.ts monolith into this zone module.]
40
+ // END_CHANGE_SUMMARY
41
+ import { applyEdits, format, modify, parse } from "jsonc-parser";
42
+ import { mkdir, readFile, writeFile } from "node:fs/promises";
43
+ import { dirname } from "node:path";
44
+ import { renderVvocConfig } from "../vvoc-config.js";
45
+ export const CLI_NAME = "vvoc";
46
+ export const OPENCODE_SCHEMA_URL = "https://opencode.ai/config.json";
47
+ export const OPENCODE_TUI_SCHEMA_URL = "https://opencode.ai/tui.json";
48
+ const MANAGED_MARKER = "Managed by vvoc";
49
+ const JSON_FORMAT = {
50
+ insertSpaces: true,
51
+ tabSize: 2,
52
+ eol: "\n",
53
+ };
54
+ // START_BLOCK_SHARED_DOCUMENT_UTILS
55
+ export function parseObjectDocument(text, label) {
56
+ const errors = [];
57
+ const value = parse(text, errors, {
58
+ allowEmptyContent: false,
59
+ allowTrailingComma: true,
60
+ disallowComments: false,
61
+ });
62
+ if (errors.length > 0) {
63
+ throw new Error(`${label}: failed to parse JSONC (${errors.length} error(s))`);
64
+ }
65
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
66
+ throw new Error(`${label}: expected a top-level object`);
67
+ }
68
+ return value;
69
+ }
70
+ export function readStringArray(value, label) {
71
+ if (!Array.isArray(value) || value.some((entry) => typeof entry !== "string")) {
72
+ throw new Error(`${label}: expected an array of strings`);
73
+ }
74
+ return value.slice();
75
+ }
76
+ export function updateAgentEntryText(text, agentName, entry) {
77
+ const nextText = applyEdits(text, modify(text, ["agent", agentName], entry, {
78
+ formattingOptions: JSON_FORMAT,
79
+ }));
80
+ return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
81
+ }
82
+ export function ensureOpenCodeConfigText(text) {
83
+ if (!text?.trim()) {
84
+ return renderJson({
85
+ $schema: OPENCODE_SCHEMA_URL,
86
+ });
87
+ }
88
+ const document = parseObjectDocument(text, "OpenCode config");
89
+ let nextText = text;
90
+ if (!Object.hasOwn(document, "$schema")) {
91
+ nextText = applyEdits(nextText, modify(nextText, ["$schema"], OPENCODE_SCHEMA_URL, {
92
+ formattingOptions: JSON_FORMAT,
93
+ getInsertionIndex: () => 0,
94
+ }));
95
+ }
96
+ return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
97
+ }
98
+ // END_BLOCK_SHARED_DOCUMENT_UTILS
99
+ // START_BLOCK_JSON_VALUE_HELPERS
100
+ export function readNonEmptyString(value, label) {
101
+ if (typeof value !== "string" || !value.trim()) {
102
+ throw new Error(`${label}: expected a non-empty string`);
103
+ }
104
+ return value.trim();
105
+ }
106
+ export function isJsonObject(value) {
107
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
108
+ }
109
+ export function mergeJsonObjects(current, patch) {
110
+ const merged = { ...current };
111
+ for (const [key, patchValue] of Object.entries(patch)) {
112
+ const currentValue = merged[key];
113
+ merged[key] =
114
+ isJsonObject(currentValue) && isJsonObject(patchValue)
115
+ ? mergeJsonObjects(currentValue, patchValue)
116
+ : patchValue;
117
+ }
118
+ return merged;
119
+ }
120
+ export function readOptionalObject(document, key, label) {
121
+ const value = document[key];
122
+ if (value === undefined) {
123
+ return undefined;
124
+ }
125
+ if (!value || typeof value !== "object" || Array.isArray(value)) {
126
+ throw new Error(`${label}: expected "${key}" to be an object`);
127
+ }
128
+ return value;
129
+ }
130
+ export function readAgentOverride(entry, label) {
131
+ if (!entry) {
132
+ return {};
133
+ }
134
+ return {
135
+ model: entry.model === undefined ? undefined : readNonEmptyString(entry.model, `${label}.model`),
136
+ };
137
+ }
138
+ // END_BLOCK_JSON_VALUE_HELPERS
139
+ // START_BLOCK_FILESYSTEM_HELPERS
140
+ export function isManagedFile(text) {
141
+ return text.includes(MANAGED_MARKER);
142
+ }
143
+ export function hasYamlFrontmatter(text) {
144
+ return text.startsWith("---\n");
145
+ }
146
+ export function renderJson(value) {
147
+ return `${JSON.stringify(value, null, 2)}\n`;
148
+ }
149
+ export function stripMarkdownFrontmatter(text) {
150
+ const normalized = text.replaceAll("\r\n", "\n");
151
+ return normalized.replace(/^---\n[\s\S]*?\n---\n?/, "");
152
+ }
153
+ export function ensureTrailingNewline(text) {
154
+ return text.endsWith("\n") ? text : `${text}\n`;
155
+ }
156
+ export async function writeResolvedVvocConfig(path, currentText, config) {
157
+ const nextText = renderVvocConfig(config);
158
+ if ((currentText ?? "") === nextText) {
159
+ return { action: "kept", path };
160
+ }
161
+ await writeText(path, nextText);
162
+ return {
163
+ action: currentText ? "updated" : "created",
164
+ path,
165
+ };
166
+ }
167
+ export async function readOptionalText(path) {
168
+ try {
169
+ return await readFile(path, "utf8");
170
+ }
171
+ catch (error) {
172
+ if (error.code === "ENOENT") {
173
+ return undefined;
174
+ }
175
+ throw error;
176
+ }
177
+ }
178
+ export async function writeText(path, text) {
179
+ await mkdir(dirname(path), { recursive: true });
180
+ await writeFile(path, text, "utf8");
181
+ }
182
+ // END_BLOCK_FILESYSTEM_HELPERS
183
+ //# sourceMappingURL=shared-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-utils.js","sourceRoot":"","sources":["../../../src/lib/opencode/shared-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ import { type GuardianConfigOverrides, type VvocConfig } from "../vvoc-config.js";
2
+ import { type WriteResult } from "./shared-utils.js";
3
+ import type { ResolvedPaths } from "./paths.js";
4
+ export declare function readVvocConfig(paths: Pick<ResolvedPaths, "vvocConfigPath">): Promise<VvocConfig | undefined>;
5
+ export declare function installVvocConfig(paths: Pick<ResolvedPaths, "vvocConfigPath">): Promise<WriteResult>;
6
+ export declare function syncVvocConfig(paths: Pick<ResolvedPaths, "vvocConfigPath">): Promise<WriteResult>;
7
+ export declare function writeGuardianConfig(paths: Pick<ResolvedPaths, "vvocConfigPath">, overrides: GuardianConfigOverrides, options?: {
8
+ merge?: boolean;
9
+ }): Promise<WriteResult>;
@@ -0,0 +1,58 @@
1
+ // FILE: src/lib/opencode/vvoc-config-io.ts
2
+ // VERSION: 1.0.0
3
+ // START_MODULE_CONTRACT
4
+ // PURPOSE: Strict scoped IO for the canonical vvoc.json config document.
5
+ // SCOPE: Read the canonical vvoc.json when present, create/refresh it with materialized plugin-owned entries (hashline-edit routing, tool-history-compaction, peak-hours, spec-guard), rewrite it preserving valid current values, and merge or replace the guardian section.
6
+ // DEPENDS: [src/lib/vvoc-config.ts, src/lib/plugin-toggle-config.ts, src/lib/opencode/shared-utils.ts, src/lib/opencode/paths.ts]
7
+ // LINKS: [M-CLI-CONFIG]
8
+ // ROLE: RUNTIME
9
+ // MAP_MODE: EXPORTS
10
+ // END_MODULE_CONTRACT
11
+ //
12
+ // START_MODULE_MAP
13
+ // readVvocConfig - Loads the canonical vvoc.json document when present.
14
+ // installVvocConfig - Creates or refreshes the canonical vvoc.json document.
15
+ // syncVvocConfig - Rewrites the canonical vvoc.json document while preserving valid current values.
16
+ // writeGuardianConfig - Writes the guardian section into the canonical vvoc.json document.
17
+ // END_MODULE_MAP
18
+ //
19
+ // START_CHANGE_SUMMARY
20
+ // LAST_CHANGE: [C-OPENCODE-MODULE-SPLIT - Extracted canonical vvoc.json IO from the former src/lib/opencode.ts monolith into this zone module.]
21
+ // END_CHANGE_SUMMARY
22
+ import { createDefaultVvocConfig, createGuardianConfig, parseVvocConfigText, } from "../vvoc-config.js";
23
+ import { materializeHashlineEditEntry, materializeToolHistoryCompactionEntry, materializePeakHoursEntry, materializeSpecGuardEntry, } from "../plugin-toggle-config.js";
24
+ import { readOptionalText, writeResolvedVvocConfig } from "./shared-utils.js";
25
+ // START_BLOCK_VVOC_CONFIG_IO
26
+ export async function readVvocConfig(paths) {
27
+ const currentText = await readOptionalText(paths.vvocConfigPath);
28
+ return currentText ? parseVvocConfigText(currentText, paths.vvocConfigPath) : undefined;
29
+ }
30
+ export async function installVvocConfig(paths) {
31
+ return syncVvocConfig(paths);
32
+ }
33
+ export async function syncVvocConfig(paths) {
34
+ const currentText = await readOptionalText(paths.vvocConfigPath);
35
+ const nextConfig = currentText
36
+ ? parseVvocConfigText(currentText, paths.vvocConfigPath)
37
+ : createDefaultVvocConfig();
38
+ nextConfig.plugins["hashline-edit"] = materializeHashlineEditEntry(nextConfig.plugins["hashline-edit"]);
39
+ nextConfig.plugins["tool-history-compaction"] = materializeToolHistoryCompactionEntry(nextConfig.plugins["tool-history-compaction"]);
40
+ nextConfig.plugins["peak-hours"] = materializePeakHoursEntry(nextConfig.plugins["peak-hours"]);
41
+ nextConfig.plugins["spec-guard"] = materializeSpecGuardEntry(nextConfig.plugins["spec-guard"]);
42
+ return writeResolvedVvocConfig(paths.vvocConfigPath, currentText, nextConfig);
43
+ }
44
+ export async function writeGuardianConfig(paths, overrides, options = {}) {
45
+ const currentText = await readOptionalText(paths.vvocConfigPath);
46
+ const currentConfig = currentText
47
+ ? parseVvocConfigText(currentText, paths.vvocConfigPath)
48
+ : createDefaultVvocConfig();
49
+ const nextConfig = {
50
+ ...currentConfig,
51
+ guardian: options.merge
52
+ ? createGuardianConfig({ ...currentConfig.guardian, ...overrides })
53
+ : createGuardianConfig(overrides),
54
+ };
55
+ return writeResolvedVvocConfig(paths.vvocConfigPath, currentText, nextConfig);
56
+ }
57
+ // END_BLOCK_VVOC_CONFIG_IO
58
+ //# sourceMappingURL=vvoc-config-io.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vvoc-config-io.js","sourceRoot":"","sources":["../../../src/lib/opencode/vvoc-config-io.ts"],"names":[],"mappings":"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"}