vgxness 1.10.1 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. package/README.md +10 -20
  2. package/dist/agents/canonical-agent-manifest.js +2 -2
  3. package/dist/behavior/behavior-contract-manifest.js +1 -3
  4. package/dist/behavior/behavior-contract-validation.js +0 -4
  5. package/dist/cli/cli-help.js +3 -9
  6. package/dist/cli/commands/index.js +2 -2
  7. package/dist/cli/commands/interactive-entrypoint-dispatcher.js +9 -153
  8. package/dist/cli/commands/setup-dispatcher.js +6 -50
  9. package/dist/cli/dispatcher.js +1 -8
  10. package/dist/cli/product-status-renderer.js +2 -2
  11. package/dist/cli/sdd-renderer.js +5 -5
  12. package/dist/mcp/client-install-claude-code.js +3 -2
  13. package/dist/mcp/client-install-opencode.js +3 -2
  14. package/dist/runs/execution-planning.js +3 -3
  15. package/dist/sdd/sdd-continuation-plan.js +5 -16
  16. package/dist/sdd/sdd-workflow-service.js +1 -1
  17. package/dist/setup/backup-rollback-service.js +10 -4
  18. package/dist/status/product-status.js +1 -1
  19. package/docs/architecture.md +13 -14
  20. package/docs/cli.md +12 -49
  21. package/docs/contributing.md +18 -3
  22. package/docs/glossary.md +5 -5
  23. package/docs/mcp.md +1 -1
  24. package/docs/prd.md +7 -7
  25. package/docs/project-health-audit-v1.10.x.md +115 -0
  26. package/docs/project-health-audit-v1.9.1.md +2 -0
  27. package/docs/providers.md +9 -37
  28. package/docs/roadmap.md +4 -10
  29. package/docs/safety.md +5 -21
  30. package/docs/storage.md +6 -5
  31. package/package.json +1 -3
  32. package/dist/cli/tui/main-menu/index.js +0 -6
  33. package/dist/cli/tui/main-menu/main-menu-actions.js +0 -34
  34. package/dist/cli/tui/main-menu/main-menu-controller.js +0 -11
  35. package/dist/cli/tui/main-menu/main-menu-read-model.js +0 -75
  36. package/dist/cli/tui/main-menu/main-menu-render-shape.js +0 -50
  37. package/dist/cli/tui/main-menu/main-menu-result.js +0 -1
  38. package/dist/cli/tui/main-menu/main-menu-state.js +0 -21
  39. package/dist/cli/tui/opentui/code/index.js +0 -210
  40. package/dist/cli/tui/opentui/code/screen.js +0 -107
  41. package/dist/cli/tui/opentui/code/smoke.js +0 -32
  42. package/dist/cli/tui/opentui/main-menu/index.js +0 -3
  43. package/dist/cli/tui/opentui/main-menu/renderer.js +0 -68
  44. package/dist/cli/tui/opentui/main-menu/screen.js +0 -66
  45. package/dist/cli/tui/opentui/main-menu/smoke.js +0 -17
  46. package/dist/cli/tui/opentui/main-menu/view.js +0 -8
  47. package/dist/cli/tui/opentui/setup/index.js +0 -3
  48. package/dist/cli/tui/opentui/setup/renderer.js +0 -87
  49. package/dist/cli/tui/opentui/setup/screen.js +0 -170
  50. package/dist/cli/tui/opentui/setup/smoke.js +0 -42
  51. package/dist/cli/tui/opentui/setup/view.js +0 -12
  52. package/dist/cli/tui/setup/setup-tui-actions.js +0 -1
  53. package/dist/cli/tui/setup/setup-tui-controller.js +0 -86
  54. package/dist/cli/tui/setup/setup-tui-input.js +0 -43
  55. package/dist/cli/tui/setup/setup-tui-read-model.js +0 -215
  56. package/dist/cli/tui/setup/setup-tui-render-shape.js +0 -171
  57. package/dist/cli/tui/setup/setup-tui-result.js +0 -1
  58. package/dist/cli/tui/setup/setup-tui-services.js +0 -79
  59. package/dist/cli/tui/setup/setup-tui-state.js +0 -193
  60. package/dist/cli/tui/setup/setup-tui-view-helpers.js +0 -62
  61. package/dist/code/cli/code-command.js +0 -104
  62. package/dist/code/config/defaults.js +0 -108
  63. package/dist/code/prompts/prompt-builder.js +0 -127
  64. package/dist/code/providers/credentials.js +0 -13
  65. package/dist/code/providers/fake-provider-adapter.js +0 -98
  66. package/dist/code/providers/message-mapper.js +0 -73
  67. package/dist/code/providers/openai-compatible-provider-adapter.js +0 -68
  68. package/dist/code/providers/provider-adapter.js +0 -10
  69. package/dist/code/providers/provider-registry.js +0 -38
  70. package/dist/code/providers/stream-normalizer.js +0 -34
  71. package/dist/code/reporting/redaction.js +0 -39
  72. package/dist/code/reporting/summary.js +0 -32
  73. package/dist/code/runtime/approval-coordinator.js +0 -468
  74. package/dist/code/runtime/code-runtime.js +0 -1031
  75. package/dist/code/runtime/gateways.js +0 -143
  76. package/dist/code/runtime/memory-service-gateway.js +0 -20
  77. package/dist/code/runtime/project-detection.js +0 -102
  78. package/dist/code/runtime/runs-code-run-gateway.js +0 -29
  79. package/dist/code/runtime/sdd-context.js +0 -164
  80. package/dist/code/runtime/sdd-workflow-gateway.js +0 -63
  81. package/dist/code/runtime/types.js +0 -1
  82. package/dist/code/runtime/verification-coordinator.js +0 -30
  83. package/dist/code/tools/read-only-executor.js +0 -145
  84. package/dist/code/tools/tool-definitions.js +0 -58
  85. package/dist/code/tools/tool-registry.js +0 -13
  86. package/dist/code/tools/tool-result-normalizer.js +0 -119
  87. package/dist/code/tools/workspace-executor.js +0 -278
  88. package/dist/code/tui/approval-actions.js +0 -33
  89. package/dist/code/tui/prompt-mode.js +0 -11
  90. package/dist/code/tui/runtime-events.js +0 -320
  91. package/docs/code-runtime.md +0 -221
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # VGXNESS
2
2
 
3
- VGXNESS is an installable CLI, MCP control plane, and native code runtime for guided AI-agent workflows, SDD artifacts, local memory, and OpenCode integration.
3
+ VGXNESS is an installable CLI and MCP control plane for guided AI-agent workflows, SDD artifacts, local memory, and OpenCode integration.
4
4
 
5
5
  ## Release status and license
6
6
 
@@ -8,7 +8,7 @@ This package is proprietary software. The npm package ships inspectable JavaScri
8
8
 
9
9
  OpenCode is the primary supported provider. Claude setup support is secondary. VGX-managed OpenCode and Claude provider configuration is user-global only; provider config writes require explicit CLI confirmation.
10
10
 
