vgxness 1.20.1 → 1.20.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/dist/agents/canonical-agent-manifest.js +1 -1
- package/dist/agents/canonical-agent-projection.js +4 -4
- package/dist/agents/renderers/opencode-renderer.js +2 -1
- package/dist/mcp/client-install-opencode-contract.js +5 -1
- package/dist/mcp/client-install-opencode.js +4 -1
- package/dist/mcp/provider-doctor.js +30 -0
- package/dist/mcp/provider-status.js +19 -7
- package/package.json +1 -1
|
@@ -168,7 +168,7 @@ Coordinate SDD; keep chat thin, use VGXNESS MCP state, delegate to exact SDD sub
|
|
|
168
168
|
- Before phase advancement, call \`vgxness_sdd_status\`/\`vgxness_sdd_next\` plus \`vgxness_sdd_ready\` or \`vgxness_sdd_get_readiness\`.
|
|
169
169
|
- Before risky VGX-managed side effects (edit, shell/tests, git, network, provider-tool, secrets, external-directory, destructive, privileged, ambiguous), call \`vgxness_run_preflight\` with runId/workflow/phase/agent when available. Stop on approval/block; never invent approval.
|
|
170
170
|
- Direct human acceptance via \`vgxness_sdd_accept_artifact\` is not a generic SDD write: do not preflight solely for it; require exact project/change/phase, \`acceptedBy.type\` \`"human"\`, non-empty \`acceptedBy.id\`, and eligible status/readiness. Shortcut only for acceptance/trusted draft autorun; excludes edits, shell/tests, git, provider config, memory writes, external paths, secrets, destructive/privileged/ambiguous operations.
|
|
171
|
-
-
|
|
171
|
+
- bounded read/search repo tools may be enabled for inspection; bash, edit, and write remain denied. Diagnostics are config-level evidence, not host runtime proof.
|
|
172
172
|
- Do not mutate provider/global OpenCode config. Do not publish packages unless explicitly requested. Never revert/overwrite unrelated user work. Preserve \`permission.task\` deny-by-default with only exact known SDD subagents.
|
|
173
173
|
- Do not change provider model/reasoning config unless explicitly requested.
|
|
174
174
|
|
|
@@ -137,7 +137,7 @@ function openCodeManagerPermissionsFor(agent) {
|
|
|
137
137
|
...openCodePermissionsFor(agent, { task: createCanonicalOpenCodeSddTaskPermissions() }),
|
|
138
138
|
bash: 'deny',
|
|
139
139
|
edit: 'deny',
|
|
140
|
-
read: '
|
|
140
|
+
read: 'allow',
|
|
141
141
|
write: 'deny',
|
|
142
142
|
};
|
|
143
143
|
}
|
|
@@ -148,9 +148,9 @@ function openCodeManagerTools() {
|
|
|
148
148
|
delegation_list: true,
|
|
149
149
|
delegation_read: true,
|
|
150
150
|
edit: false,
|
|
151
|
-
glob:
|
|
152
|
-
grep:
|
|
153
|
-
read:
|
|
151
|
+
glob: true,
|
|
152
|
+
grep: true,
|
|
153
|
+
read: true,
|
|
154
154
|
write: false,
|
|
155
155
|
};
|
|
156
156
|
}
|
|
@@ -15,7 +15,7 @@ const openCodeCapabilities = {
|
|
|
15
15
|
'instructions',
|
|
16
16
|
'mode',
|
|
17
17
|
'adapter model',
|
|
18
|
-
'adapter config keys: variant, temperature, top_p, hidden, options, color, steps, permission',
|
|
18
|
+
'adapter config keys: variant, temperature, top_p, hidden, options, color, steps, permission, tools',
|
|
19
19
|
],
|
|
20
20
|
skillInjectionModes: ['external preview services may inject skill payloads before rendering; renderer does not resolve skills'],
|
|
21
21
|
permissionCategories: ['registry permission metadata mapped from adapter permission config'],
|
|
@@ -78,6 +78,7 @@ function openCodeAgentConfig(agent) {
|
|
|
78
78
|
copyString(config, rendered, 'color');
|
|
79
79
|
copyNumber(config, rendered, 'steps');
|
|
80
80
|
copyJson(config, rendered, 'permission');
|
|
81
|
+
copyJson(config, rendered, 'tools');
|
|
81
82
|
return rendered;
|
|
82
83
|
}
|
|
83
84
|
function copyString(source, target, key) {
|
|
@@ -197,7 +197,11 @@ function warningsForScope(scope, overwriteVgxness, agentPlan, bashPermissionPoli
|
|
|
197
197
|
`Reinstall/overwrite is enabled: existing VGXNESS-managed OpenCode entries will be replaced (${agentPlan.installsAgents ? 'mcp.vgxness, default_agent, instructions AGENTS.md, and known VGXNESS agents' : 'mcp.vgxness only'}); unrelated OpenCode config is preserved.`,
|
|
198
198
|
]
|
|
199
199
|
: [];
|
|
200
|
-
const bashWarnings = bashPermissionPolicy.manager === 'deny'
|
|
200
|
+
const bashWarnings = bashPermissionPolicy.manager === 'deny'
|
|
201
|
+
? [
|
|
202
|
+
'OpenCode config sets top-level permission.bash = ask; manager read/search discovery tools (read/glob/grep) are allowed while manager bash/edit/write are denied; SDD subagents keep explicit phase permissions. This is config-level evidence only and does not verify provider runtime enforcement.',
|
|
203
|
+
]
|
|
204
|
+
: ['OpenCode top-level permission.bash is set to ask.'];
|
|
201
205
|
return [
|
|
202
206
|
'Restart OpenCode after installation so it reloads the user MCP config.',
|
|
203
207
|
'OpenCode project config may override user config for a workspace; check project-level config if vgxness is not visible.',
|
|
@@ -214,7 +214,10 @@ function confirmationRequiredMessage(scope) {
|
|
|
214
214
|
return `\`mcp install opencode\` requires explicit --yes before any ${scope} config write.`;
|
|
215
215
|
}
|
|
216
216
|
function warnings() {
|
|
217
|
-
return [
|
|
217
|
+
return [
|
|
218
|
+
'Restart OpenCode after installation so it reloads the project MCP config.',
|
|
219
|
+
'OpenCode config sets top-level permission.bash = ask; manager read/search discovery tools (read/glob/grep) are allowed while manager bash/edit/write are denied; SDD subagents keep explicit phase permissions. This is config-level evidence only and does not verify provider runtime enforcement.',
|
|
220
|
+
];
|
|
218
221
|
}
|
|
219
222
|
function manualTest(databasePath, source) {
|
|
220
223
|
return {
|
|
@@ -40,6 +40,7 @@ export class ProviderDoctorService {
|
|
|
40
40
|
configReadableCheck(readableJson.length, paths.filter((path) => path.exists).length),
|
|
41
41
|
mcpEntryCheck(config),
|
|
42
42
|
defaultAgentCheck(config),
|
|
43
|
+
managerNativeCapabilityCheck(config),
|
|
43
44
|
subagentsCheck(config),
|
|
44
45
|
delegationCheck(config),
|
|
45
46
|
{ id: 'mcp-current-call', status: 'pass', detail: 'Current MCP call reached the VGXNESS control-plane.' },
|
|
@@ -255,6 +256,35 @@ function defaultAgentCheck(config) {
|
|
|
255
256
|
return { id: 'opencode-default-agent', status: 'fail', detail: 'OpenCode default_agent is not vgxness-manager or the manager config is missing.' };
|
|
256
257
|
return { id: 'opencode-default-agent', status: 'pass', detail: 'OpenCode default agent points to vgxness-manager.' };
|
|
257
258
|
}
|
|
259
|
+
function managerNativeCapabilityCheck(config) {
|
|
260
|
+
const manager = isRecord(config?.agent) && isRecord(config.agent[vgxnessOpenCodeDefaultAgent]) ? config.agent[vgxnessOpenCodeDefaultAgent] : undefined;
|
|
261
|
+
const permission = isRecord(manager?.permission) ? manager.permission : undefined;
|
|
262
|
+
const tools = isRecord(manager?.tools) ? manager.tools : undefined;
|
|
263
|
+
const problems = [];
|
|
264
|
+
if (permission?.read !== 'allow')
|
|
265
|
+
problems.push('permission.read is not allow');
|
|
266
|
+
for (const tool of ['read', 'glob', 'grep']) {
|
|
267
|
+
if (tools?.[tool] !== true)
|
|
268
|
+
problems.push(`tools.${tool} is not enabled`);
|
|
269
|
+
}
|
|
270
|
+
for (const tool of ['bash', 'edit', 'write']) {
|
|
271
|
+
if (tools?.[tool] !== false)
|
|
272
|
+
problems.push(`tools.${tool} is not disabled`);
|
|
273
|
+
}
|
|
274
|
+
const evidenceSuffix = 'This is config-level evidence only; host runtime/tool presence is not verified.';
|
|
275
|
+
if (problems.length > 0)
|
|
276
|
+
return {
|
|
277
|
+
id: 'opencode-manager-native-capability',
|
|
278
|
+
status: 'fail',
|
|
279
|
+
detail: `Manager native capability drift detected: ${problems.join('; ')}. ${evidenceSuffix}`,
|
|
280
|
+
remediation: 'Re-run explicit OpenCode setup/install only after reviewing provider config drift; doctor does not auto-repair or write config.',
|
|
281
|
+
};
|
|
282
|
+
return {
|
|
283
|
+
id: 'opencode-manager-native-capability',
|
|
284
|
+
status: 'pass',
|
|
285
|
+
detail: `Manager config allows read/glob/grep inspection and denies bash/edit/write native tools. ${evidenceSuffix}`,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
258
288
|
function subagentsCheck(config) {
|
|
259
289
|
const agents = isRecord(config?.agent) ? config.agent : undefined;
|
|
260
290
|
const missing = vgxnessOpenCodeSddSubagents.filter((name) => !isRecord(agents?.[name]) || agents[name]?.hidden !== true);
|
|
@@ -27,10 +27,11 @@ export class ProviderStatusService {
|
|
|
27
27
|
const mcpEntry = inspectOpenCodeMcpEntry(paths);
|
|
28
28
|
const providerConfig = readFirstParsedConfig(paths);
|
|
29
29
|
const managerConfigured = hasConfiguredManager(providerConfig);
|
|
30
|
+
const managerNativeCapabilityStatus = inspectManagerNativeCapability(providerConfig);
|
|
30
31
|
const subagentsConfigured = hasConfiguredSubagents(providerConfig);
|
|
31
32
|
const tools = requiredToolPresence();
|
|
32
33
|
const evidence = providerEvidence({ staticManifestKnown: true, renderedConfigExpected: true, configPathInspected: paths.length > 0 });
|
|
33
|
-
const configStatus = resolveConfigStatus(paths, mcpEntry, managerConfigured, subagentsConfigured);
|
|
34
|
+
const configStatus = resolveConfigStatus(paths, mcpEntry, managerConfigured, managerNativeCapabilityStatus, subagentsConfigured);
|
|
34
35
|
const status = rollupProviderHealth([canonicalAgentManifest.status, configStatus, ...tools.map((tool) => (tool.present ? 'pass' : 'fail'))]);
|
|
35
36
|
const sdd = normalized.change.length > 0 ? this.readSdd(normalized.project, normalized.change) : undefined;
|
|
36
37
|
const generatedAt = 'read-only-snapshot';
|
|
@@ -38,14 +39,14 @@ export class ProviderStatusService {
|
|
|
38
39
|
? paths.map((path) => path.path)
|
|
39
40
|
: paths.filter((path) => path.exists || path.status !== 'not-configured').map((path) => path.path);
|
|
40
41
|
const verboseShape = {
|
|
41
|
-
config: { status: configStatus, paths, mcpEntry },
|
|
42
|
+
config: { status: configStatus, paths, mcpEntry, managerNativeCapability: managerNativeCapabilityStatus },
|
|
42
43
|
canonicalAgentManifest,
|
|
43
44
|
providerEvidence: evidence,
|
|
44
45
|
sdd,
|
|
45
46
|
mcpRequiredTools: tools,
|
|
46
47
|
};
|
|
47
48
|
const compactShape = {
|
|
48
|
-
config: { status: configStatus, paths: compactPaths(paths, 'compact'), mcpEntry: compactMcpEntry(mcpEntry, 'compact') },
|
|
49
|
+
config: { status: configStatus, paths: compactPaths(paths, 'compact'), mcpEntry: compactMcpEntry(mcpEntry, 'compact'), managerNativeCapability: managerNativeCapabilityStatus },
|
|
49
50
|
canonicalAgentManifest,
|
|
50
51
|
providerEvidence: evidence,
|
|
51
52
|
sdd: sdd === undefined ? undefined : compactSdd(sdd, 'compact'),
|
|
@@ -86,8 +87,8 @@ export class ProviderStatusService {
|
|
|
86
87
|
return {
|
|
87
88
|
ok: true,
|
|
88
89
|
value: normalized.payloadMode === 'verbose'
|
|
89
|
-
? { ...reportBase, payloadMode: 'verbose', config: { status: configStatus, paths: compactPaths(paths, 'verbose'), mcpEntry: compactMcpEntry(mcpEntry, 'verbose') } }
|
|
90
|
-
: { ...reportBase, payloadMode: 'compact', config: { status: configStatus, paths: compactPaths(paths, 'compact'), mcpEntry: compactMcpEntry(mcpEntry, 'compact') } },
|
|
90
|
+
? { ...reportBase, payloadMode: 'verbose', config: { status: configStatus, paths: compactPaths(paths, 'verbose'), mcpEntry: compactMcpEntry(mcpEntry, 'verbose'), managerNativeCapability: managerNativeCapabilityStatus } }
|
|
91
|
+
: { ...reportBase, payloadMode: 'compact', config: { status: configStatus, paths: compactPaths(paths, 'compact'), mcpEntry: compactMcpEntry(mcpEntry, 'compact'), managerNativeCapability: managerNativeCapabilityStatus } },
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
readSdd(project, change) {
|
|
@@ -393,12 +394,12 @@ function requiredToolPresence() {
|
|
|
393
394
|
diagnostic: 'Static VGXNESS manifest expects this MCP tool; provider host tool presence was not verified.',
|
|
394
395
|
}));
|
|
395
396
|
}
|
|
396
|
-
function resolveConfigStatus(paths, mcpEntry, managerConfigured, subagentsConfigured) {
|
|
397
|
+
function resolveConfigStatus(paths, mcpEntry, managerConfigured, managerNativeCapabilityStatus, subagentsConfigured) {
|
|
397
398
|
if (paths.some((path) => path.status === 'fail') || mcpEntry.status === 'fail')
|
|
398
399
|
return 'fail';
|
|
399
400
|
if (mcpEntry.status === 'not-configured')
|
|
400
401
|
return 'not-configured';
|
|
401
|
-
if (!managerConfigured || !subagentsConfigured)
|
|
402
|
+
if (!managerConfigured || managerNativeCapabilityStatus === 'warn' || !subagentsConfigured)
|
|
402
403
|
return 'warn';
|
|
403
404
|
if (hasProjectConfigAlongsideUser(paths))
|
|
404
405
|
return 'warn';
|
|
@@ -449,6 +450,17 @@ function hasConfiguredManager(config) {
|
|
|
449
450
|
isRecord(agent?.[vgxnessOpenCodeDefaultAgent]) &&
|
|
450
451
|
promptContractVersion(agent[vgxnessOpenCodeDefaultAgent]) === vgxnessOpenCodePromptContractVersion);
|
|
451
452
|
}
|
|
453
|
+
function inspectManagerNativeCapability(config) {
|
|
454
|
+
if (config === undefined)
|
|
455
|
+
return 'not-configured';
|
|
456
|
+
const agent = isRecord(config.agent) ? config.agent : undefined;
|
|
457
|
+
const manager = isRecord(agent?.[vgxnessOpenCodeDefaultAgent]) ? agent[vgxnessOpenCodeDefaultAgent] : undefined;
|
|
458
|
+
const permission = isRecord(manager?.permission) ? manager.permission : undefined;
|
|
459
|
+
const tools = isRecord(manager?.tools) ? manager.tools : undefined;
|
|
460
|
+
const readSearchEnabled = permission?.read === 'allow' && tools?.read === true && tools.glob === true && tools.grep === true;
|
|
461
|
+
const writeShellDenied = tools?.bash === false && tools.edit === false && tools.write === false;
|
|
462
|
+
return readSearchEnabled && writeShellDenied ? 'pass' : 'warn';
|
|
463
|
+
}
|
|
452
464
|
function hasConfiguredSubagents(config) {
|
|
453
465
|
if (config === undefined)
|
|
454
466
|
return false;
|