vgxness 1.10.0 → 1.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/commands/setup-dispatcher.js +2 -2
- package/dist/cli/doctor-renderer.js +1 -1
- package/dist/cli/setup-plan-renderer.js +2 -2
- package/dist/cli/setup-status-renderer.js +2 -2
- package/dist/cli/tui/main-menu/main-menu-read-model.js +28 -28
- package/dist/cli/tui/main-menu/main-menu-render-shape.js +5 -1
- package/dist/cli/tui/opentui/main-menu/view.js +1 -1
- package/dist/cli/tui/setup/setup-tui-read-model.js +8 -8
- package/dist/cli/tui/setup/setup-tui-render-shape.js +15 -12
- package/dist/cli/tui/setup/setup-tui-view-helpers.js +18 -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/package.json +1 -1
|
@@ -121,7 +121,7 @@ export function runSetupBackupCommand(parsed, environment) {
|
|
|
121
121
|
}
|
|
122
122
|
export async function runSetupApplyCommand(parsed, environment) {
|
|
123
123
|
if (parsed.flags.yes !== true)
|
|
124
|
-
return usageFailure('setup apply writes provider config and requires --yes');
|
|
124
|
+
return usageFailure('setup apply writes provider config and requires explicit confirmation with --yes. No provider config was written.');
|
|
125
125
|
const input = setupPlanInputFromFlags(parsed, environment);
|
|
126
126
|
if (!input.ok)
|
|
127
127
|
return resultFailure(input);
|
|
@@ -365,7 +365,7 @@ export async function runInitCommandWithSetupTui(parsed, environment, setupTui)
|
|
|
365
365
|
}
|
|
366
366
|
export async function runSetupTuiCommand(environment, input) {
|
|
367
367
|
if (!canRunInteractiveTui(environment.stdin, environment.stdout))
|
|
368
|
-
return okText('Setup TUI requires an interactive TTY
|
|
368
|
+
return okText('Setup TUI requires an interactive TTY. [read-only] No provider config was written. Run `vgxness init --plan` or `vgxness setup plan` for read-only preview output; apply later with `vgxness setup apply --yes` only after review.\n');
|
|
369
369
|
const selectedDatabasePath = databasePathSelectionFor({}, environment);
|
|
370
370
|
if (!selectedDatabasePath.ok)
|
|
371
371
|
return resultFailure(selectedDatabasePath);
|
|
@@ -21,6 +21,6 @@ export function renderDoctorReport(input) {
|
|
|
21
21
|
if (check.status !== 'pass' && check.remediation !== undefined)
|
|
22
22
|
lines.push(` Fix: ${check.remediation}`);
|
|
23
23
|
}
|
|
24
|
-
lines.push('', 'Safety: read-only
|
|
24
|
+
lines.push('', 'Safety: [read-only] No provider config was written. This diagnostic does not install or repair provider config.', `Next: ${next}`);
|
|
25
25
|
return `${lines.join('\n')}\n`;
|
|
26
26
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function renderSetupPlan(plan) {
|
|
2
2
|
return [
|
|
3
|
-
'Setup Plan',
|
|
3
|
+
'Setup Plan [read-only] [preview]',
|
|
4
4
|
`Project: ${plan.project}`,
|
|
5
5
|
`Workspace root: ${plan.workspaceRoot}`,
|
|
6
6
|
`Database: ${plan.db.mode} — ${plan.db.path} (source: ${plan.db.source})`,
|
|
@@ -10,7 +10,7 @@ export function renderSetupPlan(plan) {
|
|
|
10
10
|
...renderBackups(plan),
|
|
11
11
|
...renderConflicts(plan),
|
|
12
12
|
...renderNextCommands(plan),
|
|
13
|
-
'Safety: read-only
|
|
13
|
+
'Safety: [read-only] preview only. No provider config was written. Explicit confirmation is required before writing provider config; apply with --yes only after review.',
|
|
14
14
|
].join('\n');
|
|
15
15
|
}
|
|
16
16
|
function renderOpenCode(plan) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export function renderSetupStatus(status) {
|
|
2
2
|
return [
|
|
3
|
-
'Setup Status',
|
|
3
|
+
'Setup Status [read-only]',
|
|
4
4
|
`- Environment: ${status.environment.status} — ${status.environment.summary}`,
|
|
5
5
|
`- Project: ${status.projectState.status} — ${status.projectState.summary}`,
|
|
6
6
|
`- Store: ${status.store.status}${status.store.path === '' ? '' : ` — ${status.store.path}`}${status.store.blocker === undefined ? '' : ` (${status.store.blocker})`}`,
|
|
@@ -10,7 +10,7 @@ export function renderSetupStatus(status) {
|
|
|
10
10
|
`- Verification: ${status.verification.status} — ${status.verification.summary}`,
|
|
11
11
|
`- Next setup action: ${status.nextAction.command} — ${status.nextAction.reason}`,
|
|
12
12
|
`- Provider writes: ${status.safety.writesProviderConfig} · provider execution: ${status.safety.executesProvider}`,
|
|
13
|
-
'Safety: read-only status
|
|
13
|
+
'Safety: [read-only] status only. No provider config was written; providers were not executed. Mutating setup commands require explicit confirmation.',
|
|
14
14
|
].join('\n');
|
|
15
15
|
}
|
|
16
16
|
export function setupNeedsAction(status) {
|
|
@@ -8,7 +8,7 @@ const dashboardHero = {
|
|
|
8
8
|
badges: [tuiBadges.readOnly, tuiBadges.noProviderWrites],
|
|
9
9
|
};
|
|
10
10
|
const statCards = [
|
|
11
|
-
{ label: '
|
|
11
|
+
{ label: 'routes', value: '5', badge: '', description: 'setup diagnostics preview manual exit' },
|
|
12
12
|
{ label: 'provider', value: '1', badge: '', description: 'OpenCode' },
|
|
13
13
|
{ label: 'writes', value: '0', badge: '', description: 'dashboard render' },
|
|
14
14
|
{ label: 'SDD', value: 'OpenCode', badge: '', description: 'daily surface' },
|
|
@@ -19,39 +19,39 @@ const statusSnapshotLines = [
|
|
|
19
19
|
];
|
|
20
20
|
const optionCopy = {
|
|
21
21
|
setup: {
|
|
22
|
-
label: 'Setup OpenCode',
|
|
23
|
-
description: 'guided
|
|
24
|
-
badges: [
|
|
25
|
-
detailTitle: 'Setup OpenCode',
|
|
26
|
-
detailLines: ['
|
|
22
|
+
label: 'Setup / install OpenCode',
|
|
23
|
+
description: 'guided setup; writes only after final confirmation',
|
|
24
|
+
badges: ['[confirm required]'],
|
|
25
|
+
detailTitle: 'Setup / install OpenCode',
|
|
26
|
+
detailLines: ['Opens the guided setup flow. Provider config writes require final confirmation; review screens stay preview-only.'],
|
|
27
27
|
},
|
|
28
28
|
doctor: {
|
|
29
|
-
label: '
|
|
30
|
-
description: '
|
|
31
|
-
badges: [
|
|
32
|
-
detailTitle: '
|
|
33
|
-
detailLines: ['Shows status and recovery guidance only
|
|
29
|
+
label: 'Diagnostics / doctor',
|
|
30
|
+
description: 'status and recovery guidance only',
|
|
31
|
+
badges: ['[read-only]'],
|
|
32
|
+
detailTitle: 'Diagnostics / doctor',
|
|
33
|
+
detailLines: ['Shows status and recovery guidance only. This route does not install, repair, or call providers.'],
|
|
34
34
|
},
|
|
35
35
|
sdd: {
|
|
36
|
-
label: '
|
|
37
|
-
description: '
|
|
38
|
-
badges: [
|
|
39
|
-
detailTitle: '
|
|
40
|
-
detailLines: ['Use
|
|
36
|
+
label: 'Provider plan / preview',
|
|
37
|
+
description: 'read-only setup plan and SDD guidance',
|
|
38
|
+
badges: ['[preview]', '[read-only]'],
|
|
39
|
+
detailTitle: 'Provider plan / preview',
|
|
40
|
+
detailLines: ['Use preview/status commands to inspect provider setup. Daily SDD progression remains in OpenCode with VGXNESS MCP; this menu does not write provider config.'],
|
|
41
41
|
},
|
|
42
42
|
'advanced-cli': {
|
|
43
|
-
label: 'Advanced CLI',
|
|
44
|
-
description: 'fallback
|
|
45
|
-
badges: [
|
|
43
|
+
label: 'Advanced / manual CLI',
|
|
44
|
+
description: 'manual fallback commands and scripts',
|
|
45
|
+
badges: ['[manual]', '[read-only]'],
|
|
46
46
|
detailTitle: 'Advanced CLI',
|
|
47
47
|
detailLines: ['Prints explicit diagnostic, recovery, fallback, and scripting command references; no provider config is written.'],
|
|
48
48
|
},
|
|
49
49
|
exit: {
|
|
50
|
-
label: '
|
|
51
|
-
description: 'leave cleanly',
|
|
52
|
-
badges: [
|
|
53
|
-
detailTitle: '
|
|
54
|
-
detailLines: ['Close the dashboard; no provider config was written.'],
|
|
50
|
+
label: 'Exit / cancel',
|
|
51
|
+
description: 'leave cleanly without writes',
|
|
52
|
+
badges: ['[manual]', tuiBadges.noProviderWrites],
|
|
53
|
+
detailTitle: 'Exit / cancel',
|
|
54
|
+
detailLines: ['Close the dashboard or cancel navigation; no provider config was written.'],
|
|
55
55
|
},
|
|
56
56
|
};
|
|
57
57
|
export function buildMainMenuViewModel(state) {
|
|
@@ -62,14 +62,14 @@ export function buildMainMenuViewModel(state) {
|
|
|
62
62
|
subtitle: dashboardHero.subtitle,
|
|
63
63
|
hero: dashboardHero,
|
|
64
64
|
statCards,
|
|
65
|
-
contextLines: ['Pick a route. Dashboard render stays passive/read-only
|
|
65
|
+
contextLines: ['Pick a route: setup, diagnostics, provider preview, advanced/manual, or exit. Dashboard render stays passive/read-only.'],
|
|
66
66
|
options,
|
|
67
67
|
detail: { title: focused.detailTitle, lines: focused.detailLines, badges: focused.badges },
|
|
68
68
|
statusSnapshot: { title: 'Signal', lines: statusSnapshotLines, badges: [tuiBadges.readOnly] },
|
|
69
|
-
safetyLines: ['read-only •
|
|
69
|
+
safetyLines: ['[read-only] dashboard • [preview] plans • [confirm required] provider writes • [manual] advanced/exit'],
|
|
70
70
|
helpLines: state.helpVisible
|
|
71
|
-
? ['Keys: ↑/↓ or j/k move, Enter open, ?/h help, q/Esc
|
|
71
|
+
? ['Keys: ↑/↓ or j/k move, Enter open, b/back cancel, ?/h help, q/Esc exit.', 'Diagnostics and previews are read-only; setup writes still require final confirmation.']
|
|
72
72
|
: [],
|
|
73
|
-
footer: state.viewport.mode === 'narrow' ? '
|
|
73
|
+
footer: state.viewport.mode === 'narrow' ? 'enter open • q/Esc exit • [confirm required]' : 'j/k move • enter open • b back • q/Esc exit • no provider writes without confirmation',
|
|
74
74
|
};
|
|
75
75
|
}
|
|
@@ -34,6 +34,10 @@ function clampLine(line, width) {
|
|
|
34
34
|
'read-only',
|
|
35
35
|
'quit without writes',
|
|
36
36
|
'provider config writes',
|
|
37
|
+
'[confirm required]',
|
|
38
|
+
'[read-only]',
|
|
39
|
+
'[preview]',
|
|
40
|
+
'[manual]',
|
|
37
41
|
];
|
|
38
42
|
const phrase = protectedPhrases.find((candidate) => line.includes(candidate));
|
|
39
43
|
if (phrase !== undefined)
|
|
@@ -41,6 +45,6 @@ function clampLine(line, width) {
|
|
|
41
45
|
return `${line.slice(0, Math.max(0, width - 1)).trim()}…`;
|
|
42
46
|
}
|
|
43
47
|
function choiceLine(choice) {
|
|
44
|
-
const badges = formatBadges(choice.focused === true ? [tuiBadges.focused] : []);
|
|
48
|
+
const badges = formatBadges([...(choice.focused === true ? [tuiBadges.focused] : []), ...choice.badges]);
|
|
45
49
|
return `${choice.focused === true ? '›' : ' '} ${choice.label}${badges.length === 0 ? '' : ` ${badges}`} — ${choice.description}`;
|
|
46
50
|
}
|
|
@@ -3,6 +3,6 @@ export function formatMainMenuOptions(options) {
|
|
|
3
3
|
return options.map(formatMainMenuOption).join('\n');
|
|
4
4
|
}
|
|
5
5
|
function formatMainMenuOption(option) {
|
|
6
|
-
const badges = formatBadges(option.focused ? [tuiBadges.focused] : []);
|
|
6
|
+
const badges = formatBadges([...(option.focused ? [tuiBadges.focused] : []), ...option.badges]);
|
|
7
7
|
return `${option.focused ? '›' : ' '} ${option.label}${badges.length === 0 ? '' : ` ${badges}`} — ${option.description}`;
|
|
8
8
|
}
|
|
@@ -21,10 +21,10 @@ export function setupTuiViewModelFromPlan(plan, status, state) {
|
|
|
21
21
|
const warnings = plan?.conflicts.filter((conflict) => conflict.severity === 'warning').map((conflict) => conflict.message) ?? [];
|
|
22
22
|
const backups = plan?.backupsPlanned.map((backup) => `${backup.targetPath} (${backup.reason})`) ?? [];
|
|
23
23
|
const previewLabel = state?.previewRefresh === 'refreshing'
|
|
24
|
-
?
|
|
24
|
+
? `Preview: refreshing plan from current choices ${badgeLabels.preview} ${badgeLabels.readOnly} ${badgeLabels.noFilesWritten}`
|
|
25
25
|
: state?.previewRefresh === 'failed'
|
|
26
|
-
?
|
|
27
|
-
:
|
|
26
|
+
? `Preview: refresh failed ${badgeLabels.warning} ${badgeLabels.noFilesWritten}`
|
|
27
|
+
: `Preview: current choices are reflected in the read-only plan ${badgeLabels.preview} ${badgeLabels.readOnly} ${badgeLabels.noFilesWritten}`;
|
|
28
28
|
return {
|
|
29
29
|
title: 'VGXNESS Setup Assistant',
|
|
30
30
|
projectLabel: project,
|
|
@@ -63,15 +63,15 @@ export function setupTuiViewModelFromPlan(plan, status, state) {
|
|
|
63
63
|
nextCommands: plan?.nextCommands ?? ['vgxness setup plan'],
|
|
64
64
|
canAutoApply: plan?.provider === 'opencode' && plan.status === 'ready' && state?.selections.provider !== 'none' && plan.opencode !== undefined,
|
|
65
65
|
safetyWarning: isOpenCode && (selections?.overwriteVgxness === true || opencode?.overwriteVgxness === true)
|
|
66
|
-
?
|
|
67
|
-
:
|
|
66
|
+
? `${badgeLabels.confirmRequired} Final confirmation remains required. Explicit confirmation is required before writing provider config. Reinstall is enabled: user-global VGXNESS OpenCode entries will be overwritten after a managed backup when the target exists; unrelated config is preserved. Project-local provider files are external/manual diagnostics and will not be modified.`
|
|
67
|
+
: `${badgeLabels.confirmRequired} Final confirmation remains required. Explicit confirmation is required before writing provider config. VGXNESS will manage user-global provider configuration. Project-local provider files are external/manual diagnostics and will not be modified.`,
|
|
68
68
|
frameLabel: 'VGXNESS Setup Assistant workspace',
|
|
69
69
|
progressLabel: progressLabel(state?.screen),
|
|
70
70
|
previewLabel,
|
|
71
71
|
previewDetailLines: previewDetailLines({ plan, provider, databasePath, databaseSource, blockers, warnings, backups, isOpenCode }),
|
|
72
72
|
helpVisible: state?.helpVisible ?? false,
|
|
73
73
|
helpLines: helpLines(state?.screen),
|
|
74
|
-
footerSafetyLabel:
|
|
74
|
+
footerSafetyLabel: `Safety: plan review is ${badgeLabels.readOnly} ${badgeLabels.noFilesWritten}; final confirmation is ${badgeLabels.confirmRequired} and is the first write-capable screen.`,
|
|
75
75
|
databaseChoices: [
|
|
76
76
|
choice('database:global', 'Global database', 'Use the OS-level VGXNESS database. Recommended for normal local use.', selections?.databaseMode === 'global' || (selections === undefined && plan?.db.mode === 'global'), state?.focusedChoiceId, [badgeLabels.recommended]),
|
|
77
77
|
choice('database:project-local', 'Project-local database', 'Preview a workspace-scoped database path. No file is created here.', selections?.databaseMode === 'project-local' || (selections === undefined && plan?.db.mode === 'project-local'), state?.focusedChoiceId, [badgeLabels.readOnly]),
|
|
@@ -114,7 +114,7 @@ function previewDetailLines(input) {
|
|
|
114
114
|
`Provider installability: ${input.isOpenCode ? 'OpenCode installable after final confirmation. VGXNESS will manage user-global provider configuration. Claude first-class support requires guarded mcp install claude --yes --run-id <id>. Project-local provider files are external/manual diagnostics and will not be modified.' : 'No guided provider install from this selection; Claude uses guarded explicit user-global apply.'}`,
|
|
115
115
|
`Agent readiness: ${agentReadinessFromPlan(plan)}`,
|
|
116
116
|
`Target config: ${input.isOpenCode && opencode?.targetPath !== undefined ? compactPath(opencode.targetPath, 72) : 'none; no provider config will be written'}`,
|
|
117
|
-
`Safety: ${input.isOpenCode ?
|
|
117
|
+
`Safety: ${input.isOpenCode ? `${badgeLabels.confirmRequired} only on final confirmation; ${badgeLabels.noFilesWritten} during preview` : `${badgeLabels.readOnly} ${badgeLabels.noFilesWritten} manual/no-provider-write mode`}`,
|
|
118
118
|
...actions,
|
|
119
119
|
input.backups.length === 0 ? 'Backups: none planned' : `Backups: ${input.backups.join('; ')}`,
|
|
120
120
|
...(input.warnings.length === 0 ? ['Warnings: none'] : input.warnings.map((warning) => `Warning: ${warning}`)),
|
|
@@ -201,7 +201,7 @@ function readinessBadge(status) {
|
|
|
201
201
|
if (status === 'manual-required')
|
|
202
202
|
return badgeLabels.warning;
|
|
203
203
|
if (status === 'conflict' || status === 'blocked')
|
|
204
|
-
return badgeLabels.
|
|
204
|
+
return badgeLabels.blocked;
|
|
205
205
|
return badgeLabels.warning;
|
|
206
206
|
}
|
|
207
207
|
function opencodeActionLabel(action) {
|
|
@@ -12,8 +12,8 @@ function screenLines(input, width) {
|
|
|
12
12
|
'Guided installation sequence',
|
|
13
13
|
'Setup welcome: global memory → provider → OpenCode details → agent readiness → preview → final confirmation → doctor/restart.',
|
|
14
14
|
'VGXNESS Setup Assistant',
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
`Configure local storage and OpenCode integration with read-only previews first ${badgeLabels.readOnly} ${badgeLabels.preview}.`,
|
|
16
|
+
`No provider config is written until the final confirmation ${badgeLabels.noFilesWritten}.`,
|
|
17
17
|
], width, [setupFooterHints.continue, setupFooterHints.help, setupFooterHints.cancel]);
|
|
18
18
|
case 'project-database':
|
|
19
19
|
return workspaceLines(vm, [
|
|
@@ -32,12 +32,12 @@ function screenLines(input, width) {
|
|
|
32
32
|
'Provider selection',
|
|
33
33
|
...choiceLines(vm.providerChoices),
|
|
34
34
|
vm.providerInstallabilityLabel,
|
|
35
|
-
|
|
35
|
+
`OpenCode setup remains gated by final confirmation ${badgeLabels.confirmRequired}. Manual / none has no automatic install and no provider config will be written.`,
|
|
36
36
|
], width, choiceFooter());
|
|
37
37
|
case 'opencode-details':
|
|
38
38
|
return workspaceLines(vm, vm.providerLabel === 'OpenCode'
|
|
39
39
|
? [
|
|
40
|
-
'OpenCode plan ' + badgeLabels.
|
|
40
|
+
'OpenCode plan ' + badgeLabels.confirmRequired,
|
|
41
41
|
...choiceLines(vm.scopeChoices),
|
|
42
42
|
...choiceLines(vm.installModeChoices),
|
|
43
43
|
...choiceLines(vm.overwriteChoices),
|
|
@@ -47,7 +47,7 @@ function screenLines(input, width) {
|
|
|
47
47
|
`Action: ${vm.opencodeActionLabel}`,
|
|
48
48
|
`Agent readiness: ${vm.agentReadinessLabel}`,
|
|
49
49
|
vm.agentReadinessDetail,
|
|
50
|
-
|
|
50
|
+
`Details are preview-only here ${badgeLabels.preview} ${badgeLabels.noFilesWritten}; writes require final confirmation.`,
|
|
51
51
|
]
|
|
52
52
|
: [
|
|
53
53
|
'Manual / no-provider-write mode ' + badgeLabels.manual,
|
|
@@ -57,19 +57,22 @@ function screenLines(input, width) {
|
|
|
57
57
|
], width, vm.providerLabel === 'OpenCode' ? choiceFooter() : [setupFooterHints.continue, setupFooterHints.back, setupFooterHints.cancel]);
|
|
58
58
|
case 'plan-review':
|
|
59
59
|
return workspaceLines(vm, [
|
|
60
|
-
|
|
61
|
-
|
|
60
|
+
`Read-only plan review ${badgeLabels.preview}`,
|
|
61
|
+
`Plan summary ${badgeLabels.readOnly} ${badgeLabels.noFilesWritten}`,
|
|
62
|
+
'Plan generated. No files were written.',
|
|
62
63
|
...planLines(vm, width),
|
|
63
64
|
...nextCommandLines(vm),
|
|
64
|
-
|
|
65
|
+
`Review only: this screen does not write provider config ${badgeLabels.noFilesWritten}.`,
|
|
65
66
|
vm.canAutoApply ? 'Press Enter to continue to final confirmation.' : 'Press Enter to show manual next steps; no automatic apply is available.',
|
|
66
67
|
], width, vm.canAutoApply ? [setupFooterHints.finalConfirmation, setupFooterHints.back, setupFooterHints.cancel] : [setupFooterHints.continue, setupFooterHints.back, setupFooterHints.cancel]);
|
|
67
68
|
case 'final-confirmation':
|
|
68
69
|
return workspaceLines(vm, [
|
|
69
70
|
'Final confirmation',
|
|
70
|
-
badgeLabels.warning
|
|
71
|
+
`${badgeLabels.warning} ${badgeLabels.confirmRequired}`,
|
|
71
72
|
'Confirm OpenCode setup',
|
|
72
73
|
...planLines(vm, width),
|
|
74
|
+
'Explicit confirmation is required before writing provider config.',
|
|
75
|
+
'This is the first write-capable screen; earlier wizard steps were preview/read-only only.',
|
|
73
76
|
'WARNING: OpenCode provider config may be modified at the target path above. Existing config is backed up when planned.',
|
|
74
77
|
vm.safetyWarning,
|
|
75
78
|
'After confirmation: run doctor, then restart OpenCode to reload MCP configuration.',
|
|
@@ -84,12 +87,12 @@ function screenLines(input, width) {
|
|
|
84
87
|
'Setup recovery',
|
|
85
88
|
badgeLabels.error,
|
|
86
89
|
`Error: ${input.error ?? 'Unknown setup error'}`,
|
|
87
|
-
|
|
90
|
+
`No unconfirmed provider config write was performed ${badgeLabels.noFilesWritten}.`,
|
|
88
91
|
'Next: inspect `vgxness setup plan`, resolve blockers, then retry.',
|
|
89
92
|
footer([setupFooterHints.close], width),
|
|
90
93
|
];
|
|
91
94
|
case 'cancelled':
|
|
92
|
-
return ['Setup cancelled', badgeLabels.cancelled
|
|
95
|
+
return ['Setup cancelled', `${badgeLabels.cancelled} ${badgeLabels.noFilesWritten}`, 'Cancelled. No changes were applied.', 'No provider config was written.', 'No agent seeding was performed.', footer([setupFooterHints.close], width)];
|
|
93
96
|
}
|
|
94
97
|
}
|
|
95
98
|
function planLines(vm, width) {
|
|
@@ -153,7 +156,7 @@ function resultLines(result, vm, width) {
|
|
|
153
156
|
...vm.nextCommands.map((command) => `Next: ${command}`),
|
|
154
157
|
footer([setupFooterHints.close], width),
|
|
155
158
|
];
|
|
156
|
-
return ['Setup result',
|
|
159
|
+
return ['Setup result', `${badgeLabels.noFilesWritten} No provider config write occurred.`, footer([setupFooterHints.close], width)];
|
|
157
160
|
}
|
|
158
161
|
function resultNextCommands(vm) {
|
|
159
162
|
const filtered = vm.nextCommands.filter((command) => !/^vgx(?:ness)? setup apply\b/.test(command));
|
|
@@ -3,10 +3,14 @@ export const badgeLabels = {
|
|
|
3
3
|
recommended: '[recommended]',
|
|
4
4
|
selected: '[selected]',
|
|
5
5
|
focused: '[focused]',
|
|
6
|
+
preview: '[preview]',
|
|
6
7
|
warning: '[warning]',
|
|
7
8
|
error: '[error]',
|
|
8
|
-
|
|
9
|
+
confirmRequired: '[confirm required]',
|
|
10
|
+
writeAfterConfirm: '[confirm required]',
|
|
11
|
+
blocked: '[blocked]',
|
|
9
12
|
readOnly: '[read-only]',
|
|
13
|
+
noFilesWritten: '[no files written]',
|
|
10
14
|
manual: '[manual]',
|
|
11
15
|
deferred: '[deferred]',
|
|
12
16
|
cancelled: '[cancelled]',
|
|
@@ -35,7 +39,19 @@ export function compactPath(path, width) {
|
|
|
35
39
|
export function wrapLabel(value, width) {
|
|
36
40
|
if (width <= 0 || value.length <= width)
|
|
37
41
|
return value;
|
|
38
|
-
const protectedPhrases = [
|
|
42
|
+
const protectedPhrases = [
|
|
43
|
+
'final confirmation',
|
|
44
|
+
'confirm and apply',
|
|
45
|
+
'not installable',
|
|
46
|
+
'unrelated config is preserved',
|
|
47
|
+
'read-only',
|
|
48
|
+
'confirm required',
|
|
49
|
+
'no files written',
|
|
50
|
+
'requires confirmation',
|
|
51
|
+
'will write after confirm',
|
|
52
|
+
'error',
|
|
53
|
+
'cancelled',
|
|
54
|
+
];
|
|
39
55
|
const phrase = protectedPhrases.find((candidate) => value.includes(candidate));
|
|
40
56
|
if (phrase !== undefined)
|
|
41
57
|
return `${value.slice(0, Math.max(0, width - phrase.length - 5)).trim()} ... ${phrase}`.trim();
|
|
@@ -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)
|