vgxness 1.3.0 → 1.4.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 +16 -16
- package/dist/agents/agent-activation-service.js +9 -5
- package/dist/cli/commands/interactive-entrypoint-dispatcher.js +4 -4
- package/dist/cli/commands/setup-dispatcher.js +4 -4
- package/dist/cli/doctor-renderer.js +1 -1
- package/dist/cli/sdd-renderer.js +7 -7
- package/dist/cli/setup-status-renderer.js +1 -0
- package/dist/cli/tui/main-menu/main-menu-read-model.js +8 -0
- package/dist/cli/tui/main-menu/main-menu-render-shape.js +14 -1
- package/dist/cli/tui/opentui/code/index.js +4 -4
- package/dist/cli/tui/opentui/main-menu/screen.js +6 -0
- package/dist/cli/tui/opentui/setup/screen.js +1 -1
- package/dist/cli/tui/opentui/setup/smoke.js +1 -1
- package/dist/cli/tui/setup/setup-tui-read-model.js +3 -3
- package/dist/cli/tui/setup/setup-tui-render-shape.js +8 -9
- package/dist/cli/tui/setup/setup-tui-state.js +1 -1
- package/dist/code/runtime/sdd-context.js +2 -2
- package/dist/mcp/validation.js +6 -2
- package/dist/orchestrator/natural-language-planner.js +1 -1
- package/dist/sdd/sdd-workflow-service.js +1 -1
- package/dist/setup/backup-rollback-service.js +2 -2
- package/dist/setup/setup-lifecycle-service.js +6 -6
- package/dist/setup/setup-plan.js +3 -3
- package/dist/verification/verification-plan-service.js +1 -1
- package/docs/architecture.md +39 -38
- package/docs/cli.md +134 -127
- package/docs/funcionamiento-del-sistema.md +16 -16
- package/docs/harness-gap-analysis.md +15 -1
- package/docs/prd.md +10 -10
- package/docs/vgxcode.md +20 -9
- package/docs/vgxness-code.md +6 -4
- package/package.json +1 -1
- package/dist/cli/guided-main-menu.js +0 -470
- package/dist/cli/setup-wizard-read-model.js +0 -72
- package/dist/cli/setup-wizard-renderer.js +0 -155
- package/dist/cli/setup-wizard-state.js +0 -82
|
@@ -1,470 +0,0 @@
|
|
|
1
|
-
export const guidedMainMenuOptions = [
|
|
2
|
-
{ id: 'guided-install', label: 'Guided installation', summary: 'Recommended setup path; plans first, writes only after review and explicit confirmation.' },
|
|
3
|
-
{ id: 'doctor-recovery', label: 'Doctor / recovery', summary: 'Read-only status and recovery guidance.' },
|
|
4
|
-
{ id: 'advanced-cli', label: 'Advanced CLI', summary: 'Command-oriented help for scripting and manual workflows.' },
|
|
5
|
-
{ id: 'exit', label: 'Exit', summary: 'Quit without changes.' },
|
|
6
|
-
];
|
|
7
|
-
const guidedMemoryOptions = [
|
|
8
|
-
{ id: 'global', label: 'Global/default memory (recommended)', summary: 'Use the existing default/global VGXNESS memory path.' },
|
|
9
|
-
{
|
|
10
|
-
id: 'project-local',
|
|
11
|
-
label: 'Project-local memory (deferred)',
|
|
12
|
-
summary: 'Shown for planning only; guided install does not create a new project-local store yet.',
|
|
13
|
-
},
|
|
14
|
-
{ id: 'skip', label: 'Skip memory setup', summary: 'Continue with provider/status guidance only; no new memory storage logic is run.' },
|
|
15
|
-
];
|
|
16
|
-
const guidedProviderOptions = [
|
|
17
|
-
{ id: 'opencode', label: 'OpenCode', summary: 'Default; automatic apply-capable only after review and explicit confirmation.' },
|
|
18
|
-
{ id: 'claude', label: 'Claude', summary: 'Preview/manual guidance only; automatic apply is never called.' },
|
|
19
|
-
{ id: 'antigravity', label: 'Antigravity', summary: 'Deferred/manual guidance; automatic apply is never called.' },
|
|
20
|
-
{ id: 'custom', label: 'Custom', summary: 'Deferred/manual extension point; automatic apply is never called.' },
|
|
21
|
-
{ id: 'none', label: 'None', summary: 'Planning/status-only; no provider apply path.' },
|
|
22
|
-
];
|
|
23
|
-
export function createGuidedMainMenuState() {
|
|
24
|
-
return {
|
|
25
|
-
screen: 'menu',
|
|
26
|
-
selectedIndex: 0,
|
|
27
|
-
memorySelectedIndex: 0,
|
|
28
|
-
providerSelectedIndex: 0,
|
|
29
|
-
selectedMemory: 'global',
|
|
30
|
-
selectedProvider: 'opencode',
|
|
31
|
-
shouldExit: false,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
export function noTtyGuidedMenuGuidance() {
|
|
35
|
-
return `VGXNESS interactive menu requires a terminal.
|
|
36
|
-
|
|
37
|
-
Run one of:
|
|
38
|
-
vgxness init
|
|
39
|
-
vgxness doctor
|
|
40
|
-
vgxness --help
|
|
41
|
-
|
|
42
|
-
Or run \`vgxness\` in an interactive terminal to use Guided installation.
|
|
43
|
-
|
|
44
|
-
No changes were made.
|
|
45
|
-
`;
|
|
46
|
-
}
|
|
47
|
-
export function createGuidedSetupPreview(input) {
|
|
48
|
-
return {
|
|
49
|
-
status: input.status,
|
|
50
|
-
project: input.project,
|
|
51
|
-
databaseMode: input.database.mode,
|
|
52
|
-
databasePath: input.database.path,
|
|
53
|
-
provider: input.provider,
|
|
54
|
-
memorySelection: memorySelectionCopy(input.database.mode),
|
|
55
|
-
actions: input.actions.map((action) => `${action.description}${action.targetPath === undefined ? '' : ` (${action.targetPath})`}${action.backupRequired ? ' [backup planned]' : ''}${action.mutating ? ' [apply would mutate]' : ' [plan-only]'}`),
|
|
56
|
-
conflicts: input.conflicts.map((conflict) => `${conflict.message}${conflict.recovery === undefined ? '' : ` Recovery: ${conflict.recovery}`}`),
|
|
57
|
-
backups: input.backupsPlanned.map((backup) => `${backup.targetPath}: ${backup.reason}`),
|
|
58
|
-
nextCommands: [...input.nextCommands],
|
|
59
|
-
safety: {
|
|
60
|
-
planMutates: input.safety.mutating,
|
|
61
|
-
planWritesProviderConfig: input.safety.writesProviderConfig,
|
|
62
|
-
requiresConfirmationForApply: input.safety.requiresConfirmationForApply,
|
|
63
|
-
},
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
export function renderGuidedMainMenu(state = createGuidedMainMenuState(), context = {}) {
|
|
67
|
-
const setupPreview = guidedSetupPreviewForState(state, context.setupPreview);
|
|
68
|
-
if (state.screen === 'guided-install')
|
|
69
|
-
return renderGuidedInstallScreen();
|
|
70
|
-
if (state.screen === 'memory-selection')
|
|
71
|
-
return renderMemorySelectionScreen(state, setupPreview);
|
|
72
|
-
if (state.screen === 'provider-selection')
|
|
73
|
-
return renderProviderSelectionScreen(state, setupPreview);
|
|
74
|
-
if (state.screen === 'setup-review')
|
|
75
|
-
return renderSetupReviewScreen(setupPreview, state.confirmationNotice);
|
|
76
|
-
if (state.screen === 'setup-confirm')
|
|
77
|
-
return renderSetupConfirmScreen(setupPreview, state.confirmationNotice);
|
|
78
|
-
if (state.screen === 'apply-result')
|
|
79
|
-
return renderApplyResultScreen(state.applyResult);
|
|
80
|
-
if (state.screen === 'doctor-recovery')
|
|
81
|
-
return renderDoctorRecoveryScreen();
|
|
82
|
-
if (state.screen === 'advanced-cli')
|
|
83
|
-
return renderAdvancedCliScreen();
|
|
84
|
-
return `VGXNESS
|
|
85
|
-
|
|
86
|
-
Set up VGXNESS in your coding agent, then do daily SDD work inside that provider.
|
|
87
|
-
|
|
88
|
-
? What would you like to do?
|
|
89
|
-
${guidedMainMenuOptions.map((option, index) => renderGuidedMainMenuOption(option, index === state.selectedIndex)).join('\n')}
|
|
90
|
-
|
|
91
|
-
OpenCode automatic setup is available after review and explicit confirmation.
|
|
92
|
-
Claude is preview/manual only; Antigravity and custom providers are manual/deferred.
|
|
93
|
-
|
|
94
|
-
Keys: ↑/↓ or j/k move · Enter open · q quits. No changes are made from this menu until a reviewed plan is explicitly confirmed.
|
|
95
|
-
`;
|
|
96
|
-
}
|
|
97
|
-
export async function runGuidedMainMenuLoop(terminal) {
|
|
98
|
-
return new Promise((resolve) => {
|
|
99
|
-
let state = createGuidedMainMenuState();
|
|
100
|
-
const render = () => {
|
|
101
|
-
terminal.output.write(`\u001Bc${renderGuidedMainMenu(state, terminal.context ?? {})}`);
|
|
102
|
-
};
|
|
103
|
-
const finish = () => {
|
|
104
|
-
terminal.input.setRawMode?.(false);
|
|
105
|
-
terminal.input.pause?.();
|
|
106
|
-
if (terminal.input.off !== undefined)
|
|
107
|
-
terminal.input.off('data', onData);
|
|
108
|
-
else
|
|
109
|
-
terminal.input.removeListener?.('data', onData);
|
|
110
|
-
resolve();
|
|
111
|
-
};
|
|
112
|
-
const onData = (chunk) => {
|
|
113
|
-
void (async () => {
|
|
114
|
-
const input = chunk.toString();
|
|
115
|
-
state = await handleGuidedMainMenuInput(state, input, terminal.context ?? {});
|
|
116
|
-
render();
|
|
117
|
-
if (state.shouldExit)
|
|
118
|
-
finish();
|
|
119
|
-
})();
|
|
120
|
-
};
|
|
121
|
-
terminal.input.setRawMode?.(true);
|
|
122
|
-
terminal.input.resume?.();
|
|
123
|
-
terminal.input.on('data', onData);
|
|
124
|
-
render();
|
|
125
|
-
});
|
|
126
|
-
}
|
|
127
|
-
export function reduceGuidedMainMenuInput(state, input) {
|
|
128
|
-
if (input === 'q' || input === '\u0003')
|
|
129
|
-
return { ...state, shouldExit: true };
|
|
130
|
-
if (state.screen === 'guided-install') {
|
|
131
|
-
if (input === '\r' || input === '\n' || input === 'n')
|
|
132
|
-
return withoutConfirmationNotice({ ...state, screen: 'memory-selection' });
|
|
133
|
-
if (input === 'b' || input === '\u001B')
|
|
134
|
-
return withoutConfirmationNotice({ ...state, screen: 'menu' });
|
|
135
|
-
return state;
|
|
136
|
-
}
|
|
137
|
-
if (state.screen === 'memory-selection') {
|
|
138
|
-
if (input === 'j' || input === '\u001B[B')
|
|
139
|
-
return { ...state, memorySelectedIndex: (state.memorySelectedIndex + 1) % guidedMemoryOptions.length };
|
|
140
|
-
if (input === 'k' || input === '\u001B[A')
|
|
141
|
-
return { ...state, memorySelectedIndex: (state.memorySelectedIndex - 1 + guidedMemoryOptions.length) % guidedMemoryOptions.length };
|
|
142
|
-
if (input === 'b' || input === '\u001B')
|
|
143
|
-
return withoutConfirmationNotice({ ...state, screen: 'guided-install' });
|
|
144
|
-
if (input === '\r' || input === '\n') {
|
|
145
|
-
const selectedMemory = guidedMemoryOptions[state.memorySelectedIndex]?.id ?? 'global';
|
|
146
|
-
return withoutConfirmationNotice({ ...state, selectedMemory, screen: 'provider-selection' });
|
|
147
|
-
}
|
|
148
|
-
return state;
|
|
149
|
-
}
|
|
150
|
-
if (state.screen === 'provider-selection') {
|
|
151
|
-
if (input === 'j' || input === '\u001B[B')
|
|
152
|
-
return { ...state, providerSelectedIndex: (state.providerSelectedIndex + 1) % guidedProviderOptions.length };
|
|
153
|
-
if (input === 'k' || input === '\u001B[A')
|
|
154
|
-
return { ...state, providerSelectedIndex: (state.providerSelectedIndex - 1 + guidedProviderOptions.length) % guidedProviderOptions.length };
|
|
155
|
-
if (input === 'b' || input === '\u001B')
|
|
156
|
-
return withoutConfirmationNotice({ ...state, screen: 'memory-selection' });
|
|
157
|
-
if (input === '\r' || input === '\n') {
|
|
158
|
-
const selectedProvider = guidedProviderOptions[state.providerSelectedIndex]?.id ?? 'opencode';
|
|
159
|
-
return withoutConfirmationNotice({ ...state, selectedProvider, screen: 'setup-review' });
|
|
160
|
-
}
|
|
161
|
-
return state;
|
|
162
|
-
}
|
|
163
|
-
if (state.screen === 'setup-review') {
|
|
164
|
-
if (input === 'b' || input === '\u001B')
|
|
165
|
-
return withoutConfirmationNotice({ ...state, screen: 'provider-selection' });
|
|
166
|
-
if (input === 'a' || input === 'c' || input === '\r' || input === '\n')
|
|
167
|
-
return withoutConfirmationNotice({ ...state, screen: 'setup-confirm' });
|
|
168
|
-
return state;
|
|
169
|
-
}
|
|
170
|
-
if (state.screen === 'setup-confirm') {
|
|
171
|
-
if (input === 'b' || input === '\u001B' || input === 'n')
|
|
172
|
-
return withoutConfirmationNotice({ ...state, screen: 'setup-review' });
|
|
173
|
-
if (input === 'y')
|
|
174
|
-
return {
|
|
175
|
-
...state,
|
|
176
|
-
confirmationNotice: 'Apply is not run from this preview unless a safe apply callback is installed. Use the explicit CLI apply command after review.',
|
|
177
|
-
};
|
|
178
|
-
return state;
|
|
179
|
-
}
|
|
180
|
-
if (state.screen === 'apply-result') {
|
|
181
|
-
if (input === 'b' || input === '\u001B')
|
|
182
|
-
return withoutApplyResult(withoutConfirmationNotice({ ...state, screen: 'setup-review' }));
|
|
183
|
-
return state;
|
|
184
|
-
}
|
|
185
|
-
if (state.screen !== 'menu') {
|
|
186
|
-
if (input === 'b' || input === '\u001B')
|
|
187
|
-
return { ...state, screen: 'menu' };
|
|
188
|
-
return state;
|
|
189
|
-
}
|
|
190
|
-
if (input === 'j' || input === '\u001B[B')
|
|
191
|
-
return { ...state, selectedIndex: (state.selectedIndex + 1) % guidedMainMenuOptions.length };
|
|
192
|
-
if (input === 'k' || input === '\u001B[A')
|
|
193
|
-
return { ...state, selectedIndex: (state.selectedIndex - 1 + guidedMainMenuOptions.length) % guidedMainMenuOptions.length };
|
|
194
|
-
if (input === '\r' || input === '\n') {
|
|
195
|
-
const selected = guidedMainMenuOptions[state.selectedIndex]?.id ?? 'guided-install';
|
|
196
|
-
if (selected === 'exit')
|
|
197
|
-
return { ...state, shouldExit: true };
|
|
198
|
-
return { ...state, screen: selected };
|
|
199
|
-
}
|
|
200
|
-
return state;
|
|
201
|
-
}
|
|
202
|
-
export async function handleGuidedMainMenuInput(state, input, context = {}) {
|
|
203
|
-
if (state.screen === 'setup-confirm' && input === 'y') {
|
|
204
|
-
const preview = guidedSetupPreviewForState(state, context.setupPreview);
|
|
205
|
-
if (preview === undefined)
|
|
206
|
-
return { ...state, confirmationNotice: 'Apply is unavailable because no reviewed setup plan preview is loaded.' };
|
|
207
|
-
if (state.selectedProvider !== 'opencode' || preview.provider !== 'opencode')
|
|
208
|
-
return { ...state, confirmationNotice: 'Automatic apply is available only for OpenCode. This provider remains manual/deferred/status-only.' };
|
|
209
|
-
if (state.selectedMemory !== 'global')
|
|
210
|
-
return {
|
|
211
|
-
...state,
|
|
212
|
-
confirmationNotice: 'Automatic OpenCode apply currently uses the default/global memory setup only. The selected memory option remains preview/manual-only.',
|
|
213
|
-
};
|
|
214
|
-
if (context.onApplyConfirmed === undefined)
|
|
215
|
-
return {
|
|
216
|
-
...state,
|
|
217
|
-
confirmationNotice: 'Apply callback is not installed in this guided preview. Use `vgxness setup apply --yes` only after reviewing the plan.',
|
|
218
|
-
};
|
|
219
|
-
const applyResult = await context.onApplyConfirmed(preview);
|
|
220
|
-
return withoutConfirmationNotice({ ...state, screen: 'apply-result', applyResult });
|
|
221
|
-
}
|
|
222
|
-
return reduceGuidedMainMenuInput(state, input);
|
|
223
|
-
}
|
|
224
|
-
function withoutConfirmationNotice(state) {
|
|
225
|
-
const { confirmationNotice: _confirmationNotice, ...rest } = state;
|
|
226
|
-
return rest;
|
|
227
|
-
}
|
|
228
|
-
function withoutApplyResult(state) {
|
|
229
|
-
const { applyResult: _applyResult, ...rest } = state;
|
|
230
|
-
return rest;
|
|
231
|
-
}
|
|
232
|
-
function renderGuidedMainMenuOption(option, selected) {
|
|
233
|
-
return `${selected ? '›' : ' '} ${option.label} — ${option.summary}`;
|
|
234
|
-
}
|
|
235
|
-
function renderGuidedInstallScreen() {
|
|
236
|
-
return `VGXNESS · Guided installation
|
|
237
|
-
|
|
238
|
-
We'll set up VGXNESS safely.
|
|
239
|
-
No files are changed until review + explicit confirmation.
|
|
240
|
-
|
|
241
|
-
Steps
|
|
242
|
-
1. Memory setup
|
|
243
|
-
2. Provider
|
|
244
|
-
3. Review
|
|
245
|
-
4. Confirm/apply
|
|
246
|
-
|
|
247
|
-
Next: choose memory setup.
|
|
248
|
-
|
|
249
|
-
Enter/n: continue · b/Esc: back · q: quit
|
|
250
|
-
`;
|
|
251
|
-
}
|
|
252
|
-
function renderMemorySelectionScreen(state, setupPreview) {
|
|
253
|
-
return `VGXNESS · Guided installation · Memory setup selection
|
|
254
|
-
|
|
255
|
-
Choose memory setup
|
|
256
|
-
${guidedMemoryOptions.map((option, index) => `${index === state.memorySelectedIndex ? '›' : ' '} ${option.label} — ${option.summary}`).join('\n')}
|
|
257
|
-
|
|
258
|
-
Preview impact
|
|
259
|
-
${renderSetupPlanPreview(setupPreview)}
|
|
260
|
-
|
|
261
|
-
Safety
|
|
262
|
-
- This selection screen is read-only and does not create or migrate memory storage.
|
|
263
|
-
- Global/default is recommended and remains the default.
|
|
264
|
-
- Skip is reflected in preview/review copy; it does not run new memory storage logic.
|
|
265
|
-
|
|
266
|
-
Keys: ↑/↓ or j/k: move · Enter: select · b/Esc: back · q: quit
|
|
267
|
-
`;
|
|
268
|
-
}
|
|
269
|
-
function renderProviderSelectionScreen(state, setupPreview) {
|
|
270
|
-
return `VGXNESS · Guided installation · Provider selection
|
|
271
|
-
|
|
272
|
-
Choose provider
|
|
273
|
-
${guidedProviderOptions.map((option, index) => `${index === state.providerSelectedIndex ? '›' : ' '} ${option.label} — ${option.summary}`).join('\n')}
|
|
274
|
-
|
|
275
|
-
Preview impact
|
|
276
|
-
${renderSetupPlanPreview(setupPreview)}
|
|
277
|
-
|
|
278
|
-
Safety
|
|
279
|
-
- OpenCode is the default and the only automatic apply-capable provider.
|
|
280
|
-
- Claude shows preview/manual guidance and never calls automatic apply.
|
|
281
|
-
- Antigravity and Custom are deferred/manual and never call automatic apply.
|
|
282
|
-
- None is planning/status-only and cannot reach provider apply.
|
|
283
|
-
|
|
284
|
-
Keys: ↑/↓ or j/k: move · Enter: review · b/Esc: back · q: quit
|
|
285
|
-
`;
|
|
286
|
-
}
|
|
287
|
-
function renderSetupReviewScreen(setupPreview, confirmationNotice) {
|
|
288
|
-
return `VGXNESS · Guided installation · Review / confirmation
|
|
289
|
-
|
|
290
|
-
Review before any write
|
|
291
|
-
${renderSetupPlanPreview(setupPreview)}
|
|
292
|
-
|
|
293
|
-
Confirmation gate
|
|
294
|
-
- No provider or memory writes have been performed.
|
|
295
|
-
- This review screen still does not run setup apply.
|
|
296
|
-
- OpenCode is the only automatic provider with a confirmed apply path.
|
|
297
|
-
- Claude remains preview/manual only; Antigravity and Custom remain manual/deferred; None remains status-only.
|
|
298
|
-
- Pressing Apply/Confirm opens one final explicit confirmation; only y on that screen can apply.
|
|
299
|
-
${confirmationNotice === undefined ? '' : `\nNotice: ${confirmationNotice}`}
|
|
300
|
-
|
|
301
|
-
If you are ready outside this guided preview, use the existing explicit command path after review:
|
|
302
|
-
vgxness init --plan
|
|
303
|
-
vgxness setup plan
|
|
304
|
-
vgxness setup apply --yes
|
|
305
|
-
|
|
306
|
-
Enter/a: confirm · b/Esc: back · q: quit
|
|
307
|
-
`;
|
|
308
|
-
}
|
|
309
|
-
function renderSetupConfirmScreen(setupPreview, confirmationNotice) {
|
|
310
|
-
return `VGXNESS · Guided installation · Explicit confirmation
|
|
311
|
-
|
|
312
|
-
Final review checkpoint
|
|
313
|
-
${renderSetupPlanPreview(setupPreview)}
|
|
314
|
-
|
|
315
|
-
Explicit confirmation required
|
|
316
|
-
- Press y only after reviewing the plan above.
|
|
317
|
-
- No files have been changed yet.
|
|
318
|
-
- Only OpenCode may use an automatic apply callback.
|
|
319
|
-
- Claude is preview/manual only; Antigravity and Custom are manual/deferred; None is status-only.
|
|
320
|
-
- If no safe apply callback is installed, y remains a no-write notice and points to the explicit CLI path.
|
|
321
|
-
${confirmationNotice === undefined ? '' : `\nNotice: ${confirmationNotice}`}
|
|
322
|
-
|
|
323
|
-
Existing explicit command path remains available after review:
|
|
324
|
-
vgxness setup apply --yes
|
|
325
|
-
|
|
326
|
-
y: apply if available · n/b/Esc: back · q: quit
|
|
327
|
-
`;
|
|
328
|
-
}
|
|
329
|
-
function renderApplyResultScreen(applyResult) {
|
|
330
|
-
if (applyResult === undefined) {
|
|
331
|
-
return `VGXNESS · Guided installation · Result summary
|
|
332
|
-
|
|
333
|
-
No apply result is available. No changes were made.
|
|
334
|
-
|
|
335
|
-
Keys: b/Esc returns to Review · q quits.
|
|
336
|
-
`;
|
|
337
|
-
}
|
|
338
|
-
return `VGXNESS · Guided installation · Result summary
|
|
339
|
-
|
|
340
|
-
Status: ${applyResult.status}
|
|
341
|
-
Summary: ${applyResult.summary}
|
|
342
|
-
|
|
343
|
-
Details
|
|
344
|
-
${applyResult.details === undefined || applyResult.details.length === 0 ? '- None.' : applyResult.details.map((detail) => `- ${detail}`).join('\n')}
|
|
345
|
-
|
|
346
|
-
Next steps
|
|
347
|
-
${applyResult.nextSteps === undefined || applyResult.nextSteps.length === 0 ? '- Run vgxness doctor.' : applyResult.nextSteps.map((step) => `- ${step}`).join('\n')}
|
|
348
|
-
|
|
349
|
-
Keys: b/Esc returns to Review · q quits.
|
|
350
|
-
`;
|
|
351
|
-
}
|
|
352
|
-
function guidedSetupPreviewForState(state, basePreview) {
|
|
353
|
-
if (basePreview === undefined)
|
|
354
|
-
return undefined;
|
|
355
|
-
const memorySelection = memorySelectionCopy(state.selectedMemory);
|
|
356
|
-
if (state.selectedProvider === 'opencode') {
|
|
357
|
-
return {
|
|
358
|
-
...basePreview,
|
|
359
|
-
provider: 'opencode',
|
|
360
|
-
memorySelection,
|
|
361
|
-
actions: state.selectedMemory === 'global'
|
|
362
|
-
? basePreview.actions
|
|
363
|
-
: [`${memorySelection}; OpenCode automatic apply is disabled until default/global memory is selected.`, ...basePreview.actions],
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
if (state.selectedProvider === 'none') {
|
|
367
|
-
return {
|
|
368
|
-
...basePreview,
|
|
369
|
-
provider: 'none',
|
|
370
|
-
memorySelection,
|
|
371
|
-
actions: ['Planning/status-only provider choice; no provider install or apply will run from guided setup.'],
|
|
372
|
-
backups: [],
|
|
373
|
-
nextCommands: ['vgxness init --plan', 'vgxness setup status', 'vgxness doctor'],
|
|
374
|
-
safety: { planMutates: false, planWritesProviderConfig: false, requiresConfirmationForApply: false },
|
|
375
|
-
};
|
|
376
|
-
}
|
|
377
|
-
const providerCopy = providerSelectionCopy(state.selectedProvider);
|
|
378
|
-
return {
|
|
379
|
-
...basePreview,
|
|
380
|
-
provider: state.selectedProvider,
|
|
381
|
-
memorySelection,
|
|
382
|
-
actions: [
|
|
383
|
-
`${providerCopy}; render manual/deferred guidance only. No automatic provider apply is available.`,
|
|
384
|
-
'Use the read-only plan to copy settings manually after reviewing existing explicit setup guidance.',
|
|
385
|
-
],
|
|
386
|
-
backups: [],
|
|
387
|
-
nextCommands: ['vgxness init --plan', 'vgxness setup plan', 'vgxness doctor'],
|
|
388
|
-
safety: { planMutates: false, planWritesProviderConfig: false, requiresConfirmationForApply: false },
|
|
389
|
-
};
|
|
390
|
-
}
|
|
391
|
-
function memorySelectionCopy(memory) {
|
|
392
|
-
if (memory === 'skip')
|
|
393
|
-
return 'Skip memory setup (no new memory storage logic)';
|
|
394
|
-
if (memory === 'project-local')
|
|
395
|
-
return 'Project-local memory (deferred/unavailable in guided setup)';
|
|
396
|
-
return 'Global/default memory (recommended)';
|
|
397
|
-
}
|
|
398
|
-
function providerSelectionCopy(provider) {
|
|
399
|
-
if (provider === 'claude')
|
|
400
|
-
return 'Claude preview/manual-only guidance';
|
|
401
|
-
if (provider === 'antigravity')
|
|
402
|
-
return 'Antigravity deferred/manual guidance';
|
|
403
|
-
if (provider === 'custom')
|
|
404
|
-
return 'Custom deferred/manual guidance';
|
|
405
|
-
if (provider === 'none')
|
|
406
|
-
return 'None planning/status-only';
|
|
407
|
-
return 'OpenCode automatic-capable after review and explicit confirmation';
|
|
408
|
-
}
|
|
409
|
-
function renderSetupPlanPreview(setupPreview) {
|
|
410
|
-
if (setupPreview === undefined) {
|
|
411
|
-
return '- Setup plan preview is unavailable in this render; run `vgxness init --plan` or `vgxness setup plan` for the read-only plan.';
|
|
412
|
-
}
|
|
413
|
-
return [
|
|
414
|
-
`- Status: ${setupPreview.status}`,
|
|
415
|
-
`- Project: ${setupPreview.project}`,
|
|
416
|
-
`- Database: ${setupPreview.databaseMode} (${setupPreview.databasePath})`,
|
|
417
|
-
`- Memory selection: ${setupPreview.memorySelection}`,
|
|
418
|
-
`- Provider: ${setupPreview.provider}`,
|
|
419
|
-
`- Safety: plan mutates=${String(setupPreview.safety.planMutates)} · plan writes provider config=${String(setupPreview.safety.planWritesProviderConfig)} · apply requires confirmation=${String(setupPreview.safety.requiresConfirmationForApply)}`,
|
|
420
|
-
'- Planned actions:',
|
|
421
|
-
...(setupPreview.actions.length === 0 ? [' - None.'] : setupPreview.actions.map((action) => ` - ${action}`)),
|
|
422
|
-
'- Conflicts:',
|
|
423
|
-
...(setupPreview.conflicts.length === 0 ? [' - None.'] : setupPreview.conflicts.map((conflict) => ` - ${conflict}`)),
|
|
424
|
-
'- Backups if apply is later confirmed:',
|
|
425
|
-
...(setupPreview.backups.length === 0 ? [' - None.'] : setupPreview.backups.map((backup) => ` - ${backup}`)),
|
|
426
|
-
'- Existing explicit command path:',
|
|
427
|
-
...setupPreview.nextCommands.map((command) => ` - ${command}`),
|
|
428
|
-
].join('\n');
|
|
429
|
-
}
|
|
430
|
-
function renderDoctorRecoveryScreen() {
|
|
431
|
-
return `VGXNESS · Doctor / recovery
|
|
432
|
-
|
|
433
|
-
Read-only recovery entry
|
|
434
|
-
Use doctor/status commands to inspect provider visibility, memory/default DB status, and setup readiness.
|
|
435
|
-
|
|
436
|
-
Suggested commands
|
|
437
|
-
vgxness doctor
|
|
438
|
-
vgxness setup status
|
|
439
|
-
vgxness mcp doctor opencode
|
|
440
|
-
|
|
441
|
-
Safety
|
|
442
|
-
- Opening this screen does not run repairs or provider writes.
|
|
443
|
-
- Any future rollback/recovery write must require its own explicit command and confirmation.
|
|
444
|
-
- If setup is missing, run Guided installation or inspect a setup plan first.
|
|
445
|
-
|
|
446
|
-
Keys: b/Esc returns to menu · q quits. No changes were made.
|
|
447
|
-
`;
|
|
448
|
-
}
|
|
449
|
-
function renderAdvancedCliScreen() {
|
|
450
|
-
return `VGXNESS · Advanced CLI
|
|
451
|
-
|
|
452
|
-
The CLI remains available for setup, doctor, rollback/recovery, and advanced/manual workflows.
|
|
453
|
-
After setup, daily SDD work should happen inside OpenCode, Claude, or another configured provider.
|
|
454
|
-
|
|
455
|
-
Common commands
|
|
456
|
-
vgxness init
|
|
457
|
-
vgxness init --plan
|
|
458
|
-
vgxness setup plan
|
|
459
|
-
vgxness setup apply --yes
|
|
460
|
-
vgxness setup status
|
|
461
|
-
vgxness doctor
|
|
462
|
-
vgxness --help
|
|
463
|
-
|
|
464
|
-
Safety
|
|
465
|
-
- This screen is guidance only and does not execute setup/apply commands.
|
|
466
|
-
- Provider writes remain behind explicit setup/apply commands and confirmation.
|
|
467
|
-
|
|
468
|
-
Keys: b/Esc returns to menu · q quits. No changes were made.
|
|
469
|
-
`;
|
|
470
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
export function buildSetupWizardReadModel(status) {
|
|
2
|
-
const noProject = status.projectState.mode === 'none';
|
|
3
|
-
const modelStatus = noProject ? 'ready-without-project' : status.verification.status === 'ready' ? 'ready' : 'blocked';
|
|
4
|
-
return {
|
|
5
|
-
status: modelStatus,
|
|
6
|
-
projectMode: noProject ? 'none' : 'selected',
|
|
7
|
-
...(status.project === undefined ? {} : { project: status.project }),
|
|
8
|
-
summary: noProject ? 'Environment and provider setup can continue; project-scoped checks are deferred, not failed.' : status.verification.summary,
|
|
9
|
-
steps: [
|
|
10
|
-
{ id: 'environment', label: 'Environment', status: readinessToSection(status.environment.status), summary: status.environment.summary },
|
|
11
|
-
{
|
|
12
|
-
id: 'project',
|
|
13
|
-
label: 'Project',
|
|
14
|
-
status: status.projectState.status === 'deferred' ? 'deferred' : readinessToSection(status.projectState.status),
|
|
15
|
-
summary: status.projectState.summary,
|
|
16
|
-
},
|
|
17
|
-
{
|
|
18
|
-
id: 'providers',
|
|
19
|
-
label: 'Providers',
|
|
20
|
-
status: 'ready',
|
|
21
|
-
summary: `${status.providers.length} provider targets: ${status.providers.map((provider) => provider.displayName).join(', ')}.`,
|
|
22
|
-
},
|
|
23
|
-
{
|
|
24
|
-
id: 'agents',
|
|
25
|
-
label: 'Agents',
|
|
26
|
-
status: status.agents.deferred ? 'deferred' : readinessToSection(status.agents.status),
|
|
27
|
-
summary: status.agents.deferred
|
|
28
|
-
? 'Project-scoped manager/profile checks are deferred until a project is selected.'
|
|
29
|
-
: (status.agents.blocker ?? 'Default manager/profile context is available.'),
|
|
30
|
-
},
|
|
31
|
-
{ id: 'verification', label: 'Verification', status: readinessToSection(status.verification.status), summary: status.verification.summary },
|
|
32
|
-
],
|
|
33
|
-
providerCards: status.providers.map((provider) => ({
|
|
34
|
-
id: provider.providerId,
|
|
35
|
-
label: provider.displayName,
|
|
36
|
-
supportLevel: provider.supportLevel,
|
|
37
|
-
status: provider.status,
|
|
38
|
-
summary: provider.summary,
|
|
39
|
-
capabilities: provider.capabilities,
|
|
40
|
-
targets: provider.targets,
|
|
41
|
-
guidance: provider.guidance,
|
|
42
|
-
evidence: provider.evidence,
|
|
43
|
-
...(provider.preview === undefined ? {} : { preview: provider.preview }),
|
|
44
|
-
actions: provider.actions.map((action) => ({ ...action, safetyLabels: safetyLabels(action) })),
|
|
45
|
-
})),
|
|
46
|
-
safetySummary: [
|
|
47
|
-
'Read model is status/preview data only; renderers can consume it without side effects.',
|
|
48
|
-
'External or mutating provider actions are data-only and must be copied/run outside the TUI.',
|
|
49
|
-
],
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
function readinessToSection(status) {
|
|
53
|
-
if (status === 'ready')
|
|
54
|
-
return 'ready';
|
|
55
|
-
if (status === 'blocked')
|
|
56
|
-
return 'blocked';
|
|
57
|
-
return 'empty';
|
|
58
|
-
}
|
|
59
|
-
function safetyLabels(action) {
|
|
60
|
-
const labels = [];
|
|
61
|
-
if (action.safety.externalOnly)
|
|
62
|
-
labels.push('External');
|
|
63
|
-
if (action.safety.mutating)
|
|
64
|
-
labels.push('Mutating');
|
|
65
|
-
if (action.safety.writesProviderConfig)
|
|
66
|
-
labels.push('Writes provider config');
|
|
67
|
-
if (action.safety.requiresExplicitConfirmation)
|
|
68
|
-
labels.push('Requires explicit confirmation');
|
|
69
|
-
if (!action.safety.writesProviderConfig && !action.safety.mutating)
|
|
70
|
-
labels.push('No provider writes');
|
|
71
|
-
return labels;
|
|
72
|
-
}
|