11
- VGXNESS v1.9.1 has a canonical project health audit with validated evidence: 38 MCP tools, 106 test files, and the official Bun validation path passing, including package evidence with `releaseReadiness: pass`. Current unreleased builds expose 41 MCP tools after adding read-only SDD/run recovery parity. See [Project health audit v1.9.1](./docs/project-health-audit-v1.9.1.md) for the versioned matrix and safety taxonomy.
11
+ VGXNESS v1.10.x has a current project health audit describing the implemented CLI/MCP/SDD control plane, OpenCode health, known docs drift, interrupted runs, and the remaining execution/recovery gaps. See [Project health audit v1.10.x](./docs/project-health-audit-v1.10.x.md) for the current system snapshot; [v1.9.1](./docs/project-health-audit-v1.9.1.md) remains historical validation evidence for that release.
12
12
 
13
13
  ## Requirements
14
14
 
@@ -132,13 +132,13 @@ vgx --help # compatibility alias
132
132
 
133
133
  ## First setup with OpenCode
134
134
 
135
- Run the guided setup wizard in a TTY:
135
+ Preview the setup plan:
136
136
 
137
137
  ```bash
138
138
  vgxness init
139
139
  ```
140
140
 
141
- In non-TTY shells, `vgxness init` prints the same read-only setup plan instead of prompting. For a copyable bootstrap and diagnostic path after installing the package globally:
141
+ `vgxness init` is read-only by default, including in TTYs; apply still requires explicit `--yes`. For a copyable bootstrap and diagnostic path after installing the package globally:
142
142
 
143
143
  ```bash
144
144
  vgxness setup plan
@@ -147,7 +147,6 @@ vgxness doctor
147
147
  vgxness status --project <project> --change <change>
148
148
  vgxness next --project <project> --change <change>
149
149
  vgxness sdd continue --project <project> --change <change>
150
- vgxness code sdd <change> <phase> --project <project> --save-artifact
151
150
  ```
152
151
 
153
152
  Stable defaults are: package `vgxness`, provider `opencode`, global user data DB, user-global OpenCode config (`$HOME/.config/opencode/opencode.json`), and `mcp-plus-agents` mode. VGX-managed OpenCode and Claude provider configuration is user-global only; runtime VGXNESS state remains project-aware through `--project`, `--change`, workspace, and database context. Existing project-local provider files such as `.opencode/`, `opencode.json`, `.mcp.json`, `.claude/`, and `CLAUDE.md` remain untouched by VGXNESS setup. They may still affect OpenCode or Claude behavior externally, but VGXNESS treats them as external/manual diagnostics and will not repair, write, back up, or delete them. The generated MCP command for the global DB default is:
@@ -164,20 +163,11 @@ vgxness setup apply --yes
164
163
 
165
164
  `vgxness setup plan` and `vgxness setup status` are human-readable and do not write provider config by default; local VGXNESS store initialization may occur when a command needs the selected SQLite store. `vgxness doctor`, `vgxness status`, `vgxness next`, `vgxness sdd status`, `vgxness sdd next`, `vgxness sdd continue`, and `vgxness sdd accept-artifact` are also human-readable by default. Pass `--json` when you need parseable automation output. `vgxness setup apply --yes` is the explicit provider-config write path.
166
165
 
167
- The daily SDD happy path is OpenCode conversation with the installed VGXNESS MCP server and hidden SDD subagents. Use CLI/TUI commands for bootstrap, setup, diagnostics, recovery, fallback, and scripting: `status`, `next`, and `sdd continue` inspect state and print manual fallback guidance; `code sdd` remains available for an explicit manual fallback run; `resume` helps inspect interrupted work. After a draft is ready, `sdd accept-artifact` records explicit human acceptance, and `sdd reopen-artifact` returns rejected artifacts to draft. Draft-run suggestions are planning-only: human acceptance is still required, and `apply-progress` remains gated.
166
+ The daily SDD happy path is OpenCode conversation with the installed VGXNESS MCP server and hidden SDD subagents. Use CLI commands for bootstrap, setup, diagnostics, recovery, fallback, and scripting: `status`, `next`, and `sdd continue` inspect state and print read-only continuation guidance; `resume` helps inspect interrupted work. After a draft is ready, `sdd accept-artifact` records explicit human acceptance, and `sdd reopen-artifact` returns rejected artifacts to draft.
168
167
 
169
- ## Code runtime (`vgxness code`)
168
+ ## Code runtime status
170
169
 
171
- Beyond setup and SDD control, VGXNESS ships a native code runtime for bounded agentic work in the local workspace:
172
-
173
- ```bash
174
- vgxness code inspect "<question>" # read-only investigation
175
- vgxness code plan "<task>" # read-only implementation plan
176
- vgxness code craft-preview "<task>" # show the diff you would make
177
- vgxness code craft "<task>" # approval-gated, bounded edit-capable work
178
- ```
179
-
180
- Edits, shell, network, git mutations, SDD persistence, and memory saves route through explicit permission decisions. External workspace edits are denied, destructive commands require approval, and secret-like values are redacted from prompts, transcripts, and reports. See [Code runtime](./docs/code-runtime.md) and [Safety model](./docs/safety.md) for the full contract.
170
+ The experimental `vgxness code` runtime and principal OpenTUI code surface have been removed temporarily because they were copied OpenCode-like runtime work. Continue SDD work in OpenCode through VGXNESS MCP, and use the safe CLI commands above for diagnostics and recovery.
181
171
 
182
172
  ## Safety model
183
173
 
@@ -191,9 +181,9 @@ Edits, shell, network, git mutations, SDD persistence, and memory saves route th
191
181
  - OpenCode is the primary supported provider; other providers are preview/manual extension points.
192
182
  - VGXNESS exposes 41 typed MCP tools across SDD, memory, sessions, agents, skills, runs, providers, and verification. See [MCP tools](./docs/mcp.md).
193
183
 
194
- ## Main menu entrypoint
184
+ ## Principal entrypoint
195
185
 
196
- Run `vgxness` with no arguments in an interactive terminal to open the OpenTUI main menu. `vgx` remains a compatibility alias. In non-TTY shells, no-args prints static safe setup guidance and exits 0 without inferring project state.
186
+ Run `vgxness` with no arguments to print static safe guidance and exit 0 without opening local memory, importing OpenTUI, or writing provider config. `vgx` remains a compatibility alias.
197
187
 
198
188
  For scripts, use explicit read-only commands with an explicit project:
199
189
 
@@ -266,9 +256,9 @@ Remove any user-global OpenCode/Claude config entries and local/global VGXNESS d
266
256
  ## More docs
267
257
 
268
258
  - [CLI reference](./docs/cli.md)
259
+ - [Project health audit v1.10.x](./docs/project-health-audit-v1.10.x.md)
269
260
  - [Project health audit v1.9.1](./docs/project-health-audit-v1.9.1.md)
270
261
  - [Architecture](./docs/architecture.md)
271
- - [Code runtime](./docs/code-runtime.md)
272
262
  - [MCP tools](./docs/mcp.md)
