vgxness 1.2.1 → 1.3.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.
Files changed (85) hide show
  1. package/README.md +20 -19
  2. package/dist/cli/cli-help.js +4 -7
  3. package/dist/cli/commands/index.js +1 -1
  4. package/dist/cli/commands/interactive-entrypoint-dispatcher.js +150 -0
  5. package/dist/cli/commands/setup-dispatcher.js +11 -8
  6. package/dist/cli/dispatcher.js +1 -8
  7. package/dist/cli/doctor-renderer.js +1 -1
  8. package/dist/cli/index.js +0 -0
  9. package/dist/cli/sdd-renderer.js +7 -7
  10. package/dist/cli/setup-status-renderer.js +1 -0
  11. package/dist/cli/tui/main-menu/index.js +0 -1
  12. package/dist/cli/tui/main-menu/main-menu-controller.js +0 -2
  13. package/dist/cli/tui/main-menu/main-menu-read-model.js +10 -8
  14. package/dist/cli/tui/main-menu/main-menu-render-shape.js +19 -2
  15. package/dist/cli/tui/main-menu/main-menu-state.js +1 -1
  16. package/dist/cli/tui/opentui/code/index.js +210 -0
  17. package/dist/cli/tui/opentui/code/screen.js +107 -0
  18. package/dist/cli/tui/opentui/code/smoke.js +32 -0
  19. package/dist/cli/tui/opentui/main-menu/index.js +3 -0
  20. package/dist/cli/tui/opentui/main-menu/renderer.js +68 -0
  21. package/dist/cli/tui/opentui/main-menu/screen.js +68 -0
  22. package/dist/cli/tui/opentui/main-menu/smoke.js +17 -0
  23. package/dist/cli/tui/opentui/main-menu/view.js +8 -0
  24. package/dist/cli/tui/opentui/setup/index.js +3 -0
  25. package/dist/cli/tui/opentui/setup/renderer.js +87 -0
  26. package/dist/cli/tui/opentui/setup/screen.js +170 -0
  27. package/dist/cli/tui/opentui/setup/smoke.js +42 -0
  28. package/dist/cli/tui/opentui/setup/view.js +12 -0
  29. package/dist/cli/tui/setup/setup-tui-input.js +43 -0
  30. package/dist/cli/tui/setup/setup-tui-read-model.js +4 -4
  31. package/dist/cli/tui/setup/setup-tui-render-shape.js +9 -10
  32. package/dist/cli/tui/setup/setup-tui-state.js +1 -1
  33. package/dist/cli/tui/setup/setup-tui-view-helpers.js +46 -0
  34. package/dist/cli/tui/visual/index.js +0 -2
  35. package/dist/code/runtime/sdd-context.js +2 -2
  36. package/dist/code/tui/approval-actions.js +33 -0
  37. package/dist/code/tui/prompt-mode.js +11 -0
  38. package/dist/code/tui/runtime-events.js +320 -0
  39. package/dist/mcp/validation.js +6 -2
  40. package/dist/orchestrator/natural-language-planner.js +1 -1
  41. package/dist/sdd/sdd-workflow-service.js +1 -25
  42. package/dist/setup/backup-rollback-service.js +2 -2
  43. package/dist/setup/providers/antigravity-setup-adapter.js +1 -1
  44. package/dist/setup/providers/claude-setup-adapter.js +2 -2
  45. package/dist/setup/providers/custom-setup-adapter.js +1 -1
  46. package/dist/setup/providers/opencode-setup-adapter.js +3 -3
  47. package/dist/setup/setup-lifecycle-service.js +6 -6
  48. package/dist/setup/setup-plan.js +3 -3
  49. package/dist/verification/verification-plan-service.js +1 -1
  50. package/docs/architecture.md +43 -42
  51. package/docs/cli.md +141 -133
  52. package/docs/funcionamiento-del-sistema.md +22 -23
  53. package/docs/harness-gap-analysis.md +15 -1
  54. package/docs/prd.md +14 -14
  55. package/docs/vgxcode.md +87 -0
  56. package/docs/vgxness-code.md +6 -4
  57. package/package.json +5 -6
  58. package/dist/cli/commands/dashboard-dispatcher.js +0 -560
  59. package/dist/cli/dashboard-operational-read-models.js +0 -428
  60. package/dist/cli/dashboard-renderer.js +0 -158
  61. package/dist/cli/dashboard-screen-renderers.js +0 -256
  62. package/dist/cli/dashboard-tui-read-model.js +0 -73
  63. package/dist/cli/dashboard-tui-state.js +0 -314
  64. package/dist/cli/guided-main-menu.js +0 -470
  65. package/dist/cli/interactive-dashboard.js +0 -34
  66. package/dist/cli/setup-wizard-read-model.js +0 -72
  67. package/dist/cli/setup-wizard-renderer.js +0 -155
  68. package/dist/cli/setup-wizard-state.js +0 -82
  69. package/dist/cli/tui/dashboard/dashboard-adapter.js +0 -4
  70. package/dist/cli/tui/main-menu/main-menu-app.js +0 -28
  71. package/dist/cli/tui/render-ink-app.js +0 -10
  72. package/dist/cli/tui/setup/screens/applying-screen.js +0 -6
  73. package/dist/cli/tui/setup/screens/cancellation-screen.js +0 -6
  74. package/dist/cli/tui/setup/screens/error-recovery-screen.js +0 -6
  75. package/dist/cli/tui/setup/screens/final-confirmation-screen.js +0 -6
  76. package/dist/cli/tui/setup/screens/opencode-details-screen.js +0 -10
  77. package/dist/cli/tui/setup/screens/plan-review-screen.js +0 -6
  78. package/dist/cli/tui/setup/screens/project-database-screen.js +0 -6
  79. package/dist/cli/tui/setup/screens/provider-screen.js +0 -7
  80. package/dist/cli/tui/setup/screens/result-screen.js +0 -16
  81. package/dist/cli/tui/setup/screens/screen-components.js +0 -103
  82. package/dist/cli/tui/setup/screens/welcome-screen.js +0 -6
  83. package/dist/cli/tui/setup/setup-tui-app.js +0 -113
  84. package/dist/cli/tui/visual/choice-list.js +0 -10
  85. package/dist/cli/tui/visual/layout.js +0 -10
