vgxness 1.14.1 → 1.15.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.
@@ -0,0 +1,23 @@
1
+ export const agentSelectorNameFallbackCode = 'AGENT_SELECTOR_NAME_FALLBACK';
2
+ export function resolveAgentSelector(input, lookup) {
3
+ const byId = lookup.getById(input.selector);
4
+ if (byId.ok)
5
+ return ok({ agent: byId.value });
6
+ const byName = lookup.getByName(input.project, input.scope, input.selector);
7
+ if (byName.ok) {
8
+ return ok({
9
+ agent: byName.value,
10
+ warning: `${agentSelectorNameFallbackCode}: selector "${input.selector}" matched scoped agent name; using canonical agent id "${byName.value.id}" name "${byName.value.name}".`,
11
+ });
12
+ }
13
+ return {
14
+ ok: false,
15
+ error: {
16
+ code: 'not_found',
17
+ message: `Agent selector not found: "${input.selector}". Looked up registry id first, then scoped agent name for project "${input.project}" and scope "${input.scope}". Accepted forms: canonical agent id or agent name within the requested project/scope.`,
18
+ },
19
+ };
20
+ }
21
+ function ok(value) {
22
+ return { ok: true, value };
23
+ }
@@ -12,6 +12,7 @@ Areas:
12
12
  init [--project <name>] [--provider opencode|claude|none] [--scope user|global|personal] [--db global|project-local|custom|<path>] [--db-path <path>] [--mode mcp-only|mcp-plus-agents] [--json]
13
13
  setup plan [--project <name>] [--provider opencode|claude|none] [--scope user|global|personal] [--db global|project-local|custom|<path>] [--db-path <path>] [--mode mcp-only|mcp-plus-agents] [--json]
14
14
  setup apply --yes [--project <name>] [--provider opencode|claude|none] [--scope user|global|personal] [--db global|project-local|custom|<path>] [--db-path <path>] [--mode mcp-only|mcp-plus-agents]
15
+ setup reinstall [--yes] [--project <name>] [--scope user|global|personal] [--db global|project-local|custom|<path>] [--db-path <path>] [--mode mcp-only|mcp-plus-agents] [--json]
15
16
  setup backup list --provider opencode [--scope project|user|global] [--target <path>] [--json]
16
17
  setup rollback --backup <path> [--preview|--yes] [--json]
17
18
  setup status [--project <name>] [--scope project|personal] [--db <path>] [--json]
@@ -23,7 +24,7 @@ Areas:
23
24
  Next answers "what should I do now?" with a shorter next-action view.
24
25
  Resume answers "how do I continue interrupted work?" with run inspection guidance.
25
26
  Without --change or --run-id they stay orientation-only and do not open local memory; with --change or --run-id they read SQLite read-only. Pass --json for automation.
26
- Setup plan/init default to human-readable read-only output; pass --json for automation. VGX-managed provider configuration is user-global only for OpenCode and Claude; setup apply writes provider config only with --yes and uses the global user DB plus mcp-plus-agents by default.
27
+ Setup plan/init default to human-readable read-only output; pass --json for automation. VGX-managed provider configuration is user-global only for OpenCode and Claude; setup apply writes provider config only with --yes and uses the global user DB plus mcp-plus-agents by default. setup reinstall is the explicit safe overwrite path: it replaces only VGXNESS-managed OpenCode entries, preserves unrelated config, and still requires --yes to write.
27
28
  Setup status defaults to human-readable read-only output; pass --json for automation. It never writes provider config or executes providers.
28
29
  Doctor defaults to human-readable output; pass --json for automation.
29
30
  Verification plans are read-only recommendations only; they never execute commands, write provider config, persist results, mutate SDD artifacts, or infer acceptance.
@@ -40,8 +41,9 @@ Areas:
40
41
  Seed loading writes only to the local registry; it does not install or write .opencode/, .claude/, or provider config.
41
42
 
42
43
  opencode preview --provider opencode (--agent <name> | --agent-id <id>) --project <name> --change <id> --phase <phase> [--scope project|personal]