273
263
  - [Safety model](./docs/safety.md)
274
264
  - [Storage](./docs/storage.md)
@@ -183,7 +183,7 @@ Daily SDD happens inside OpenCode through conversation, VGXNESS MCP, and hidden
183
183
  - Proposal/spec/design/tasks: status/next -> readiness -> prerequisites -> exact subagent -> delegate -> persist by governance; if proposal is accepted, spec/design/tasks may run as the trusted draft autorun chain without extra confirmation, but drafts remain unaccepted.
184
184
  - Apply/verify: require prerequisites -> artifacts -> exact subagent -> start/recover run -> preflight writes/shell/git/tests -> delegate -> checkpoint -> save -> finalize.
185
185
  - Config/provider/prompt change: inspect manager/profile or payload first; persistent changes need explicit human authorization.
186
- - Recovery: MCP first. Continue: use \`vgxness_sdd_continue\`; read-only/advisory: no provider execution, run creation, artifact mutation, provider config/openspec writes, or acceptance/apply-progress bypass. CLI \`vgxness sdd continue\` is human fallback only. \`vgxness resume --project\` is for candidate runs; \`vgxness code sdd ... --draft-run\` is a planning-only path, never for apply-progress.
186
+ - Recovery: MCP first. Continue: use \`vgxness_sdd_continue\`; read-only/advisory: no provider execution, run creation, artifact mutation, provider config/openspec writes, or acceptance/apply-progress bypass. CLI \`vgxness sdd continue\` is human fallback only. \`vgxness resume --project\` is for candidate runs. The removed experimental \`vgxness code\` runtime is not an SDD fallback.
187
187
 
188
188
  ## Delegation thresholds
189
189
  Default to delegation for SDD phase-shaped work, repository exploration beyond one narrow lookup, implementation, verification, incident recovery, or multi-step analysis. Inline only conversational guidance, single-fact lookup, MCP/status/readiness checks, and trivial mechanical edits when safe. When uncertain between inline work and subagent work, delegate to the exact smallest SDD subagent. Never delegate to unknown agents; use exact SDD phase mapping.
@@ -203,7 +203,7 @@ const registryManagerInstructionsV10 = [
203
203
  'Check SDD status/next/ready/cockpit, read prerequisites with sdd_get_artifact or sdd_list_artifacts, use public sdd_continue/internal vgxness_sdd_continue first for advisory read-only continuation plans, use sdd_reopen_artifact only for rejected artifacts returning to draft with explicit human actor/audit context, save phase output with sdd_save_artifact only by governance; when proposal is accepted, spec/design/tasks may run sequentially as draft-only autorun without extra confirmation, while acceptance remains human-only. Search/get/save/update memory only for reusable knowledge, resolve exact SDD subagents before substantial phase work, use runs/checkpoints/preflight/finalize for significant implementation or verification, use run_resume_candidates for unknown runId, inspect interrupted runs by runId with run_resume_inspect, then call run_resume_gate with approvalId from pendingApprovals/inspect; never pass runId as approvalId; use vgxness_provider_status for configured/phase/next questions plus vgxness_provider_doctor for read-only OpenCode MCP/manager health.',
204
204
  'Prefer payloadMode=compact for manager-facing status/context reads, SDD artifact reads/lists, and activation handoffs so the primary context stays clean; request payloadMode=verbose only when full artifact contents, provider payloads, or skill context are actually needed, preferably inside delegated phase subagents.',
205
205
  'MCP sdd_continue must not execute providers, create runs, mutate artifacts, write provider config/openspec, bypass human acceptance, or treat draft-run as apply-progress.',
206
- 'CLI is an escape hatch for bootstrap, doctor, rollback, recovery, MCP unavailable/setup missing, or explicit user request; do not tell users to run terminal SDD phase commands for normal daily flow. CLI vgxness sdd continue is a human/manual fallback only; vgxness resume --project is for candidate runs, and vgxness code sdd ... --draft-run is planning-only.',
206
+ 'CLI is an escape hatch for bootstrap, doctor, rollback, recovery, MCP unavailable/setup missing, or explicit user request; do not tell users to run terminal SDD phase commands for normal daily flow. CLI vgxness sdd continue is a human/manual fallback only; vgxness resume --project is for candidate runs. The removed experimental vgxness code runtime is not an SDD fallback.',
207
207
  'OpenCode native/provider tools are governance-v1 audit-only/non-hard-blocking; report warnings, never say they are hard-blocked by config.',
208
208
  ].join(' ');
209
209
  const subagentData = {
@@ -12,13 +12,12 @@ export const criticalBehaviorContractInvariantIds = [
12
12
  'context.manager-compact-default',
13
13
  'context.progressive-disclosure',
14
14
  'flow.provider-native-no-terminal-sdd-daily',
15
- 'scope.exclude-vgxcode-runtime',
16
15
  'worktree.preserve-unrelated-user-work',
17
16
  ];
18
17
  export const behaviorContractManifest = {
19
18
  name: canonicalBehaviorContractName,
20
19
  contractVersion: canonicalBehaviorContractVersion,
21
- excludedTargets: ['vgxcode', 'src/code/runtime/*', 'src/code/prompts/*'],
20
+ excludedTargets: [],
22
21
  invariants: [
23
22
  { id: 'sdd.acceptance.human-only', category: 'sdd', severity: 'critical', summary: 'SDD acceptance is recorded only from explicit human acceptance.' },
24
23
  { id: 'sdd.draft-is-not-accepted', category: 'sdd', severity: 'critical', summary: 'Draft, rejected, superseded, legacy, or unaccepted artifacts are not accepted prerequisites.' },
@@ -31,7 +30,6 @@ export const behaviorContractManifest = {
31
30
  { id: 'context.manager-compact-default', category: 'context', severity: 'critical', summary: 'Manager-facing context defaults to compact payloads.' },
32
31
  { id: 'context.progressive-disclosure', category: 'context', severity: 'critical', summary: 'Expanded and verbose context are requested only when needed.' },
33
32
  { id: 'flow.provider-native-no-terminal-sdd-daily', category: 'flow', severity: 'critical', summary: 'Daily SDD progression happens provider-natively through conversation and MCP, not mandatory terminal phase commands.' },
34
- { id: 'scope.exclude-vgxcode-runtime', category: 'scope', severity: 'critical', summary: 'This behavior contract excludes vgxcode and src/code runtime/prompt implementation targets.' },
35
33
  { id: 'worktree.preserve-unrelated-user-work', category: 'worktree', severity: 'critical', summary: 'Unrelated user work and dirty files are preserved.' },
36
34
  ],
37
35
  };
@@ -22,10 +22,6 @@ export function validateBehaviorContractManifest(manifest = behaviorContractMani
22
22
  else if (invariant.severity !== 'critical')
23
23
  errors.push(`critical invariant ${id} must have severity critical`);
24
24
  }
25
- for (const target of ['vgxcode', 'src/code/runtime/*', 'src/code/prompts/*']) {
26
- if (!manifest.excludedTargets.includes(target))
27
- errors.push(`missing excluded target: ${target}`);
28
- }
29
25
  return { ok: errors.length === 0, errors };
30
26
  }
31
27
  export function validateBehaviorContractProjection(metadata, manifest = behaviorContractManifest) {
@@ -41,12 +41,7 @@ Areas:
41
41
 
42
42
  opencode preview --provider opencode (--agent <name> | --agent-id <id>) --project <name> --change <id> --phase <phase> [--scope project|personal]
43
43
 
44
- code inspect "<question>" [--json|--events-jsonl] [--max-source-bytes <n>] [--provider fake|openai-compatible] [--model <id>] [--stream] [--transcript off|summary|full] [--memory off|ask|auto]
45
- code plan "<task>" [--json|--events-jsonl] [--max-source-bytes <n>] [--provider fake|openai-compatible] [--model <id>] [--stream] [--transcript off|summary|full] [--memory off|ask|auto]
46
- code craft-preview "<task>" [--events-jsonl] [--provider fake|openai-compatible] [--model <id>] [--stream]
47
- code craft "<task>" [--json|--events-jsonl --approval-channel stdio] [--max-source-bytes <n>] [--provider fake|openai-compatible] [--model <id>] [--stream] [--approval-policy ask|allow|deny] [--verification none|suggest|run|repair] [--transcript off|summary|full] [--memory off|ask|auto]
48
- code sdd <change> <phase> [--json] [--save-artifact] [--draft-run] [--provider fake|openai-compatible] [--model <id>] [--stream] [--verification none|suggest|run|repair] [--transcript off|summary|full] [--memory off|ask|auto]
49
- VGXNESS Code inspect and plan are native read-only repository flows. Craft is bounded edit-capable work with approval-gated edits and shell verification; craft JSONL approvals require explicit --approval-channel stdio. SDD mode follows phase-specific artifact boundaries and saves only with --save-artifact. --draft-run lets planning phases use draft prerequisites only; human acceptance is still required and apply-progress remains gated.
44
+ The experimental vgxness code runtime and principal OpenTUI code surface were removed and are temporarily unavailable. Daily SDD progression should happen inside OpenCode through conversation, VGXNESS MCP, and hidden SDD subagents; use status/next/sdd continue for read-only CLI guidance.
50
45
 
51
46
  orchestrator preview --project <name> --intent <text> [--change <id>] [--db <path>]
52
47
  Orchestrator preview classifies natural-language requests only; it never executes providers, edits files, records runs, or writes provider config.
@@ -102,9 +97,8 @@ Areas:
102
97
  subagents list --parent-agent-id <id>
103
98
  subagents get --id <id> | --project <name> --name <name> [--scope project|personal]
104
99
 
105
- No args in an interactive TTY opens the OpenTUI main menu.
106
- No args without a TTY prints static safe setup guidance and exits 0 without opening project state.
107
- Setup TUI may launch without --project; Installation remains available and project-scoped checks are deferred while project screens render project-required recovery states.
100
+ No args prints static safe guidance and exits 0 without opening project state, importing OpenTUI, or writing provider config.
101
+ Setup is CLI-only: use setup plan/status for read-only guidance and setup apply --yes only after review.
108
102
  Provider setup support: OpenCode first-class supported default guided install; Claude first-class supported guarded user-global install; project/local provider files are diagnostics only; Antigravity placeholder; Custom/future extension point.
109
103
  Provider config writes/install/apply are external-only and require explicit confirmation.
110
104
 
@@ -1,9 +1,9 @@
1
1
  export { runAgentCommand, runSkillCommand, runSubagentCommand } from './agent-skill-dispatcher.js';
2
- export { runCodeCliCommand, runDefaultInteractiveEntrypoint } from './interactive-entrypoint-dispatcher.js';
2
+ export { runDefaultInteractiveEntrypoint } from './interactive-entrypoint-dispatcher.js';
3
3
  export { runDoctorAliasCommand, runMcpDoctorCommand, runMcpDoctorOpenCodeCommand, runMcpInstallCommand, runMcpSetupCommand } from './mcp-dispatcher.js';
4
4
  export { runMemoryCommand, runMemoryImportCommand, runOpenCodeCommand, runOrchestratorCommand, runSddCommand } from './memory-sdd-dispatcher.js';
5
5
  export { runApprovalsCommand, runPermissionsCommand, runRunsCommand } from './run-permission-dispatcher.js';
6
6
  export { runProductNextCommand, runProductResumeCommand, runProductStatusCommand } from './status-dispatcher.js';
7
- export { applySetupPlanInput, collectRunDetails, collectRunInsights, createSetupLifecycleService, promptSetupWizard, readSetupStatus, runInitCommand, runSetupApplyCommand, runSetupBackupCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupRollbackCommand, runSetupTuiCommand, setupMcpEvidence, setupPlanInputFromFlags, } from './setup-dispatcher.js';
7
+ export { applySetupPlanInput, collectRunDetails, collectRunInsights, createSetupLifecycleService, promptSetupWizard, readSetupStatus, runInitCommand, runSetupApplyCommand, runSetupBackupCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupRollbackCommand, setupMcpEvidence, setupPlanInputFromFlags, } from './setup-dispatcher.js';
8
8
  export { runWorkflowExecuteCommand, runWorkflowPreviewCommand, runWorkflowRunCommand } from './workflow-dispatcher.js';
9
9
  export { runVerificationPlanCommand, runVerificationReportCommand } from './verification-dispatcher.js';
@@ -1,158 +1,14 @@
1
- import { runCodeCommand } from '../../code/cli/code-command.js';
2
- import { InMemoryRunGateway } from '../../code/runtime/gateways.js';
3
- import { MemoryServiceCodeGateway } from '../../code/runtime/memory-service-gateway.js';
4
- import { RunsCodeRunGateway } from '../../code/runtime/runs-code-run-gateway.js';
5
- import { SddWorkflowGateway } from '../../code/runtime/sdd-workflow-gateway.js';
6
- import { MemoryService } from '../../memory/memory-service.js';
7
- import { RunService } from '../../runs/run-service.js';
8
- import { SddWorkflowService } from '../../sdd/sdd-workflow-service.js';
9
- import { codeApprovalPolicyFlag, codeMemoryPolicyFlag, codeTranscriptModeFlag, codeVerificationModeFlag, databasePathFor, optionalNumberFlag, optionalStringFlag, } from '../cli-flags.js';
10
- import { okText, usageFailure, validationFailure } from '../cli-help.js';
11
- import { openCliDatabase, resultFailure } from '../cli-helpers.js';
12
- import { canRunInteractiveTui } from '../tui/terminal-capabilities.js';
13
- import { runSetupTuiCommand } from './setup-dispatcher.js';
14
- function defaultNoTtyGuidance() {
1
+ import { okText } from '../cli-help.js';
2
+ function defaultNoArgsGuidance() {
15
3
  return ([
16
- 'VGXNESS Dashboard requires a TTY; no provider config was written.',
17
- 'Next: rerun `vgxness` in an interactive terminal, run `vgxness init --plan`, or run `vgxness setup plan` for read-only installation guidance.',
4
+ 'VGXNESS no-args entrypoint is safe and deterministic; no local DB was opened and no provider config was written.',
5
+ 'The experimental principal code/OpenTUI surface was removed and is temporarily unavailable.',
6
+ 'Next: use `vgxness status`, `vgxness next`, `vgxness init --plan`, `vgxness setup plan`, or `vgxness --help`.',
18
7
  ].join('\n') + '\n');
19
8
  }
20
- function guidanceForMainMenuResult(result) {
21
- if (result.type === 'show-doctor-guidance')
22
- return ['Doctor / recovery guidance:', '- Read-only status: `vgxness setup status`', '- Provider doctor: `vgxness mcp doctor opencode`', '- No provider config was written.'].join('\n') + '\n';
23
- if (result.type === 'show-sdd-guidance')
24
- return ['SDD / workflow guidance:', '- Use VGXNESS MCP tools from OpenCode for normal SDD progression.', '- Manual status: `vgxness sdd status --project <name> --change <change>`', '- No provider config was written.'].join('\n') + '\n';
25
- if (result.type === 'show-advanced-cli')
26
- return ['Advanced CLI guidance:', '- Installation preview: `vgxness init --plan` or `vgxness setup plan`', '- Setup status: `vgxness setup status --project <name>`', '- SDD status: `vgxness sdd status --project <name> --change <change>`', '- No provider config was written.'].join('\n') + '\n';
27
- if (result.type === 'exit')
28
- return 'Exited dashboard; no provider config was written.\n';
29
- return undefined;
30
- }
31
- async function renderDefaultMainMenu(environment, onResult) {
32
- const { renderOpenTuiMainMenu } = await import('../tui/opentui/main-menu/renderer.js');
33
- await renderOpenTuiMainMenu({
34
- stdin: environment.stdin,
35
- stdout: environment.stdout,
36
- onResult,
37
- });
38
- }
39
- export async function runDefaultInteractiveEntrypointWithMainMenu(environment, input = {}) {
40
- if (!canRunInteractiveTui(environment.stdin, environment.stdout))
41
- return okText(defaultNoTtyGuidance());
42
- let selected;
43
- await (input.renderMainMenu ?? ((onResult) => renderDefaultMainMenu(environment, onResult)))((result) => {
44
- selected = result;
45
- });
46
- const result = selected ?? { type: 'exit' };
47
- if (result.type === 'open-setup')
48
- return (input.setupTui ?? runSetupTuiCommand)(environment);
49
- return okText(guidanceForMainMenuResult(result) ?? 'No provider config was written.\n');
50
- }
51
- function codeApprovalChannelFlag(flags) {
52
- const value = optionalStringFlag(flags, 'approval-channel');
53
- if (value === undefined)
54
- return { ok: true, value: undefined };
55
- return value === 'stdio' ? { ok: true, value } : validationFailure('--approval-channel must be stdio');
56
- }
57
9
  export async function runDefaultInteractiveEntrypoint(environment) {
58
- return runDefaultInteractiveEntrypointWithMainMenu(environment);
59
- }
60
- export async function runCodeCliCommand(parsed, environment) {
61
- const [, command] = parsed.positionals;
62
- if (command !== 'inspect' && command !== 'plan' && command !== 'craft' && command !== 'craft-preview' && command !== 'sdd')
63
- return usageFailure(`Unknown code command: ${command ?? ''}`.trim());
64
- const eventsJsonl = parsed.flags['events-jsonl'] === true;
65
- const approvalChannel = codeApprovalChannelFlag(parsed.flags);
66
- if (!approvalChannel.ok)
67
- return resultFailure(approvalChannel);
68
- if (approvalChannel.value === 'stdio' && (command !== 'craft' || !eventsJsonl))
69
- return usageFailure('--approval-channel stdio is supported only for code craft --events-jsonl');
70
- if (eventsJsonl && command !== 'inspect' && command !== 'plan' && command !== 'craft-preview' && approvalChannel.value !== 'stdio')
71
- return usageFailure('code craft --events-jsonl requires --approval-channel stdio; JSONL without approvals is currently supported only for read-only inspect, plan, and craft-preview');
72
- const draftRunFlag = parsed.flags['draft-run'];
73
- if (draftRunFlag !== undefined && command !== 'sdd')
74
- return usageFailure('--draft-run is supported only for code sdd');
75
- if (draftRunFlag !== undefined && draftRunFlag !== true)
76
- return usageFailure('--draft-run does not accept a value; use --draft-run for code sdd draft mode');
77
- const sddRuntimeMode = draftRunFlag === true ? 'draft-run' : undefined;
78
- const maxSourceBytes = optionalNumberFlag(parsed.flags, 'max-source-bytes');
79
- if (!maxSourceBytes.ok)
80
- return resultFailure(maxSourceBytes);
81
- const output = parsed.flags.json === true || optionalStringFlag(parsed.flags, 'output') === 'json' ? 'json' : 'human';
82
- const approvalPolicy = codeApprovalPolicyFlag(parsed.flags);
83
- if (!approvalPolicy.ok)
84
- return resultFailure(approvalPolicy);
85
- const verificationMode = codeVerificationModeFlag(parsed.flags);
86
- if (!verificationMode.ok)
87
- return resultFailure(verificationMode);
88
- const transcriptMode = codeTranscriptModeFlag(parsed.flags);
89
- if (!transcriptMode.ok)
90
- return resultFailure(transcriptMode);
91
- const memoryPolicy = codeMemoryPolicyFlag(parsed.flags);
92
- if (!memoryPolicy.ok)
93
- return resultFailure(memoryPolicy);
94
- const provider = optionalStringFlag(parsed.flags, 'provider');
95
- const model = optionalStringFlag(parsed.flags, 'model');
96
- if (eventsJsonl) {
97
- if (approvalChannel.value === 'stdio' && (environment.stdin === undefined || environment.stdout === undefined))
98
- return resultFailure(validationFailure('--approval-channel stdio requires CLI stdin and stdout streams'));
99
- return await runCodeCommand({
100
- command,
101
- args: parsed.positionals.slice(2),
102
- cwd: environment.cwd,
103
- output,
104
- runGateway: new InMemoryRunGateway(),
105
- project: optionalStringFlag(parsed.flags, 'project') ?? 'vgxness',
106
- ...(provider === undefined ? {} : { provider }),
107
- ...(model === undefined ? {} : { model }),
108
- stream: parsed.flags.stream === true,
109
- env: environment.env,
110
- eventsJsonl,
111
- memoryPolicy: 'off',
112
- ...(approvalChannel.value === undefined ? {} : { approvalChannel: approvalChannel.value }),
113
- ...(approvalChannel.value === 'stdio' ? { approvalDecisionInput: environment.stdin, eventOutput: environment.stdout } : {}),
114
- ...(maxSourceBytes.value !== undefined ? { maxSourceBytes: maxSourceBytes.value } : {}),
115
- ...(approvalPolicy.value === undefined ? {} : { approvalPolicy: approvalPolicy.value }),
116
- ...(verificationMode.value === undefined ? {} : { verificationMode: verificationMode.value }),
117
- ...(transcriptMode.value === undefined ? {} : { transcriptMode: transcriptMode.value }),
118
- ...(sddRuntimeMode === undefined ? {} : { sddRuntimeMode }),
119
- });
120
- }
121
- const selectedDatabasePath = databasePathFor(parsed.flags, environment);
122
- if (!selectedDatabasePath.ok)
123
- return resultFailure(selectedDatabasePath);
124
- const opened = openCliDatabase(selectedDatabasePath.value);
125
- if (!opened.ok)
126
- return resultFailure(opened);
127
- try {
128
- const runs = new RunService(opened.value);
129
- const memory = new MemoryService(opened.value);
130
- return await runCodeCommand({
131
- command,
132
- args: parsed.positionals.slice(2),
133
- cwd: environment.cwd,
134
- output,
135
- runGateway: new RunsCodeRunGateway(runs),
136
- sddGateway: new SddWorkflowGateway(new SddWorkflowService(memory)),
137
- memoryGateway: new MemoryServiceCodeGateway(memory),
138
- project: optionalStringFlag(parsed.flags, 'project') ?? 'vgxness',
139
- ...(provider === undefined ? {} : { provider }),
140
- ...(model === undefined ? {} : { model }),
141
- stream: parsed.flags.stream === true,
142
- env: environment.env,
143
- eventsJsonl,
144
- persistArtifact: parsed.flags['save-artifact'] === true || parsed.flags.persist === true,
145
- ...(sddRuntimeMode === undefined ? {} : { sddRuntimeMode }),
146
- ...(maxSourceBytes.value !== undefined ? { maxSourceBytes: maxSourceBytes.value } : {}),
147
- ...(approvalPolicy.value === undefined ? {} : { approvalPolicy: approvalPolicy.value }),
148
- ...(verificationMode.value === undefined ? {} : { verificationMode: verificationMode.value }),
149
- ...(transcriptMode.value === undefined ? {} : { transcriptMode: transcriptMode.value }),
150
- ...(memoryPolicy.value === undefined ? {} : { memoryPolicy: memoryPolicy.value }),
151
- });
152
- }
153
- finally {
154
- opened.value.close();
155
- }
10
+ void environment;
11
+ return okText(defaultNoArgsGuidance());
156
12
  }
157
- // Re-export helpers
158
- export { defaultNoTtyGuidance, };
13
+ // Re-export helper for focused CLI tests.
14
+ export { defaultNoArgsGuidance };
@@ -9,13 +9,11 @@ import { applyRollbackConfigBackup, listProviderConfigBackups, previewRollbackCo
9
9
  import { vgxnessSetupDefaults } from '../../setup/setup-defaults.js';
10
10
  import { SetupLifecycleService } from '../../setup/setup-lifecycle-service.js';
11
11
  import { createSetupPlan } from '../../setup/setup-plan.js';
12
- import { databasePathFor, databasePathSelectionFor, opencodeInstallScopeFlag, optionalStringFlag, providerUserGlobalOnlyMigrationMessage, scopeFlag, setupDatabaseFlags, setupInstallModeFlag, setupProviderFlag, } from '../cli-flags.js';
12
+ import { databasePathFor, opencodeInstallScopeFlag, optionalStringFlag, providerUserGlobalOnlyMigrationMessage, scopeFlag, setupDatabaseFlags, setupInstallModeFlag, setupProviderFlag, } from '../cli-flags.js';
13
13
  import { okText, usageFailure, validationFailure } from '../cli-help.js';
14
14
  import { jsonResult, openCliDatabase, resultFailure } from '../cli-helpers.js';
15
15
  import { renderSetupPlan } from '../setup-plan-renderer.js';
16
16
  import { renderSetupStatus } from '../setup-status-renderer.js';
17
- import { createDefaultSetupTuiServices } from '../tui/setup/setup-tui-services.js';
18
- import { canRunInteractiveTui } from '../tui/terminal-capabilities.js';
19
17
  function renderSetupRollbackApply(result, parsed) {
20
18
  if (parsed.flags.json === true)
21
19
  return jsonResult(result);
@@ -344,63 +342,21 @@ export function promptLineExport(environment, prompt) {
344
342
  export function renderSetupPlanForHumansExport(plan) {
345
343
  return renderSetupPlanForHumans(plan);
346
344
  }
347
- export function resolveInitDispatchMode(parsed, environment) {
345
+ export function resolveInitDispatchMode(parsed, _environment) {
348
346
  if (parsed.flags.plan === true || parsed.flags.json === true)
349
347
  return 'setup-plan';
350
348
  if (parsed.flags.yes === true)
351
349
  return 'setup-apply';
352
- return environment.stdin?.isTTY === true && environment.stdout?.isTTY === true ? 'setup-tui' : 'setup-plan';
350
+ return 'setup-plan';
353
351
  }
354
352
  export async function runInitCommand(parsed, environment) {
355
- return runInitCommandWithSetupTui(parsed, environment, runSetupTuiCommand);
353
+ return runInitCommandWithoutSetupTui(parsed, environment);
356
354
  }
357
- export async function runInitCommandWithSetupTui(parsed, environment, setupTui) {
355
+ export async function runInitCommandWithoutSetupTui(parsed, environment) {
358
356
  const mode = resolveInitDispatchMode(parsed, environment);
359
357
  if (mode === 'setup-plan')
360
358
  return runSetupPlanCommand(parsed, environment);
361
- if (mode === 'setup-apply')
362
- return runSetupApplyCommand({ ...parsed, flags: { ...parsed.flags, yes: true } }, environment);
363
- const project = optionalStringFlag(parsed.flags, 'project');
364
- return setupTui(environment, project === undefined ? undefined : { project });
365
- }
366
- export async function runSetupTuiCommand(environment, input) {
367
- if (!canRunInteractiveTui(environment.stdin, environment.stdout))
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
- const selectedDatabasePath = databasePathSelectionFor({}, environment);
370
- if (!selectedDatabasePath.ok)
371
- return resultFailure(selectedDatabasePath);
372
- const opened = input?.lifecycle === undefined ? openCliDatabase(selectedDatabasePath.value.path) : undefined;
373
- if (opened !== undefined && !opened.ok)
374
- return resultFailure(opened);
375
- const lifecycle = input?.lifecycle ??
376
- createSetupLifecycleService({ opened: opened ?? validationFailure('Store is unavailable.'), databasePath: selectedDatabasePath.value.path, environment });
377
- const project = input?.project ?? environment.cwd.replace(/[/]+$/, '').split(/[/]/).pop() ?? 'vgxness';
378
- const runtime = {
379
- project,
380
- workspaceRoot: environment.cwd,
381
- env: environment.env,
382
- selections: {
383
- databaseMode: vgxnessSetupDefaults.defaultDatabaseMode,
384
- provider: vgxnessSetupDefaults.defaultProvider,
385
- scope: vgxnessSetupDefaults.defaultOpenCodeScope,
386
- installMode: vgxnessSetupDefaults.defaultInstallMode,
387
- overwriteVgxness: false,
388
- },
389
- };
390
- try {
391
- const { renderOpenTuiSetup } = await import('../tui/opentui/setup/index.js');
392
- await renderOpenTuiSetup({
393
- services: createDefaultSetupTuiServices({ lifecycle, cwd: environment.cwd, env: environment.env }),
394
- runtime,
395
- stdin: environment.stdin,
396
- stdout: environment.stdout,
397
- });
398
- return { exitCode: 0, stdout: '', stderr: '' };
399
- }
400
- finally {
401
- if (opened?.ok)
402
- opened.value.close();
403
- }
359
+ return runSetupApplyCommand({ ...parsed, flags: { ...parsed.flags, yes: true } }, environment);
404
360
  }
405
361
  export function createSetupLifecycleService(input) {
406
362
  return new SetupLifecycleService({
@@ -5,7 +5,7 @@ import { databasePathFor, parseArgs, requiredFlag } from './cli-flags.js';
5
5
  import { okText, usageFailure, visibleHelpText } from './cli-help.js';
6
6
  import { openCliDatabase, resultFailure } from './cli-helpers.js';
7
7
  import { runBootAgentSeedUpgrade } from '../agents/boot-upgrade.js';
8
- import { runAgentCommand, runApprovalsCommand, runCodeCliCommand, runDefaultInteractiveEntrypoint, runDoctorAliasCommand, runInitCommand, runMcpDoctorCommand, runMcpInstallCommand, runMcpSetupCommand, runMemoryCommand, runMemoryImportCommand, runOpenCodeCommand, runOrchestratorCommand, runPermissionsCommand, runProductNextCommand, runProductResumeCommand, runRunsCommand, runSddCommand, runSetupApplyCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupRollbackCommand, runProductStatusCommand, runSkillCommand, runSubagentCommand, runVerificationPlanCommand, runVerificationReportCommand, runWorkflowExecuteCommand, runWorkflowPreviewCommand, runWorkflowRunCommand, } from './commands/index.js';
8
+ import { runAgentCommand, runApprovalsCommand, runDefaultInteractiveEntrypoint, runDoctorAliasCommand, runInitCommand, runMcpDoctorCommand, runMcpInstallCommand, runMcpSetupCommand, runMemoryCommand, runMemoryImportCommand, runOpenCodeCommand, runOrchestratorCommand, runPermissionsCommand, runProductNextCommand, runProductResumeCommand, runRunsCommand, runSddCommand, runSetupApplyCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupRollbackCommand, runProductStatusCommand, runSkillCommand, runSubagentCommand, runVerificationPlanCommand, runVerificationReportCommand, runWorkflowExecuteCommand, runWorkflowPreviewCommand, runWorkflowRunCommand, } from './commands/index.js';
9
9
  const _promptBuffers = new WeakMap();
10
10
  const require = createRequire(import.meta.url);
11
11
  const packageJson = require('../../package.json');
@@ -110,8 +110,6 @@ export async function dispatchCliAsync(argv, environment) {
110
110
  }
111
111
  if (area === 'doctor')
112
112
  return runDoctorAliasCommand(parsed, environment);
113
- if (area === 'code')
114
- return runCodeCliCommand(parsed, environment);
115
113
  if (area === 'init')
116
114
  return runInitCommand(parsed, environment);
117
115
  if (area === 'setup' && command === 'apply')
@@ -228,10 +226,5 @@ function validateCommand(area, command) {
228
226
  if (area === 'verification') {
229
227
  return command === 'plan' || command === 'report' ? { ok: true } : { ok: false, message: `Unknown verification command: ${command}` };
230
228
  }
231
- if (area === 'code') {
232
- return command === 'inspect' || command === 'plan' || command === 'craft' || command === 'sdd'
233
- ? { ok: true }
234
- : { ok: false, message: `Unknown code command: ${command}` };
235
- }
236
229
  return { ok: false, message: `Unknown command area: ${area}` };
237
230
  }
@@ -44,7 +44,7 @@ function buildBlockedNextCommand(status) {
44
44
  return `vgxness next --project ${status.project.value} --change ${change}${dbHint}`;
45
45
  }
46
46
  export function renderProductNext(next) {
47
- const commandHeading = next.blocked ? 'Recovery/diagnostic command' : 'Manual fallback command';
47
+ const commandHeading = next.blocked ? 'Recovery/diagnostic command' : 'Continuation guidance command';
48
48
  const lines = [
49
49
  'Next',
50
50
  ...next.next.map((line) => `- ${line}`),
@@ -64,7 +64,7 @@ export function renderProductNext(next) {
64
64
  }
65
65
  function productCommandHeading(status) {
66
66
  if (status.sddNextStatus === 'runnable')
67
- return 'Manual fallback command';
67
+ return 'Continuation guidance command';
68
68
  return 'Recovery/diagnostic command';
69
69
  }
70
70
  function relatedRunContextLines(relatedRunContext, includeTrailingBlank) {
@@ -5,13 +5,13 @@ export function renderSddStatus(input) {
5
5
  const blockers = input.status.phases.filter((phase) => phase.present && phase.accepted !== true);
6
6
  const complete = input.status.phases.length > 0 && input.status.phases.every((phase) => phase.present && phase.accepted === true);
7
7
  const statusLabel = complete ? 'complete' : input.status.nextReadyPhase === undefined ? 'blocked' : 'ready';
8
- const directPhaseCommand = input.status.nextReadyPhase === undefined ? undefined : `vgxness code sdd ${input.status.change} ${input.status.nextReadyPhase} --save-artifact`;
8
+ const directPhaseCommand = input.status.nextReadyPhase === undefined ? undefined : `vgxness sdd continue --project ${input.project} --change ${input.status.change}`;
9
9
  const recommendedAction = complete
10
10
  ? 'No next SDD phase remains for this change.'
11
11
  : input.status.nextReadyPhase === undefined
12
12
  ? 'Review blockers or accept present draft artifacts before continuing.'
13
13
  : `Continue the ${input.status.nextReadyPhase} phase in OpenCode using VGXNESS MCP and hidden SDD subagents.`;
14
- const commandLabel = directPhaseCommand === undefined ? 'Diagnostic command' : 'Manual fallback command';
14
+ const commandLabel = directPhaseCommand === undefined ? 'Diagnostic command' : 'Continuation guidance command';
15
15
  const lines = [
16
16
  'SDD Status',
17
17
  `Project: ${input.project}`,
@@ -39,9 +39,9 @@ export function renderSddNext(input) {
39
39
  const guidance = input.decision.blockerGuidance ?? [];
40
40
  const phase = input.decision.nextPhase ?? 'none';
41
41
  const commandGuidance = input.decision.status === 'runnable' && input.decision.nextPhase !== undefined
42
- ? `vgxness code sdd ${input.decision.change} ${input.decision.nextPhase} --save-artifact`
42
+ ? `vgxness sdd continue --project ${input.project} --change ${input.decision.change}`
43
43
  : `vgxness sdd status --project ${input.project} --change ${input.decision.change}`;
44
- const commandLabel = input.decision.status === 'runnable' && input.decision.nextPhase !== undefined ? 'Manual fallback command' : 'Diagnostic command';
44
+ const commandLabel = input.decision.status === 'runnable' && input.decision.nextPhase !== undefined ? 'Continuation guidance command' : 'Diagnostic command';
45
45
  const primaryAction = input.decision.status === 'runnable' && input.decision.nextPhase !== undefined
46
46
  ? `Continue the ${input.decision.nextPhase} phase in OpenCode using VGXNESS MCP and hidden SDD subagents.`
47
47
  : input.decision.recommendedAction;
@@ -76,7 +76,7 @@ export function renderSddNext(input) {
76
76
  return `${lines.join('\n')}\n`;
77
77
  }
78
78
  export function renderSddContinuationPlan(plan) {
79
- const suggestedCommandLabel = plan.status === 'runnable' ? 'Manual fallback command' : 'Diagnostic command';
79
+ const suggestedCommandLabel = plan.status === 'runnable' ? 'Continuation guidance command' : 'Diagnostic command';
80
80
  const lines = [
81
81
  'SDD Continue (read-only)',
82
82
  `Project: ${plan.project}`,
@@ -129,7 +129,7 @@ function writeProjectMemory(plan) {
129
129
  async function applyUserInstall(input, plan, server, writtenPaths, backups) {
130
130
  const existingTargets = plan.targets.filter((target) => target.kind !== 'cli-mcp-registration' && (target.action === 'merge' || target.action === 'update-vgxness' || target.action === 'append-managed-block' || target.action === 'update-managed-block'));
131
131
  for (const target of existingTargets) {
132
- const backup = createBackup(target.path, target.kind === 'user-memory' ? 'user-memory' : 'config', 'user');
132
+ const backup = createBackup(target.path, target.kind === 'user-memory' ? 'user-memory' : 'config', 'user', input.env?.HOME);
133
133
  if (!backup.ok)
134
134
  return refusal('backup_failed', backup.error.message, plan, server, writtenPaths, backups);
135
135
  backups.push(toBackupSummary(backup.value));
@@ -173,7 +173,7 @@ function writeUserMemory(env, plan) {
173
173
  const after = inspectClaudeUserMemory(env);
174
174
  return after.status === 'managed-current' ? { ok: true, value: target.path } : { ok: false, error: { code: 'validation_failed', message: 'Claude user memory did not validate as managed-current after write.' } };
175
175
  }
176
- function createBackup(path, kind, scope = 'project') {
176
+ function createBackup(path, kind, scope = 'project', allowedManagedHome) {
177
177
  return createManagedProviderConfigBackup({
178
178
  targetPath: path,
179
179
  provider: 'claude',
@@ -181,6 +181,7 @@ function createBackup(path, kind, scope = 'project') {
181
181
  createdByOperation: 'mcp-client-install-claude-code',
182
182
  reason: kind === 'project-memory' ? 'pre-project-memory-update-safety' : kind === 'user-memory' ? 'pre-user-memory-update-safety' : 'pre-merge-safety',
183
183
  description: kind === 'project-memory' ? 'Backup existing Claude Code project memory before appending or updating the VGXNESS managed block.' : kind === 'user-memory' ? 'Backup existing Claude Code user memory before appending or updating the VGXNESS managed block.' : 'Backup existing Claude Code config before merging VGXNESS MCP or agent configuration.',
184
+ ...(allowedManagedHome !== undefined ? { allowedManagedHome } : {}),
184
185
  });
185
186
  }
186
187
  function refusal(reason, message, plan, server, writtenPaths, backups, cliResult) {
@@ -55,7 +55,7 @@ export async function installOpenCodeMcpClient(input) {
55
55
  });
56
56
  if (conflictingAgents.length > 0 && input.overwriteVgxness !== true)
57
57
  return agentConflictRefusal(conflictingAgents, input.databasePath, databasePathSource, server, applySafety(plan), plan.targetPath, plan.verificationHints, plan.warnings, plan.manualTest, agentPlan, plan.bashPermissionPolicy);
58
- const backup = createBackup(plan.targetPath, plan.scope);
58
+ const backup = createBackup(plan.targetPath, plan.scope, input.env?.HOME);
59
59
  if (!backup.ok)
60
60
  return refusal('post_write_validation_failed', backup.error.message, input.databasePath, databasePathSource, server, applySafety(plan), plan.targetPath, plan.verificationHints, plan.warnings, plan.manualTest, agentPlan, plan.overwriteVgxness, plan.bashPermissionPolicy);
61
61
  const config = parsed.value;
@@ -97,7 +97,7 @@ function writeConfig(path, config) {
97
97
  mkdirSync(dirname(path), { recursive: true });
98
98
  writeFileSync(path, `${JSON.stringify(config, null, 2)}\n`);
99
99
  }
100
- function createBackup(path, scope) {
100
+ function createBackup(path, scope, allowedManagedHome) {
101
101
  return createManagedProviderConfigBackup({
102
102
  targetPath: path,
103
103
  provider: 'opencode',
@@ -105,6 +105,7 @@ function createBackup(path, scope) {
105
105
  createdByOperation: 'mcp-client-install-opencode',
106
106
  reason: 'pre-merge-safety',
107
107
  description: 'Backup existing OpenCode config before merging VGXNESS MCP configuration.',
108
+ ...(allowedManagedHome !== undefined ? { allowedManagedHome } : {}),
108
109
  });
109
110
  }
110
111
  function validateInstalledResult(targetPath, backup, server, databasePath, source, safety, verificationHints, warningMessages, manualTestGuidance, agentPlan, overwriteVgxness = false, bashPermissionPolicy = bashPermissionPolicyFor(agentPlan)) {
@@ -79,11 +79,11 @@ function conditionRequirements(operation, decision, realpathHardeningRequired, s
79
79
  return conditions;
80
80
  }
81
81
  function planLimitations(operation, decision, strategy, sandbox) {
82
- const limitations = ['planning-only: no command, provider tool, worktree, sandbox, directory, or filesystem mutation is performed'];
82
+ const limitations = ['planning-only: this preflight records an execution plan only; no command, provider tool, worktree, sandbox, directory, or filesystem mutation was performed'];
83
83
  if (strategy === 'worktree')
84
- limitations.push('worktree is a planned isolation target only; creation is future executor work');
84
+ limitations.push('worktree is only the planned isolation target; no worktree was created and mutations still require a separate executor or manual worktree');
85
85
  if (strategy === 'process-sandbox')
86
- limitations.push('process-sandbox is a planned isolation target only; launch/enforcement is future executor work');
86
+ limitations.push('process-sandbox is only the planned isolation target; no sandbox was launched and execution still requires a separate executor');
87
87
  if (decision.decision === 'deny')
88
88
  limitations.push(`permission policy denies execution: ${decision.reason}`);
89
89
  if (sandbox?.decision === 'rejected')