@osovv/vv-opencode 0.10.0 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +14 -16
- package/dist/commands/agent.js +11 -14
- package/dist/commands/agent.js.map +1 -1
- package/dist/commands/completion.js +3 -2
- package/dist/commands/completion.js.map +1 -1
- package/dist/commands/init.js +7 -13
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/install.js +6 -8
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/sync.js +6 -8
- package/dist/commands/sync.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +6 -7
- package/dist/index.js.map +1 -1
- package/dist/lib/managed-agents.d.ts +17 -1
- package/dist/lib/managed-agents.js +49 -4
- package/dist/lib/managed-agents.js.map +1 -1
- package/dist/lib/opencode.d.ts +6 -11
- package/dist/lib/opencode.js +32 -148
- package/dist/lib/opencode.js.map +1 -1
- package/package.json +2 -6
- package/templates/agents/enhancer.md +95 -0
- package/dist/plugins/enhance/index.d.ts +0 -2
- package/dist/plugins/enhance/index.js +0 -135
- package/dist/plugins/enhance/index.js.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// FILE: src/lib/managed-agents.ts
|
|
2
|
-
// VERSION: 0.
|
|
2
|
+
// VERSION: 0.3.0
|
|
3
3
|
// START_MODULE_CONTRACT
|
|
4
4
|
// PURPOSE: Describe vvoc-managed OpenCode agent prompts and load them from bundled templates or scoped vvoc config roots.
|
|
5
|
-
// SCOPE: Built-in subagent metadata, managed prompt names, prompt file path resolution, bundled template loading, and project/global prompt lookup.
|
|
5
|
+
// SCOPE: Built-in primary/subagent metadata, managed prompt names, prompt file path resolution, bundled template loading, and project/global prompt lookup.
|
|
6
6
|
// DEPENDS: [node:fs/promises, node:path, src/lib/vvoc-paths.ts]
|
|
7
7
|
// LINKS: [M-CLI-CONFIG, M-PLUGIN-GUARDIAN, M-PLUGIN-MEMORY]
|
|
8
8
|
// ROLE: RUNTIME
|
|
@@ -11,20 +11,29 @@
|
|
|
11
11
|
//
|
|
12
12
|
// START_MODULE_MAP
|
|
13
13
|
// ManagedSubagentName - Canonical vvoc-managed subagent names.
|
|
14
|
+
// ManagedPrimaryAgentName - Canonical vvoc-managed primary agent names.
|
|
15
|
+
// ManagedOpenCodeAgentName - Canonical vvoc-managed OpenCode agent registration names.
|
|
14
16
|
// ManagedAgentPromptName - Canonical vvoc-managed agent prompt names including Guardian and memory-reviewer.
|
|
15
17
|
// ManagedSubagentDefinition - Metadata used to register a managed subagent in OpenCode config.
|
|
18
|
+
// ManagedPrimaryAgentDefinition - Metadata used to register a managed primary agent in OpenCode config.
|
|
16
19
|
// MANAGED_SUBAGENT_NAMES - Ordered managed subagent names.
|
|
20
|
+
// MANAGED_PRIMARY_AGENT_NAMES - Ordered managed primary agent names.
|
|
21
|
+
// MANAGED_OPENCODE_AGENT_NAMES - Ordered managed OpenCode agent registration names.
|
|
17
22
|
// MANAGED_AGENT_PROMPT_NAMES - Ordered managed agent prompt names.
|
|
18
23
|
// MANAGED_SUBAGENTS - Built-in managed subagent definitions.
|
|
24
|
+
// MANAGED_PRIMARY_AGENTS - Built-in managed primary agent definitions.
|
|
25
|
+
// MANAGED_OPENCODE_AGENTS - Built-in managed OpenCode agent definitions.
|
|
19
26
|
// isManagedSubagentName - Checks whether a string is one of the managed subagent names.
|
|
27
|
+
// isManagedOpenCodeAgentName - Checks whether a string is one of the managed OpenCode agent names.
|
|
20
28
|
// getManagedSubagentDefinition - Returns metadata for a managed subagent.
|
|
29
|
+
// getManagedOpenCodeAgentDefinition - Returns metadata for a managed OpenCode agent.
|
|
21
30
|
// getManagedAgentPromptPath - Resolves the prompt file path inside a vvoc agents directory.
|
|
22
31
|
// loadManagedAgentPromptTemplate - Loads the bundled prompt template for a managed agent prompt.
|
|
23
32
|
// loadManagedAgentPromptText - Loads a managed prompt from project or global vvoc config and errors if neither exists.
|
|
24
33
|
// END_MODULE_MAP
|
|
25
34
|
//
|
|
26
35
|
// START_CHANGE_SUMMARY
|
|
27
|
-
// LAST_CHANGE: [v0.
|
|
36
|
+
// LAST_CHANGE: [v0.3.0 - Added the managed enhancer primary agent alongside the existing vvoc subagent definitions.]
|
|
28
37
|
// END_CHANGE_SUMMARY
|
|
29
38
|
import { readFile } from "node:fs/promises";
|
|
30
39
|
import { join } from "node:path";
|
|
@@ -35,21 +44,28 @@ export const MANAGED_SUBAGENT_NAMES = [
|
|
|
35
44
|
"code-reviewer",
|
|
36
45
|
"investitagor",
|
|
37
46
|
];
|
|
47
|
+
export const MANAGED_PRIMARY_AGENT_NAMES = ["enhancer"];
|
|
48
|
+
export const MANAGED_OPENCODE_AGENT_NAMES = [
|
|
49
|
+
...MANAGED_PRIMARY_AGENT_NAMES,
|
|
50
|
+
...MANAGED_SUBAGENT_NAMES,
|
|
51
|
+
];
|
|
38
52
|
export const MANAGED_AGENT_PROMPT_NAMES = [
|
|
39
53
|
"guardian",
|
|
40
54
|
"memory-reviewer",
|
|
41
|
-
...
|
|
55
|
+
...MANAGED_OPENCODE_AGENT_NAMES,
|
|
42
56
|
];
|
|
43
57
|
export const MANAGED_SUBAGENTS = [
|
|
44
58
|
{
|
|
45
59
|
name: "implementer",
|
|
46
60
|
description: "Implements approved changes with focused verification and a minimal diff.",
|
|
47
61
|
promptFileName: "implementer.md",
|
|
62
|
+
mode: "subagent",
|
|
48
63
|
},
|
|
49
64
|
{
|
|
50
65
|
name: "spec-reviewer",
|
|
51
66
|
description: "Checks an implementation against the requested spec and flags missing or extra behavior.",
|
|
52
67
|
promptFileName: "spec-reviewer.md",
|
|
68
|
+
mode: "subagent",
|
|
53
69
|
permission: {
|
|
54
70
|
edit: "deny",
|
|
55
71
|
},
|
|
@@ -58,6 +74,7 @@ export const MANAGED_SUBAGENTS = [
|
|
|
58
74
|
name: "code-reviewer",
|
|
59
75
|
description: "Reviews changes for bugs, regressions, maintainability risks, and missing tests.",
|
|
60
76
|
promptFileName: "code-reviewer.md",
|
|
77
|
+
mode: "subagent",
|
|
61
78
|
permission: {
|
|
62
79
|
edit: "deny",
|
|
63
80
|
},
|
|
@@ -66,15 +83,33 @@ export const MANAGED_SUBAGENTS = [
|
|
|
66
83
|
name: "investitagor",
|
|
67
84
|
description: "Investigates bugs and unclear behavior before implementation work begins.",
|
|
68
85
|
promptFileName: "investitagor.md",
|
|
86
|
+
mode: "subagent",
|
|
87
|
+
permission: {
|
|
88
|
+
edit: "deny",
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
export const MANAGED_PRIMARY_AGENTS = [
|
|
93
|
+
{
|
|
94
|
+
name: "enhancer",
|
|
95
|
+
description: "Turns raw user intent into a structured XML prompt for a follow-up agent.",
|
|
96
|
+
promptFileName: "enhancer.md",
|
|
97
|
+
mode: "primary",
|
|
69
98
|
permission: {
|
|
70
99
|
edit: "deny",
|
|
100
|
+
bash: "deny",
|
|
101
|
+
task: "deny",
|
|
102
|
+
todowrite: "deny",
|
|
71
103
|
},
|
|
72
104
|
},
|
|
73
105
|
];
|
|
106
|
+
export const MANAGED_OPENCODE_AGENTS = [...MANAGED_PRIMARY_AGENTS, ...MANAGED_SUBAGENTS];
|
|
74
107
|
const MANAGED_SUBAGENT_MAP = new Map(MANAGED_SUBAGENTS.map((definition) => [definition.name, definition]));
|
|
108
|
+
const MANAGED_OPENCODE_AGENT_MAP = new Map(MANAGED_OPENCODE_AGENTS.map((definition) => [definition.name, definition]));
|
|
75
109
|
const MANAGED_AGENT_PROMPT_FILE_NAMES = new Map([
|
|
76
110
|
["guardian", "guardian.md"],
|
|
77
111
|
["memory-reviewer", "memory-reviewer.md"],
|
|
112
|
+
["enhancer", "enhancer.md"],
|
|
78
113
|
["implementer", "implementer.md"],
|
|
79
114
|
["spec-reviewer", "spec-reviewer.md"],
|
|
80
115
|
["code-reviewer", "code-reviewer.md"],
|
|
@@ -83,6 +118,9 @@ const MANAGED_AGENT_PROMPT_FILE_NAMES = new Map([
|
|
|
83
118
|
export function isManagedSubagentName(value) {
|
|
84
119
|
return MANAGED_SUBAGENT_MAP.has(value);
|
|
85
120
|
}
|
|
121
|
+
export function isManagedOpenCodeAgentName(value) {
|
|
122
|
+
return MANAGED_OPENCODE_AGENT_MAP.has(value);
|
|
123
|
+
}
|
|
86
124
|
export function getManagedSubagentDefinition(name) {
|
|
87
125
|
const definition = MANAGED_SUBAGENT_MAP.get(name);
|
|
88
126
|
if (!definition) {
|
|
@@ -90,6 +128,13 @@ export function getManagedSubagentDefinition(name) {
|
|
|
90
128
|
}
|
|
91
129
|
return definition;
|
|
92
130
|
}
|
|
131
|
+
export function getManagedOpenCodeAgentDefinition(name) {
|
|
132
|
+
const definition = MANAGED_OPENCODE_AGENT_MAP.get(name);
|
|
133
|
+
if (!definition) {
|
|
134
|
+
throw new Error(`unknown managed OpenCode agent: ${name}`);
|
|
135
|
+
}
|
|
136
|
+
return definition;
|
|
137
|
+
}
|
|
93
138
|
export function getManagedAgentPromptPath(agentsDirPath, name) {
|
|
94
139
|
return join(agentsDirPath, getManagedAgentPromptFileName(name));
|
|
95
140
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"managed-agents.js","sourceRoot":"","sources":["../../src/lib/managed-agents.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAClC,iBAAiB;AACjB,wBAAwB;AACxB,4HAA4H;AAC5H,
|
|
1
|
+
{"version":3,"file":"managed-agents.js","sourceRoot":"","sources":["../../src/lib/managed-agents.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/opencode.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ManagedOpenCodeAgentName } from "./managed-agents.js";
|
|
2
2
|
import { type MemoryConfigOverrides } from "../plugins/memory-store.js";
|
|
3
3
|
import { PACKAGE_NAME } from "./package.js";
|
|
4
4
|
export declare const CLI_NAME = "vvoc";
|
|
@@ -33,7 +33,7 @@ export type WriteResult = {
|
|
|
33
33
|
path: string;
|
|
34
34
|
reason?: string;
|
|
35
35
|
};
|
|
36
|
-
export type
|
|
36
|
+
export type ManagedAgentModelMap = Record<ManagedOpenCodeAgentName, string | undefined>;
|
|
37
37
|
export type InstallationInspection = {
|
|
38
38
|
scope: Scope;
|
|
39
39
|
opencode: {
|
|
@@ -76,13 +76,8 @@ export declare function resolvePaths(options: {
|
|
|
76
76
|
configDir?: string;
|
|
77
77
|
}): Promise<ResolvedPaths>;
|
|
78
78
|
export declare function ensurePackageConfigText(text: string | undefined, packageSpecifier?: string): string;
|
|
79
|
-
export declare function
|
|
80
|
-
export declare function
|
|
81
|
-
path: string;
|
|
82
|
-
changed: boolean;
|
|
83
|
-
}>;
|
|
84
|
-
export declare function ensureManagedSubagentsConfigText(text: string | undefined, paths: Pick<ResolvedPaths, "managedAgentsDirPath" | "opencodeConfigPath">): string;
|
|
85
|
-
export declare function syncManagedSubagentRegistrations(paths: ResolvedPaths): Promise<{
|
|
79
|
+
export declare function ensureManagedAgentRegistrationsConfigText(text: string | undefined, paths: Pick<ResolvedPaths, "managedAgentsDirPath" | "opencodeConfigPath">): string;
|
|
80
|
+
export declare function syncManagedAgentRegistrations(paths: ResolvedPaths): Promise<{
|
|
86
81
|
path: string;
|
|
87
82
|
changed: boolean;
|
|
88
83
|
}>;
|
|
@@ -92,13 +87,13 @@ export declare function installManagedAgentPrompts(paths: ResolvedPaths, options
|
|
|
92
87
|
export declare function syncManagedAgentPrompts(paths: ResolvedPaths, options: {
|
|
93
88
|
force: boolean;
|
|
94
89
|
}): Promise<WriteResult[]>;
|
|
95
|
-
export declare function
|
|
90
|
+
export declare function readManagedAgentModels(paths: Pick<ResolvedPaths, "opencodeConfigPath">): Promise<ManagedAgentModelMap>;
|
|
96
91
|
export declare function readOpenCodeAgentModel(paths: Pick<ResolvedPaths, "opencodeConfigPath">, agentName: string): Promise<string | undefined>;
|
|
97
92
|
export declare function writeOpenCodeAgentModel(paths: Pick<ResolvedPaths, "opencodeConfigPath">, agentName: string, options: {
|
|
98
93
|
model?: string;
|
|
99
94
|
ensureEntry: boolean;
|
|
100
95
|
}): Promise<WriteResult>;
|
|
101
|
-
export declare function
|
|
96
|
+
export declare function writeManagedAgentModel(paths: Pick<ResolvedPaths, "managedAgentsDirPath" | "opencodeConfigPath">, agentName: ManagedOpenCodeAgentName, options: {
|
|
102
97
|
model?: string;
|
|
103
98
|
ensureEntry: boolean;
|
|
104
99
|
}): Promise<WriteResult>;
|
package/dist/lib/opencode.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// FILE: src/lib/opencode.ts
|
|
2
|
-
// VERSION: 0.
|
|
2
|
+
// VERSION: 0.5.0
|
|
3
3
|
// START_MODULE_CONTRACT
|
|
4
4
|
// PURPOSE: Manage OpenCode config mutation, provider patching, and vvoc-owned config files.
|
|
5
|
-
// SCOPE: Scope-aware path resolution, pinned plugin writes, provider baseURL patching, managed OpenCode
|
|
5
|
+
// SCOPE: Scope-aware path resolution, pinned plugin writes, provider baseURL patching, managed OpenCode agent registration/model overrides, managed agent prompt sync, Guardian/Memory config rendering and sync, and installation inspection.
|
|
6
6
|
// DEPENDS: [jsonc-parser, node:fs/promises, node:path, src/lib/managed-agents.ts, src/lib/package.ts, src/lib/vvoc-paths.ts, src/plugins/memory-store.ts]
|
|
7
7
|
// LINKS: [M-CLI-CONFIG]
|
|
8
8
|
// ROLE: RUNTIME
|
|
@@ -21,20 +21,18 @@
|
|
|
21
21
|
// resolvePaths - Resolves OpenCode and vvoc config paths for global/project scopes.
|
|
22
22
|
// ensurePackageConfigText - Ensures OpenCode config contains the pinned vvoc plugin specifier.
|
|
23
23
|
// ensureProviderBaseUrlConfigText - Ensures OpenCode config contains the requested provider options.baseURL override.
|
|
24
|
-
//
|
|
25
|
-
// ensureManagedSubagentsConfigText - Ensures OpenCode config contains the vvoc-managed subagent registrations.
|
|
24
|
+
// ensureManagedAgentRegistrationsConfigText - Ensures OpenCode config contains the vvoc-managed OpenCode agent registrations.
|
|
26
25
|
// parseGuardianConfigText - Parses Guardian config JSONC into typed overrides.
|
|
27
26
|
// renderGuardianConfig - Renders managed Guardian config JSONC.
|
|
28
27
|
// ensurePackageInstalled - Writes the pinned vvoc plugin specifier into OpenCode config.
|
|
29
28
|
// writeProviderBaseUrl - Writes a provider options.baseURL override into OpenCode config.
|
|
30
|
-
//
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
// syncManagedAgentPrompts - Rewrites managed vvoc prompt files for the bundled Guardian/subagent agents.
|
|
29
|
+
// syncManagedAgentRegistrations - Syncs the canonical vvoc-managed OpenCode agent registrations into OpenCode config.
|
|
30
|
+
// installManagedAgentPrompts - Creates managed vvoc prompt files for the bundled Guardian and managed OpenCode agents when missing.
|
|
31
|
+
// syncManagedAgentPrompts - Rewrites managed vvoc prompt files for the bundled Guardian and managed OpenCode agents.
|
|
34
32
|
// readOpenCodeAgentModel - Reads a model override for any OpenCode agent from config.
|
|
35
33
|
// writeOpenCodeAgentModel - Writes or removes a model override for any OpenCode agent in config.
|
|
36
|
-
//
|
|
37
|
-
//
|
|
34
|
+
// readManagedAgentModels - Reads model overrides for the bundled vvoc-managed OpenCode agents from OpenCode config.
|
|
35
|
+
// writeManagedAgentModel - Writes or removes a bundled vvoc-managed OpenCode agent model override in OpenCode config.
|
|
38
36
|
// installGuardianConfig - Creates or preserves managed Guardian config.
|
|
39
37
|
// syncGuardianConfig - Rewrites managed Guardian config while preserving current values.
|
|
40
38
|
// writeGuardianConfig - Writes explicit Guardian overrides to managed config.
|
|
@@ -45,12 +43,12 @@
|
|
|
45
43
|
// END_MODULE_MAP
|
|
46
44
|
//
|
|
47
45
|
// START_CHANGE_SUMMARY
|
|
48
|
-
// LAST_CHANGE: [v0.
|
|
46
|
+
// LAST_CHANGE: [v0.5.0 - Removed the legacy enhance command path and kept enhancer as a managed primary agent only.]
|
|
49
47
|
// END_CHANGE_SUMMARY
|
|
50
48
|
import { applyEdits, format, modify, parse } from "jsonc-parser";
|
|
51
49
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
52
50
|
import { dirname, join, relative } from "node:path";
|
|
53
|
-
import { MANAGED_AGENT_PROMPT_NAMES,
|
|
51
|
+
import { MANAGED_AGENT_PROMPT_NAMES, MANAGED_OPENCODE_AGENTS, getManagedAgentPromptPath, getManagedOpenCodeAgentDefinition, loadManagedAgentPromptTemplate, } from "./managed-agents.js";
|
|
54
52
|
import { parseMemoryConfigText, renderMemoryConfig, } from "../plugins/memory-store.js";
|
|
55
53
|
import { getPinnedPackageSpecifier, PACKAGE_NAME } from "./package.js";
|
|
56
54
|
import { getConfigHome, getGlobalOpencodeDir, getGlobalVvocDir, getProjectVvocDir, getVvocAgentsDir, } from "./vvoc-paths.js";
|
|
@@ -72,35 +70,6 @@ const JSON_FORMAT = {
|
|
|
72
70
|
tabSize: 2,
|
|
73
71
|
eol: "\n",
|
|
74
72
|
};
|
|
75
|
-
const ENHANCE_COMMAND_TEMPLATE = [
|
|
76
|
-
'<vvoc_enhance version="1.0">',
|
|
77
|
-
" <source_request><![CDATA[$ARGUMENTS]]></source_request>",
|
|
78
|
-
" <execution_goal>Interpret the source request and carry the work through to completion.</execution_goal>",
|
|
79
|
-
" <rules>",
|
|
80
|
-
" <preserve_user_intent>true</preserve_user_intent>",
|
|
81
|
-
" <preserve_explicit_constraints>true</preserve_explicit_constraints>",
|
|
82
|
-
" <do_not_invent_requirements>true</do_not_invent_requirements>",
|
|
83
|
-
" <inspect_relevant_context_first>true</inspect_relevant_context_first>",
|
|
84
|
-
" <prefer_minimal_correct_change>true</prefer_minimal_correct_change>",
|
|
85
|
-
" <ask_only_when_blocked>true</ask_only_when_blocked>",
|
|
86
|
-
" <run_relevant_verification>true</run_relevant_verification>",
|
|
87
|
-
" </rules>",
|
|
88
|
-
" <missing_request_behavior>",
|
|
89
|
-
" If the source request is empty, ask the user to provide the raw request to enhance instead of guessing.",
|
|
90
|
-
" </missing_request_behavior>",
|
|
91
|
-
" <deliverables>",
|
|
92
|
-
" <item>Complete the requested work or explain the concrete blocker.</item>",
|
|
93
|
-
" <item>Summarize the result and the verification you ran.</item>",
|
|
94
|
-
" </deliverables>",
|
|
95
|
-
"</vvoc_enhance>",
|
|
96
|
-
].join("\n");
|
|
97
|
-
const MANAGED_COMMANDS = [
|
|
98
|
-
{
|
|
99
|
-
name: "enhance",
|
|
100
|
-
description: "Wrap a raw request in vvoc's structured XML execution prompt.",
|
|
101
|
-
template: ENHANCE_COMMAND_TEMPLATE,
|
|
102
|
-
},
|
|
103
|
-
];
|
|
104
73
|
// START_BLOCK_RESOLVE_CONFIG_PATHS
|
|
105
74
|
export async function resolvePaths(options) {
|
|
106
75
|
const configHome = getConfigHome(options.configDir);
|
|
@@ -157,59 +126,14 @@ export function ensurePackageConfigText(text, packageSpecifier = PACKAGE_NAME) {
|
|
|
157
126
|
return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
|
|
158
127
|
}
|
|
159
128
|
// END_BLOCK_ENSURE_OPENCODE_PLUGIN_CONFIG
|
|
160
|
-
//
|
|
161
|
-
export function
|
|
129
|
+
// START_BLOCK_ENSURE_MANAGED_AGENT_CONFIG
|
|
130
|
+
export function ensureManagedAgentRegistrationsConfigText(text, paths) {
|
|
162
131
|
if (!text?.trim()) {
|
|
163
132
|
return renderJson({
|
|
164
133
|
$schema: OPENCODE_SCHEMA_URL,
|
|
165
|
-
|
|
134
|
+
agent: Object.fromEntries(MANAGED_OPENCODE_AGENTS.map((definition) => [
|
|
166
135
|
definition.name,
|
|
167
|
-
|
|
168
|
-
])),
|
|
169
|
-
});
|
|
170
|
-
}
|
|
171
|
-
const document = parseObjectDocument(text, "OpenCode config");
|
|
172
|
-
const currentCommands = readCommandMap(document, "OpenCode config");
|
|
173
|
-
let nextText = text;
|
|
174
|
-
if (!Object.hasOwn(document, "$schema")) {
|
|
175
|
-
nextText = applyEdits(nextText, modify(nextText, ["$schema"], OPENCODE_SCHEMA_URL, {
|
|
176
|
-
formattingOptions: JSON_FORMAT,
|
|
177
|
-
getInsertionIndex: () => 0,
|
|
178
|
-
}));
|
|
179
|
-
}
|
|
180
|
-
for (const definition of MANAGED_COMMANDS) {
|
|
181
|
-
const currentEntry = currentCommands[definition.name];
|
|
182
|
-
const nextEntry = {
|
|
183
|
-
...getManagedCommandRegistration(definition.name),
|
|
184
|
-
...currentEntry,
|
|
185
|
-
};
|
|
186
|
-
if (JSON.stringify(currentEntry) === JSON.stringify(nextEntry)) {
|
|
187
|
-
continue;
|
|
188
|
-
}
|
|
189
|
-
nextText = applyEdits(nextText, modify(nextText, ["command", definition.name], nextEntry, {
|
|
190
|
-
formattingOptions: JSON_FORMAT,
|
|
191
|
-
}));
|
|
192
|
-
}
|
|
193
|
-
return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
|
|
194
|
-
}
|
|
195
|
-
export async function syncManagedCommandRegistrations(paths) {
|
|
196
|
-
const currentText = await readOptionalText(paths.opencodeConfigPath);
|
|
197
|
-
const nextText = ensureManagedCommandsConfigText(currentText);
|
|
198
|
-
if (currentText === nextText) {
|
|
199
|
-
return { path: paths.opencodeConfigPath, changed: false };
|
|
200
|
-
}
|
|
201
|
-
await writeText(paths.opencodeConfigPath, nextText);
|
|
202
|
-
return { path: paths.opencodeConfigPath, changed: true };
|
|
203
|
-
}
|
|
204
|
-
// END_BLOCK_ENSURE_MANAGED_COMMAND_CONFIG
|
|
205
|
-
// START_BLOCK_ENSURE_MANAGED_SUBAGENT_CONFIG
|
|
206
|
-
export function ensureManagedSubagentsConfigText(text, paths) {
|
|
207
|
-
if (!text?.trim()) {
|
|
208
|
-
return renderJson({
|
|
209
|
-
$schema: OPENCODE_SCHEMA_URL,
|
|
210
|
-
agent: Object.fromEntries(MANAGED_SUBAGENTS.map((definition) => [
|
|
211
|
-
definition.name,
|
|
212
|
-
getManagedSubagentRegistration(paths, definition.name),
|
|
136
|
+
getManagedOpenCodeAgentRegistration(paths, definition.name),
|
|
213
137
|
])),
|
|
214
138
|
});
|
|
215
139
|
}
|
|
@@ -222,10 +146,10 @@ export function ensureManagedSubagentsConfigText(text, paths) {
|
|
|
222
146
|
getInsertionIndex: () => 0,
|
|
223
147
|
}));
|
|
224
148
|
}
|
|
225
|
-
for (const definition of
|
|
149
|
+
for (const definition of MANAGED_OPENCODE_AGENTS) {
|
|
226
150
|
const currentEntry = currentAgents[definition.name];
|
|
227
151
|
const nextEntry = {
|
|
228
|
-
...
|
|
152
|
+
...getManagedOpenCodeAgentRegistration(paths, definition.name),
|
|
229
153
|
...currentEntry,
|
|
230
154
|
};
|
|
231
155
|
if (JSON.stringify(currentEntry) === JSON.stringify(nextEntry)) {
|
|
@@ -237,15 +161,16 @@ export function ensureManagedSubagentsConfigText(text, paths) {
|
|
|
237
161
|
}
|
|
238
162
|
return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
|
|
239
163
|
}
|
|
240
|
-
export async function
|
|
164
|
+
export async function syncManagedAgentRegistrations(paths) {
|
|
241
165
|
const currentText = await readOptionalText(paths.opencodeConfigPath);
|
|
242
|
-
const nextText =
|
|
166
|
+
const nextText = ensureManagedAgentRegistrationsConfigText(currentText, paths);
|
|
243
167
|
if (currentText === nextText) {
|
|
244
168
|
return { path: paths.opencodeConfigPath, changed: false };
|
|
245
169
|
}
|
|
246
170
|
await writeText(paths.opencodeConfigPath, nextText);
|
|
247
171
|
return { path: paths.opencodeConfigPath, changed: true };
|
|
248
172
|
}
|
|
173
|
+
// END_BLOCK_ENSURE_MANAGED_AGENT_CONFIG
|
|
249
174
|
export async function installManagedAgentPrompts(paths, options) {
|
|
250
175
|
const results = [];
|
|
251
176
|
for (const agentName of MANAGED_AGENT_PROMPT_NAMES) {
|
|
@@ -280,15 +205,15 @@ export async function syncManagedAgentPrompts(paths, options) {
|
|
|
280
205
|
}
|
|
281
206
|
return results;
|
|
282
207
|
}
|
|
283
|
-
export async function
|
|
284
|
-
const models = Object.fromEntries(
|
|
208
|
+
export async function readManagedAgentModels(paths) {
|
|
209
|
+
const models = Object.fromEntries(MANAGED_OPENCODE_AGENTS.map((definition) => [definition.name, undefined]));
|
|
285
210
|
const currentText = await readOptionalText(paths.opencodeConfigPath);
|
|
286
211
|
if (!currentText) {
|
|
287
212
|
return models;
|
|
288
213
|
}
|
|
289
214
|
const document = parseObjectDocument(currentText, paths.opencodeConfigPath);
|
|
290
215
|
const agentMap = readAgentMap(document, paths.opencodeConfigPath);
|
|
291
|
-
for (const definition of
|
|
216
|
+
for (const definition of MANAGED_OPENCODE_AGENTS) {
|
|
292
217
|
const currentEntry = agentMap[definition.name];
|
|
293
218
|
if (currentEntry?.model !== undefined) {
|
|
294
219
|
models[definition.name] = readNonEmptyString(currentEntry.model, `${definition.name}: model`);
|
|
@@ -341,13 +266,13 @@ export async function writeOpenCodeAgentModel(paths, agentName, options) {
|
|
|
341
266
|
path: paths.opencodeConfigPath,
|
|
342
267
|
};
|
|
343
268
|
}
|
|
344
|
-
export async function
|
|
269
|
+
export async function writeManagedAgentModel(paths, agentName, options) {
|
|
345
270
|
const currentText = await readOptionalText(paths.opencodeConfigPath);
|
|
346
271
|
if (!currentText && !options.ensureEntry) {
|
|
347
272
|
return { action: "kept", path: paths.opencodeConfigPath };
|
|
348
273
|
}
|
|
349
274
|
const baseText = options.ensureEntry
|
|
350
|
-
?
|
|
275
|
+
? ensureManagedAgentRegistrationsConfigText(currentText, paths)
|
|
351
276
|
: currentText;
|
|
352
277
|
if (!baseText) {
|
|
353
278
|
return { action: "kept", path: paths.opencodeConfigPath };
|
|
@@ -359,7 +284,7 @@ export async function writeManagedSubagentModel(paths, agentName, options) {
|
|
|
359
284
|
return { action: "kept", path: paths.opencodeConfigPath };
|
|
360
285
|
}
|
|
361
286
|
const nextEntry = {
|
|
362
|
-
...
|
|
287
|
+
...getManagedOpenCodeAgentRegistration(paths, agentName),
|
|
363
288
|
...currentEntry,
|
|
364
289
|
};
|
|
365
290
|
if (options.model) {
|
|
@@ -798,23 +723,6 @@ function readPluginList(document, label) {
|
|
|
798
723
|
}
|
|
799
724
|
return raw.slice();
|
|
800
725
|
}
|
|
801
|
-
function readCommandMap(document, label) {
|
|
802
|
-
const raw = document.command;
|
|
803
|
-
if (raw === undefined) {
|
|
804
|
-
return {};
|
|
805
|
-
}
|
|
806
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
807
|
-
throw new Error(`${label}: expected "command" to be an object`);
|
|
808
|
-
}
|
|
809
|
-
const entries = {};
|
|
810
|
-
for (const [name, value] of Object.entries(raw)) {
|
|
811
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
812
|
-
throw new Error(`${label}: expected "command.${name}" to be an object`);
|
|
813
|
-
}
|
|
814
|
-
entries[name] = value;
|
|
815
|
-
}
|
|
816
|
-
return entries;
|
|
817
|
-
}
|
|
818
726
|
function normalizePluginList(currentPlugins, packageSpecifier) {
|
|
819
727
|
const nextPlugins = [];
|
|
820
728
|
const seen = new Set();
|
|
@@ -843,31 +751,7 @@ function normalizePluginList(currentPlugins, packageSpecifier) {
|
|
|
843
751
|
function isPackagePluginSpecifier(value) {
|
|
844
752
|
return value === PACKAGE_NAME || value.startsWith(`${PACKAGE_NAME}@`);
|
|
845
753
|
}
|
|
846
|
-
|
|
847
|
-
const definition = MANAGED_COMMANDS.find((entry) => entry.name === commandName);
|
|
848
|
-
if (!definition) {
|
|
849
|
-
throw new Error(`unknown managed command: ${commandName}`);
|
|
850
|
-
}
|
|
851
|
-
return definition;
|
|
852
|
-
}
|
|
853
|
-
function getManagedCommandRegistration(commandName) {
|
|
854
|
-
const definition = getManagedCommandDefinition(commandName);
|
|
855
|
-
const registration = {
|
|
856
|
-
description: definition.description,
|
|
857
|
-
template: definition.template,
|
|
858
|
-
};
|
|
859
|
-
if (definition.agent) {
|
|
860
|
-
registration.agent = definition.agent;
|
|
861
|
-
}
|
|
862
|
-
if (definition.model) {
|
|
863
|
-
registration.model = definition.model;
|
|
864
|
-
}
|
|
865
|
-
if (definition.subtask !== undefined) {
|
|
866
|
-
registration.subtask = definition.subtask;
|
|
867
|
-
}
|
|
868
|
-
return registration;
|
|
869
|
-
}
|
|
870
|
-
// START_BLOCK_MANAGED_SUBAGENT_HELPERS
|
|
754
|
+
// START_BLOCK_MANAGED_AGENT_HELPERS
|
|
871
755
|
function readAgentMap(document, label) {
|
|
872
756
|
const raw = document.agent;
|
|
873
757
|
if (raw === undefined) {
|
|
@@ -928,17 +812,17 @@ function ensureAgentConfigText(text) {
|
|
|
928
812
|
}
|
|
929
813
|
return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
|
|
930
814
|
}
|
|
931
|
-
function
|
|
815
|
+
function getManagedOpenCodeAgentPromptReference(paths, agentName) {
|
|
932
816
|
const promptPath = getManagedPromptPath(paths, agentName);
|
|
933
817
|
const promptRef = relative(dirname(paths.opencodeConfigPath), promptPath).replaceAll("\\", "/");
|
|
934
818
|
return `{file:${promptRef.startsWith(".") ? promptRef : `./${promptRef}`}}`;
|
|
935
819
|
}
|
|
936
|
-
function
|
|
937
|
-
const definition =
|
|
820
|
+
function getManagedOpenCodeAgentRegistration(paths, agentName) {
|
|
821
|
+
const definition = getManagedOpenCodeAgentDefinition(agentName);
|
|
938
822
|
const registration = {
|
|
939
823
|
description: definition.description,
|
|
940
|
-
mode:
|
|
941
|
-
prompt:
|
|
824
|
+
mode: definition.mode,
|
|
825
|
+
prompt: getManagedOpenCodeAgentPromptReference(paths, agentName),
|
|
942
826
|
};
|
|
943
827
|
if (definition.permission) {
|
|
944
828
|
registration.permission = definition.permission;
|
|
@@ -983,7 +867,7 @@ function updateAgentEntryText(text, agentName, entry) {
|
|
|
983
867
|
}));
|
|
984
868
|
return ensureTrailingNewline(applyEdits(nextText, format(nextText, undefined, JSON_FORMAT)));
|
|
985
869
|
}
|
|
986
|
-
//
|
|
870
|
+
// END_BLOCK_MANAGED_AGENT_HELPERS
|
|
987
871
|
function normalizeGuardianOverrides(raw, label) {
|
|
988
872
|
if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
|
|
989
873
|
throw new Error(`${label}: expected a top-level object`);
|