vgxness 1.10.0 → 1.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 +10 -20
- package/dist/agents/canonical-agent-manifest.js +2 -2
- package/dist/behavior/behavior-contract-manifest.js +1 -3
- package/dist/behavior/behavior-contract-validation.js +0 -4
- package/dist/cli/cli-help.js +3 -9
- package/dist/cli/commands/index.js +2 -2
- package/dist/cli/commands/interactive-entrypoint-dispatcher.js +9 -153
- package/dist/cli/commands/setup-dispatcher.js +7 -51
- package/dist/cli/dispatcher.js +1 -8
- package/dist/cli/doctor-renderer.js +1 -1
- package/dist/cli/product-status-renderer.js +2 -2
- package/dist/cli/sdd-renderer.js +5 -5
- package/dist/cli/setup-plan-renderer.js +2 -2
- package/dist/cli/setup-status-renderer.js +2 -2
- package/dist/mcp/client-install-claude-code.js +3 -2
- package/dist/mcp/client-install-opencode.js +3 -2
- package/dist/mcp/provider-change-plan.js +8 -8
- package/dist/mcp/provider-doctor.js +7 -6
- package/dist/mcp/provider-status.js +10 -8
- package/dist/runs/execution-planning.js +3 -3
- package/dist/sdd/sdd-continuation-plan.js +5 -16
- package/dist/sdd/sdd-workflow-service.js +1 -1
- package/dist/setup/backup-rollback-service.js +10 -4
- package/dist/status/product-status.js +1 -1
- package/docs/architecture.md +13 -14
- package/docs/cli.md +12 -49
- package/docs/contributing.md +18 -3
- package/docs/glossary.md +5 -5
- package/docs/mcp.md +1 -1
- package/docs/prd.md +7 -7
- package/docs/project-health-audit-v1.10.x.md +115 -0
- package/docs/project-health-audit-v1.9.1.md +2 -0
- package/docs/providers.md +9 -37
- package/docs/roadmap.md +4 -10
- package/docs/safety.md +5 -21
- package/docs/storage.md +6 -5
- package/package.json +1 -3
- package/dist/cli/tui/main-menu/index.js +0 -6
- package/dist/cli/tui/main-menu/main-menu-actions.js +0 -34
- package/dist/cli/tui/main-menu/main-menu-controller.js +0 -11
- package/dist/cli/tui/main-menu/main-menu-read-model.js +0 -75
- package/dist/cli/tui/main-menu/main-menu-render-shape.js +0 -46
- package/dist/cli/tui/main-menu/main-menu-result.js +0 -1
- package/dist/cli/tui/main-menu/main-menu-state.js +0 -21
- package/dist/cli/tui/opentui/code/index.js +0 -210
- package/dist/cli/tui/opentui/code/screen.js +0 -107
- package/dist/cli/tui/opentui/code/smoke.js +0 -32
- package/dist/cli/tui/opentui/main-menu/index.js +0 -3
- package/dist/cli/tui/opentui/main-menu/renderer.js +0 -68
- package/dist/cli/tui/opentui/main-menu/screen.js +0 -66
- package/dist/cli/tui/opentui/main-menu/smoke.js +0 -17
- package/dist/cli/tui/opentui/main-menu/view.js +0 -8
- package/dist/cli/tui/opentui/setup/index.js +0 -3
- package/dist/cli/tui/opentui/setup/renderer.js +0 -87
- package/dist/cli/tui/opentui/setup/screen.js +0 -170
- package/dist/cli/tui/opentui/setup/smoke.js +0 -42
- package/dist/cli/tui/opentui/setup/view.js +0 -12
- package/dist/cli/tui/setup/setup-tui-actions.js +0 -1
- package/dist/cli/tui/setup/setup-tui-controller.js +0 -86
- package/dist/cli/tui/setup/setup-tui-input.js +0 -43
- package/dist/cli/tui/setup/setup-tui-read-model.js +0 -215
- package/dist/cli/tui/setup/setup-tui-render-shape.js +0 -168
- package/dist/cli/tui/setup/setup-tui-result.js +0 -1
- package/dist/cli/tui/setup/setup-tui-services.js +0 -79
- package/dist/cli/tui/setup/setup-tui-state.js +0 -193
- package/dist/cli/tui/setup/setup-tui-view-helpers.js +0 -46
- package/dist/code/cli/code-command.js +0 -104
- package/dist/code/config/defaults.js +0 -108
- package/dist/code/prompts/prompt-builder.js +0 -127
- package/dist/code/providers/credentials.js +0 -13
- package/dist/code/providers/fake-provider-adapter.js +0 -98
- package/dist/code/providers/message-mapper.js +0 -73
- package/dist/code/providers/openai-compatible-provider-adapter.js +0 -68
- package/dist/code/providers/provider-adapter.js +0 -10
- package/dist/code/providers/provider-registry.js +0 -38
- package/dist/code/providers/stream-normalizer.js +0 -34
- package/dist/code/reporting/redaction.js +0 -39
- package/dist/code/reporting/summary.js +0 -32
- package/dist/code/runtime/approval-coordinator.js +0 -468
- package/dist/code/runtime/code-runtime.js +0 -1031
- package/dist/code/runtime/gateways.js +0 -143
- package/dist/code/runtime/memory-service-gateway.js +0 -20
- package/dist/code/runtime/project-detection.js +0 -102
- package/dist/code/runtime/runs-code-run-gateway.js +0 -29
- package/dist/code/runtime/sdd-context.js +0 -164
- package/dist/code/runtime/sdd-workflow-gateway.js +0 -63
- package/dist/code/runtime/types.js +0 -1
- package/dist/code/runtime/verification-coordinator.js +0 -30
- package/dist/code/tools/read-only-executor.js +0 -145
- package/dist/code/tools/tool-definitions.js +0 -58
- package/dist/code/tools/tool-registry.js +0 -13
- package/dist/code/tools/tool-result-normalizer.js +0 -119
- package/dist/code/tools/workspace-executor.js +0 -278
- package/dist/code/tui/approval-actions.js +0 -33
- package/dist/code/tui/prompt-mode.js +0 -11
- package/dist/code/tui/runtime-events.js +0 -320
- package/docs/code-runtime.md +0 -221
|
@@ -55,7 +55,7 @@ export async function installOpenCodeMcpClient(input) {
|
|
|
55
55
|
});
|
|
56
56
|
if (conflictingAgents.length > 0 && input.overwriteVgxness !== true)
|
|
57
57
|
return agentConflictRefusal(conflictingAgents, input.databasePath, databasePathSource, server, applySafety(plan), plan.targetPath, plan.verificationHints, plan.warnings, plan.manualTest, agentPlan, plan.bashPermissionPolicy);
|
|
58
|
-
const backup = createBackup(plan.targetPath, plan.scope);
|
|
58
|
+
const backup = createBackup(plan.targetPath, plan.scope, input.env?.HOME);
|
|
59
59
|
if (!backup.ok)
|
|
60
60
|
return refusal('post_write_validation_failed', backup.error.message, input.databasePath, databasePathSource, server, applySafety(plan), plan.targetPath, plan.verificationHints, plan.warnings, plan.manualTest, agentPlan, plan.overwriteVgxness, plan.bashPermissionPolicy);
|
|
61
61
|
const config = parsed.value;
|
|
@@ -97,7 +97,7 @@ function writeConfig(path, config) {
|
|
|
97
97
|
mkdirSync(dirname(path), { recursive: true });
|
|
98
98
|
writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`);
|
|
99
99
|
}
|
|
100
|
-
function createBackup(path, scope) {
|
|
100
|
+
function createBackup(path, scope, allowedManagedHome) {
|
|
101
101
|
return createManagedProviderConfigBackup({
|
|
102
102
|
targetPath: path,
|
|
103
103
|
provider: 'opencode',
|
|
@@ -105,6 +105,7 @@ function createBackup(path, scope) {
|
|
|
105
105
|
createdByOperation: 'mcp-client-install-opencode',
|
|
106
106
|
reason: 'pre-merge-safety',
|
|
107
107
|
description: 'Backup existing OpenCode config before merging VGXNESS MCP configuration.',
|
|
108
|
+
...(allowedManagedHome !== undefined ? { allowedManagedHome } : {}),
|
|
108
109
|
});
|
|
109
110
|
}
|
|
110
111
|
function validateInstalledResult(targetPath, backup, server, databasePath, source, safety, verificationHints, warningMessages, manualTestGuidance, agentPlan, overwriteVgxness = false, bashPermissionPolicy = bashPermissionPolicyFor(agentPlan)) {
|
|
@@ -100,7 +100,7 @@ function unsupportedProviderEnvelope(input) {
|
|
|
100
100
|
supported: false,
|
|
101
101
|
status: 'unsupported',
|
|
102
102
|
code: 'UNSUPPORTED_PROVIDER',
|
|
103
|
-
summary:
|
|
103
|
+
summary: `[read-only] ${input.provider} is a recognized provider value, but provider change planning currently supports OpenCode and Claude. No provider config was written. This diagnostic does not install or repair provider config.`,
|
|
104
104
|
providerIdentity: {
|
|
105
105
|
provider: input.provider,
|
|
106
106
|
adapter: input.provider,
|
|
@@ -114,7 +114,7 @@ function unsupportedProviderEnvelope(input) {
|
|
|
114
114
|
backupRollback: descriptiveBackupPolicy(false),
|
|
115
115
|
confirmations: confirmationPolicy(),
|
|
116
116
|
risks: ['No provider-specific change preview is available for this provider yet.'],
|
|
117
|
-
warnings: ['Known provider enum value is unsupported by this read-only planner.'],
|
|
117
|
+
warnings: ['Known provider enum value is unsupported by this read-only planner. No files were written.'],
|
|
118
118
|
};
|
|
119
119
|
}
|
|
120
120
|
function blockedPlanEnvelope(input, status, doctor, message) {
|
|
@@ -124,7 +124,7 @@ function blockedPlanEnvelope(input, status, doctor, message) {
|
|
|
124
124
|
supported: true,
|
|
125
125
|
status: 'blocked',
|
|
126
126
|
code: 'PLAN_UNAVAILABLE',
|
|
127
|
-
summary:
|
|
127
|
+
summary: `[read-only] ${providerName} change planning could not resolve the future MCP server command: ${message}. No provider config was written. This diagnostic does not install or repair provider config.`,
|
|
128
128
|
providerIdentity: {
|
|
129
129
|
provider: input.provider,
|
|
130
130
|
adapter: input.provider,
|
|
@@ -143,7 +143,7 @@ function blockedPlanEnvelope(input, status, doctor, message) {
|
|
|
143
143
|
backupRollback: descriptiveBackupPolicy(false),
|
|
144
144
|
confirmations: confirmationPolicy(),
|
|
145
145
|
risks: ['Future write planning requires a resolvable VGXNESS database path.'],
|
|
146
|
-
warnings: [message],
|
|
146
|
+
warnings: [message, 'No files were written.'],
|
|
147
147
|
};
|
|
148
148
|
}
|
|
149
149
|
function opencodeEnvelope(input, status, doctor, installPlan, source) {
|
|
@@ -185,7 +185,7 @@ function claudeEnvelope(input, status, doctor, installPlan, source) {
|
|
|
185
185
|
supported: true,
|
|
186
186
|
status: installPlan.status === 'refused' ? 'blocked' : 'planned',
|
|
187
187
|
...(installPlan.status === 'refused' ? { code: 'PLAN_UNAVAILABLE' } : {}),
|
|
188
|
-
summary: installPlan.status === 'refused' ? `
|
|
188
|
+
summary: installPlan.status === 'refused' ? `[read-only] Claude ${input.changeType} planning completed; future install is currently refused: ${installPlan.message}. No provider config was written. This diagnostic does not install or repair provider config.` : '[read-only] Claude planning completed. No provider config was written. This diagnostic does not install or repair provider config. A future confirmed write would update ~/.claude.json, user agents, and ~/.claude/CLAUDE.md as needed. Project/local Claude files are diagnostics only.',
|
|
189
189
|
providerIdentity: { provider: 'claude', adapter: 'claude', support: 'supported' },
|
|
190
190
|
statusSummary: statusSummary(status),
|
|
191
191
|
statusFindings: status.config,
|
|
@@ -307,7 +307,7 @@ function confirmationPolicy() {
|
|
|
307
307
|
requiredNow: false,
|
|
308
308
|
requiredBeforeFutureWrite: true,
|
|
309
309
|
acceptedMutationInputs: false,
|
|
310
|
-
message: '
|
|
310
|
+
message: '[read-only] No provider config was written. Any future provider config write must be requested and confirmed separately.',
|
|
311
311
|
};
|
|
312
312
|
}
|
|
313
313
|
function statusWarnings(status) {
|
|
@@ -339,6 +339,6 @@ function risksForClaude(status, doctor, plan, source) {
|
|
|
339
339
|
}
|
|
340
340
|
function summaryForOpenCode(input, plan) {
|
|
341
341
|
if (plan.status === 'refused')
|
|
342
|
-
return `
|
|
343
|
-
return `
|
|
342
|
+
return `[read-only] OpenCode ${input.changeType} planning completed; future install is currently refused: ${plan.message}. No provider config was written. This diagnostic does not install or repair provider config.`;
|
|
343
|
+
return `[read-only] OpenCode ${input.changeType} planning completed. No provider config was written. This diagnostic does not install or repair provider config. A future confirmed write would ${plan.action} ${plan.targetPath}.`;
|
|
344
344
|
}
|
|
@@ -174,15 +174,16 @@ function managedUserGlobalClassification(paths) {
|
|
|
174
174
|
return { managedUserGlobalConfig: [...paths], detectedExternalProjectConfig: [], detectedExternalUserConfig: [] };
|
|
175
175
|
}
|
|
176
176
|
function summarizeDoctor(status, failedCount, recommendationCount) {
|
|
177
|
+
const suffix = '[read-only] No provider config was written. This diagnostic does not install or repair provider config.';
|
|
177
178
|
if (status === 'healthy')
|
|
178
|
-
return
|
|
179
|
+
return `Provider doctor checks passed. ${suffix}`;
|
|
179
180
|
if (status === 'degraded')
|
|
180
|
-
return `Provider doctor found warnings and ${recommendationCount} recommendation(s)
|
|
181
|
+
return `Provider doctor found warnings and ${recommendationCount} recommendation(s). ${suffix}`;
|
|
181
182
|
if (status === 'failed')
|
|
182
|
-
return `Provider doctor found ${failedCount} failed check(s)
|
|
183
|
+
return `Provider doctor found ${failedCount} failed check(s). ${suffix}`;
|
|
183
184
|
if (status === 'skipped')
|
|
184
|
-
return
|
|
185
|
-
return
|
|
185
|
+
return `Provider doctor checks were skipped. ${suffix}`;
|
|
186
|
+
return `Provider doctor status is unknown; review checks before continuing. ${suffix}`;
|
|
186
187
|
}
|
|
187
188
|
function compactChecks(checks, mode) {
|
|
188
189
|
if (mode === 'verbose')
|
|
@@ -280,7 +281,7 @@ function readonlySafetyCheck(before, after) {
|
|
|
280
281
|
? {
|
|
281
282
|
id: 'provider-config-readonly-safety',
|
|
282
283
|
status: 'pass',
|
|
283
|
-
detail: 'Provider config path existence and mtimes were unchanged
|
|
284
|
+
detail: '[read-only] Provider config path existence and mtimes were unchanged. No files were written. This diagnostic does not install or repair provider config.',
|
|
284
285
|
}
|
|
285
286
|
: { id: 'provider-config-readonly-safety', status: 'fail', detail: 'Provider config path existence or mtimes changed during read-only doctor.' };
|
|
286
287
|
}
|
|
@@ -354,22 +354,24 @@ function hasProjectConfigAlongsideUser(paths) {
|
|
|
354
354
|
return paths.some((path) => path.label.startsWith('user ') && path.exists) && paths.some((path) => !path.label.startsWith('user ') && path.exists);
|
|
355
355
|
}
|
|
356
356
|
function summarizeStatus(status, mcpEntry) {
|
|
357
|
+
const suffix = '[read-only] No provider config was written. This diagnostic does not install or repair provider config.';
|
|
357
358
|
if (status === 'ready')
|
|
358
|
-
return
|
|
359
|
+
return `OpenCode provider config is readable and the vgxness MCP entry is present. ${suffix}`;
|
|
359
360
|
if (status === 'not-configured')
|
|
360
|
-
return mcpEntry.detail
|
|
361
|
+
return `${mcpEntry.detail} ${suffix}`;
|
|
361
362
|
if (status === 'warning')
|
|
362
|
-
return
|
|
363
|
-
return
|
|
363
|
+
return `OpenCode provider config has warnings. ${suffix}`;
|
|
364
|
+
return `OpenCode provider status check found a blocking issue. ${suffix}`;
|
|
364
365
|
}
|
|
365
366
|
function summarizeClaudeStatus(status, mcpEntry) {
|
|
367
|
+
const suffix = '[read-only] No provider config was written. This diagnostic does not install or repair provider config.';
|
|
366
368
|
if (status === 'ready')
|
|
367
|
-
return
|
|
369
|
+
return `Claude provider files were inspected and VGXNESS entries are readable. ${suffix}`;
|
|
368
370
|
if (status === 'not-configured')
|
|
369
|
-
return mcpEntry.detail
|
|
371
|
+
return `${mcpEntry.detail} ${suffix}`;
|
|
370
372
|
if (status === 'warning')
|
|
371
|
-
return
|
|
372
|
-
return
|
|
373
|
+
return `Claude provider project config has warnings. ${suffix}`;
|
|
374
|
+
return `Claude provider status check found a blocking issue. ${suffix}`;
|
|
373
375
|
}
|
|
374
376
|
function nextActionFor(status, mcpEntry, sddNext) {
|
|
375
377
|
if (sddNext !== undefined)
|
|
@@ -79,11 +79,11 @@ function conditionRequirements(operation, decision, realpathHardeningRequired, s
|
|
|
79
79
|
return conditions;
|
|
80
80
|
}
|
|
81
81
|
function planLimitations(operation, decision, strategy, sandbox) {
|
|
82
|
-
const limitations = ['planning-only: no command, provider tool, worktree, sandbox, directory, or filesystem mutation
|
|
82
|
+
const limitations = ['planning-only: this preflight records an execution plan only; no command, provider tool, worktree, sandbox, directory, or filesystem mutation was performed'];
|
|
83
83
|
if (strategy === 'worktree')
|
|
84
|
-
limitations.push('worktree is
|
|
84
|
+
limitations.push('worktree is only the planned isolation target; no worktree was created and mutations still require a separate executor or manual worktree');
|
|
85
85
|
if (strategy === 'process-sandbox')
|
|
86
|
-
limitations.push('process-sandbox is
|
|
86
|
+
limitations.push('process-sandbox is only the planned isolation target; no sandbox was launched and execution still requires a separate executor');
|
|
87
87
|
if (decision.decision === 'deny')
|
|
88
88
|
limitations.push(`permission policy denies execution: ${decision.reason}`);
|
|
89
89
|
if (sandbox?.decision === 'rejected')
|
|
@@ -4,8 +4,7 @@ export function sddContinuationPlanFrom(input) {
|
|
|
4
4
|
const inspectCommand = `vgxness sdd cockpit --project ${input.project} --change ${input.next.change} --json${dbFlag}`;
|
|
5
5
|
const suggestedCommand = suggestedContinuationCommand(input.project, input.next, inspectCommand, dbFlag);
|
|
6
6
|
const blockerGuidance = input.next.blockerGuidance ?? [];
|
|
7
|
-
const blockerActions = blockerGuidance.map((blocker) => continuationBlockerAction(input.project, input.next.change,
|
|
8
|
-
const hasDraftRunAction = blockerActions.some((action) => action.draftRunCommand !== undefined);
|
|
7
|
+
const blockerActions = blockerGuidance.map((blocker) => continuationBlockerAction(input.project, input.next.change, blocker, dbFlag));
|
|
9
8
|
const relatedRunContext = relatedRunContextView(input.project, input.relatedRunContext, dbFlag);
|
|
10
9
|
return {
|
|
11
10
|
kind: 'sdd-continuation-plan',
|
|
@@ -24,7 +23,7 @@ export function sddContinuationPlanFrom(input) {
|
|
|
24
23
|
safety: [
|
|
25
24
|
'Read-only planner: this command does not execute providers or mutate SDD artifacts, runs, provider config, or openspec/ files.',
|
|
26
25
|
'Human acceptance remains explicit; artifact presence is not treated as acceptance.',
|
|
27
|
-
|
|
26
|
+
'Continue SDD phases in OpenCode conversation through VGXNESS MCP and hidden SDD subagents; the removed code runtime is not a CLI fallback.',
|
|
28
27
|
'No openspec/ files are created or written.',
|
|
29
28
|
],
|
|
30
29
|
};
|
|
@@ -43,15 +42,13 @@ function suggestedContinuationCommand(project, next, fallbackInspectCommand, dbF
|
|
|
43
42
|
return runPhaseCommand(project, next.change, next.nextPhase, dbFlag);
|
|
44
43
|
return fallbackInspectCommand;
|
|
45
44
|
}
|
|
46
|
-
function continuationBlockerAction(project, change,
|
|
47
|
-
const draftRunCommand = blocker.reason === 'draft' && isDraftRunPlanningPhase(blockedPhase) ? draftRunPhaseCommand(project, change, blockedPhase, dbFlag) : undefined;
|
|
45
|
+
function continuationBlockerAction(project, change, blocker, dbFlag) {
|
|
48
46
|
return {
|
|
49
47
|
phase: blocker.phase,
|
|
50
48
|
topicKey: blocker.topicKey,
|
|
51
49
|
reason: blocker.reason,
|
|
52
50
|
action: blocker.action,
|
|
53
51
|
command: blockerCommand(project, change, blocker, dbFlag),
|
|
54
|
-
...(draftRunCommand === undefined ? {} : { draftRunCommand, warning: draftRunWarning() }),
|
|
55
52
|
...(blocker.artifactId === undefined ? {} : { artifactId: blocker.artifactId }),
|
|
56
53
|
};
|
|
57
54
|
}
|
|
@@ -65,16 +62,8 @@ function blockerCommand(project, change, blocker, dbFlag) {
|
|
|
65
62
|
return `vgxness sdd get-artifact --project ${project} --change ${change} --phase ${blocker.phase} --json${dbFlag}`;
|
|
66
63
|
}
|
|
67
64
|
function runPhaseCommand(project, change, phase, dbFlag) {
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
function draftRunPhaseCommand(project, change, phase, dbFlag) {
|
|
71
|
-
return `vgxness code sdd ${change} ${phase} --project ${project} --draft-run --save-artifact${dbFlag}`;
|
|
72
|
-
}
|
|
73
|
-
function isDraftRunPlanningPhase(phase) {
|
|
74
|
-
return phase === 'explore' || phase === 'proposal' || phase === 'spec' || phase === 'design' || phase === 'tasks';
|
|
75
|
-
}
|
|
76
|
-
function draftRunWarning() {
|
|
77
|
-
return 'Draft-run is planning-only; human acceptance is still required; apply-progress remains gated.';
|
|
65
|
+
void phase;
|
|
66
|
+
return `vgxness sdd continue --project ${project} --change ${change}${dbFlag}`;
|
|
78
67
|
}
|
|
79
68
|
function continuationDbFlag(explicitDatabasePath) {
|
|
80
69
|
return explicitDatabasePath === undefined ? '' : ` --db ${explicitDatabasePath}`;
|
|
@@ -644,7 +644,7 @@ function blockerActionForBlocker(blocker, blockedPhase) {
|
|
|
644
644
|
return `Run or create the ${blocker.phase} SDD phase artifact at ${blocker.topicKey}`;
|
|
645
645
|
case 'draft':
|
|
646
646
|
if (blockedPhase !== undefined && isDraftRunPlanningPhase(blockedPhase))
|
|
647
|
-
return `Accept ${blocker.topicKey} if it is ready, or
|
|
647
|
+
return `Accept ${blocker.topicKey} if it is ready, or continue planning ${blockedPhase} in OpenCode with VGXNESS MCP after explicitly acknowledging that human acceptance is still required and apply-progress remains gated`;
|
|
648
648
|
return `Accept ${blocker.topicKey}, or continue and re-run the ${blocker.phase} phase if the draft is incomplete`;
|
|
649
649
|
case 'accepted':
|
|
650
650
|
return `Inspect ${blocker.topicKey}; it is marked accepted but still appears in blocker data`;
|
|
@@ -10,6 +10,9 @@ export function createManagedProviderConfigBackup(input) {
|
|
|
10
10
|
const readable = validateReadableFile(targetPath, 'target');
|
|
11
11
|
if (!readable.ok)
|
|
12
12
|
return readable;
|
|
13
|
+
const rollbackTargetBlocker = validateProviderRollbackTarget(targetPath, input.allowedManagedHome);
|
|
14
|
+
if (rollbackTargetBlocker !== undefined)
|
|
15
|
+
return { ok: false, error: { code: 'validation_failed', message: rollbackTargetBlocker } };
|
|
13
16
|
const provider = input.provider ?? 'opencode';
|
|
14
17
|
const createdAt = (input.now ?? new Date()).toISOString();
|
|
15
18
|
const timestamp = createdAt.replaceAll(/[-:.]/g, '');
|
|
@@ -250,14 +253,14 @@ function validateMetadataBinding(backupPath, metadata) {
|
|
|
250
253
|
blockers.push(rollbackTargetBlocker);
|
|
251
254
|
return { blockers, warnings };
|
|
252
255
|
}
|
|
253
|
-
function validateProviderRollbackTarget(targetPath) {
|
|
256
|
+
function validateProviderRollbackTarget(targetPath, allowedManagedHome) {
|
|
254
257
|
const normalizedTarget = resolve(targetPath);
|
|
255
|
-
if (isManagedUserGlobalProviderTarget(normalizedTarget))
|
|
258
|
+
if (isManagedUserGlobalProviderTarget(normalizedTarget, allowedManagedHome))
|
|
256
259
|
return undefined;
|
|
257
260
|
return `Refusing to restore provider config backup to ${normalizedTarget}. VGX-managed provider rollback writes user-global OpenCode/Claude targets only; project-local provider files are external/manual diagnostics and will not be restored.`;
|
|
258
261
|
}
|
|
259
|
-
function isManagedUserGlobalProviderTarget(targetPath) {
|
|
260
|
-
const home =
|
|
262
|
+
function isManagedUserGlobalProviderTarget(targetPath, allowedManagedHome) {
|
|
263
|
+
const home = resolveManagedHome(allowedManagedHome);
|
|
261
264
|
if (targetPath === resolve(home, '.config', 'opencode', 'opencode.json'))
|
|
262
265
|
return true;
|
|
263
266
|
if (targetPath === resolve(home, '.claude.json'))
|
|
@@ -267,6 +270,9 @@ function isManagedUserGlobalProviderTarget(targetPath) {
|
|
|
267
270
|
const claudeAgentsRoot = resolve(home, '.claude', 'agents');
|
|
268
271
|
return isPathInside(claudeAgentsRoot, targetPath) && dirname(targetPath) === claudeAgentsRoot && basename(targetPath).endsWith('.md');
|
|
269
272
|
}
|
|
273
|
+
function resolveManagedHome(allowedManagedHome) {
|
|
274
|
+
return resolve(typeof allowedManagedHome === 'string' && allowedManagedHome.trim().length > 0 ? allowedManagedHome : homedir());
|
|
275
|
+
}
|
|
270
276
|
function isPathInside(parentPath, candidatePath) {
|
|
271
277
|
const relation = relative(parentPath, candidatePath);
|
|
272
278
|
return relation === '' || (relation !== '' && !relation.startsWith('..') && !isAbsolute(relation));
|
|
@@ -65,7 +65,7 @@ function resolveProject(input) {
|
|
|
65
65
|
function fromSddCockpit(cockpit, project, baseSafety, relatedRunContext) {
|
|
66
66
|
const nextLabel = cockpit.next.nextPhase === undefined ? cockpit.next.status : `${cockpit.next.status} / ${cockpit.next.nextPhase}`;
|
|
67
67
|
const command = cockpit.next.status === 'runnable' && cockpit.next.nextPhase !== undefined
|
|
68
|
-
? `vgxness
|
|
68
|
+
? `vgxness sdd continue --project ${cockpit.project} --change ${cockpit.change}`
|
|
69
69
|
: `vgxness sdd cockpit --project ${cockpit.project} --change ${cockpit.change} --json`;
|
|
70
70
|
return {
|
|
71
71
|
version: 1,
|
package/docs/architecture.md
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# vgxness Architecture
|
|
2
2
|
|
|
3
|
-
> **Scope:** this document describes the v1.
|
|
3
|
+
> **Scope:** this document describes the current v1.10.x architecture as it is actually built. It is the source of truth for how the product works today, with the latest health snapshot captured in [Project health audit v1.10.x](./project-health-audit-v1.10.x.md). Planned work that is not yet shipped lives in [Roadmap](./roadmap.md); historical planning context that no longer reflects reality has been retired. Where this doc disagrees with code, code wins — file a doc-sync task against the relevant module.
|
|
4
4
|
|
|
5
5
|
`vgxness` is a local-first, provider-agnostic, Gentle-AI-like harness for agentic development. Its core architecture separates the product domain from provider-specific tooling so agents, skills, memory, SDD workflows, runs, and traces can work across OpenCode, Claude Code, and future adapters such as Pi.
|
|
6
6
|
|
|
7
|
-
The architectural goal is not only to install better prompts or agent configs. `vgxness` combines an ecosystem configurator with a runtime control plane
|
|
7
|
+
The architectural goal is not only to install better prompts or agent configs. `vgxness` combines an ecosystem configurator with a runtime control plane: configured agents may execute the work, and the control plane keeps explicit state for phase readiness, artifacts, runs, approvals, checkpoints, and audit evidence.
|
|
8
8
|
|
|
9
|
-
The user-facing shape is deliberately
|
|
9
|
+
The user-facing shape is deliberately provider-native: **MCP for agents** and **CLI for scriptable operator control**, with TUI/setup work deferred. The experimental `vgxness code` runtime and principal OpenTUI code surface were removed temporarily.
|
|
10
10
|
|
|
11
11
|
## Architecture decision summary
|
|
12
12
|
|
|
@@ -16,9 +16,9 @@ The user-facing shape is deliberately four-surface: **MCP for agents**, **CLI fo
|
|
|
16
16
|
| Reference model | Similar product surface to Gentle-AI/`gentle-pi`: agent setup, SDD orchestration, memory wiring, skills, profiles, permissions, verification. |
|
|
17
17
|
| Differentiator | Verifiable runtime state engine: SDD phases, artifacts, runs, approvals, checkpoints, and audit trails are queryable product state, not prompt-only convention. |
|
|
18
18
|
| Core workflow | SDD-first canonical state: explore → proposal → spec → design → tasks → apply-progress → verify → archive. |
|
|
19
|
-
| Interfaces | MCP server for AI tools
|
|
19
|
+
| Interfaces | MCP server for AI tools and CLI for automation/power users. The experimental `vgxness code` runtime and principal OpenTUI code surface are temporarily unavailable. |
|
|
20
20
|
| Installation UX | Step-based guided setup with doctor checks, dry-run support, and no manual provider JSON editing on the happy path. |
|
|
21
|
-
| Provider strategy | Provider-agnostic domain model with OpenCode as the primary/default supported provider; Claude Code is supported secondary for user-global CLI MCP registration, direct user `~/.claude.json` MCP merge, and VGXNESS-owned user agent/memory files. VGX-managed OpenCode and Claude provider configuration is user-global only. Project-local provider files are external/manual diagnostics that may still affect providers externally, but VGXNESS does not repair, write, back up, or delete them. Read-only status/doctor/change-plan never execute providers. Pi/`gentle-pi` compatibility is a future adapter/reference target.
|
|
21
|
+
| Provider strategy | Provider-agnostic domain model with OpenCode as the primary/default supported provider; Claude Code is supported secondary for user-global CLI MCP registration, direct user `~/.claude.json` MCP merge, and VGXNESS-owned user agent/memory files. VGX-managed OpenCode and Claude provider configuration is user-global only. Project-local provider files are external/manual diagnostics that may still affect providers externally, but VGXNESS does not repair, write, back up, or delete them. Read-only status/doctor/change-plan never execute providers. Pi/`gentle-pi` compatibility is a future adapter/reference target. |
|
|
22
22
|
| Memory | Project memory plus personal/global memory, backed locally. |
|
|
23
23
|
| Agents | Agents/subagents are registered in a neutral schema, then rendered into provider-specific config. |
|
|
24
24
|
| Skills | Skills are first-class, versioned, attachable to agents/workflows/adapters, and improved through reviewable proposals. |
|
|
@@ -474,7 +474,7 @@ The checked-in OpenCode default config and `seeds/agents/agent-seed-v1.json` def
|
|
|
474
474
|
|
|
475
475
|
## Run lifecycle
|
|
476
476
|
|
|
477
|
-
A run is the core unit of execution. Run records are stored locally in SQLite and stay provider-neutral. The lifecycle is complete in
|
|
477
|
+
A run is the core unit of execution. Run records are stored locally in SQLite and stay provider-neutral. The lifecycle is complete in the current architecture:
|
|
478
478
|
|
|
479
479
|
```text
|
|
480
480
|
created → planned → running → needs-human
|
|
@@ -501,16 +501,16 @@ Timeline events store audit entries such as tool calls, permission decisions, ap
|
|
|
501
501
|
|
|
502
502
|
Current operation enforcement is safe-by-default and executor-injected: `RunService.executeOperation(...)` evaluates permission, records the `permission-decision`, then either blocks or calls the supplied `RunOperationExecutor`.
|
|
503
503
|
|
|
504
|
-
Execution isolation is currently **planning-only**. `planExecutionIsolation(...)` and `RunService.planOperationExecution(...)` produce an auditable plan before any real executor exists; they do not create worktrees, launch sandboxes, run shell commands, call providers, or mutate files.
|
|
504
|
+
Execution isolation is currently **planning-only**. `planExecutionIsolation(...)` and `RunService.planOperationExecution(...)` produce an auditable plan before any real executor exists; they do not create worktrees, launch sandboxes, run shell commands, call providers, or mutate files. Treat `strategy: "worktree"` as a recommended future/manual isolation boundary, not proof that isolation has already happened.
|
|
505
505
|
|
|
506
506
|
| Operation shape | Current planned strategy | Current behavior |
|
|
507
507
|
|---|---|---|
|
|
508
508
|
| In-workspace read | `workspace` | Allowed when permission policy allows it; filesystem plans require realpath/symlink hardening before any future execution. |
|
|
509
|
-
| Edit, git, destructive mutation | `git-worktree` | Planned as isolated mutation work, but still asks/blocks according to permission policy. No worktree is created yet. |
|
|
510
|
-
| Shell, network, provider tool, privileged operation | `process-sandbox` | Planned as sandboxed process/provider work, but approval is still required by default. No sandbox is launched yet. |
|
|
509
|
+
| Edit, git, destructive mutation | `git-worktree` | Planned as isolated mutation work, but still asks/blocks according to permission policy. No worktree is created yet; mutation still happens in the current checkout unless a human or future executor creates a separate worktree first. |
|
|
510
|
+
| Shell, network, provider tool, privileged operation | `process-sandbox` | Planned as sandboxed process/provider work, but approval is still required by default. No sandbox is launched yet; execution requires a separate executor with enforceable sandbox evidence. |
|
|
511
511
|
| External directory or out-of-workspace path | `process-sandbox` or blocked workspace plan | Denied by default or requires explicit stronger future approval conditions; external paths are not allowed by current plans. |
|
|
512
512
|
|
|
513
|
-
Every plan includes path constraints, required approvals/conditions, whether realpath hardening must happen before execution, and limitations that state the future boundary. Real sandbox/worktree executors are follow-up work after this planner is connected to a safe execution backend.
|
|
513
|
+
Every plan includes path constraints, required approvals/conditions, whether realpath hardening must happen before execution, and limitations that state the future boundary. Real sandbox/worktree executors are follow-up work after this planner is connected to a safe execution backend. Until then, large or risky edits should use a human-created branch/worktree and PR flow.
|
|
514
514
|
|
|
515
515
|
| Decision | Current behavior |
|
|
516
516
|
|---|---|
|
|
@@ -619,17 +619,17 @@ Current foundation API: `evaluatePermission(request)` in `src/permissions/policy
|
|
|
619
619
|
- destructive, external, privileged, or ambiguous requests require ask even when an agent override would otherwise allow the category
|
|
620
620
|
- workspace boundary denials cannot be relaxed by agent/subagent overrides
|
|
621
621
|
|
|
622
|
-
The code runtime
|
|
622
|
+
The experimental code runtime layer was removed. Current risky side effects are governed through the policy evaluator, run preflight, SDD phase permissions, and explicit setup confirmation.
|
|
623
623
|
|
|
624
624
|
## Interface surface (current)
|
|
625
625
|
|
|
626
626
|
CLI surface groups are documented in [CLI reference](./cli.md). The plural form is canonical — singular shortcuts are not added.
|
|
627
627
|
|
|
628
|
-
MCP tools mirror the same core services for agent use. The full, current list of 41 tools is in [MCP tools](./mcp.md) and `SUPPORTED_VGX_MCP_TOOL_NAMES` (`src/mcp/schema.ts`); treat that array as the source of truth. The CLI
|
|
628
|
+
MCP tools mirror the same core services for agent use. The full, current list of 41 tools is in [MCP tools](./mcp.md) and `SUPPORTED_VGX_MCP_TOOL_NAMES` (`src/mcp/schema.ts`); treat that array as the source of truth. The CLI is the human/operator control surface. MCP is the agent-facing control surface.
|
|
629
629
|
|
|
630
630
|
## Evaluation strategy
|
|
631
631
|
|
|
632
|
-
Minimum eval/test targets
|
|
632
|
+
Minimum eval/test targets, asserted through `node:test` files under `test/`:
|
|
633
633
|
|
|
634
634
|
- Agent resolution selects the expected agent (`test/agents/agent-resolver.test.ts`).
|
|
635
635
|
- Skill resolution injects the expected skill (`test/skills/`).
|
|
@@ -640,7 +640,6 @@ Minimum eval/test targets (asserted through `node:test` files under `test/`, tot
|
|
|
640
640
|
- Run resume restores expected run state and respects retry policies (`test/runs/`).
|
|
641
641
|
- Skill improvement proposals are versioned and require approval (`test/skills/`).
|
|
642
642
|
- MCP tools call the same core services as CLI/TUI and return actionable blocked states (`test/mcp/`).
|
|
643
|
-
- Code runtime behavior across inspect, plan, craft-preview, and craft modes (`test/code/`).
|
|
644
643
|
- OpenCode config rendering and drift detection (`test/mcp/opencode-agent-config-drift.test.ts`).
|
|
645
644
|
- Installation dry-run reports the exact provider config changes before mutation.
|
|
646
645
|
|
package/docs/cli.md
CHANGED
|
@@ -53,8 +53,8 @@ Recommended bootstrap and diagnostic flow after `npm install -g vgxness`:
|
|
|
53
53
|
|
|
54
54
|
```bash
|
|
55
55
|
vgxness --help
|
|
56
|
-
vgxness #
|
|
57
|
-
vgxness init #
|
|
56
|
+
vgxness # static safe guidance; no DB open, provider write, or OpenTUI import
|
|
57
|
+
vgxness init # read-only setup plan unless --yes is provided
|
|
58
58
|
vgxness setup plan # human-readable, read-only plan
|
|
59
59
|
vgxness setup status # human-readable, read-only setup status
|
|
60
60
|
vgxness setup apply --yes # writes OpenCode config only after explicit consent
|
|
@@ -70,7 +70,7 @@ Daily SDD phase progression is OpenCode-first: talk to OpenCode with the VGXNESS
|
|
|
70
70
|
|
|
71
71
|
`setup plan`, `setup status`, and non-TTY `init` planning do not write provider config. Local VGXNESS store initialization may occur when the selected SQLite store is needed. They are human-readable by default; pass `--json` when you need parseable automation output. With the default global database, the OpenCode MCP command is `vgxness mcp start`; for custom/project-local DBs it includes `--db <path>`. The default and only VGX-managed OpenCode target is `$HOME/.config/opencode/opencode.json`; Claude managed targets are user-global (`~/.claude.json`, `~/.claude/agents/*.md`, and `~/.claude/CLAUDE.md`). `setup apply --yes` is the explicit provider-config write path. `setup rollback --backup <path>` validates a VGXNESS/OpenCode backup such as `opencode.json.backup-<timestamp>`, creates a pre-rollback backup of the current user-global target when present, restores the selected backup byte-for-byte, and recommends `vgxness doctor`.
|
|
72
72
|
|
|
73
|
-
`vgxness init`
|
|
73
|
+
`vgxness init` returns the read-only setup plan by default, including in interactive terminals. It applies only when `--yes` is provided, preserving the same explicit confirmation path as `vgxness setup apply --yes`. `vgxness doctor`, `vgxness sdd status`, `vgxness sdd next`, `vgxness sdd cockpit`, `vgxness sdd get-artifact`, and `vgxness sdd list-artifacts` are also human-readable by default; use `--json` for scripts.
|
|
74
74
|
|
|
75
75
|
`vgxness sdd cockpit --json` returns the same additive compatibility shape as the MCP cockpit: all existing raw `SddCockpit` top-level fields remain present, with an additional top-level `readModel`. The cockpit is read-only and metadata-only: it does not include artifact bodies, infer acceptance from artifact presence, advance phases, execute acceptance, call providers, or write provider config. Text output renders from read-model concepts such as next action, phase metadata, blockers, guidance, and `Content included: no`.
|
|
76
76
|
|
|
@@ -87,7 +87,7 @@ Use OpenCode conversation + VGXNESS MCP + hidden SDD subagents for normal daily
|
|
|
87
87
|
|
|
88
88
|
Without `--change`, `--project`, or `--run-id`, these commands stay orientation-only and do not open the local memory store. With a selected change, project, or run, top-level `status`, `next`, and `resume` inspect SQLite read-only; formal `sdd` commands are non-provider, non-run-executing planning/artifact commands that may use the normal local store path. Pass `--json` for automation.
|
|
89
89
|
|
|
90
|
-
The usual SDD operator loop happens inside OpenCode: continue the phase in conversation while VGXNESS MCP and hidden SDD subagents inspect readiness, persist artifacts, and report evidence. CLI commands remain fallback/recovery tools: inspect `status`, ask `next`, run `sdd continue` for a
|
|
90
|
+
The usual SDD operator loop happens inside OpenCode: continue the phase in conversation while VGXNESS MCP and hidden SDD subagents inspect readiness, persist artifacts, and report evidence. CLI commands remain fallback/recovery tools: inspect `status`, ask `next`, run `sdd continue` for a read-only continuation plan, or run `vgxness resume ...` for interrupted work. After a draft is ready, use `sdd accept-artifact` for explicit human acceptance; if an artifact was rejected, use `sdd reopen-artifact` before revising it. Related interrupted run hints in `status`, `next`, and `sdd continue` are advisory only; they help avoid duplicate work but do not retry or execute runs.
|
|
91
91
|
|
|
92
92
|
## Bun-first repository verification
|
|
93
93
|
|
|
@@ -232,17 +232,17 @@ The checked-in agent seed is currently a repository development asset. It is not
|
|
|
232
232
|
|
|
233
233
|
`opencode preview` returns a combined, preview-only injection envelope for future OpenCode/MCP/hook callers. It does **not** execute OpenCode, install hooks or MCP servers, create runs, record skill usage, or write provider config.
|
|
234
234
|
|
|
235
|
-
##
|
|
235
|
+
## Principal entrypoint
|
|
236
236
|
|
|
237
|
-
Use no arguments
|
|
237
|
+
Use no arguments from a checkout to print static safe guidance:
|
|
238
238
|
|
|
239
239
|
```bash
|
|
240
240
|
bun run cli:bun --
|
|
241
241
|
```
|
|
242
242
|
|
|
243
|
-
The installed `vgxness`/`vgx` binary
|
|
243
|
+
The installed `vgxness`/`vgx` binary prints deterministic safe setup guidance with no arguments, exits 0, and does not infer a project, open project state, import OpenTUI, toggle raw mode, or write provider/config artifacts. The experimental principal code/OpenTUI surface was removed and is temporarily unavailable. Use `vgxness --help` or `vgxness -h` to print command help; explicit subcommands keep their normal behavior.
|
|
244
244
|
|
|
245
|
-
|
|
245
|
+
Setup is CLI-only: use `setup plan` and `setup status` for read-only guidance, and `setup apply --yes` only after review. Daily SDD progression stays in OpenCode with VGXNESS MCP.
|
|
246
246
|
|
|
247
247
|
For scriptable status, use explicit read-only commands:
|
|
248
248
|
|
|
@@ -253,14 +253,14 @@ bun run cli:bun -- next --project vgxness --change my-change
|
|
|
253
253
|
bun run cli:bun -- resume --project vgxness --run-id <id>
|
|
254
254
|
```
|
|
255
255
|
|
|
256
|
-
Provider support
|
|
256
|
+
Provider support for setup is:
|
|
257
257
|
|
|
258
258
|
- **OpenCode** — supported primary provider with preview/status/doctor and read-only install planning.
|
|
259
259
|
- **Claude** — supported secondary provider for user-global Claude CLI MCP registration, user `~/.claude.json` MCP merge, and VGXNESS-owned user agents/memory. Project-local Claude files are external/manual diagnostics only. Explicit guarded apply is outside the guided OpenCode flow and requires `mcp install claude --scope user --yes --run-id <id>`. Read-only status/doctor/change-plan do not execute Claude Code.
|
|
260
260
|
- **Antigravity** — placeholder/coming-soon guidance only.
|
|
261
261
|
- **Custom/future** — extension point with safe manual/default unsupported behavior.
|
|
262
262
|
|
|
263
|
-
Setup
|
|
263
|
+
Setup CLI surfaces do **not** silently write OpenCode or other provider config, do **not** call provider executables, and do **not** approve/reject preflights. They print diagnostics, recovery hints, and manual fallback commands; daily SDD work should continue in OpenCode.
|
|
264
264
|
|
|
265
265
|
## Natural-language orchestrator preview
|
|
266
266
|
|
|
@@ -280,42 +280,7 @@ Safety boundary: this is a preview only. It does **not** call providers, edit fi
|
|
|
280
280
|
|
|
281
281
|
## Code runtime CLI (`vgxness code`)
|
|
282
282
|
|
|
283
|
-
`vgxness code`
|
|
284
|
-
|
|
285
|
-
Modes (read-only by default unless `--approval-channel` and `--approval-policy` are passed):
|
|
286
|
-
|
|
287
|
-
| Mode | Purpose | Mutations |
|
|
288
|
-
|---|---|---|
|
|
289
|
-
| `inspect` | Read-only investigation of the workspace. | None. |
|
|
290
|
-
| `plan` | Read-only implementation planning. | None. |
|
|
291
|
-
| `craft-preview` | Show the diff that would be applied. | None. |
|
|
292
|
-
| `craft` | Approval-gated, bounded edit-capable work. | Edits, shell, network, git, SDD persistence all routed through explicit policy decisions. |
|
|
293
|
-
|
|
294
|
-
Common flags across modes:
|
|
295
|
-
|
|
296
|
-
```bash
|
|
297
|
-
vgxness code inspect "<question>" \
|
|
298
|
-
--provider openai-compatible \ # or "fake" for offline testing
|
|
299
|
-
--model <model-id> \
|
|
300
|
-
--stream \ # emit JSONL runtime events as they happen
|
|
301
|
-
--json \ # final response as JSON
|
|
302
|
-
--max-source-bytes <bytes> \ # bound on sources loaded into prompt
|
|
303
|
-
--approval-policy ask|allow|deny \
|
|
304
|
-
--approval-channel stdio|auto \
|
|
305
|
-
--verification none|suggest|run|repair \
|
|
306
|
-
--transcript off|summary|full \
|
|
307
|
-
--memory off|ask|auto
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
SDD-aware mode is exposed through `vgxness code sdd <change> <phase>`; pass `--save-artifact` only when persistence is intended, and pass `--change-id`/`--phase` to scope work. Read-only phases stay artifact-oriented; `apply-progress` may expose edit and shell tools; `verify` may expose verification shell tools. `--draft-run` lets planning phases use draft prerequisites for planning only; human acceptance is still required, and `apply-progress` remains gated. `apply` is accepted as a user-facing alias for `apply-progress`.
|
|
311
|
-
|
|
312
|
-
Useful events-only output for piping into the OpenTUI shell or your own tooling:
|
|
313
|
-
|
|
314
|
-
```bash
|
|
315
|
-
vgxness code inspect "Summarize the current architecture" --events-jsonl
|
|
316
|
-
```
|
|
317
|
-
|
|
318
|
-
Safety boundary: `inspect`, `plan`, and `craft-preview` never mutate. `craft` may only mutate through the permission-aware executors and the explicit approval channel; it never writes outside the workspace, never pushes to remote, and never edits `openspec/`. Secret-like values are redacted from prompts, transcripts, checkpoints, and memory saves. See [Safety model](./safety.md).
|
|
283
|
+
The experimental `vgxness code` runtime and principal OpenTUI code surface were removed and are temporarily unavailable. Do not use `vgxness code` as an SDD fallback. Continue SDD phases in OpenCode conversation with VGXNESS MCP and hidden SDD subagents, and use `vgxness status`, `vgxness next`, `vgxness sdd continue`, or `vgxness resume` for safe CLI diagnostics and recovery.
|
|
319
284
|
|
|
320
285
|
## Workflow CLI
|
|
321
286
|
|
|
@@ -570,7 +535,6 @@ bun run cli:bun -- sdd status --project vgxness --change sdd-workflow-engine --d
|
|
|
570
535
|
bun run cli:bun -- sdd ready --project vgxness --change sdd-workflow-engine --phase spec --db /tmp/vgxness-memory.sqlite
|
|
571
536
|
bun run cli:bun -- sdd save-artifact --project vgxness --change sdd-workflow-engine --phase proposal --content "# Proposal" --db /tmp/vgxness-memory.sqlite
|
|
572
537
|
bun run cli:bun -- sdd continue --project vgxness --change sdd-workflow-engine --db /tmp/vgxness-memory.sqlite
|
|
573
|
-
bun run cli:bun -- code sdd sdd-workflow-engine spec --project vgxness --draft-run --save-artifact --db /tmp/vgxness-memory.sqlite
|
|
574
538
|
bun run cli:bun -- sdd accept-artifact --project vgxness --change sdd-workflow-engine --phase proposal --actor user --note "Approved for spec" --db /tmp/vgxness-memory.sqlite
|
|
575
539
|
bun run cli:bun -- resume --project vgxness --db /tmp/vgxness-memory.sqlite
|
|
576
540
|
bun run cli:bun -- sdd get-artifact --project vgxness --change sdd-workflow-engine --phase proposal --db /tmp/vgxness-memory.sqlite
|
|
@@ -580,7 +544,7 @@ bun run cli:bun -- sdd reopen-artifact --project vgxness --change sdd-workflow-e
|
|
|
580
544
|
VGXNESS_DB_PATH=/tmp/vgxness-memory.sqlite bun run cli:bun -- sdd list-artifacts --project vgxness --change sdd-workflow-engine
|
|
581
545
|
```
|
|
582
546
|
|
|
583
|
-
Current canonical phases are `explore`, `proposal`, `spec`, `design`, `tasks`, `apply-progress`, `verify`, and `archive`. `apply` is accepted as a user-facing input alias, but artifacts, topic keys, readiness/status/cockpit JSON, and internal metadata continue to use canonical `apply-progress`. Each artifact is stored under `sdd/{change}/{phase}` in the local SQLite memory store. `sdd status` reports which phase artifacts are present, blocker-specific next actions, and related interrupted run hints when available. `sdd next` reports the next SDD action for a project/change and frames runnable phase work as OpenCode-first while preserving
|
|
547
|
+
Current canonical phases are `explore`, `proposal`, `spec`, `design`, `tasks`, `apply-progress`, `verify`, and `archive`. `apply` is accepted as a user-facing input alias, but artifacts, topic keys, readiness/status/cockpit JSON, and internal metadata continue to use canonical `apply-progress`. Each artifact is stored under `sdd/{change}/{phase}` in the local SQLite memory store. `sdd status` reports which phase artifacts are present, blocker-specific next actions, and related interrupted run hints when available. `sdd next` reports the next SDD action for a project/change and frames runnable phase work as OpenCode-first while preserving safe continuation command fields. `sdd continue` turns that state into a read-only continuation plan and related interrupted run context when a matching stopped run exists. `sdd status`, `sdd next`, `sdd continue`, `sdd get-artifact`, and `sdd list-artifacts` are human-readable by default; pass `--json` for automation/stable structured output. `sdd ready` reports satisfied prerequisites and missing artifact topic keys for one phase. `sdd get-artifact` shows artifact metadata and then full content after `--- Content ---`; `sdd list-artifacts` shows one compact row for every canonical SDD phase in phase order and does not print full artifact content.
|
|
584
548
|
|
|
585
549
|
`sdd accept-artifact` records explicit human-only acceptance of an existing artifact through the same SDD workflow service used by MCP. It requires `--project`, `--change`, `--phase`, and `--actor`; `--display-name` defaults to the actor id. `--accepted-at` is optional, but when supplied it must be an ISO date-time with an explicit timezone (`Z` or offset) and is normalized to UTC `toISOString()` output. The default output is a human-readable confirmation with a JSON hint; `--json` returns a content-free success object with project/change/phase/topic key/artifact id/status/acceptedBy/acceptedAt and optional note. `save-artifact` creates or updates draft content only and does not imply acceptance. `sdd reopen-artifact` moves a rejected artifact back to draft after an explicit human decision, so the artifact can be revised and accepted again.
|
|
586
550
|
|
|
@@ -978,7 +942,6 @@ For more on schema, scopes, and lifecycle, see [Storage](./storage.md).
|
|
|
978
942
|
## See also
|
|
979
943
|
|
|
980
944
|
- [Architecture](./architecture.md) — current-state architecture and core domain model.
|
|
981
|
-
- [Code runtime](./code-runtime.md) — `vgxness code` modes, tools, providers, and approval flow.
|
|
982
945
|
- [MCP tools](./mcp.md) — full reference for the 41 MCP tools exposed to agents.
|
|
983
946
|
- [Safety model](./safety.md) — permission categories, approval flow, redactors, and runtime gates.
|
|
984
947
|
- [Storage](./storage.md) — SQLite schema, scopes, and lifecycle.
|
package/docs/contributing.md
CHANGED
|
@@ -8,7 +8,6 @@ VGXNESS is an alpha local-first control plane. The repository follows a few rule
|
|
|
8
8
|
src/
|
|
9
9
|
agents/ # agent + subagent registry, resolver, canonical manifest
|
|
10
10
|
cli/ # CLI dispatch, command modules, TUI, OpenTUI
|
|
11
|
-
code/ # native code runtime (vgxness code)
|
|
12
11
|
export/ # redaction and export helpers
|
|
13
12
|
governance/ # governance report builder, overlay fingerprint
|
|
14
13
|
harness/ # harness-side tool handlers
|
|
@@ -74,7 +73,7 @@ These rules are non-negotiable. The harness is loaded with capability; do not re
|
|
|
74
73
|
- Do not create or write `openspec/`. SDD artifacts are stored through the local SQLite artifact service under canonical topic keys `sdd/{change}/{phase}`.
|
|
75
74
|
- Human acceptance is distinct from artifact presence. Do not infer acceptance from generated content or saved drafts. The runtime rejects `acceptedBy.type !== 'human'`.
|
|
76
75
|
- Workspace boundary denials cannot be relaxed by agent or subagent overrides. The policy evaluator uses `realpathSync` to defeat symlink escapes.
|
|
77
|
-
- Secrets and external directory access deny by default. Redaction helpers in `src/
|
|
76
|
+
- Secrets and external directory access deny by default. Redaction helpers in `src/export/redaction.ts` strip secret-shaped values for export surfaces.
|
|
78
77
|
|
|
79
78
|
## Style
|
|
80
79
|
|
|
@@ -92,7 +91,7 @@ The docs are the user-facing contract. When the code drifts, the docs must catch
|
|
|
92
91
|
- When you add a new CLI command, document it in [CLI reference](./cli.md).
|
|
93
92
|
- When you change a permission category, default, or phase mode, update [Safety model](./safety.md).
|
|
94
93
|
- When you add a migration, append it to the table in [Storage](./storage.md).
|
|
95
|
-
- When you add or change a provider, update [Providers](./providers.md) and
|
|
94
|
+
- When you add or change a provider, update [Providers](./providers.md) and setup/status documentation.
|
|
96
95
|
|
|
97
96
|
## Pull request process
|
|
98
97
|
|
|
@@ -106,6 +105,22 @@ VGXNESS is shipped as a proprietary package. The npm publication step is a separ
|
|
|
106
105
|
|
|
107
106
|
PRs that touch safety gates, permission categories, default policies, the run lifecycle, or the SDD acceptance gate are reviewed by a maintainer who can answer "does this still match the safety model?" without consulting the diff. If you are unsure, open the PR as a draft and ask.
|
|
108
107
|
|
|
108
|
+
Do not push directly to `main` for normal development. Use a branch, open a PR, and let CI/check requirements enforce the review boundary. Direct pushes are reserved for exceptional maintainer recovery and must be followed by an explicit note that branch protection was bypassed.
|
|
109
|
+
|
|
110
|
+
### Stacked PRs
|
|
111
|
+
|
|
112
|
+
Use stacked PRs when a change naturally splits into reviewable layers, for example docs groundwork → safety-policy hardening → CLI/MCP behavior. A stacked PR keeps each review small while preserving dependency order.
|
|
113
|
+
|
|
114
|
+
Recommended pattern:
|
|
115
|
+
|
|
116
|
+
1. Start from `main` for the first branch: `feature/base-slice`.
|
|
117
|
+
2. Open PR 1 into `main`.
|
|
118
|
+
3. Branch PR 2 from PR 1: `feature/follow-up-slice`, and open PR 2 with PR 1 as its base.
|
|
119
|
+
4. Keep each PR focused on one logical change and explain its base PR in the description.
|
|
120
|
+
5. Rebase or retarget follow-up PRs after their base merges; do not squash unrelated stacked slices into one large review.
|
|
121
|
+
|
|
122
|
+
Avoid stacked PRs for emergency CI repairs: use one small hotfix PR against `main` unless the repair truly depends on another unmerged branch.
|
|
123
|
+
|
|
109
124
|
## Commit conventions
|
|
110
125
|
|
|
111
126
|
- Conventional Commits (`feat:`, `fix:`, `chore:`, `docs:`, `refactor:`, `test:`, `build:`, `ci:`).
|