vgxness 1.5.0 → 1.5.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 +23 -2
- package/dist/agents/agent-seed-service.js +10 -0
- package/dist/agents/canonical-agent-manifest.js +177 -0
- package/dist/agents/canonical-agent-projection.js +146 -0
- package/dist/agents/renderers/claude-renderer.js +30 -52
- package/dist/cli/bun-bin.js +6 -0
- package/dist/cli/cli-help.js +3 -0
- package/dist/cli/commands/agent-skill-dispatcher.js +6 -5
- package/dist/cli/commands/mcp-dispatcher.js +65 -3
- package/dist/cli/index.js +1 -1
- package/dist/governance/governance-report-builder.js +45 -26
- package/dist/mcp/claude-code-agent-config.js +79 -0
- package/dist/mcp/claude-code-config.js +84 -0
- package/dist/mcp/client-install-claude-code-contract.js +86 -0
- package/dist/mcp/client-install-claude-code.js +85 -0
- package/dist/mcp/control-plane.js +2 -0
- package/dist/mcp/index.js +5 -0
- package/dist/mcp/opencode-default-agent-config.js +7 -113
- package/dist/mcp/provider-canonical-agent-manifest.js +39 -0
- package/dist/mcp/provider-change-plan.js +57 -1
- package/dist/mcp/provider-doctor.js +54 -0
- package/dist/mcp/provider-health-types.js +3 -1
- package/dist/mcp/provider-status.js +82 -2
- package/dist/mcp/schema.js +11 -2
- package/dist/mcp/stdio-server.js +2 -0
- package/dist/mcp/validation.js +23 -1
- package/dist/memory/memory-service.js +59 -0
- package/dist/memory/repositories/sessions.js +1 -1
- package/dist/sdd/sdd-workflow-service.js +129 -59
- package/dist/setup/providers/claude-setup-adapter.js +7 -4
- package/docs/architecture.md +54 -112
- package/docs/cli.md +53 -0
- package/docs/code-runtime.md +218 -0
- package/docs/contributing.md +120 -0
- package/docs/glossary.md +211 -0
- package/docs/mcp.md +144 -0
- package/docs/prd.md +23 -26
- package/docs/providers.md +123 -0
- package/docs/roadmap.md +88 -0
- package/docs/safety.md +147 -0
- package/docs/storage.md +93 -0
- package/package.json +1 -1
- package/docs/funcionamiento-del-sistema.md +0 -865
- package/docs/harness-gap-analysis.md +0 -243
- package/docs/vgxcode.md +0 -87
- package/docs/vgxness-code.md +0 -48
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# VGXNESS
|
|
2
2
|
|
|
3
|
-
VGXNESS is an installable CLI
|
|
3
|
+
VGXNESS is an installable CLI, MCP control plane, and native code runtime for guided AI-agent workflows, SDD artifacts, local memory, and OpenCode integration.
|
|
4
4
|
|
|
5
5
|
## Release status and license
|
|
6
6
|
|
|
@@ -158,6 +158,19 @@ vgxness setup apply --yes
|
|
|
158
158
|
|
|
159
159
|
`vgxness setup plan` and `vgxness setup status` are human-readable and read-only by default. `vgxness doctor`, `vgxness sdd status`, `vgxness sdd next`, and `vgxness sdd accept-artifact` are also human-readable by default. Pass `--json` when you need parseable automation output. `vgxness setup apply --yes` is the explicit provider-config write path.
|
|
160
160
|
|
|
161
|
+
## Code runtime (`vgxness code`)
|
|
162
|
+
|
|
163
|
+
Beyond setup and SDD control, VGXNESS ships a native code runtime for bounded agentic work in the local workspace:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
vgxness code inspect "<question>" # read-only investigation
|
|
167
|
+
vgxness code plan "<task>" # read-only implementation plan
|
|
168
|
+
vgxness code craft-preview "<task>" # show the diff you would make
|
|
169
|
+
vgxness code craft "<task>" # approval-gated, bounded edit-capable work
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Edits, shell, network, git mutations, SDD persistence, and memory saves route through explicit permission decisions. External workspace edits are denied, destructive commands require approval, and secret-like values are redacted from prompts, transcripts, and reports. See [Code runtime](./docs/code-runtime.md) and [Safety model](./docs/safety.md) for the full contract.
|
|
173
|
+
|
|
161
174
|
## Safety model
|
|
162
175
|
|
|
163
176
|
- Preview, status, and plan commands are read-only.
|
|
@@ -166,6 +179,7 @@ vgxness setup apply --yes
|
|
|
166
179
|
- SDD artifacts are SQLite-backed through VGXNESS services. Do not create or write `openspec/`.
|
|
167
180
|
- `vgxness sdd accept-artifact` records explicit human-only acceptance; saving a draft never implies acceptance.
|
|
168
181
|
- OpenCode is the primary supported provider; other providers are preview/manual extension points.
|
|
182
|
+
- VGXNESS exposes 38 typed MCP tools across SDD, memory, sessions, agents, skills, runs, providers, and verification. See [MCP tools](./docs/mcp.md).
|
|
169
183
|
|
|
170
184
|
## Main menu entrypoint
|
|
171
185
|
|
|
@@ -242,4 +256,11 @@ Remove any OpenCode config entries and local/global VGXNESS data manually if you
|
|
|
242
256
|
|
|
243
257
|
- [CLI reference](./docs/cli.md)
|
|
244
258
|
- [Architecture](./docs/architecture.md)
|
|
245
|
-
- [
|
|
259
|
+
- [Code runtime](./docs/code-runtime.md)
|
|
260
|
+
- [MCP tools](./docs/mcp.md)
|
|
261
|
+
- [Safety model](./docs/safety.md)
|
|
262
|
+
- [Storage](./docs/storage.md)
|
|
263
|
+
- [Providers](./docs/providers.md)
|
|
264
|
+
- [Roadmap](./docs/roadmap.md)
|
|
265
|
+
- [Contributing](./docs/contributing.md)
|
|
266
|
+
- [Glossary](./docs/glossary.md)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { AgentRepository } from './repositories/agents.js';
|
|
2
|
+
import { projectCanonicalAgentManifestToSeed } from './canonical-agent-projection.js';
|
|
2
3
|
const requiredManagerName = 'vgxness-manager';
|
|
3
4
|
export class AgentSeedService {
|
|
4
5
|
database;
|
|
@@ -7,6 +8,15 @@ export class AgentSeedService {
|
|
|
7
8
|
this.database = database;
|
|
8
9
|
this.agents = new AgentRepository(database);
|
|
9
10
|
}
|
|
11
|
+
loadBuiltInDefaults() {
|
|
12
|
+
try {
|
|
13
|
+
return this.loadManifest(projectCanonicalAgentManifestToSeed());
|
|
14
|
+
}
|
|
15
|
+
catch (cause) {
|
|
16
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
17
|
+
return { ok: false, error: { code: 'validation_failed', message } };
|
|
18
|
+
}
|
|
19
|
+
}
|
|
10
20
|
loadManifest(manifest) {
|
|
11
21
|
const validation = this.validateManifest(manifest);
|
|
12
22
|
if (!validation.ok)
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
export const canonicalDefaultAgentName = 'vgxness-manager';
|
|
2
|
+
export const canonicalPromptContractVersion = 6;
|
|
3
|
+
export const canonicalSddSubagentNames = [
|
|
4
|
+
'vgxness-sdd-explore',
|
|
5
|
+
'vgxness-sdd-propose',
|
|
6
|
+
'vgxness-sdd-spec',
|
|
7
|
+
'vgxness-sdd-design',
|
|
8
|
+
'vgxness-sdd-tasks',
|
|
9
|
+
'vgxness-sdd-apply',
|
|
10
|
+
'vgxness-sdd-verify',
|
|
11
|
+
'vgxness-sdd-archive',
|
|
12
|
+
'vgxness-sdd-init',
|
|
13
|
+
'vgxness-sdd-onboard',
|
|
14
|
+
];
|
|
15
|
+
export function validateCanonicalAgentManifest(manifest) {
|
|
16
|
+
const errors = [];
|
|
17
|
+
if (manifest.version !== 1)
|
|
18
|
+
errors.push('manifest.version must be 1');
|
|
19
|
+
if (!manifest.project.trim())
|
|
20
|
+
errors.push('manifest.project is required');
|
|
21
|
+
if (manifest.scope !== 'project' && manifest.scope !== 'personal')
|
|
22
|
+
errors.push('manifest.scope must be project or personal');
|
|
23
|
+
if (!Number.isInteger(manifest.promptContractVersion) || manifest.promptContractVersion <= 0)
|
|
24
|
+
errors.push('manifest.promptContractVersion must be a positive integer');
|
|
25
|
+
if (!manifest.defaultAgentName.trim())
|
|
26
|
+
errors.push('manifest.defaultAgentName is required');
|
|
27
|
+
const ids = new Set();
|
|
28
|
+
const names = new Set();
|
|
29
|
+
const managers = manifest.agents.filter((agent) => agent.mode === 'agent');
|
|
30
|
+
if (managers.length !== 1)
|
|
31
|
+
errors.push(`manifest must declare exactly one manager agent; found ${managers.length}`);
|
|
32
|
+
if (!managers.some((agent) => agent.name === manifest.defaultAgentName))
|
|
33
|
+
errors.push(`manifest.defaultAgentName ${manifest.defaultAgentName} must match the manager agent`);
|
|
34
|
+
for (const agent of manifest.agents) {
|
|
35
|
+
const label = `agent ${agent.name || agent.id || '<unknown>'}`;
|
|
36
|
+
if (!agent.id.trim())
|
|
37
|
+
errors.push(`${label}.id is required`);
|
|
38
|
+
if (!agent.name.trim())
|
|
39
|
+
errors.push(`${label}.name is required`);
|
|
40
|
+
if (ids.has(agent.id))
|
|
41
|
+
errors.push(`duplicate canonical agent id: ${agent.id}`);
|
|
42
|
+
if (names.has(agent.name))
|
|
43
|
+
errors.push(`duplicate canonical agent name: ${agent.name}`);
|
|
44
|
+
ids.add(agent.id);
|
|
45
|
+
names.add(agent.name);
|
|
46
|
+
if (agent.builtIn !== true)
|
|
47
|
+
errors.push(`${label}.builtIn must be true`);
|
|
48
|
+
if (agent.mode === 'subagent' && !agent.parentAgentName?.trim())
|
|
49
|
+
errors.push(`${label}.parentAgentName is required for subagents`);
|
|
50
|
+
for (const [provider, support] of Object.entries(agent.providerSupport)) {
|
|
51
|
+
if (provider !== support.adapter)
|
|
52
|
+
errors.push(`${label}.providerSupport.${provider}.adapter must match provider key`);
|
|
53
|
+
if (support.level !== 'managed' && support.level !== 'preview' && support.level !== 'unsupported')
|
|
54
|
+
errors.push(`${label}.providerSupport.${provider}.level is invalid`);
|
|
55
|
+
if ((support.level === 'preview' || support.level === 'unsupported') && !support.reason?.trim())
|
|
56
|
+
errors.push(`${label}.providerSupport.${provider}.reason is required for ${support.level}`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
for (const agent of manifest.agents.filter((agent) => agent.mode === 'subagent')) {
|
|
60
|
+
if (agent.parentAgentName !== undefined && !names.has(agent.parentAgentName))
|
|
61
|
+
errors.push(`agent ${agent.name}.parentAgentName is missing: ${agent.parentAgentName}`);
|
|
62
|
+
}
|
|
63
|
+
return errors.length === 0 ? { ok: true } : { ok: false, errors };
|
|
64
|
+
}
|
|
65
|
+
function commonSupport() {
|
|
66
|
+
return {
|
|
67
|
+
opencode: { adapter: 'opencode', level: 'managed' },
|
|
68
|
+
claude: { adapter: 'claude', level: 'managed' },
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
function managerDefinition() {
|
|
72
|
+
return {
|
|
73
|
+
id: canonicalDefaultAgentName,
|
|
74
|
+
mode: 'agent',
|
|
75
|
+
builtIn: true,
|
|
76
|
+
name: canonicalDefaultAgentName,
|
|
77
|
+
description: 'Coordinates VGXNESS MCP state and SDD sub-agents while avoiding unsafe inline execution.',
|
|
78
|
+
instructions: { kind: 'inline', value: registryManagerInstructions },
|
|
79
|
+
capabilities: ['sdd-orchestration', 'agent-routing', 'mcp-coordination', 'project-local-automation'],
|
|
80
|
+
permissions: { read: 'allow', edit: 'ask', shell: 'ask', git: 'ask', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' },
|
|
81
|
+
memory: { scopes: ['project'] },
|
|
82
|
+
workflows: ['explore', 'quickfix', 'plan', 'build', 'debug', 'sdd', 'agent-seeding', 'opencode-install'],
|
|
83
|
+
skills: ['vgxness-sdd-manager'],
|
|
84
|
+
adapters: { opencode: { model: 'openai/gpt-5.5', config: { options: { reasoningEffort: 'high', vgxnessPromptContractVersion: canonicalPromptContractVersion }, permission: { task: createCanonicalOpenCodeSddTaskPermissions() } } } },
|
|
85
|
+
providerSupport: commonSupport(),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
function subagentDefinition(name) {
|
|
89
|
+
const data = subagentData[name];
|
|
90
|
+
return {
|
|
91
|
+
id: name,
|
|
92
|
+
mode: 'subagent',
|
|
93
|
+
builtIn: true,
|
|
94
|
+
parentAgentName: canonicalDefaultAgentName,
|
|
95
|
+
name,
|
|
96
|
+
description: data.seedDescription,
|
|
97
|
+
instructions: { kind: 'inline', value: data.seedInstructions },
|
|
98
|
+
capabilities: data.capabilities,
|
|
99
|
+
permissions: data.permissions,
|
|
100
|
+
memory: { scopes: ['project'] },
|
|
101
|
+
workflows: data.workflows,
|
|
102
|
+
skills: data.skills,
|
|
103
|
+
adapters: { opencode: { model: 'openai/gpt-5.5', config: { hidden: true, options: { vgxnessPromptContractVersion: canonicalPromptContractVersion } } } },
|
|
104
|
+
providerSupport: commonSupport(),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
export function createCanonicalOpenCodeSddTaskPermissions() {
|
|
108
|
+
return Object.fromEntries([['*', 'deny'], ...canonicalSddSubagentNames.map((name) => [name, 'allow'])]);
|
|
109
|
+
}
|
|
110
|
+
export function createCanonicalOpenCodeSddSubagentPrompt(name) {
|
|
111
|
+
const phase = name.replace('vgxness-sdd-', '');
|
|
112
|
+
const common = `You are the VGXNESS SDD ${phase} executor, not the orchestrator. Do this phase's work yourself. Do NOT delegate, do NOT call task/delegate, and do NOT launch sub-agents. Use provided SDD artifacts, VGXNESS MCP state, and local repository evidence as needed. Retrieve full artifact content through MCP when the phase requires it; do not expect the manager to paste verbose artifacts into your prompt. Do not depend on external local skill files; this inline contract is sufficient. Preserve unrelated user work, keep output concise, and report evidence.`;
|
|
113
|
+
const contract = subagentData[name].phaseContract;
|
|
114
|
+
return `${common}\n\nPhase contract: ${contract}\n\nSDD governance v1: SDD artifact acceptance is human-only. Do not mark, describe, or persist generated phase output as accepted unless the user explicitly accepts it or an MCP acceptance record shows a human actor. Before advancing phases, use VGXNESS MCP readiness/status tools so draft, rejected, superseded, or legacy artifacts are not treated as accepted prerequisites. For risky VGX-managed side effects, use VGXNESS run preflight/reporting and include runId, phase, and agent context when available. OpenCode native/provider tools are audit-only and non-hard-blocking in governance v1; do not claim they are hard-blocked by OpenCode config.\n\nProvider-native daily progression: daily SDD progression happens inside OpenCode through conversation, VGXNESS MCP, and hidden SDD subagents. Do not instruct the user to run terminal SDD phase commands for normal daily flow. Return phase output, decisions, changed files, and evidence so the manager can persist artifacts and advance through MCP. Preserve confirmation/preflight requirements for apply, verify, init, archive, edits, shell, git, provider-tool, secrets, destructive, privileged, or ambiguous operations.`;
|
|
115
|
+
}
|
|
116
|
+
export const canonicalOpenCodeManagerPrompt = `# VGXNESS Manager - compact SDD orchestrator
|
|
117
|
+
|
|
118
|
+
Bind only to the primary \`vgxness-manager\` agent. Executor agents (for example \`vgxness-sdd-apply\`) use their own prompts.
|
|
119
|
+
|
|
120
|
+
## Role
|
|
121
|
+
Coordinate SDD; do not become a monolithic executor. Keep the chat thin, use VGXNESS MCP as durable state, delegate phase work to the smallest exact hidden SDD subagent, then synthesize concise evidence for the user. Be direct, practical, repository-grounded, user-controlled, and willing to challenge unsafe or weak assumptions.
|
|
122
|
+
|
|
123
|
+
Coach while coordinating: teach briefly when helpful, explain practical tradeoffs, stay realistic about risk/effort/unknowns, respectfully challenge weak assumptions, keep the user comfortable and in control, and avoid lectures or unnecessary verbosity.
|
|
124
|
+
|
|
125
|
+
## Non-negotiable governance
|
|
126
|
+
- SDD artifact acceptance is human-only. Never infer acceptance from generated output, file presence, confidence, or legacy artifacts. Treat draft/rejected/superseded/unaccepted artifacts as not accepted until a human acceptance record exists.
|
|
127
|
+
- Before phase advancement, call readiness/status tools: \`vgxness_sdd_status\`/\`vgxness_sdd_next\` and \`vgxness_sdd_ready\` or \`vgxness_sdd_get_readiness\`.
|
|
128
|
+
- 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 context when available. If approval/block is required, stop; do not invent approval.
|
|
129
|
+
- OpenCode native/provider tools are governance-v1 audit-only/non-hard-blocking. Report warnings; do not say native OpenCode tools are hard-blocked by config.
|
|
130
|
+
- Do not mutate provider/global OpenCode config unless explicitly requested. Do not write to \`openspec/\`. Never revert/overwrite unrelated user work. Preserve \`permission.task\` deny-by-default with only exact known SDD subagents allowed.
|
|
131
|
+
- Do not publish packages unless explicitly requested.
|
|
132
|
+
- Do not change model or reasoning effort.
|
|
133
|
+
|
|
134
|
+
## Provider-native daily flow
|
|
135
|
+
Normal SDD progression happens inside OpenCode through conversation, VGXNESS MCP, and hidden SDD subagents. Do not tell users to run terminal SDD phase commands for daily flow. CLI is an escape hatch only for bootstrap, doctor, rollback/recovery, MCP unavailable/setup missing, provider-native repair out of scope, or explicit user request.
|
|
136
|
+
|
|
137
|
+
## MCP playbook
|
|
138
|
+
- For starting, resuming, or recovering context: prefer \`vgxness_context_cockpit\` with project + workspace; treat \`vgxness_session_restore\` as one signal inside the cockpit, not authoritative truth. If cockpit is unavailable, use \`vgxness_session_restore\` with project + workspace before inferring state. For ending, pausing, handing off, or compacting: \`vgxness_session_close\` with current session id and actor \`manager\`; if no id, do not invent one, say so and include summary in final response.
|
|
139
|
+
- SDD artifacts: list/read with \`vgxness_sdd_get_artifact\`/\`vgxness_sdd_list_artifacts\`; use \`payloadMode: "compact"\` by default for manager-facing reads/lists so the primary context stays clean. Use \`payloadMode: "verbose"\` only when full content is truly required, preferably inside the delegated phase subagent rather than the manager context. Save phase output with \`vgxness_sdd_save_artifact\` only after the appropriate flow. SDD artifacts are not generic memory.
|
|
140
|
+
- Acceptance/readiness: confirm explicit human acceptance, use \`vgxness_sdd_accept_artifact\` only for explicit human acceptance, then \`vgxness_sdd_get_readiness\`/readiness tools before reporting state. Use \`vgxness_governance_report\` for readiness, artifact states, preflight posture, and audit warnings before risky/ambiguous transitions and in apply/verify summaries.
|
|
141
|
+
- Memory: call \`vgxness_memory_search\`/\`vgxness_memory_get\` when prior work or unclear project context is referenced; call \`vgxness_memory_save\` for durable discoveries, decisions, bug fixes, config, patterns, or preferences; use \`vgxness_memory_update\` only to correct/evolve a known id. Do not duplicate full SDD artifacts as memory.
|
|
142
|
+
- Agents/profile/payloads: resolve exact phase with \`vgxness_agent_resolve\`. \`vgxness_agent_activate\`, \`vgxness_opencode_manager_payload\`, and \`vgxness_skill_payload\` prepare/read preview context only; agent_activate does not execute a provider or write provider config. Use \`vgxness_manager_profile_get\` before behavior changes; \`vgxness_manager_profile_set\` requires explicit human authorization.
|
|
143
|
+
- Runs: use \`vgxness_run_start\`/\`vgxness_run_list\`/\`vgxness_run_get\` for significant implementation/verification or multi-step delegated work; checkpoint with \`vgxness_run_checkpoint\`, preflight with \`vgxness_run_preflight\`, and close with \`vgxness_run_finalize\`.
|
|
144
|
+
- Provider diagnostics: \`vgxness_provider_status\` and \`vgxness_provider_doctor\` are read-only reports.
|
|
145
|
+
|
|
146
|
+
## Minimum flows
|
|
147
|
+
- Simple answer: respond inline; memory only if prior context is referenced; no run by default.
|
|
148
|
+
- Proposal/spec/design/tasks: status/next -> readiness -> read prerequisites -> resolve exact subagent -> delegate -> persist returned output only according to acceptance/governance.
|
|
149
|
+
- Apply/verify: require tasks/apply-progress as appropriate -> read artifacts -> resolve exact subagent -> recover/start run -> preflight writes/shell/git/tests -> delegate -> checkpoint -> save apply-progress/verify -> finalize when clear.
|
|
150
|
+
- Config/provider/prompt change: inspect manager/profile or payload first; persistent changes require explicit human authorization.
|
|
151
|
+
|
|
152
|
+
## Delegation thresholds
|
|
153
|
+
Inline only small decisions, 1-3 file reads, status commands, and atomic one-file mechanical edits. Delegate broad exploration (4+ files), substantial implementation, writes with analysis/new logic, and execution-heavy verification. Never delegate to unknown agents; use exact SDD phase mapping: explore/propose/spec/design/tasks/apply/verify/archive/init/onboard.
|
|
154
|
+
|
|
155
|
+
## Output
|
|
156
|
+
Be concise: what was delegated, what came back, files/decisions changed, evidence/tests, risks, and next step.`;
|
|
157
|
+
const registryManagerInstructions = 'You are the VGXNESS SDD coordinator, not a monolithic executor. Coach briefly while coordinating: explain useful tradeoffs, be realistic about risks and unknowns, respectfully challenge weak assumptions with better options, keep the user comfortable and in control, and stay concise. Use VGXNESS MCP as the durable control plane: restore session context with vgxness_session_restore before inferring start/resume state from chat, and close/pause/compact with vgxness_session_close using actor manager plus an actionable summary when a current session id exists. Check SDD status/next/ready, read prerequisites with sdd_get_artifact or sdd_list_artifacts, save accepted phase output with sdd_save_artifact, search/get/save/update memory only for reusable knowledge, resolve exact SDD subagents before substantial phase work, use runs/checkpoints/preflight/finalize for significant implementation or verification, and use vgxness_provider_status for configured/phase/next questions plus vgxness_provider_doctor for read-only OpenCode MCP/manager health. Prefer payloadMode=compact for manager-facing status/context reads, SDD artifact reads/lists, and activation handoffs so the primary context stays clean; request payloadMode=verbose only when full artifact contents, provider payloads, or skill context are actually needed, preferably inside delegated phase subagents. CLI is an escape hatch for bootstrap, doctor, rollback, recovery, MCP unavailable/setup missing, or explicit user request; do not tell users to run terminal SDD phase commands for normal daily flow. Delegate real SDD phase work to the smallest exact vgxness-sdd-* subagent allowed by permission.task, synthesize results, and persist artifacts/checkpoints. Do not perform substantial multi-file implementation inline. Do not mutate global/provider OpenCode config, install skills, publish packages, or write openspec/ unless explicitly authorized. Checked-in manager and subagent instructions are self-contained; external sdd-* skill files are optional registry assets, not requirements.';
|
|
158
|
+
const subagentData = {
|
|
159
|
+
'vgxness-sdd-explore': { seedDescription: 'Investigates codebase context and identifies options before proposals.', seedInstructions: 'You are the explore phase executor, not the orchestrator. Do not delegate. Explore repository evidence for the requested SDD change. Do not implement code changes. Return concise findings, risks, and recommended next artifacts.', capabilities: ['sdd-exploration', 'codebase-research', 'discovery'], permissions: { read: 'allow', edit: 'deny', shell: 'ask', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:explore'], skills: ['vgxness-sdd-explore'], phaseContract: 'Investigate codebase context, constraints, options, and risks. Do not implement code changes. Return findings and recommended next artifacts.' },
|
|
160
|
+
'vgxness-sdd-propose': { seedDescription: 'Creates focused change proposals from exploration findings.', seedInstructions: 'You are the proposal phase executor, not the orchestrator. Do not delegate. Create a focused SDD proposal from exploration evidence. Do not implement code changes. Identify scope, tradeoffs, non-goals, and acceptance direction.', capabilities: ['sdd-proposal', 'proposal-planning', 'scope-definition'], permissions: { read: 'allow', edit: 'deny', shell: 'deny', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:proposal'], skills: ['vgxness-sdd-proposal'], phaseContract: 'Create or refine a focused SDD proposal from exploration evidence. Do not implement code changes. Include scope, tradeoffs, non-goals, and acceptance direction.' },
|
|
161
|
+
'vgxness-sdd-spec': { seedDescription: 'Writes detailed requirements and acceptance criteria for SDD changes.', seedInstructions: 'You are the spec phase executor, not the orchestrator. Do not delegate. Write a detailed SDD specification with requirements, acceptance criteria, edge cases, and out-of-scope items. Do not implement code changes.', capabilities: ['sdd-specification', 'requirements', 'acceptance-criteria'], permissions: { read: 'allow', edit: 'deny', shell: 'deny', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:spec'], skills: ['vgxness-sdd-spec'], phaseContract: 'Write requirements, acceptance criteria, edge cases, and out-of-scope items. Do not implement code changes.' },
|
|
162
|
+
'vgxness-sdd-design': { seedDescription: 'Creates technical design from approved specs and proposals.', seedInstructions: 'You are the design phase executor, not the orchestrator. Do not delegate. Create a technical design grounded in the repository. Identify affected modules, data shapes, risks, rollout, and verification strategy. Do not implement code changes.', capabilities: ['sdd-design', 'technical-design', 'architecture-planning'], permissions: { read: 'allow', edit: 'deny', shell: 'ask', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:design'], skills: ['vgxness-sdd-design'], phaseContract: 'Create technical design grounded in the repository: affected modules, data shapes, safety, rollout, and verification. Do not implement code changes.' },
|
|
163
|
+
'vgxness-sdd-tasks': { seedDescription: 'Breaks specs and designs into implementation tasks.', seedInstructions: 'You are the tasks phase executor, not the orchestrator. Do not delegate. Break the SDD spec/design into small, ordered, testable implementation tasks. Do not implement code changes.', capabilities: ['sdd-tasks', 'task-breakdown', 'implementation-planning'], permissions: { read: 'allow', edit: 'deny', shell: 'deny', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:tasks'], skills: ['vgxness-sdd-tasks'], phaseContract: 'Break approved spec/design into small ordered testable implementation tasks. Do not implement code changes.' },
|
|
164
|
+
'vgxness-sdd-apply': { seedDescription: 'Implements code changes from SDD task definitions.', seedInstructions: 'You are the apply phase executor, not the orchestrator. Implement only the assigned SDD tasks directly. Do not delegate. Keep changes small, preserve unrelated user work, run focused checks when authorized, and report changed files plus verification evidence.', capabilities: ['sdd-apply', 'implementation', 'code-change'], permissions: { read: 'allow', edit: 'ask', shell: 'ask', git: 'ask', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:apply-progress'], skills: ['vgxness-sdd-apply'], phaseContract: 'Implement only assigned SDD tasks. Preserve unrelated dirty files and user work. Use focused tests when authorized. Report changed files, tests/evidence, and residual risks.' },
|
|
165
|
+
'vgxness-sdd-verify': { seedDescription: 'Validates implementation against specs, tasks, and evidence.', seedInstructions: 'You are the verify phase executor, not the orchestrator. Do not delegate. Verify the implementation against SDD artifacts. Prefer focused local tests, inspect evidence, and report residual risk. Do not implement unrelated changes.', capabilities: ['sdd-verify', 'verification', 'test-review', 'risk-review'], permissions: { read: 'allow', edit: 'deny', shell: 'ask', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:verify'], skills: ['vgxness-sdd-verify'], phaseContract: 'Validate implementation against SDD artifacts and task acceptance criteria. Prefer focused local tests and evidence review. Do not implement unrelated changes.' },
|
|
166
|
+
'vgxness-sdd-archive': { seedDescription: 'Archives completed SDD change artifacts and outcomes.', seedInstructions: 'You are the archive phase executor, not the orchestrator. Do not delegate. Archive completed SDD artifacts and summarize final outcome, verification, and follow-ups. Confirm before writes beyond the requested archive artifact.', capabilities: ['sdd-archive', 'artifact-archive', 'release-notes'], permissions: { read: 'allow', edit: 'ask', shell: 'deny', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:archive'], skills: ['vgxness-sdd-archive'], phaseContract: 'Archive completed SDD outcome with summary, verification evidence, follow-ups, and residual risks. Confirm before any repository writes beyond the requested archive artifact.' },
|
|
167
|
+
'vgxness-sdd-init': { seedDescription: 'Bootstraps SDD context and project configuration.', seedInstructions: 'You are the init phase executor, not the orchestrator. Do not delegate. Initialize SDD context and project setup safely. Prefer read-only diagnostics and explicit user confirmation before writes or provider/global config changes.', capabilities: ['sdd-init', 'setup', 'bootstrap'], permissions: { read: 'allow', edit: 'ask', shell: 'ask', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:init', 'setup'], skills: [], phaseContract: 'Bootstrap SDD context and project setup safely. Prefer diagnostics/read-only inspection and require explicit confirmation before writes or provider/global config changes.' },
|
|
168
|
+
'vgxness-sdd-onboard': { seedDescription: 'Guides users through a complete SDD cycle using their real codebase.', seedInstructions: 'You are the onboard phase executor, not the orchestrator. Do not delegate. Guide onboarding through the SDD workflow. Ask for the smallest missing decision, keep repository assumptions explicit, and confirm before writes or provider/global config changes.', capabilities: ['sdd-onboard', 'workflow-guidance', 'project-onboarding'], permissions: { read: 'allow', edit: 'ask', shell: 'ask', git: 'deny', memory: 'allow', 'provider-tool': 'deny', secrets: 'deny' }, workflows: ['sdd:onboard', 'sdd'], skills: [], phaseContract: 'Guide the user through the SDD cycle with the smallest missing decision at each step. Keep assumptions explicit and confirm before writes or provider/global config changes.' },
|
|
169
|
+
};
|
|
170
|
+
export const canonicalAgentManifest = {
|
|
171
|
+
version: 1,
|
|
172
|
+
project: 'vgxness',
|
|
173
|
+
scope: 'project',
|
|
174
|
+
promptContractVersion: canonicalPromptContractVersion,
|
|
175
|
+
defaultAgentName: canonicalDefaultAgentName,
|
|
176
|
+
agents: [managerDefinition(), ...canonicalSddSubagentNames.map(subagentDefinition)],
|
|
177
|
+
};
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import { canonicalAgentManifest, canonicalDefaultAgentName, canonicalOpenCodeManagerPrompt, canonicalPromptContractVersion, canonicalSddSubagentNames, createCanonicalOpenCodeSddSubagentPrompt, createCanonicalOpenCodeSddTaskPermissions, validateCanonicalAgentManifest, } from './canonical-agent-manifest.js';
|
|
2
|
+
export function canonicalManifestValidationErrors(manifest = canonicalAgentManifest) {
|
|
3
|
+
const validation = validateCanonicalAgentManifest(manifest);
|
|
4
|
+
return validation.ok ? [] : validation.errors;
|
|
5
|
+
}
|
|
6
|
+
export function projectCanonicalAgentManifestToSeed(manifest = canonicalAgentManifest) {
|
|
7
|
+
assertValidCanonicalManifest(manifest);
|
|
8
|
+
const agents = manifest.agents.filter((agent) => agent.mode === 'agent').map(toSeedAgent);
|
|
9
|
+
const subagents = manifest.agents.filter((agent) => agent.mode === 'subagent').map(toSeedSubagent);
|
|
10
|
+
return { version: 1, project: manifest.project, scope: manifest.scope, agents, subagents };
|
|
11
|
+
}
|
|
12
|
+
export function projectCanonicalAgentManifestToOpenCode(manifest = canonicalAgentManifest) {
|
|
13
|
+
assertValidCanonicalManifest(manifest);
|
|
14
|
+
const manager = manifest.agents.find((agent) => agent.name === manifest.defaultAgentName && agent.mode === 'agent');
|
|
15
|
+
if (manager === undefined)
|
|
16
|
+
throw new Error(`Canonical OpenCode projection missing manager agent: ${manifest.defaultAgentName}`);
|
|
17
|
+
const agents = {
|
|
18
|
+
[canonicalDefaultAgentName]: {
|
|
19
|
+
description: 'VGXNESS SDD Manager - coordinates MCP state and SDD sub-agents, avoids inline execution when delegation is safer',
|
|
20
|
+
mode: 'primary',
|
|
21
|
+
...(manager.adapters?.opencode?.model !== undefined ? { model: manager.adapters.opencode.model } : {}),
|
|
22
|
+
options: { reasoningEffort: 'high', vgxnessPromptContractVersion: canonicalPromptContractVersion },
|
|
23
|
+
permission: { task: createCanonicalOpenCodeSddTaskPermissions() },
|
|
24
|
+
prompt: canonicalOpenCodeManagerPrompt,
|
|
25
|
+
reasoningEffort: 'high',
|
|
26
|
+
tools: { bash: true, delegate: true, delegation_list: true, delegation_read: true, edit: true, read: true, write: true },
|
|
27
|
+
variant: '',
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
for (const name of canonicalSddSubagentNames) {
|
|
31
|
+
const subagent = manifest.agents.find((agent) => agent.name === name && agent.mode === 'subagent');
|
|
32
|
+
if (subagent === undefined)
|
|
33
|
+
throw new Error(`Canonical OpenCode projection missing subagent: ${name}`);
|
|
34
|
+
agents[name] = {
|
|
35
|
+
description: openCodeSubagentDescriptions[name],
|
|
36
|
+
hidden: true,
|
|
37
|
+
mode: 'subagent',
|
|
38
|
+
...(subagent.adapters?.opencode?.model !== undefined ? { model: subagent.adapters.opencode.model } : {}),
|
|
39
|
+
options: { vgxnessPromptContractVersion: canonicalPromptContractVersion },
|
|
40
|
+
prompt: createCanonicalOpenCodeSddSubagentPrompt(name),
|
|
41
|
+
tools: { bash: true, edit: true, read: true, write: true },
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
return { defaultAgent: canonicalDefaultAgentName, agents };
|
|
45
|
+
}
|
|
46
|
+
export function projectCanonicalAgentManifestToClaudeCode(manifest = canonicalAgentManifest) {
|
|
47
|
+
assertValidCanonicalManifest(manifest);
|
|
48
|
+
const manager = manifest.agents.find((agent) => agent.name === manifest.defaultAgentName && agent.mode === 'agent');
|
|
49
|
+
if (manager === undefined)
|
|
50
|
+
throw new Error(`Canonical Claude projection missing manager agent: ${manifest.defaultAgentName}`);
|
|
51
|
+
const agents = [
|
|
52
|
+
{
|
|
53
|
+
name: canonicalDefaultAgentName,
|
|
54
|
+
canonicalName: canonicalDefaultAgentName,
|
|
55
|
+
description: manager.description,
|
|
56
|
+
fileName: `${canonicalDefaultAgentName}.md`,
|
|
57
|
+
instructions: canonicalOpenCodeManagerPrompt,
|
|
58
|
+
promptContractVersion: canonicalPromptContractVersion,
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
for (const mapping of claudeSddNameMappings) {
|
|
62
|
+
const subagent = manifest.agents.find((agent) => agent.name === mapping.canonical && agent.mode === 'subagent');
|
|
63
|
+
if (subagent === undefined)
|
|
64
|
+
throw new Error(`Canonical Claude projection missing subagent: ${mapping.canonical}`);
|
|
65
|
+
agents.push({
|
|
66
|
+
name: mapping.claude,
|
|
67
|
+
canonicalName: mapping.canonical,
|
|
68
|
+
description: claudeSubagentDescriptions[mapping.claude],
|
|
69
|
+
fileName: `${mapping.claude}.md`,
|
|
70
|
+
instructions: createCanonicalOpenCodeSddSubagentPrompt(mapping.canonical),
|
|
71
|
+
promptContractVersion: canonicalPromptContractVersion,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
return { defaultAgent: canonicalDefaultAgentName, agents };
|
|
75
|
+
}
|
|
76
|
+
export function canonicalProviderProjection(provider, manifest = canonicalAgentManifest) {
|
|
77
|
+
assertValidCanonicalManifest(manifest);
|
|
78
|
+
const normalized = provider.trim().toLowerCase();
|
|
79
|
+
if (normalized === 'opencode')
|
|
80
|
+
return { provider: normalized, level: 'managed', manifest, projection: projectCanonicalAgentManifestToOpenCode(manifest) };
|
|
81
|
+
if (normalized === 'claude')
|
|
82
|
+
return { provider: normalized, level: 'managed', manifest, projection: projectCanonicalAgentManifestToClaudeCode(manifest) };
|
|
83
|
+
return { provider: normalized, level: 'unsupported', manifest, reason: `Unsupported provider projection: ${provider}` };
|
|
84
|
+
}
|
|
85
|
+
function assertValidCanonicalManifest(manifest) {
|
|
86
|
+
const errors = canonicalManifestValidationErrors(manifest);
|
|
87
|
+
if (errors.length > 0)
|
|
88
|
+
throw new Error(`Invalid canonical agent manifest: ${errors.join('; ')}`);
|
|
89
|
+
}
|
|
90
|
+
function toSeedAgent(agent) {
|
|
91
|
+
const seed = {
|
|
92
|
+
name: agent.name,
|
|
93
|
+
description: agent.description,
|
|
94
|
+
instructions: agent.instructions,
|
|
95
|
+
};
|
|
96
|
+
if (agent.capabilities !== undefined)
|
|
97
|
+
seed.capabilities = agent.capabilities;
|
|
98
|
+
if (agent.permissions !== undefined)
|
|
99
|
+
seed.permissions = agent.permissions;
|
|
100
|
+
if (agent.memory !== undefined)
|
|
101
|
+
seed.memory = agent.memory;
|
|
102
|
+
if (agent.workflows !== undefined)
|
|
103
|
+
seed.workflows = agent.workflows;
|
|
104
|
+
if (agent.skills !== undefined)
|
|
105
|
+
seed.skills = agent.skills;
|
|
106
|
+
if (agent.adapters !== undefined)
|
|
107
|
+
seed.adapters = agent.adapters;
|
|
108
|
+
return seed;
|
|
109
|
+
}
|
|
110
|
+
function toSeedSubagent(agent) {
|
|
111
|
+
if (agent.parentAgentName === undefined)
|
|
112
|
+
throw new Error(`Canonical subagent ${agent.name} is missing parentAgentName`);
|
|
113
|
+
return { ...toSeedAgent(agent), parentAgentName: agent.parentAgentName };
|
|
114
|
+
}
|
|
115
|
+
const openCodeSubagentDescriptions = {
|
|
116
|
+
'vgxness-sdd-explore': 'Investigate codebase and think through ideas',
|
|
117
|
+
'vgxness-sdd-propose': 'Create change proposals from explorations',
|
|
118
|
+
'vgxness-sdd-spec': 'Write detailed specifications from proposals',
|
|
119
|
+
'vgxness-sdd-design': 'Create technical design from proposals',
|
|
120
|
+
'vgxness-sdd-tasks': 'Break down specs and designs into implementation tasks',
|
|
121
|
+
'vgxness-sdd-apply': 'Implement code changes from task definitions',
|
|
122
|
+
'vgxness-sdd-verify': 'Validate implementation against specs',
|
|
123
|
+
'vgxness-sdd-archive': 'Archive completed change artifacts',
|
|
124
|
+
'vgxness-sdd-init': 'Bootstrap SDD context and project configuration',
|
|
125
|
+
'vgxness-sdd-onboard': 'Guide user through a complete SDD cycle using their real codebase',
|
|
126
|
+
};
|
|
127
|
+
const claudeSddNameMappings = [
|
|
128
|
+
{ canonical: 'vgxness-sdd-explore', claude: 'vgxness-sdd-explore' },
|
|
129
|
+
{ canonical: 'vgxness-sdd-propose', claude: 'vgxness-sdd-proposal' },
|
|
130
|
+
{ canonical: 'vgxness-sdd-spec', claude: 'vgxness-sdd-spec' },
|
|
131
|
+
{ canonical: 'vgxness-sdd-design', claude: 'vgxness-sdd-design' },
|
|
132
|
+
{ canonical: 'vgxness-sdd-tasks', claude: 'vgxness-sdd-tasks' },
|
|
133
|
+
{ canonical: 'vgxness-sdd-apply', claude: 'vgxness-sdd-apply-progress' },
|
|
134
|
+
{ canonical: 'vgxness-sdd-verify', claude: 'vgxness-sdd-verify' },
|
|
135
|
+
{ canonical: 'vgxness-sdd-archive', claude: 'vgxness-sdd-archive' },
|
|
136
|
+
];
|
|
137
|
+
const claudeSubagentDescriptions = {
|
|
138
|
+
'vgxness-sdd-explore': 'Investigate codebase context and risks for VGXNESS SDD changes.',
|
|
139
|
+
'vgxness-sdd-proposal': 'Create focused proposals for VGXNESS SDD changes.',
|
|
140
|
+
'vgxness-sdd-spec': 'Write detailed specifications for VGXNESS SDD changes.',
|
|
141
|
+
'vgxness-sdd-design': 'Create technical designs for VGXNESS SDD changes.',
|
|
142
|
+
'vgxness-sdd-tasks': 'Break accepted designs into implementation tasks.',
|
|
143
|
+
'vgxness-sdd-apply-progress': 'Implement accepted VGXNESS SDD tasks and report apply progress.',
|
|
144
|
+
'vgxness-sdd-verify': 'Verify VGXNESS SDD implementation evidence and risks.',
|
|
145
|
+
'vgxness-sdd-archive': 'Archive completed VGXNESS SDD outcomes and follow-ups.',
|
|
146
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ok, validationFailure } from './provider-adapter.js';
|
|
2
2
|
const previewWarnings = [
|
|
3
|
-
'Claude rendering returns preview artifacts only; it does not install or write provider configuration.',
|
|
3
|
+
'Claude rendering returns installable preview artifacts only; it does not install or write provider configuration.',
|
|
4
4
|
'VGX does not execute Claude or run Claude Code from this preview.',
|
|
5
|
-
'
|
|
5
|
+
'VGXNESS does not install Claude Code, does not write CLAUDE.md, and does not write provider configuration from renderer previews.',
|
|
6
6
|
'VGX does not guarantee exact Claude Code configuration compatibility; this output is a neutral preview only.',
|
|
7
7
|
];
|
|
8
8
|
const previewSafety = {
|
|
9
9
|
executesProvider: false,
|
|
10
10
|
writesProviderConfig: false,
|
|
11
|
-
installable:
|
|
11
|
+
installable: true,
|
|
12
12
|
previewOnly: true,
|
|
13
13
|
};
|
|
14
14
|
const claudeCapabilities = {
|
|
@@ -17,18 +17,19 @@ const claudeCapabilities = {
|
|
|
17
17
|
permissionCategories: ['included as registry permission metadata in preview output'],
|
|
18
18
|
memoryInjectionModes: ['included as registry memory metadata in preview output'],
|
|
19
19
|
delegationModel: 'registry agents and subagents are represented in preview output without executing Claude delegation',
|
|
20
|
-
lifecycleHooks: ['preview render/export only'],
|
|
21
|
-
configFileLocations: ['rendered/claude
|
|
20
|
+
lifecycleHooks: ['preview render/export only; confirmed install is handled by MCP install service'],
|
|
21
|
+
configFileLocations: ['rendered/claude/.../.mcp.json', 'rendered/claude/.../.claude/agents/*.md'],
|
|
22
22
|
limitations: [
|
|
23
23
|
'Preview artifacts only; does not execute Claude or Claude Code.',
|
|
24
24
|
'Does not install Claude Code or provider tooling.',
|
|
25
|
-
'
|
|
26
|
-
'
|
|
25
|
+
'Renderer preview does not write .claude/, CLAUDE.md, or provider configuration.',
|
|
26
|
+
'Confirmed apply writes only project .mcp.json and .claude/agents/*.md.',
|
|
27
|
+
'Claude Code compatibility can drift; validate with provider doctor after confirmed install.',
|
|
27
28
|
],
|
|
28
29
|
render: {
|
|
29
|
-
format: 'claude-
|
|
30
|
-
artifactContentTypes: ['application/json'],
|
|
31
|
-
installable:
|
|
30
|
+
format: 'claude-code-project-preview',
|
|
31
|
+
artifactContentTypes: ['application/json', 'text/markdown'],
|
|
32
|
+
installable: true,
|
|
32
33
|
previewOnly: true,
|
|
33
34
|
},
|
|
34
35
|
};
|
|
@@ -37,58 +38,35 @@ export class ClaudeAgentRenderer {
|
|
|
37
38
|
capabilities = claudeCapabilities;
|
|
38
39
|
render(input) {
|
|
39
40
|
const agents = [input.agent, ...(input.subagents ?? [])];
|
|
40
|
-
const
|
|
41
|
+
const artifacts = [
|
|
42
|
+
{
|
|
43
|
+
relativePath: `rendered/claude/${pathSegment(input.agent.project)}/${input.agent.scope}/${pathSegment(input.agent.name)}/.mcp.json`,
|
|
44
|
+
contentType: 'application/json',
|
|
45
|
+
contents: `${JSON.stringify({ mcpServers: { vgxness: { type: 'stdio', command: 'vgxness', args: ['mcp', 'start'] } } }, null, 2)}\n`,
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
const renderedKeys = new Set();
|
|
41
49
|
for (const agent of agents) {
|
|
42
50
|
const key = claudeAgentKey(agent.name);
|
|
43
|
-
if (
|
|
51
|
+
if (renderedKeys.has(key))
|
|
44
52
|
return validationFailure(`Rendered Claude agent key collision: ${key}`);
|
|
45
|
-
|
|
53
|
+
renderedKeys.add(key);
|
|
54
|
+
artifacts.push({
|
|
55
|
+
relativePath: `rendered/claude/${pathSegment(input.agent.project)}/${input.agent.scope}/${pathSegment(input.agent.name)}/.claude/agents/${key}.md`,
|
|
56
|
+
contentType: 'text/markdown',
|
|
57
|
+
contents: renderClaudeAgentMarkdown(agent, key),
|
|
58
|
+
});
|
|
46
59
|
}
|
|
47
|
-
const preview = {
|
|
48
|
-
version: 1,
|
|
49
|
-
provider: 'claude',
|
|
50
|
-
installable: false,
|
|
51
|
-
compatibility: 'preview-only',
|
|
52
|
-
agents: renderedAgents,
|
|
53
|
-
safety: {
|
|
54
|
-
...previewSafety,
|
|
55
|
-
writesClaudeDirectory: false,
|
|
56
|
-
compatibilityGuaranteed: false,
|
|
57
|
-
},
|
|
58
|
-
warnings: previewWarnings,
|
|
59
|
-
};
|
|
60
|
-
const artifact = {
|
|
61
|
-
relativePath: `rendered/claude/${pathSegment(input.agent.project)}/${input.agent.scope}/${pathSegment(input.agent.name)}/claude-preview.json`,
|
|
62
|
-
contentType: 'application/json',
|
|
63
|
-
contents: `${JSON.stringify(preview, null, 2)}\n`,
|
|
64
|
-
};
|
|
65
60
|
return ok({
|
|
66
61
|
provider: this.provider,
|
|
67
|
-
installable:
|
|
68
|
-
artifacts
|
|
62
|
+
installable: true,
|
|
63
|
+
artifacts,
|
|
69
64
|
warnings: previewWarnings,
|
|
70
65
|
});
|
|
71
66
|
}
|
|
72
67
|
}
|
|
73
|
-
function
|
|
74
|
-
|
|
75
|
-
const rendered = {
|
|
76
|
-
name: agent.name,
|
|
77
|
-
description: agent.description,
|
|
78
|
-
instructions: agent.instructions.value,
|
|
79
|
-
mode: agent.mode === 'subagent' ? 'subagent' : 'primary',
|
|
80
|
-
...(adapter?.model !== undefined ? { model: adapter.model } : {}),
|
|
81
|
-
permissions: agent.permissions,
|
|
82
|
-
memory: agent.memory,
|
|
83
|
-
skills: agent.skills,
|
|
84
|
-
};
|
|
85
|
-
const profile = adapter?.config?.profile;
|
|
86
|
-
if (typeof profile === 'string')
|
|
87
|
-
rendered.profile = profile;
|
|
88
|
-
return rendered;
|
|
89
|
-
}
|
|
90
|
-
function claudeAdapter(agent) {
|
|
91
|
-
return agent.adapters.claude ?? agent.adapters['claude-code'];
|
|
68
|
+
function renderClaudeAgentMarkdown(agent, key) {
|
|
69
|
+
return `---\nname: ${JSON.stringify(key)}\ndescription: ${JSON.stringify(agent.description)}\n---\n\n<!-- VGXNESS-GENERATED claude-code-provider-support provider=claude artifact=claude-code-subagent promptContractVersion=6 safe-update=true -->\n\n${agent.instructions.value.trim()}\n`;
|
|
92
70
|
}
|
|
93
71
|
function claudeAgentKey(value) {
|
|
94
72
|
return pathSegment(value);
|
package/dist/cli/bun-bin.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env bun
|
|
2
2
|
import { writeFileSync } from 'node:fs';
|
|
3
3
|
import { basename } from 'node:path';
|
|
4
|
+
import { canonicalDefaultAgentName, canonicalPromptContractVersion, canonicalSddSubagentNames } from '../agents/canonical-agent-manifest.js';
|
|
4
5
|
writeRuntimeEvidence();
|
|
5
6
|
await import('./index.js');
|
|
6
7
|
function writeRuntimeEvidence() {
|
|
@@ -30,6 +31,11 @@ function writeRuntimeEvidence() {
|
|
|
30
31
|
isHelp: command.includes('--help') || command.includes('-h'),
|
|
31
32
|
cwd: process.cwd(),
|
|
32
33
|
},
|
|
34
|
+
canonicalAgents: {
|
|
35
|
+
defaultAgentName: canonicalDefaultAgentName,
|
|
36
|
+
promptContractVersion: canonicalPromptContractVersion,
|
|
37
|
+
sddSubagentCount: canonicalSddSubagentNames.length,
|
|
38
|
+
},
|
|
33
39
|
};
|
|
34
40
|
try {
|
|
35
41
|
writeFileSync(evidencePath, `${JSON.stringify(evidence, null, 2)}\n`, 'utf8');
|
package/dist/cli/cli-help.js
CHANGED
|
@@ -59,6 +59,8 @@ Areas:
|
|
|
59
59
|
mcp setup --preview --provider opencode|claude [--db <path>]
|
|
60
60
|
mcp install opencode --plan [--scope user|project] [--db <path>] [--mcp-only|--no-agents] [--overwrite-vgxness|--reinstall]
|
|
61
61
|
mcp install opencode --yes [--scope user|project] [--db <path>] [--mcp-only|--no-agents] [--overwrite-vgxness|--reinstall]
|
|
62
|
+
mcp install claude --plan [--db <path>] [--overwrite-vgxness|--reinstall]
|
|
63
|
+
mcp install claude --yes [--db <path>] [--overwrite-vgxness|--reinstall]
|
|
62
64
|
mcp doctor opencode [--scope user|project] [--project-root <path>]
|
|
63
65
|
mcp doctor [--db <path>] [--project <name>] [--change <id>] [--timeout-ms <ms>]
|
|
64
66
|
MCP setup preview is read-only; it does not install or write .opencode/, .claude/, or provider config.
|
|
@@ -67,6 +69,7 @@ Areas:
|
|
|
67
69
|
Use --overwrite-vgxness (alias --reinstall) to reinstall only VGXNESS-managed OpenCode entries while preserving unrelated config; --yes is still required to write.
|
|
68
70
|
It writes only after --yes. The default target is $HOME/.config/opencode/opencode.json; use --scope project to target .opencode/opencode.json explicitly.
|
|
69
71
|
Project OpenCode config can override user config. Plans are read-only; applies refuse unsafe existing config and create backups before merge.
|
|
72
|
+
Claude install support is project-local only: confirmed applies write .mcp.json and .claude/agents/*.md. VGXNESS never writes ~/.claude.json, CLAUDE.md, or .claude/CLAUDE.md and does not execute/install Claude Code.
|
|
70
73
|
|
|
71
74
|
skills register --project <name> --name <name> --description <text>
|
|
72
75
|
skills list [--project <name>] [--scope project|personal]
|
|
@@ -266,13 +266,14 @@ export function runAgentCommand(command, parsed, database, environment) {
|
|
|
266
266
|
if (command === 'seed') {
|
|
267
267
|
if (parsed.positionals[2] !== 'load')
|
|
268
268
|
return usageFailure('agents seed requires load');
|
|
269
|
-
const file =
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
269
|
+
const file = optionalStringFlag(parsed.flags, 'file');
|
|
270
|
+
const seed = new AgentSeedService(database);
|
|
271
|
+
if (file === undefined)
|
|
272
|
+
return jsonResult(seed.loadBuiltInDefaults());
|
|
273
|
+
const manifest = readJsonFile(file, environment);
|
|
273
274
|
if (!manifest.ok)
|
|
274
275
|
return resultFailure(manifest);
|
|
275
|
-
return jsonResult(
|
|
276
|
+
return jsonResult(seed.loadManifest(manifest.value));
|
|
276
277
|
}
|
|
277
278
|
if (command === 'register') {
|
|
278
279
|
const payload = registerPayload(parsed, environment, false);
|