44
+ OpenCode CLI preview prints the legacy injection preview JSON for inspection; MCP opencode_handoff_preview is the read-only conversation handoff preview and can be paired with opencode_manager_payload for verbose manager payload details.
43
45
 
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.
46
+ Interactive Home TUI opens from \`vgxness\` in a real terminal; non-TTY use prints safe guidance. 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.
45
47
 
46
48
  orchestrator preview --project <name> --intent <text> [--change <id>] [--db <path>]
47
49
  Orchestrator preview classifies natural-language requests only; it never executes providers, edits files, records runs, or writes provider config.
@@ -81,6 +83,8 @@ Areas:
81
83
  skills detach (--id <id> | --project <name> --name <name>) --target-type agent|subagent|workflow-phase|provider-adapter|intent-signal --target-key <key>
82
84
  skills record-usage (--id <id> | --project <name> --name <name>) --outcome selected|injected|helped|failed|neutral [--run-id <id>]
83
85
  skills resolve [--agent <name> | --agent-id <id>] [--project <name>] [--workflow <name>] [--phase <name>] [--intent-signals a,b] [--provider <name>] [--run <id>] [--record-usage selected|injected]
86
+ skills index --project <name> --scope project|personal
87
+ skills export --project <name> --scope project|personal
84
88
  skills status --project <name> [--scope project|personal] [--provider opencode] [--mode agent|subagent] [--agent <name-or-id>]
85
89
  skills payload [--agent <name> | --agent-id <id>] [--project <name>] [--workflow <name>] [--phase <name>] [--intent-signals a,b] [--provider <name>]
86
90
  skills propose (--id <id> | --project <name> --name <name>) --proposed-version <version> --source-kind path|url|inline --rationale <text>
@@ -91,14 +95,15 @@ Areas:
91
95
  skills list-evaluation-results [--scenario <id>] [--skill-id <id>] [--proposal <id>] [--version-id <id>] [--evaluator <actor>] [--status passed|failed|needs-review|not-applicable]
92
96
  skills get-proposal --proposal <id>
93
97
  skills submit-proposal|approve-proposal|reject-proposal|cancel-proposal|apply-proposal --proposal <id> --actor <name> [--reason <text>]
98
+ Skills export returns a read-only registry manifest for inspection/automation only; it is not backup, restore, import, or provider/native skill installation.
94
99
 
95
100
  subagents register --parent-agent-id <id> --project <name> --name <name> --description <text> --instructions <text>
96
101
  subagents register --file <subagent.json>
97
102
  subagents list --parent-agent-id <id>
98
103
  subagents get --id <id> | --project <name> --name <name> [--scope project|personal]
99
104
 
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.
105
+ No args opens the read-only Home TUI in an interactive terminal; non-TTY prints safe guidance and exits 0 without writing provider config.
106
+ Setup can run as an interactive TUI or as CLI commands: use setup plan/status for read-only guidance, setup apply --yes for first install, and setup reinstall --yes only after reviewing the VGXNESS-managed overwrite warning.
102
107
  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.
103
108
  Provider config writes/install/apply are external-only and require explicit confirmation.
104
109
 
@@ -5,6 +5,8 @@ import { getProviderRenderer } from '../../agents/renderers/index.js';
5
5
  import { ManagerProfileOverlayRepository } from '../../agents/repositories/manager-profile-overlays.js';
6
6
  import { createAgentRegistryToolHandlers } from '../../harness/tools/agents.js';
7
7
  import { runBootSkillSeed } from '../../skills/boot-seed.js';
8
+ import { SkillExportService } from '../../skills/skill-export-service.js';
9
+ import { SkillIndexService } from '../../skills/skill-index-service.js';
8
10
  import { SkillRegistryService } from '../../skills/skill-registry-service.js';
9
11
  import { SkillStatusService } from '../../skills/skill-status-service.js';
10
12
  import { csvFlag, instructionKindFlag, jsonFlag, optionalJsonFlag, optionalModeFlag, optionalScopeFlag, optionalSkillEvaluationResultStatusFlag, optionalSkillImprovementProposalStatusFlag, optionalSkillResolutionUsageFlag, optionalSkillTargetTypeFlag, optionalSkillVersionStatusFlag, optionalStringFlag, requiredFlag, scopeFlag, skillEvaluationResultStatusFlag, skillSourceFromFlags, skillTargetTypeFlag, skillUsageOutcomeFlag, } from '../cli-flags.js';
@@ -88,6 +90,17 @@ function skillStatusInput(flags) {
88
90
  },
89
91
  };
90
92
  }
93
+ function skillIndexInput(flags) {
94
+ const project = requiredFlag(flags, 'project');
95
+ const scope = requiredFlag(flags, 'scope');
96
+ if (!project.ok)
97
+ return project;
98
+ if (!scope.ok)
99
+ return scope;
100
+ if (scope.value !== 'project' && scope.value !== 'personal')
101
+ return validationFailure('--scope must be project or personal');
102
+ return { ok: true, value: { project: project.value, scope: scope.value } };
103
+ }
91
104
  function skillPayloadInput(flags) {
92
105
  if (flags['record-usage'] !== undefined)
93
106
  return validationFailure('skills payload is read-only; use skills resolve with --record-usage for explicit usage writes');
@@ -504,6 +517,18 @@ export function runSkillCommand(command, parsed, database, environment) {
504
517
  const input = resolveSkillsInput(parsed.flags);
505
518
  return input.ok ? jsonResult(registry.resolveSkills(input.value)) : resultFailure(input);
506
519
  }
520
+ if (command === 'index') {
521
+ const input = skillIndexInput(parsed.flags);
522
+ if (!input.ok)
523
+ return resultFailure(input);
524
+ return jsonResult(new SkillIndexService(registry).getIndex(input.value));
525
+ }
526
+ if (command === 'export') {
527
+ const input = skillIndexInput(parsed.flags);
528
+ if (!input.ok)
529
+ return resultFailure(input);
530
+ return jsonResult(new SkillExportService(new SkillIndexService(registry)).export(input.value));
531
+ }
507
532
  if (command === 'status') {
508
533
  const input = skillStatusInput(parsed.flags);
509
534
  if (!input.ok)
@@ -672,4 +697,4 @@ export function runSkillCommand(command, parsed, database, environment) {
672
697
  return usageFailure(`Unknown skills command: ${command}`);
673
698
  }
674
699
  // Re-export helpers for external use
675
- export { expectAgentMode, managerProfileInput, managerProfileOverlayInput, proposalActorInput, registerPayload, resolveAgentForRender, resolveAgentsInput, resolveSkill, resolveSkillsInput, resolveSubagentsForRender, scenarioNameFlag, skillPayloadInput, skillStatusInput, validateFileInputIsComplete, };
700
+ export { expectAgentMode, managerProfileInput, managerProfileOverlayInput, proposalActorInput, registerPayload, resolveAgentForRender, resolveAgentsInput, resolveSkill, resolveSkillsInput, resolveSubagentsForRender, scenarioNameFlag, skillPayloadInput, skillIndexInput, skillStatusInput, validateFileInputIsComplete, };
@@ -4,6 +4,6 @@ export { runDoctorAliasCommand, runMcpDoctorCommand, runMcpDoctorOpenCodeCommand
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, setupMcpEvidence, setupPlanInputFromFlags, } from './setup-dispatcher.js';
7
+ export { applySetupPlanInput, collectRunDetails, collectRunInsights, createSetupLifecycleService, promptSetupWizard, readSetupStatus, runHomeTuiCommand, runInitCommand, runSetupApplyCommand, runSetupBackupCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupReinstallApplyCommand, runSetupReinstallCommand, 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';
@@ -2,8 +2,8 @@ import { okText } from '../cli-help.js';
2
2
  function defaultNoArgsGuidance() {
3
3
  return ([
4
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`.',
5
+ 'In a real terminal, `vgxness` opens the read-only Home TUI. In non-TTY contexts, use explicit CLI commands.',
6
+ 'Next: use `vgxness setup plan`, `vgxness init --plan`, `vgxness status`, `vgxness next`, or `vgxness --help`.',
7
7
  ].join('\n') + '\n');