@@ -0,0 +1,320 @@
1
+ export function sampleEvents(now = new Date('2026-05-26T23:30:00.000Z')) {
2
+ const createdAt = now.toISOString();
3
+ return [
4
+ {
5
+ type: 'session.started',
6
+ projectRoot: 'vgxness',
7
+ userIntent: 'Build the vgxcode OpenTUI shell',
8
+ createdAt,
9
+ },
10
+ {
11
+ type: 'provider.message',
12
+ content: 'I will inspect the runtime event stream and prepare a safe UI shell.',
13
+ toolCallCount: 1,
14
+ createdAt,
15
+ },
16
+ {
17
+ type: 'tool.requested',
18
+ toolName: 'read_file',
19
+ createdAt,
20
+ },
21
+ {
22
+ type: 'tool.completed',
23
+ toolName: 'read_file',
24
+ ok: true,
25
+ changedFiles: [],
26
+ createdAt,
27
+ },
28
+ {
29
+ type: 'verification.completed',
30
+ status: 'not-run',
31
+ reason: 'Static shell preview; no runtime commands executed.',
32
+ createdAt,
33
+ },
34
+ {
35
+ type: 'session.completed',
36
+ status: 'completed',
37
+ outcome: 'success',
38
+ createdAt,
39
+ },
40
+ ];
41
+ }
42
+ export function parseVgxcodeJsonl(input) {
43
+ const events = [];
44
+ const errors = [];
45
+ const lines = input.split(/\r?\n/);
46
+ for (const [index, line] of lines.entries()) {
47
+ const trimmed = line.trim();
48
+ if (!trimmed)
49
+ continue;
50
+ try {
51
+ const parsed = JSON.parse(trimmed);
52
+ if (isVgxcodeEvent(parsed))
53
+ events.push(parsed);
54
+ else
55
+ errors.push(formatUnsupportedRuntimeEvent(parsed, index + 1));
56
+ }
57
+ catch (error) {
58
+ errors.push(`Line ${index + 1}: ${formatJsonlParseError(trimmed, error)}`);
59
+ }
60
+ }
61
+ return { events, errors };
62
+ }
63
+ export function parseVgxcodeJsonlLine(line, lineNumber) {
64
+ const trimmed = line.trim();
65
+ if (!trimmed)
66
+ return {};
67
+ try {
68
+ const parsed = JSON.parse(trimmed);
69
+ if (isVgxcodeEvent(parsed))
70
+ return { event: parsed };
71
+ return { error: formatUnsupportedRuntimeEvent(parsed, lineNumber) };
72
+ }
73
+ catch (error) {
74
+ return { error: `Line ${lineNumber}: ${formatJsonlParseError(trimmed, error)}` };
75
+ }
76
+ }
77
+ function formatJsonlParseError(line, error) {
78
+ const reason = error instanceof Error ? error.message : 'invalid JSON';
79
+ const looksLikeNpmBanner = line.startsWith('>') || line.includes('npm') || line.includes('run-script');
80
+ const snippet = line.length > 80 ? `${line.slice(0, 77)}...` : line;
81
+ return looksLikeNpmBanner
82
+ ? `${reason} (non-JSON output; use npm --silent for the bridge; got: ${snippet})`
83
+ : `${reason} (invalid JSONL; got: ${snippet})`;
84
+ }
85
+ function formatUnsupportedRuntimeEvent(value, lineNumber) {
86
+ const type = isRecord(value) && typeof value.type === 'string' ? value.type : 'missing type';
87
+ return `Line ${lineNumber}: unsupported runtime event (${type}); expected vgxcode read-only JSONL event`;
88
+ }
89
+ export function summarizeEvent(event) {
90
+ switch (event.type) {
91
+ case 'session.started':
92
+ return `◇ Session started — ${event.userIntent}`;
93
+ case 'prompt.accepted':
94
+ return `◇ Prompt accepted — ${event.messageCount} messages, ${event.toolCount} tools`;
95
+ case 'provider.message':
96
+ return `● Assistant — ${event.content}`;
97
+ case 'tool.requested':
98
+ return `▸ Tool requested — ${event.toolName}`;
99
+ case 'approval.pending':
100
+ return `! Approval pending — ${event.toolName}`;
101
+ case 'approval.decided':
102
+ return `! Approval ${event.final} — ${event.toolName}: ${event.reason}`;
103
+ case 'approval.decision_rejected':
104
+ return `! Approval decision rejected — ${event.bindingResult}: ${event.reason}`;
105
+ case 'approval.preview':
106
+ return `! Approval preview — ${event.toolName}: No mutation executed`;
107
+ case 'tool.completed':
108
+ return `${event.ok ? '✓' : '✕'} Tool completed — ${event.toolName}`;
109
+ case 'diff.preview':
110
+ return `◇ Diff preview — ${event.files.length} files, ${event.bodyBytes}/${event.originalBytes} bytes${event.truncated ? ' (truncated)' : ''}`;
111
+ case 'verification.completed':
112
+ return `${event.status === 'passed' ? '✓' : event.status === 'failed' ? '✕' : '·'} Verification — ${event.reason}`;
113
+ case 'session.completed':
114
+ return `◆ Session ${event.status} — ${event.outcome}`;
115
+ case 'session.failed':
116
+ return `✕ Session ${event.status} — ${event.message}`;
117
+ }
118
+ }
119
+ export function buildSafetyReadModel(events) {
120
+ const pendingApprovals = new Map();
121
+ let latestApprovalDecision;
122
+ let latestApprovalPreview;
123
+ const changedFiles = [];
124
+ const seenChangedFiles = new Set();
125
+ let latestDiffPreview;
126
+ for (const event of events) {
127
+ switch (event.type) {
128
+ case 'approval.pending':
129
+ if (event.approvalId === undefined || event.toolCallId === undefined)
130
+ break;
131
+ pendingApprovals.set(approvalKey(event.approvalId, event.toolCallId), {
132
+ ...(event.approvalId === undefined ? {} : { approvalId: event.approvalId }),
133
+ ...(event.toolCallId === undefined ? {} : { toolCallId: event.toolCallId }),
134
+ toolName: event.toolName,
135
+ ...(event.operationSummary === undefined ? {} : { operationSummary: event.operationSummary }),
136
+ ...(event.targetPath === undefined ? {} : { targetPath: event.targetPath }),
137
+ ...(event.risk === undefined ? {} : { risk: event.risk }),
138
+ createdAt: event.createdAt,
139
+ });
140
+ break;
141
+ case 'approval.decided':
142
+ if (event.approvalId !== undefined && event.toolCallId !== undefined)
143
+ pendingApprovals.delete(approvalKey(event.approvalId, event.toolCallId));
144
+ latestApprovalDecision = {
145
+ ...(event.approvalId === undefined ? {} : { approvalId: event.approvalId }),
146
+ ...(event.toolCallId === undefined ? {} : { toolCallId: event.toolCallId }),
147
+ toolName: event.toolName,
148
+ ...(event.status === undefined ? {} : { status: event.status }),
149
+ final: event.final,
150
+ reason: event.reason,
151
+ createdAt: event.createdAt,
152
+ };
153
+ break;
154
+ case 'approval.decision_rejected':
155
+ if (event.approvalId !== undefined && event.toolCallId !== undefined && isResolvingDecisionRejection(event.bindingResult)) {
156
+ pendingApprovals.delete(approvalKey(event.approvalId, event.toolCallId));
157
+ }
158
+ break;
159
+ case 'approval.preview':
160
+ latestApprovalPreview = {
161
+ toolName: event.toolName,
162
+ capability: event.capability,
163
+ ...(event.targetPath === undefined ? {} : { targetPath: event.targetPath }),
164
+ reason: event.reason,
165
+ risk: event.risk,
166
+ createdAt: event.createdAt,
167
+ };
168
+ break;
169
+ case 'tool.completed':
170
+ for (const changedFile of event.changedFiles) {
171
+ if (seenChangedFiles.has(changedFile))
172
+ continue;
173
+ seenChangedFiles.add(changedFile);
174
+ changedFiles.push(changedFile);
175
+ }
176
+ break;
177
+ case 'diff.preview':
178
+ latestDiffPreview = {
179
+ files: event.files,
180
+ body: event.body,
181
+ bodyBytes: event.bodyBytes,
182
+ originalBytes: event.originalBytes,
183
+ truncated: event.truncated,
184
+ redacted: event.redacted,
185
+ hash: event.hash,
186
+ createdAt: event.createdAt,
187
+ };
188
+ for (const file of event.files) {
189
+ if (seenChangedFiles.has(file))
190
+ continue;
191
+ seenChangedFiles.add(file);
192
+ changedFiles.push(file);
193
+ }
194
+ break;
195
+ default:
196
+ break;
197
+ }
198
+ }
199
+ const pendingApprovalValues = [...pendingApprovals.values()];
200
+ const latestPendingApproval = pendingApprovalValues.at(-1);
201
+ return {
202
+ pendingApprovals: pendingApprovalValues,
203
+ pendingApprovalCount: pendingApprovalValues.length,
204
+ ...(latestPendingApproval ? { latestPendingApproval } : {}),
205
+ ...(latestApprovalDecision ? { latestApprovalDecision } : {}),
206
+ ...(latestApprovalPreview ? { latestApprovalPreview } : {}),
207
+ changedFiles,
208
+ diffAvailability: latestDiffPreview !== undefined ? 'preview' : changedFiles.length > 0 ? 'filenames-only' : 'none',
209
+ ...(latestDiffPreview ? { latestDiffPreview } : {}),
210
+ };
211
+ }
212
+ function isVgxcodeEvent(value) {
213
+ if (!isRecord(value) || typeof value.type !== 'string' || typeof value.createdAt !== 'string')
214
+ return false;
215
+ switch (value.type) {
216
+ case 'session.started':
217
+ return typeof value.projectRoot === 'string' && typeof value.userIntent === 'string';
218
+ case 'prompt.accepted':
219
+ return typeof value.messageCount === 'number' && typeof value.toolCount === 'number';
220
+ case 'provider.message':
221
+ return typeof value.content === 'string' && typeof value.toolCallCount === 'number';
222
+ case 'tool.requested':
223
+ return typeof value.toolName === 'string';
224
+ case 'approval.pending':
225
+ return typeof value.toolName === 'string' && isOptionalApprovalContext(value);
226
+ case 'approval.decided':
227
+ return (typeof value.toolName === 'string' &&
228
+ typeof value.reason === 'string' &&
229
+ isApprovalFinal(value.final) &&
230
+ (value.approvalId === undefined || typeof value.approvalId === 'string') &&
231
+ (value.toolCallId === undefined || typeof value.toolCallId === 'string') &&
232
+ (value.status === undefined || isApprovalStatus(value.status)));
233
+ case 'approval.decision_rejected':
234
+ return (typeof value.reason === 'string' &&
235
+ isApprovalDecisionBindingResult(value.bindingResult) &&
236
+ (value.approvalId === undefined || typeof value.approvalId === 'string') &&
237
+ (value.toolCallId === undefined || typeof value.toolCallId === 'string') &&
238
+ (value.status === undefined || value.status === 'approved' || value.status === 'denied'));
239
+ case 'approval.preview':
240
+ return (typeof value.toolCallId === 'string' &&
241
+ typeof value.toolName === 'string' &&
242
+ isCapability(value.capability) &&
243
+ isRecord(value.risk) &&
244
+ typeof value.risk.mutatesWorkspace === 'boolean' &&
245
+ typeof value.risk.requiresApproval === 'boolean' &&
246
+ value.reason === 'preview_only' &&
247
+ (value.targetPath === undefined || typeof value.targetPath === 'string'));
248
+ case 'tool.completed':
249
+ return typeof value.toolName === 'string' && typeof value.ok === 'boolean' && Array.isArray(value.changedFiles) && value.changedFiles.every((changedFile) => typeof changedFile === 'string');
250
+ case 'diff.preview':
251
+ return (typeof value.sourceToolCallId === 'string' &&
252
+ value.sourceToolName === 'git_diff' &&
253
+ value.format === 'unified' &&
254
+ Array.isArray(value.files) &&
255
+ value.files.every((file) => typeof file === 'string') &&
256
+ typeof value.body === 'string' &&
257
+ typeof value.bodyBytes === 'number' &&
258
+ typeof value.originalBytes === 'number' &&
259
+ typeof value.truncated === 'boolean' &&
260
+ typeof value.redacted === 'boolean' &&
261
+ typeof value.hash === 'string');
262
+ case 'verification.completed':
263
+ return isVerificationStatus(value.status) && typeof value.reason === 'string';
264
+ case 'session.completed':
265
+ return isSessionStatus(value.status) && isOutcome(value.outcome);
266
+ case 'session.failed':
267
+ return isFailedSessionStatus(value.status) && typeof value.message === 'string';
268
+ default:
269
+ return false;
270
+ }
271
+ }
272
+ function isRecord(value) {
273
+ return typeof value === 'object' && value !== null;
274
+ }
275
+ function isApprovalFinal(value) {
276
+ return value === 'allow' || value === 'deny' || value === 'blocked';
277
+ }
278
+ function isApprovalStatus(value) {
279
+ return value === 'approved' || value === 'denied' || value === 'blocked' || value === 'cancelled' || value === 'timed_out';
280
+ }
281
+ function isApprovalDecisionBindingResult(value) {
282
+ return value === 'malformed' || value === 'unknown' || value === 'binding_mismatch' || value === 'duplicate' || value === 'stale' || value === 'invalid_status' || value === 'cancelled';
283
+ }
284
+ function isResolvingDecisionRejection(bindingResult) {
285
+ return bindingResult === 'duplicate' || bindingResult === 'stale' || bindingResult === 'cancelled';
286
+ }
287
+ function approvalKey(approvalId, toolCallId) {
288
+ return `${approvalId}:${toolCallId}`;
289
+ }
290
+ function isOptionalApprovalContext(value) {
291
+ return ((value.approvalId === undefined || typeof value.approvalId === 'string') &&
292
+ (value.toolCallId === undefined || typeof value.toolCallId === 'string') &&
293
+ (value.operationSummary === undefined || typeof value.operationSummary === 'string') &&
294
+ (value.targetPath === undefined || typeof value.targetPath === 'string') &&
295
+ (value.risk === undefined || isApprovalRisk(value.risk)));
296
+ }
297
+ function isApprovalRisk(value) {
298
+ return (isRecord(value) &&
299
+ typeof value.mutatesWorkspace === 'boolean' &&
300
+ typeof value.requiresApproval === 'boolean' &&
301
+ (value.destructive === undefined || typeof value.destructive === 'boolean') &&
302
+ (value.external === undefined || typeof value.external === 'boolean') &&
303
+ (value.privileged === undefined || typeof value.privileged === 'boolean') &&
304
+ (value.ambiguous === undefined || typeof value.ambiguous === 'boolean'));
305
+ }
306
+ function isCapability(value) {
307
+ return value === 'read' || value === 'edit' || value === 'shell' || value === 'git' || value === 'network' || value === 'memory' || value === 'sdd' || value === 'run' || value === 'mcp';
308
+ }
309
+ function isVerificationStatus(value) {
310
+ return value === 'not-run' || value === 'passed' || value === 'failed';
311
+ }
312
+ function isSessionStatus(value) {
313
+ return value === 'completed' || value === 'partial' || value === 'blocked' || value === 'failed' || value === 'cancelled';
314
+ }
315
+ function isFailedSessionStatus(value) {
316
+ return value === 'blocked' || value === 'failed' || value === 'cancelled';
317
+ }
318
+ function isOutcome(value) {
319
+ return value === 'success' || value === 'partial' || value === 'failure' || value === 'blocked' || value === 'cancelled';
320
+ }
@@ -244,7 +244,7 @@ function readProjectAndChange(record, tool) {
244
244
  return { ok: true, value: { project: project.value, change: change.value } };
245
245
  }