8
8
  }
9
9
  export async function runDefaultInteractiveEntrypoint(environment) {
@@ -14,6 +14,9 @@ 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 { runHomeTuiController } from '../home-tui-controller.js';
18
+ import { runSetupTuiController } from '../setup-tui-controller.js';
19
+ import { canRunInteractiveTui } from '../tui/terminal-capabilities.js';
17
20
  function renderSetupRollbackApply(result, parsed) {
18
21
  if (parsed.flags.json === true)
19
22
  return jsonResult(result);
@@ -34,6 +37,8 @@ export function runSetupLifecycleCommand(parsed, environment) {
34
37
  return runSetupPlanCommand(parsed, environment);
35
38
  if (area === 'setup' && command === 'apply')
36
39
  return usageFailure('setup apply is available through the async CLI entrypoint; run vgxness setup apply --yes from the installed CLI.');
40
+ if (area === 'setup' && command === 'reinstall')
41
+ return runSetupReinstallCommand(parsed, environment);
37
42
  if (area === 'setup' && command === 'backup')
38
43
  return runSetupBackupCommand(parsed, environment);
39
44
  if (area === 'setup' && command === 'rollback')
@@ -70,6 +75,16 @@ export function runSetupPlanCommand(parsed, environment) {
70
75
  return jsonResult(plan);
71
76
  return okText(`${renderSetupPlan(plan.value)}\n`);
72
77
  }
78
+ export function runSetupReinstallCommand(parsed, environment) {
79
+ const reinstallParsed = withReinstallFlags(parsed);
80
+ const input = setupPlanInputFromFlags(reinstallParsed, environment);
81
+ if (!input.ok)
82
+ return resultFailure(input);
83
+ const plan = createSetupPlan(input.value);
84
+ if (!plan.ok || parsed.flags.json === true)
85
+ return jsonResult(plan);
86
+ return okText(`${renderSetupReinstallPreview(plan.value)}\n`);
87
+ }
73
88
  export function runSetupRollbackCommand(parsed, environment) {
74
89
  const backupPath = optionalStringFlag(parsed.flags, 'backup');
75
90
  if (backupPath === undefined)
@@ -126,6 +141,15 @@ export async function runSetupApplyCommand(parsed, environment) {
126
141
  const applied = await applySetupPlanInput(input.value, environment);
127
142
  return applied.ok ? jsonResult({ ok: true, value: applied.value }) : resultFailure(applied);
128
143
  }
144
+ export async function runSetupReinstallApplyCommand(parsed, environment) {
145
+ if (parsed.flags.yes !== true)
146
+ return usageFailure('setup reinstall rewrites VGXNESS-managed provider entries and requires explicit confirmation with --yes. Unrelated OpenCode config is preserved. No provider config was written.');
147
+ const input = setupPlanInputFromFlags(withReinstallFlags(parsed), environment);
148
+ if (!input.ok)
149
+ return resultFailure(input);
150
+ const applied = await applySetupPlanInput(input.value, environment);
151
+ return applied.ok ? jsonResult({ ok: true, value: applied.value }) : resultFailure(applied);
152
+ }
129
153
  export async function applySetupPlanInput(input, environment) {
130
154
  const plan = createSetupPlan(input);
131
155
  if (!plan.ok)
@@ -208,6 +232,22 @@ export function setupPlanInputFromFlags(parsed, environment) {
208
232
  },
209
233
  };
210
234
  }
235
+ function withReinstallFlags(parsed) {
236
+ return { ...parsed, flags: { ...parsed.flags, 'overwrite-vgxness': true, reinstall: true } };
237
+ }
238
+ function renderSetupReinstallPreview(plan) {
239
+ return [
240
+ 'VGXNESS Setup Reinstall Preview',
241
+ '',
242
+ 'Warning: reinstall replaces only VGXNESS-managed OpenCode entries: mcp.vgxness and known VGXNESS agents/instructions.',
243
+ 'Unrelated OpenCode config is preserved. This is not a full opencode.json reset.',
244
+ 'A managed backup is planned before existing user-global OpenCode config is changed.',
245
+ '',
246
+ renderSetupPlan(plan).trimEnd(),
247
+ '',
248
+ 'Apply after review: vgxness setup reinstall --yes',
249
+ ].join('\n');
250
+ }
211
251
  function defaultWizardInput(environment) {
212
252
  return {
213
253
  project: environment.cwd
@@ -350,14 +390,37 @@ export function resolveInitDispatchMode(parsed, _environment) {
350
390
  return 'setup-plan';
351
391
  }
352
392
  export async function runInitCommand(parsed, environment) {
393
+ if (shouldRunSetupTui(parsed, environment)) {
394
+ const input = setupPlanInputFromFlags(parsed, environment);
395
+ if (!input.ok)
396
+ return resultFailure(input);
397
+ const plan = createSetupPlan(input.value);
398
+ if (!plan.ok)
399
+ return resultFailure(plan);
400
+ return runSetupTuiController({ environment, plan: plan.value });
401
+ }
353
402
  return runInitCommandWithoutSetupTui(parsed, environment);
354
403
  }
404
+ export async function runHomeTuiCommand(parsed, environment) {
405
+ const input = setupPlanInputFromFlags(parsed, environment);
406
+ if (!input.ok)
407
+ return resultFailure(input);
408
+ const plan = createSetupPlan(input.value);
409
+ if (!plan.ok)
410
+ return resultFailure(plan);
411
+ return runHomeTuiController({ environment, plan: plan.value });
412
+ }
355
413
  export async function runInitCommandWithoutSetupTui(parsed, environment) {
356
414
  const mode = resolveInitDispatchMode(parsed, environment);
357
415
  if (mode === 'setup-plan')
358
416
  return runSetupPlanCommand(parsed, environment);
359
417
  return runSetupApplyCommand({ ...parsed, flags: { ...parsed.flags, yes: true } }, environment);
360
418
  }
419
+ function shouldRunSetupTui(parsed, environment) {
420
+ if (parsed.flags.plan === true || parsed.flags.json === true || parsed.flags.yes === true)
421
+ return false;
422
+ return canRunInteractiveTui(environment.stdin, environment.stdout);
423
+ }
361
424
  export function createSetupLifecycleService(input) {
362
425
  return new SetupLifecycleService({
363
426
  store: () => (input.opened.ok ? { ok: true, value: { path: input.databasePath } } : input.opened),
@@ -5,7 +5,8 @@ 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, 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, runHomeTuiCommand, runInitCommand, runMcpDoctorCommand, runMcpInstallCommand, runMcpSetupCommand, runMemoryCommand, runMemoryImportCommand, runOpenCodeCommand, runOrchestratorCommand, runPermissionsCommand, runProductNextCommand, runProductResumeCommand, runRunsCommand, runSddCommand, runSetupApplyCommand, runSetupLifecycleCommand, runSetupPlanCommand, runSetupReinstallApplyCommand, runSetupRollbackCommand, runProductStatusCommand, runSkillCommand, runSubagentCommand, runVerificationPlanCommand, runVerificationReportCommand, runWorkflowExecuteCommand, runWorkflowPreviewCommand, runWorkflowRunCommand, } from './commands/index.js';
9
+ import { canRunInteractiveTui } from './tui/terminal-capabilities.js';
9
10
  const _promptBuffers = new WeakMap();
10
11
  const require = createRequire(import.meta.url);
11
12
  const packageJson = require('../../package.json');
@@ -55,7 +56,8 @@ export function dispatchCli(argv, environment) {
55
56
  const opened = openCliDatabase(databasePath);
56
57
  if (!opened.ok)
57
58
  return resultFailure(opened);
58
- runBootAgentSeedUpgrade(opened.value, environment.env);
59
+ if (!skipsBootAgentSeedUpgrade(area, command))
60
+ runBootAgentSeedUpgrade(opened.value, environment.env);
59
61
  try {
60
62
  if (isWorkflowId(area) && command === 'run')
61
63
  return runWorkflowRunCommand(area, parsed, opened.value);
@@ -89,14 +91,20 @@ export function dispatchCli(argv, environment) {
89
91
  opened.value.close();
90
92
  }
91
93
  }
94
+ function skipsBootAgentSeedUpgrade(area, command) {
95
+ return area === 'skills' && (command === 'index' || command === 'export');
96
+ }
92
97
  function isGlobalVersionRequest(argv) {
93
98
  return argv.length === 1 && (argv[0] === '--version' || argv[0] === '-v');
94
99
  }
95
100
  export async function dispatchCliAsync(argv, environment) {
96
101
  const parsed = parseArgs(argv);
97
102
  const [area, command] = parsed.positionals;
98
- if (argv.length === 0)
103
+ if (argv.length === 0) {
104
+ if (canRunInteractiveTui(environment.stdin, environment.stdout))
105
+ return runHomeTuiCommand({ positionals: [], flags: {} }, environment);
99
106
  return runDefaultInteractiveEntrypoint(environment);
107
+ }
100
108
  if (area === 'mcp') {
101
109
  if (!command)
102
110
  return usageFailure('Missing command for mcp');
@@ -114,6 +122,8 @@ export async function dispatchCliAsync(argv, environment) {
114
122
  return runInitCommand(parsed, environment);
115
123
  if (area === 'setup' && command === 'apply')
116
124
  return runSetupApplyCommand(parsed, environment);
125
+ if (area === 'setup' && command === 'reinstall' && parsed.flags.yes === true)
126
+ return runSetupReinstallApplyCommand(parsed, environment);
117
127
  if (area === 'setup' && command === 'rollback')
118
128
  return runSetupRollbackCommand(parsed, environment);
119
129
  return dispatchCli(argv, environment);
@@ -173,6 +183,8 @@ function validateCommand(area, command) {
173
183
  command === 'detach' ||
174
184
  command === 'record-usage' ||
175
185
  command === 'resolve' ||
186
+ command === 'index' ||
187
+ command === 'export' ||
176
188
  command === 'status' ||
177
189
  command === 'payload' ||
178
190
  command === 'propose' ||
@@ -219,7 +231,7 @@ function validateCommand(area, command) {
219
231
  return command === 'preview' ? { ok: true } : { ok: false, message: `Unknown opencode command: ${command}` };
220
232
  }
221
233
  if (area === 'setup') {
222
- return command === 'status' || command === 'plan' || command === 'apply' || command === 'backup' || command === 'rollback'
234
+ return command === 'status' || command === 'plan' || command === 'apply' || command === 'reinstall' || command === 'backup' || command === 'rollback'
223
235
  ? { ok: true }
224
236
  : { ok: false, message: `Unknown setup command: ${command}` };
225
237
  }