246
246
  function validateSddReadyInput(input, tool) {
247
- const record = inputRecord(input, tool, ['project', 'change', 'phase']);
247
+ const record = inputRecord(input, tool, ['project', 'change', 'phase', 'runId', 'agentId']);
248
248
  if (!record.ok)
249
249
  return record;
250
250
  const base = readProjectAndChange(record.value, tool);
@@ -253,7 +253,11 @@ function validateSddReadyInput(input, tool) {
253
253
  const phase = readPhase(record.value, tool);
254
254
  if (!phase.ok)
255
255
  return phase;
256
- return { ok: true, value: { ...base.value, phase: phase.value } };
256
+ const result = { ...base.value, phase: phase.value };
257
+ const copied = copyOptionalStrings(result, record.value, tool, ['runId', 'agentId']);
258
+ if (!copied.ok)
259
+ return copied;
260
+ return { ok: true, value: result };
257
261
  }
258
262
  function validateSddGetReadinessInput(input, tool) {
259
263
  return validateSddReadyInput(input, tool);
@@ -226,7 +226,7 @@ function buildPreviewActions(input, flow, needsClarification) {
226
226
  if (flow === 'build')
227
227
  return [{ kind: 'workflow-preview', description: 'Preview a scoped build workflow; no execution occurs in this planner response.' }];
228
228
  const change = input.change;
229
- const command = change === undefined ? undefined : `npm run cli -- sdd next --project ${input.project} --change ${change}`;
229
+ const command = change === undefined ? undefined : `vgxness sdd next --project ${input.project} --change ${change}`;
230
230
  return [
231
231
  {
232
232
  kind: 'sdd-preview',
@@ -38,30 +38,6 @@ export class SddWorkflowService {
38
38
  const phases = this.getPhaseStatuses(validated.value.project, validated.value.change);
39
39
  return statusFromPhases(validated.value.change, phases);
40
40
  }
41
- getDashboardStatus(input) {
42
- const validated = validateProjectAndChange(input.project, input.change);
43
- if (!validated.ok)
44
- return validated;
45
- const phases = this.getPhaseStatusesNoTrace(validated.value.project, validated.value.change);
46
- if (!phases.ok)
47
- return phases;
48
- return statusFromPhases(validated.value.change, phases.value);
49
- }
50
- getPhaseStatusesNoTrace(project, change) {
51
- const statuses = [];
52
- for (const phase of sddPhases) {
53
- const topicKey = sddTopicKey(change, phase);
54
- const artifact = this.memory.getArtifactNoTrace(project, topicKey);
55
- if (!artifact.ok) {
56
- if (artifact.error.code !== 'not_found')
57
- return artifact;
58
- statuses.push({ phase, topicKey, present: false, state: 'missing', accepted: false, legacy: false });
59
- continue;
60
- }
61
- statuses.push(phaseStatusFromArtifact(phase, topicKey, artifact.value));
62
- }
63
- return { ok: true, value: statuses };
64
- }
65
41
  getNext(input) {
66
42
  const validated = validateProjectAndChange(input.project, input.change);
67
43
  if (!validated.ok)
@@ -120,7 +96,7 @@ export class SddWorkflowService {
120
96
  acceptedCount: cockpitPhases.filter((phase) => phase.accepted).length,
121
97
  legacyCount: cockpitPhases.filter((phase) => phase.legacy).length,
122
98
  aggregateBlockers,
123
- inspectCommand: `vgx sdd cockpit --project ${validated.value.project} --change ${validated.value.change} --json`,
99
+ inspectCommand: `vgxness sdd cockpit --project ${validated.value.project} --change ${validated.value.change} --json`,
124
100
  };
125
101
  return ok(cockpit);
126
102
  }
@@ -81,7 +81,7 @@ export function previewRollbackConfigBackup(input) {
81
81
  restorable: blockers.length === 0 && targetPath !== undefined,
82
82
  blockers,
83
83
  warnings,
84
- nextCommands: blockers.length === 0 ? [`vgx setup rollback --backup ${backupPath} --yes`] : ['Resolve blockers, then rerun rollback preview.'],
84
+ nextCommands: blockers.length === 0 ? [`vgxness setup rollback --backup ${backupPath} --yes`] : ['Resolve blockers, then rerun rollback preview.'],
85
85
  },
86
86
  };
87
87
  }
@@ -133,7 +133,7 @@ export function applyRollbackConfigBackup(input) {
133
133
  targetPath,
134
134
  ...(preRollbackBackup === undefined ? {} : { preRollbackBackupPath: preRollbackBackup.backupPath, preRollbackBackup }),
135
135
  backup: preview.value.backup,
136
- nextCommands: ['vgx doctor', 'Restart OpenCode and verify the vgxness MCP server is visible.'],
136
+ nextCommands: ['vgxness doctor', 'Restart OpenCode and verify the vgxness MCP server is visible.'],
137
137
  },
138
138
  };
139
139
  }
@@ -4,7 +4,7 @@ export const antigravitySetupAdapter = {
4
4
  displayName: 'Antigravity',
5
5
  supportLevel: 'placeholder',
6
6
  capabilities: ['manual-guidance'],
7
- targets: [{ kind: 'manual', label: 'Coming soon manual guidance', writableByDashboard: false }],
7
+ targets: [{ kind: 'manual', label: 'Coming soon manual guidance', writableBySetup: false }],
8
8
  getStatus() {
9
9
  return {
10
10
  providerId: 'antigravity',
@@ -5,7 +5,7 @@ export const claudeSetupAdapter = {
5
5
  displayName: 'Claude',
6
6
  supportLevel: 'preview-only',
7
7
  capabilities: ['mcp-preview', 'manual-guidance'],
8
- targets: [{ kind: 'manual', label: 'Claude MCP config snippet', writableByDashboard: false }],
8
+ targets: [{ kind: 'manual', label: 'Claude MCP config snippet', writableBySetup: false }],
9
9
  getStatus(context) {
10
10
  return {
11
11
  providerId: 'claude',
@@ -14,7 +14,7 @@ export const claudeSetupAdapter = {
14
14
  evidence: context.databasePath !== undefined
15
15
  ? ['Claude MCP preview can be generated from the selected database path.']
16
16
  : ['Claude MCP preview uses a placeholder until a database path is selected.'],
17
- guidance: ['Copy snippets manually after reviewing them. The dashboard does not install or apply Claude config.'],
17
+ guidance: ['Copy snippets manually after reviewing them. The TUI does not install or apply Claude config.'],
18
18
  actions: [
19
19
  {
20
20
  id: 'claude-manual-guidance',
@@ -4,7 +4,7 @@ export const customSetupAdapter = {
4
4
  displayName: 'Custom',
5
5
  supportLevel: 'extension-point',
6
6
  capabilities: ['manual-guidance'],
7
- targets: [{ kind: 'extension', label: 'Custom provider extension point', writableByDashboard: false }],
7
+ targets: [{ kind: 'extension', label: 'Custom provider extension point', writableBySetup: false }],
8
8
  getStatus() {
9
9
  return {
10
10
  providerId: 'custom',
@@ -8,8 +8,8 @@ export const openCodeSetupAdapter = {
8
8
  supportLevel: 'supported-primary',
9
9
  capabilities: ['mcp-preview', 'mcp-install-plan', 'mcp-install-apply-external', 'agent-preview', 'doctor', 'visibility-check'],
10
10
  targets: [
11
- { kind: 'user-config', label: 'User/global OpenCode config (default)', path: '$HOME/.config/opencode/opencode.json', writableByDashboard: false },
12
- { kind: 'project-config', label: 'Project OpenCode config (explicit opt-in)', path: '.opencode/opencode.json', writableByDashboard: false },
11
+ { kind: 'user-config', label: 'User/global OpenCode config (default)', path: '$HOME/.config/opencode/opencode.json', writableBySetup: false },
12
+ { kind: 'project-config', label: 'Project OpenCode config (explicit opt-in)', path: '.opencode/opencode.json', writableBySetup: false },
13
13
  ],
14
14
  getStatus(context) {
15
15
  const visibility = this.getVisibility?.(context);
@@ -161,7 +161,7 @@ function externalInstallAction(scope, targetPath) {
161
161
  label: `Copy external OpenCode ${scope === 'user' ? 'user/global' : 'project'} install command`,
162
162
  kind: 'copy-command',
163
163
  command: ['vgxness', 'mcp', 'install', 'opencode', '--scope', scope, '--yes'],
164
- description: 'Copy and run this outside the dashboard only after reviewing the read-only plan.',
164
+ description: 'Copy and run this outside the TUI only after reviewing the read-only plan.',
165
165
  safety: externalProviderWriteSafety(targetPath),
166
166
  };
167
167
  }
@@ -74,7 +74,7 @@ function storeStatus(result) {
74
74
  status: 'blocked',
75
75
  path: '',
76
76
  blocker: result.error.message,
77
- recovery: 'Run `vgx doctor` and verify the configured local memory path is writable.',
77
+ recovery: 'Run `vgxness doctor` and verify the configured local memory path is writable.',
78
78
  };
79
79
  }
80
80
  function mcpStatus(result, storeReadiness) {
@@ -178,17 +178,17 @@ function verificationSummary(environment, project, providers, agents, mcp) {
178
178
  }
179
179
  function nextAction(store, mcp, defaults, providers, project) {
180
180
  if (store.status !== 'ready') {
181
- return { command: 'vgx doctor', reason: `Local store is blocked: ${store.blocker ?? 'local store is unavailable'}` };
181
+ return { command: 'vgxness doctor', reason: `Local store is blocked: ${store.blocker ?? 'local store is unavailable'}` };
182
182
  }
183
183
  if (defaults.status !== 'ready') {
184
184
  if (defaults.blocker?.startsWith('No project selected') === true) {
185
185
  return {
186
- command: 'vgx dashboard interactive --project <project>',
186
+ command: 'vgxness setup status --project <project>',
187
187
  reason: defaults.nextAction ?? 'Select a project to verify project-scoped setup checks.',
188
188
  };
189
189
  }
190
190
  return {
191
- command: 'vgx agents seed --scope project',
191
+ command: 'vgxness agents seed --scope project',
192
192
  reason: `Default context is blocked: ${defaults.blocker ?? 'default context is unavailable'}`,
193
193
  };
194
194
  }
@@ -201,8 +201,8 @@ function nextAction(store, mcp, defaults, providers, project) {
201
201
  reason: `Provider MCP status is not ready; review the Providers section for provider-specific preview/install guidance (${providerSummary}).`,
202
202
  };
203
203
  }
204
- return { command: 'vgx runs list', reason: 'Project setup is ready; continue with normal vgxness usage.' };
204
+ return { command: 'vgxness runs list', reason: 'Project setup is ready; continue with normal vgxness usage.' };
205
205
  }
206
206
  function setupStatusCommand(project) {
207
- return project === undefined ? 'vgx setup status' : `vgx setup status --project ${project}`;
207
+ return project === undefined ? 'vgxness setup status' : `vgxness setup status --project ${project}`;
208
208
  }
@@ -78,11 +78,11 @@ function setupPlanFromOpenCode(input) {
78
78
  severity: 'blocking',
79
79
  message: input.opencode.message,
80
80
  ...(input.opencode.targetPath === undefined ? {} : { targetPath: input.opencode.targetPath }),
81
- recovery: 'Inspect the OpenCode config, resolve the conflict, then rerun `vgx setup plan`.',
81
+ recovery: 'Inspect the OpenCode config, resolve the conflict, then rerun `vgxness setup plan`.',
82
82
  },
83
83
  ],
84
84
  backupsPlanned: [],
85
- nextCommands: ['vgx setup plan', 'vgxness mcp doctor opencode'],
85
+ nextCommands: ['vgxness setup plan', 'vgxness mcp doctor opencode'],
86
86
  };
87
87
  }
88
88
  return {
@@ -115,7 +115,7 @@ function setupPlanFromOpenCode(input) {
115
115
  },
116
116
  ]
117
117
  : [],
118
- nextCommands: ['vgx setup apply --yes', 'vgx doctor', 'Restart OpenCode and verify the vgxness MCP server is visible.'],
118
+ nextCommands: ['vgxness setup apply --yes', 'vgxness doctor', 'Restart OpenCode and verify the vgxness MCP server is visible.'],
119
119
  };
120
120
  }
121
121
  function resolveSetupDatabase(input) {
@@ -21,7 +21,7 @@ const templates = {
21
21
  },
22
22
  cli: {
23
23
  rationale: ['CLI changes affect TypeScript dispatch/rendering paths and user-visible behavior.', 'Only typecheck is currently allowlisted; CLI execution remains manual/copy-only.'],
24
- recommendations: [typecheckRecommendation(), manualRecommendation('manual-cli-smoke', 'Smoke-test CLI command manually', 'Use npm run cli -- <command> as copy-only text for an operator-selected CLI scenario.', 'npm run cli -- <command>')],
24
+ recommendations: [typecheckRecommendation(), manualRecommendation('manual-cli-smoke', 'Smoke-test CLI command manually', 'Use bun run cli:bun -- <command> as copy-only text for an operator-selected CLI scenario.', 'bun run cli:bun -- <command>')],
25
25
  manualChecks: [manualCheck('review-cli-output', 'Review CLI output shape', 'Confirm human output is concise and JSON output remains structured where applicable.')],
26
26
  },
27
27
  mcp: {