create-quiver 0.14.0 → 0.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.
Files changed (92) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +187 -518
  3. package/README_FOR_AI.md +39 -27
  4. package/ROADMAP.md +11 -0
  5. package/assets/quiver-wordmark.svg +22 -0
  6. package/docs/AI_CONTEXT.md.template +2 -0
  7. package/docs/AI_ONBOARDING_PROMPT.md.template +9 -1
  8. package/docs/CLI_UX_GUIDE.md +185 -0
  9. package/docs/COMMANDS.md.template +22 -3
  10. package/docs/GITFLOW_PR_GUIDE.md +70 -0
  11. package/docs/getting-started/linux.md +84 -0
  12. package/docs/getting-started/macos.md +85 -0
  13. package/docs/getting-started/windows-git-bash-wsl.md +78 -0
  14. package/docs/getting-started/windows-powershell.md +96 -0
  15. package/docs/reference/commands.md +98 -0
  16. package/docs/workflows/existing-project.md +131 -0
  17. package/docs/workflows/full-ai-spec-to-pr.md +311 -0
  18. package/docs/workflows/legacy-quiver-project.md +102 -0
  19. package/docs/workflows/new-project.md +76 -0
  20. package/package.json +5 -1
  21. package/specs/quiver-v29-planner-prepare-context-cli-ux/EVIDENCE_REPORT.md +163 -0
  22. package/specs/quiver-v29-planner-prepare-context-cli-ux/EXECUTION_PLAN.md +72 -0
  23. package/specs/quiver-v29-planner-prepare-context-cli-ux/SPEC.md +173 -0
  24. package/specs/quiver-v29-planner-prepare-context-cli-ux/STATUS.md +34 -0
  25. package/specs/quiver-v29-planner-prepare-context-cli-ux/pr.md +95 -0
  26. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/CLOSURE_BRIEF.md +32 -0
  27. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/EXECUTION_BRIEF.md +45 -0
  28. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/slice.json +58 -0
  29. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/CLOSURE_BRIEF.md +33 -0
  30. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/EXECUTION_BRIEF.md +49 -0
  31. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/slice.json +75 -0
  32. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/CLOSURE_BRIEF.md +32 -0
  33. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/EXECUTION_BRIEF.md +47 -0
  34. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/slice.json +71 -0
  35. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/CLOSURE_BRIEF.md +33 -0
  36. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/EXECUTION_BRIEF.md +52 -0
  37. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/slice.json +82 -0
  38. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/CLOSURE_BRIEF.md +34 -0
  39. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/EXECUTION_BRIEF.md +46 -0
  40. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/slice.json +73 -0
  41. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/CLOSURE_BRIEF.md +34 -0
  42. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/EXECUTION_BRIEF.md +46 -0
  43. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/slice.json +83 -0
  44. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/CLOSURE_BRIEF.md +31 -0
  45. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/EXECUTION_BRIEF.md +50 -0
  46. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/slice.json +95 -0
  47. package/specs/quiver-v30-interactive-cli-ux-agent-selection/EVIDENCE_REPORT.md +213 -0
  48. package/specs/quiver-v30-interactive-cli-ux-agent-selection/EXECUTION_PLAN.md +85 -0
  49. package/specs/quiver-v30-interactive-cli-ux-agent-selection/SPEC.md +213 -0
  50. package/specs/quiver-v30-interactive-cli-ux-agent-selection/STATUS.md +31 -0
  51. package/specs/quiver-v30-interactive-cli-ux-agent-selection/pr.md +103 -0
  52. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +33 -0
  53. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +56 -0
  54. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/slice.json +71 -0
  55. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/CLOSURE_BRIEF.md +31 -0
  56. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/EXECUTION_BRIEF.md +54 -0
  57. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/slice.json +69 -0
  58. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/CLOSURE_BRIEF.md +33 -0
  59. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/EXECUTION_BRIEF.md +56 -0
  60. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/slice.json +81 -0
  61. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/CLOSURE_BRIEF.md +32 -0
  62. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/EXECUTION_BRIEF.md +54 -0
  63. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/slice.json +75 -0
  64. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/CLOSURE_BRIEF.md +32 -0
  65. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/EXECUTION_BRIEF.md +57 -0
  66. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/slice.json +85 -0
  67. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/CLOSURE_BRIEF.md +33 -0
  68. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/EXECUTION_BRIEF.md +57 -0
  69. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/slice.json +85 -0
  70. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/CLOSURE_BRIEF.md +35 -0
  71. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/EXECUTION_BRIEF.md +55 -0
  72. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/slice.json +81 -0
  73. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/CLOSURE_BRIEF.md +34 -0
  74. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/EXECUTION_BRIEF.md +55 -0
  75. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/slice.json +85 -0
  76. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/CLOSURE_BRIEF.md +34 -0
  77. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/EXECUTION_BRIEF.md +59 -0
  78. package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/slice.json +95 -0
  79. package/src/create-quiver/commands/ai.js +809 -71
  80. package/src/create-quiver/commands/spec.js +167 -5
  81. package/src/create-quiver/index.js +582 -71
  82. package/src/create-quiver/lib/agent-profiles.js +111 -10
  83. package/src/create-quiver/lib/ai/context-proposal.js +389 -0
  84. package/src/create-quiver/lib/ai/context-proposal.schema.js +31 -0
  85. package/src/create-quiver/lib/ai/execution-plan.js +106 -8
  86. package/src/create-quiver/lib/ai/executor.js +284 -28
  87. package/src/create-quiver/lib/ai/providers.js +71 -1
  88. package/src/create-quiver/lib/cli/editor.js +118 -0
  89. package/src/create-quiver/lib/cli/selectors.js +107 -0
  90. package/src/create-quiver/lib/cli/theme.js +103 -0
  91. package/src/create-quiver/lib/cli/ux-flags.js +169 -0
  92. package/src/create-quiver/lib/cli/ux.js +225 -0
@@ -53,6 +53,9 @@ const { checkPrReadiness, checkScope, checkSliceReadiness } = require('./lib/rea
53
53
  const { cleanupSlice, refreshActiveSlicesBoard, startSlice } = require('./lib/lifecycle');
54
54
  const { buildSpecStatus, closeSpecWorktree, formatSpecCloseResult, formatSpecStartResult, formatSpecStatus, startSpecWorktree } = require('./lib/spec-worktrees');
55
55
  const { getContextPathExclusionReason } = require('./lib/ai/safety');
56
+ const { selectOption } = require('./lib/cli/selectors');
57
+ const { createUx } = require('./lib/cli/ux');
58
+ const { validateUxFlags } = require('./lib/cli/ux-flags');
56
59
  const { relativePosixPath, resolveTargetRoot } = require('./lib/paths');
57
60
  const {
58
61
  CURRENT_SCAN_RELATIVE_PATH,
@@ -306,6 +309,11 @@ Options:
306
309
  --include-templates Export packaged templates in init profile
307
310
  --dry-run Preview init, analyze, migrate, prepare, spec create/start/close, demo, ai agent set, or AI work without executing writes/providers
308
311
  --print-prompt Print the exact AI prompt and exit without executing provider CLIs
312
+ --with-planner Enable planner-assisted behavior on commands that explicitly support it
313
+ --interactive Enable prompts on commands that explicitly support interactive choices
314
+ --review Open or prepare human review before persistent writes where supported
315
+ --methodology <name> Select methodology where supported (currently wdd-sdd)
316
+ --no-color Disable ANSI colors in human output
309
317
  --fix For doctor, apply safe non-destructive repairs
310
318
  --execute For ai execute-plan, run the planned slices instead of printing commands
311
319
  --create For ai pr, create the PR after preflight instead of printing the plan only
@@ -329,6 +337,7 @@ Options:
329
337
 
330
338
  Examples:
331
339
  npx create-quiver init --name "My Project"
340
+ npx create-quiver init --interactive
332
341
  npx create-quiver init --name "My Project" --dry-run
333
342
  npx create-quiver --name "My Project"
334
343
  npx create-quiver --name "My Project" --dir ./my-project
@@ -417,6 +426,10 @@ function parseArgs(argv) {
417
426
  strict: false,
418
427
  strictOverlap: false,
419
428
  json: false,
429
+ noColor: false,
430
+ withPlanner: false,
431
+ interactive: false,
432
+ review: false,
420
433
  includeCompleted: false,
421
434
  onlyReady: false,
422
435
  allReady: false,
@@ -425,6 +438,7 @@ function parseArgs(argv) {
425
438
  format: 'tree',
426
439
  formatExplicit: false,
427
440
  showConflicts: false,
441
+ methodology: '',
428
442
  level: null,
429
443
  unicode: false,
430
444
  aiCommand: '',
@@ -647,6 +661,26 @@ function parseArgs(argv) {
647
661
  continue;
648
662
  }
649
663
 
664
+ if (arg === '--no-color') {
665
+ result.noColor = true;
666
+ continue;
667
+ }
668
+
669
+ if (arg === '--with-planner') {
670
+ result.withPlanner = true;
671
+ continue;
672
+ }
673
+
674
+ if (arg === '--interactive') {
675
+ result.interactive = true;
676
+ continue;
677
+ }
678
+
679
+ if (arg === '--review') {
680
+ result.review = true;
681
+ continue;
682
+ }
683
+
650
684
  if (arg === '--include-completed') {
651
685
  result.includeCompleted = true;
652
686
  continue;
@@ -720,6 +754,74 @@ function parseArgs(argv) {
720
754
  continue;
721
755
  }
722
756
 
757
+ if (arg === '--id') {
758
+ const value = args[++index];
759
+ if (!value) {
760
+ throw new Error(formatError('missing value for --id'));
761
+ }
762
+ result.aiProfileId = value;
763
+ continue;
764
+ }
765
+
766
+ if (arg === '--display-name') {
767
+ const value = args[++index];
768
+ if (!value) {
769
+ throw new Error(formatError('missing value for --display-name'));
770
+ }
771
+ result.aiDisplayName = value;
772
+ continue;
773
+ }
774
+
775
+ if (arg === '--default') {
776
+ result.aiDefaultProfile = true;
777
+ continue;
778
+ }
779
+
780
+ if (arg === '--planner') {
781
+ const value = args[++index];
782
+ if (!value) {
783
+ throw new Error(formatError('missing value for --planner'));
784
+ }
785
+ result.aiPlannerProfile = value;
786
+ continue;
787
+ }
788
+
789
+ if (arg === '--executor') {
790
+ const value = args[++index];
791
+ if (!value) {
792
+ throw new Error(formatError('missing value for --executor'));
793
+ }
794
+ result.aiExecutorProfile = value;
795
+ continue;
796
+ }
797
+
798
+ if (arg === '--reviewer') {
799
+ const value = args[++index];
800
+ if (!value) {
801
+ throw new Error(formatError('missing value for --reviewer'));
802
+ }
803
+ result.aiReviewerProfile = value;
804
+ continue;
805
+ }
806
+
807
+ if (arg === '--doctor') {
808
+ const value = args[++index];
809
+ if (!value) {
810
+ throw new Error(formatError('missing value for --doctor'));
811
+ }
812
+ result.aiDoctorProfile = value;
813
+ continue;
814
+ }
815
+
816
+ if (arg === '--methodology') {
817
+ const value = args[++index];
818
+ if (!value) {
819
+ throw new Error(formatError('missing value for --methodology'));
820
+ }
821
+ result.methodology = value;
822
+ continue;
823
+ }
824
+
723
825
  if (arg === '--label') {
724
826
  const value = args[++index];
725
827
  if (!value) {
@@ -2145,28 +2247,21 @@ function runMigrate(targetDir, options = {}) {
2145
2247
  }
2146
2248
  }
2147
2249
 
2148
- function runDoctor(targetDir, options = {}) {
2149
- const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
2150
-
2151
- if (!fs.existsSync(projectRoot)) {
2152
- throw new Error(formatError(`target directory does not exist: ${projectRoot}`));
2153
- }
2154
-
2155
- if (!hasQuiverInitializationEvidence(projectRoot)) {
2156
- throw new Error(formatError('doctor requires a project previously initialized by Quiver.\nRun init first: npx create-quiver --name "Project Name"'));
2157
- }
2158
-
2159
- const fixPlan = buildDoctorFixPlan(projectRoot);
2160
- if (options.fix) {
2161
- if (options.dryRun) {
2162
- console.log(formatDoctorFixPlan(fixPlan, { dryRun: true }));
2163
- return;
2250
+ function uniqueLines(lines) {
2251
+ const seen = new Set();
2252
+ const unique = [];
2253
+ for (const line of lines) {
2254
+ const value = String(line || '').trim();
2255
+ if (!value || seen.has(value)) {
2256
+ continue;
2164
2257
  }
2165
-
2166
- applyDoctorFixPlan(projectRoot, fixPlan);
2167
- console.log(formatDoctorFixPlan(fixPlan));
2258
+ seen.add(value);
2259
+ unique.push(value);
2168
2260
  }
2261
+ return unique;
2262
+ }
2169
2263
 
2264
+ function buildDoctorCommandReport(projectRoot) {
2170
2265
  const doctorReport = collectDoctorReport(projectRoot);
2171
2266
  const specSlugs = doctorReport.specSlugs;
2172
2267
  const doctorExampleTarget = doctorReport.exampleTarget || {
@@ -2253,65 +2348,425 @@ function runDoctor(targetDir, options = {}) {
2253
2348
  ...nonExecutableScripts.map((file) => `missing executable bit: ${file}`),
2254
2349
  ...missingScripts.map((name) => `missing package.json script: ${name}`),
2255
2350
  ];
2256
- const softWarnings = doctorReport.warnings;
2351
+ const checks = [];
2352
+
2353
+ const addCheck = (id, status, message, details = {}) => {
2354
+ checks.push({
2355
+ id,
2356
+ status,
2357
+ message,
2358
+ ...details,
2359
+ });
2360
+ };
2257
2361
 
2258
- if (migrationProblems.length > 0) {
2259
- throw new Error(formatError(`doctor failed:\n- ${migrationProblems.join('\n- ')}\n- Run migration first: npx create-quiver migrate`));
2260
- }
2362
+ addCheck('project-root', 'ok', `Quiver doctor passed for ${projectRoot}`);
2363
+ addCheck(
2364
+ 'layout',
2365
+ doctorReport.layout === 'incomplete' ? 'error' : 'ok',
2366
+ `Layout: ${doctorReport.layout}`,
2367
+ );
2368
+ addCheck('specs', 'ok', specSlugs.length > 0 ? `Specs: ${specSlugs.join(', ')}` : 'Specs: none yet');
2261
2369
 
2262
- console.log(`Quiver doctor passed for ${projectRoot}`);
2263
- console.log(`Layout: ${doctorReport.layout}`);
2264
- if (specSlugs.length > 0) {
2265
- console.log(`Specs: ${specSlugs.join(', ')}`);
2266
- } else {
2267
- console.log('Specs: none yet');
2268
- }
2269
2370
  if (doctorReport.legacySignals.length > 0) {
2270
- console.log(`Legacy signals: ${doctorReport.legacySignals.join(', ')}`);
2271
- }
2272
- console.log('Next steps:');
2273
- for (const recommendation of doctorReport.recommendations) {
2274
- console.log(`- ${recommendation}`);
2275
- }
2276
- for (const warning of stateWarnings) {
2277
- console.log(`- Warning: ${warning}`);
2278
- }
2371
+ addCheck('legacy-signals', doctorReport.layout === 'legacy' || doctorReport.layout === 'hybrid' ? 'warning' : 'ok', `Legacy signals: ${doctorReport.legacySignals.join(', ')}`);
2372
+ }
2373
+
2374
+ addCheck(
2375
+ 'required-files',
2376
+ missingFiles.length > 0 ? 'error' : 'ok',
2377
+ missingFiles.length > 0 ? `Missing required files: ${missingFiles.join(', ')}` : 'Required files found',
2378
+ { missing: missingFiles },
2379
+ );
2380
+
2381
+ if (requiredExecutables.length > 0 || nonExecutableScripts.length > 0) {
2382
+ addCheck(
2383
+ 'legacy-executables',
2384
+ nonExecutableScripts.length > 0 ? 'error' : 'ok',
2385
+ nonExecutableScripts.length > 0 ? `Missing executable bit: ${nonExecutableScripts.join(', ')}` : 'Legacy executable scripts are runnable',
2386
+ { missing: nonExecutableScripts },
2387
+ );
2388
+ }
2389
+
2390
+ addCheck(
2391
+ 'workflow-scripts',
2392
+ missingScripts.length > 0 ? 'error' : 'ok',
2393
+ missingScripts.length > 0 ? `Missing package.json workflow scripts: ${missingScripts.join(', ')}` : 'Workflow scripts available',
2394
+ { missing: missingScripts },
2395
+ );
2396
+
2397
+ addCheck(
2398
+ 'state',
2399
+ hasQuiverState ? 'ok' : 'warning',
2400
+ hasQuiverState ? 'Quiver state metadata found' : 'Warning: missing Quiver state metadata: .quiver/state.json',
2401
+ );
2402
+
2403
+ addCheck(
2404
+ 'project-scan',
2405
+ hasScanArtifacts ? 'ok' : 'warning',
2406
+ hasScanArtifacts ? 'Project analysis artifacts found' : 'Warning: project analysis artifacts not found; run analyze when you need the visible project map',
2407
+ );
2408
+
2279
2409
  for (const scriptName of missingNodeNativeScripts) {
2280
- console.log(`- Warning: missing Node-native script: ${scriptName}`);
2410
+ addCheck(`node-script:${scriptName}`, 'warning', `Warning: missing Node-native script: ${scriptName}`);
2281
2411
  }
2412
+
2282
2413
  for (const scriptName of missingAiScripts) {
2283
- console.log(`- Warning: missing AI orchestration script: ${scriptName}`);
2414
+ addCheck(`ai-script:${scriptName}`, 'warning', `Warning: missing AI orchestration script: ${scriptName}`);
2284
2415
  }
2416
+
2285
2417
  if (legacyOnlyScripts.length > 0) {
2286
- console.log(`- Warning: legacy Bash workflow scripts detected for ${legacyOnlyScripts.join(', ')}. Run npx create-quiver migrate to add quiver:* npm scripts.`);
2418
+ addCheck(
2419
+ 'legacy-only-scripts',
2420
+ 'warning',
2421
+ `Warning: legacy Bash workflow scripts detected for ${legacyOnlyScripts.join(', ')}. Run npx create-quiver migrate to add quiver:* npm scripts.`,
2422
+ );
2287
2423
  }
2424
+
2288
2425
  for (const script of unsupportedCreateQuiverScripts) {
2289
- console.log(`- Warning: package.json script ${script.scriptName} targets ${script.reason}: \`${script.command}\`. Update create-quiver or regenerate scripts with npx create-quiver migrate.`);
2290
- }
2291
- for (const warning of softWarnings) {
2292
- console.log(`- Warning: ${warning}`);
2293
- }
2294
- if (!hasQuiverState) {
2295
- console.log('- Run migration first: npx create-quiver migrate');
2296
- } else if (!hasScanArtifacts) {
2297
- console.log('- Analyze the project first: npx create-quiver analyze');
2298
- } else {
2299
- console.log('- Ask your AI agent: Read AGENTS.md, then docs/AI_ONBOARDING_PROMPT.md and execute it.');
2300
- }
2301
- console.log('- Check the next ready slice: npx create-quiver next');
2426
+ addCheck(
2427
+ `unsupported-script:${script.scriptName}`,
2428
+ 'warning',
2429
+ `Warning: package.json script ${script.scriptName} targets ${script.reason}: \`${script.command}\`. Update create-quiver or regenerate scripts with npx create-quiver migrate.`,
2430
+ { script_name: script.scriptName, command: script.command, reason: script.reason },
2431
+ );
2432
+ }
2433
+
2434
+ for (const warning of doctorReport.warnings) {
2435
+ addCheck(`warning:${checks.length + 1}`, 'warning', `Warning: ${warning}`);
2436
+ }
2437
+
2438
+ const suggestedFixes = [
2439
+ ...doctorReport.recommendations,
2440
+ !hasQuiverState
2441
+ ? 'Run migration first: npx create-quiver migrate'
2442
+ : !hasScanArtifacts
2443
+ ? 'Analyze the project first: npx create-quiver analyze'
2444
+ : 'Ask your AI agent: Read AGENTS.md, then docs/AI_ONBOARDING_PROMPT.md and execute it.',
2445
+ 'Check the next ready slice: npx create-quiver next',
2446
+ ];
2447
+
2302
2448
  if (specSlugs.length > 0) {
2303
2449
  const projectSlug = doctorExampleTarget.specSlug;
2304
2450
  const sliceId = doctorExampleTarget.sliceId || '<slice-id>';
2305
2451
  if (doctorExampleTarget.source === 'active-slice') {
2306
- console.log(`- Example target: ${projectSlug}/${sliceId} (${doctorExampleTarget.status})`);
2452
+ suggestedFixes.push(`Example target: ${projectSlug}/${sliceId} (${doctorExampleTarget.status})`);
2307
2453
  } else if (doctorExampleTarget.source === 'generic-multiple-specs') {
2308
- console.log('- Example target: specs/<spec-slug>/slices/<slice-id>/slice.json (generic because no active slice is obvious)');
2454
+ suggestedFixes.push('Example target: specs/<spec-slug>/slices/<slice-id>/slice.json (generic because no active slice is obvious)');
2455
+ }
2456
+ suggestedFixes.push(`Start a slice: npx create-quiver start-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
2457
+ suggestedFixes.push(`Validate a slice: npx create-quiver check-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
2458
+ suggestedFixes.push(`Validate the PR gate: npx create-quiver check-pr specs/${projectSlug}/slices/${sliceId}/slice.json`);
2459
+ } else {
2460
+ suggestedFixes.push('Create real specs and slices only after acceptance criteria are approved and the technical plan is reviewed and approved.');
2461
+ }
2462
+
2463
+ const errors = checks.filter((check) => check.status === 'error').map((check) => check.message);
2464
+ const warnings = checks.filter((check) => check.status === 'warning').map((check) => check.message);
2465
+ const status = errors.length > 0 ? 'error' : warnings.length > 0 ? 'warning' : 'ok';
2466
+
2467
+ return {
2468
+ schema_version: 1,
2469
+ command: 'doctor',
2470
+ project_root: projectRoot,
2471
+ status,
2472
+ exit_code: errors.length > 0 ? 1 : 0,
2473
+ layout: doctorReport.layout,
2474
+ specs: specSlugs,
2475
+ legacy_signals: doctorReport.legacySignals,
2476
+ checks,
2477
+ suggested_fixes: uniqueLines(suggestedFixes),
2478
+ warnings,
2479
+ errors: migrationProblems.length > 0 ? uniqueLines([...migrationProblems, ...errors]) : errors,
2480
+ };
2481
+ }
2482
+
2483
+ function formatDoctorHumanReport(report, options = {}) {
2484
+ const lines = [];
2485
+ const ux = createUx({
2486
+ ...options,
2487
+ spinner: false,
2488
+ write: (text) => lines.push(String(text)),
2489
+ });
2490
+ const symbolForStatus = (status) => {
2491
+ if (status === 'ok') return ux.theme.symbols.success;
2492
+ if (status === 'error') return ux.theme.symbols.error;
2493
+ return ux.theme.symbols.warning;
2494
+ };
2495
+ const colorForStatus = (status) => {
2496
+ if (status === 'ok') return 'success';
2497
+ if (status === 'error') return 'error';
2498
+ return 'warning';
2499
+ };
2500
+
2501
+ ux.section('Quiver Doctor');
2502
+ ux.line('');
2503
+ ux.line('Checks');
2504
+ for (const check of report.checks) {
2505
+ const line = ` ${symbolForStatus(check.status)} ${check.message}`;
2506
+ ux.line(ux.mode.decoration ? ux.theme.status(colorForStatus(check.status), line) : line);
2507
+ }
2508
+
2509
+ ux.line('');
2510
+ ux.line('Suggested fixes');
2511
+ for (const fix of report.suggested_fixes) {
2512
+ const line = ` ${ux.theme.symbols.bullet} ${fix}`;
2513
+ ux.line(ux.mode.decoration ? ux.theme.status('command', line) : line);
2514
+ }
2515
+
2516
+ return lines.join('');
2517
+ }
2518
+
2519
+ const METHODOLOGY_OPTIONS = Object.freeze([
2520
+ {
2521
+ label: 'WDD + SDD',
2522
+ value: 'wdd-sdd',
2523
+ hint: 'Workflow Driven Development + Spec Driven Development',
2524
+ default: true,
2525
+ },
2526
+ ]);
2527
+
2528
+ const INIT_MODE_OPTIONS = Object.freeze([
2529
+ {
2530
+ label: 'Proyecto existente',
2531
+ value: 'existing',
2532
+ hint: 'Agrega Quiver sin sobrescribir archivos existentes',
2533
+ default: true,
2534
+ },
2535
+ {
2536
+ label: 'Proyecto nuevo',
2537
+ value: 'new',
2538
+ hint: 'Crea el contrato base en una carpeta nueva o vacia',
2539
+ },
2540
+ {
2541
+ label: 'Solo validar estructura',
2542
+ value: 'validate',
2543
+ hint: 'Ejecuta Doctor en lugar de escribir archivos',
2544
+ },
2545
+ ]);
2546
+
2547
+ const INIT_PROFILE_OPTIONS = Object.freeze([
2548
+ {
2549
+ label: 'Default',
2550
+ value: 'default',
2551
+ hint: 'Contrato AI-first recomendado',
2552
+ default: true,
2553
+ },
2554
+ {
2555
+ label: 'Minimal',
2556
+ value: 'minimal',
2557
+ hint: 'Solo documentos esenciales',
2558
+ },
2559
+ {
2560
+ label: 'Full compatibility',
2561
+ value: 'full',
2562
+ hint: 'Incluye compatibilidad historica y templates visibles',
2563
+ },
2564
+ ]);
2565
+
2566
+ function hasDirectoryContent(dirPath) {
2567
+ return fs.existsSync(dirPath)
2568
+ && fs.statSync(dirPath).isDirectory()
2569
+ && fs.readdirSync(dirPath).length > 0;
2570
+ }
2571
+
2572
+ function assertSupportedMethodology(value) {
2573
+ const normalized = String(value || '').trim();
2574
+ if (!normalized) {
2575
+ return 'wdd-sdd';
2576
+ }
2577
+ if (normalized !== 'wdd-sdd') {
2578
+ throw new Error(formatError(`unsupported methodology '${normalized}'. Supported methodologies: wdd-sdd.`));
2579
+ }
2580
+ return normalized;
2581
+ }
2582
+
2583
+ async function resolveInteractiveInitOptions(args, targetDir, projectName, options = {}) {
2584
+ const explicitMethodology = assertSupportedMethodology(args.methodology);
2585
+
2586
+ if (args.interactive !== true) {
2587
+ return {
2588
+ action: 'init',
2589
+ full: args.initFull,
2590
+ includeTemplates: args.initIncludeTemplates,
2591
+ legacyScripts: args.initLegacyScripts,
2592
+ methodology: explicitMethodology,
2593
+ minimal: args.initMinimal,
2594
+ projectName,
2595
+ };
2596
+ }
2597
+
2598
+ const ux = createUx({
2599
+ env: options.env,
2600
+ input: options.input,
2601
+ interactive: true,
2602
+ noColor: args.noColor,
2603
+ output: options.output,
2604
+ promptConfirm: options.promptConfirm,
2605
+ stderrIsTTY: options.stderrIsTTY,
2606
+ stdinIsTTY: options.stdinIsTTY,
2607
+ stdoutIsTTY: options.stdoutIsTTY,
2608
+ write: options.write,
2609
+ });
2610
+
2611
+ if (!ux.mode.usePrompts) {
2612
+ throw new Error(formatError('init --interactive requires an interactive TTY. Use explicit flags such as --name, --minimal, --full, --legacy-scripts, --include-templates, or run doctor to validate structure.'));
2613
+ }
2614
+
2615
+ const selectorOptions = {
2616
+ env: options.env,
2617
+ input: options.input,
2618
+ interactive: true,
2619
+ noColor: args.noColor,
2620
+ output: options.output,
2621
+ prompts: options.prompts,
2622
+ promptSelect: options.promptSelect,
2623
+ stderrIsTTY: options.stderrIsTTY,
2624
+ stdinIsTTY: options.stdinIsTTY,
2625
+ stdoutIsTTY: options.stdoutIsTTY,
2626
+ };
2627
+
2628
+ ux.heading('Bienvenido a Quiver');
2629
+ const selectedMode = await selectOption('¿Qué querés configurar?', INIT_MODE_OPTIONS, {
2630
+ ...selectorOptions,
2631
+ defaultValue: hasDirectoryContent(targetDir) ? 'existing' : 'new',
2632
+ flag: 'init|doctor',
2633
+ name: 'init mode',
2634
+ });
2635
+ const selectedMethodology = await selectOption('¿Qué metodología vas a usar?', METHODOLOGY_OPTIONS, {
2636
+ ...selectorOptions,
2637
+ defaultValue: explicitMethodology,
2638
+ flag: '--methodology',
2639
+ name: 'methodology',
2640
+ value: args.methodology || '',
2641
+ });
2642
+
2643
+ assertSupportedMethodology(selectedMethodology.value);
2644
+
2645
+ if (selectedMode.value === 'validate') {
2646
+ ux.summary([
2647
+ { label: 'Modo', value: 'Solo validar estructura' },
2648
+ { label: 'Metodologia', value: selectedMethodology.label },
2649
+ { label: 'Comando equivalente', value: 'npx create-quiver doctor' },
2650
+ ], { title: 'Configuracion elegida' });
2651
+ if (!args.force && !args.dryRun) {
2652
+ const confirmed = await ux.promptConfirm('Ejecutar Doctor ahora?', { initialValue: true });
2653
+ if (!confirmed) {
2654
+ throw new Error(formatError('init interactive validation declined. No files were written.'));
2655
+ }
2309
2656
  }
2310
- console.log(`- Start a slice: npx create-quiver start-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
2311
- console.log(`- Validate a slice: npx create-quiver check-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
2312
- console.log(`- Validate the PR gate: npx create-quiver check-pr specs/${projectSlug}/slices/${sliceId}/slice.json`);
2657
+ return {
2658
+ action: 'doctor',
2659
+ methodology: selectedMethodology.value,
2660
+ projectName,
2661
+ };
2662
+ }
2663
+
2664
+ const defaultProfile = args.initFull ? 'full' : args.initMinimal ? 'minimal' : 'default';
2665
+ const selectedProfile = await selectOption('¿Qué contrato inicial querés crear?', INIT_PROFILE_OPTIONS, {
2666
+ ...selectorOptions,
2667
+ defaultValue: defaultProfile,
2668
+ flag: '--minimal|--full',
2669
+ name: 'init profile',
2670
+ });
2671
+ const agentGuidance = await selectOption('¿Querés ver el próximo paso para perfiles de agentes?', [
2672
+ {
2673
+ label: 'Mostrar comandos sugeridos',
2674
+ value: 'show',
2675
+ hint: 'No guarda credenciales ni ejecuta proveedores',
2676
+ default: true,
2677
+ },
2678
+ {
2679
+ label: 'Omitir por ahora',
2680
+ value: 'skip',
2681
+ },
2682
+ ], {
2683
+ ...selectorOptions,
2684
+ defaultValue: 'show',
2685
+ flag: 'ai agent set',
2686
+ name: 'agent profile guidance',
2687
+ });
2688
+ const nextFlags = {
2689
+ full: selectedProfile.value === 'full',
2690
+ includeTemplates: args.initIncludeTemplates || selectedProfile.value === 'full',
2691
+ legacyScripts: args.initLegacyScripts,
2692
+ methodology: selectedMethodology.value,
2693
+ minimal: selectedProfile.value === 'minimal',
2694
+ projectName,
2695
+ };
2696
+
2697
+ ux.summary([
2698
+ { label: 'Proyecto', value: projectName },
2699
+ { label: 'Modo', value: selectedMode.label },
2700
+ { label: 'Metodologia', value: selectedMethodology.label },
2701
+ { label: 'Perfil', value: selectedProfile.label },
2702
+ { label: 'Perfiles de agentes', value: agentGuidance.value === 'show' ? 'mostrar proximo paso' : 'omitir' },
2703
+ ], { title: 'Configuracion elegida' });
2704
+
2705
+ if (agentGuidance.value === 'show') {
2706
+ ux.nextSteps([
2707
+ 'npx create-quiver ai agent set planner --provider codex --model "<modelo-planner>" --dry-run',
2708
+ 'npx create-quiver ai agent set executor --provider claude --model "<modelo-executor>" --dry-run',
2709
+ ], { title: 'Despues de inicializar' });
2710
+ }
2711
+
2712
+ if (!args.force && !args.dryRun) {
2713
+ const confirmed = await ux.promptConfirm(`Inicializar Quiver en ${targetDir}?`, { initialValue: true });
2714
+ if (!confirmed) {
2715
+ throw new Error(formatError('init interactive approval declined. No files were written.'));
2716
+ }
2717
+ }
2718
+
2719
+ return {
2720
+ action: 'init',
2721
+ ...nextFlags,
2722
+ };
2723
+ }
2724
+
2725
+ function runDoctor(targetDir, options = {}) {
2726
+ const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
2727
+
2728
+ if (!fs.existsSync(projectRoot)) {
2729
+ throw new Error(formatError(`target directory does not exist: ${projectRoot}`));
2730
+ }
2731
+
2732
+ if (!hasQuiverInitializationEvidence(projectRoot)) {
2733
+ throw new Error(formatError('doctor requires a project previously initialized by Quiver.\nRun init first: npx create-quiver --name "Project Name"'));
2734
+ }
2735
+
2736
+ const fixPlan = buildDoctorFixPlan(projectRoot);
2737
+ if (options.fix) {
2738
+ if (options.dryRun) {
2739
+ if (options.json) {
2740
+ console.log(JSON.stringify({
2741
+ schema_version: 1,
2742
+ command: 'doctor fix',
2743
+ dry_run: true,
2744
+ fixes: fixPlan,
2745
+ }, null, 2));
2746
+ return;
2747
+ }
2748
+ console.log(formatDoctorFixPlan(fixPlan, { dryRun: true }));
2749
+ return;
2750
+ }
2751
+
2752
+ applyDoctorFixPlan(projectRoot, fixPlan);
2753
+ if (!options.json) {
2754
+ console.log(formatDoctorFixPlan(fixPlan));
2755
+ }
2756
+ }
2757
+
2758
+ const commandReport = buildDoctorCommandReport(projectRoot);
2759
+ if (options.json) {
2760
+ console.log(JSON.stringify(commandReport, null, 2));
2313
2761
  } else {
2314
- console.log('- Create real specs and slices only after acceptance criteria are approved and the technical plan is reviewed and approved.');
2762
+ process.stdout.write(formatDoctorHumanReport(commandReport, {
2763
+ noColor: options.noColor,
2764
+ unicode: options.unicode,
2765
+ }));
2766
+ }
2767
+
2768
+ if (commandReport.exit_code !== 0) {
2769
+ process.exitCode = commandReport.exit_code;
2315
2770
  }
2316
2771
  }
2317
2772
 
@@ -2342,6 +2797,8 @@ async function run(argv) {
2342
2797
  return;
2343
2798
  }
2344
2799
 
2800
+ validateUxFlags(args);
2801
+
2345
2802
  if (args.mode === 'analyze') {
2346
2803
  runAnalyze(args.targetDir, {
2347
2804
  dryRun: args.dryRun,
@@ -2456,6 +2913,9 @@ async function run(argv) {
2456
2913
  runAiAgent(process.cwd(), {
2457
2914
  command: args.aiAgentCommand,
2458
2915
  context: args.aiContext || undefined,
2916
+ defaultProfile: args.aiDefaultProfile,
2917
+ displayName: args.aiDisplayName || undefined,
2918
+ id: args.aiProfileId || undefined,
2459
2919
  label: args.aiLabel || undefined,
2460
2920
  model: args.aiModel || undefined,
2461
2921
  provider: args.aiProviderExplicit ? args.aiProvider : undefined,
@@ -2473,6 +2933,8 @@ async function run(argv) {
2473
2933
  printPrompt: args.aiPrintPrompt,
2474
2934
  provider: args.aiProvider,
2475
2935
  providerExplicit: args.aiProviderExplicit,
2936
+ model: args.aiModel || undefined,
2937
+ plannerProfile: args.aiPlannerProfile || undefined,
2476
2938
  role: args.aiRole,
2477
2939
  timeout: args.aiTimeout,
2478
2940
  });
@@ -2481,8 +2943,19 @@ async function run(argv) {
2481
2943
 
2482
2944
  if (args.aiCommand === 'prepare-context') {
2483
2945
  await runAiPrepareContext(process.cwd(), {
2946
+ context: args.aiContext || undefined,
2484
2947
  dryRun: args.dryRun,
2948
+ interactive: args.interactive,
2949
+ printPrompt: args.aiPrintPrompt,
2950
+ provider: args.aiProvider,
2951
+ providerExplicit: args.aiProviderExplicit,
2952
+ model: args.aiModel || undefined,
2953
+ plannerProfile: args.aiPlannerProfile || undefined,
2954
+ review: args.review,
2955
+ role: args.aiRole,
2485
2956
  runId: args.aiRunId || undefined,
2957
+ timeout: args.aiTimeout,
2958
+ withPlanner: args.withPlanner,
2486
2959
  });
2487
2960
  return;
2488
2961
  }
@@ -2496,10 +2969,15 @@ async function run(argv) {
2496
2969
  printPrompt: args.aiPrintPrompt,
2497
2970
  provider: args.aiProvider,
2498
2971
  providerExplicit: args.aiProviderExplicit,
2972
+ model: args.aiModel || undefined,
2973
+ plannerProfile: args.aiPlannerProfile || undefined,
2974
+ interactive: args.interactive,
2975
+ review: args.review,
2499
2976
  role: args.aiRole,
2500
2977
  runId: args.aiRunId || undefined,
2501
2978
  specSlug: args.specSlug || undefined,
2502
2979
  timeout: args.aiTimeout,
2980
+ withPlanner: args.withPlanner,
2503
2981
  });
2504
2982
  return;
2505
2983
  }
@@ -2512,6 +2990,8 @@ async function run(argv) {
2512
2990
  printPrompt: args.aiPrintPrompt,
2513
2991
  provider: args.aiProvider,
2514
2992
  providerExplicit: args.aiProviderExplicit,
2993
+ model: args.aiModel || undefined,
2994
+ reviewerProfile: args.aiReviewerProfile || undefined,
2515
2995
  timeout: args.aiTimeout,
2516
2996
  });
2517
2997
  return;
@@ -2525,6 +3005,8 @@ async function run(argv) {
2525
3005
  printPrompt: args.aiPrintPrompt,
2526
3006
  provider: args.aiProvider,
2527
3007
  providerExplicit: args.aiProviderExplicit,
3008
+ model: args.aiModel || undefined,
3009
+ plannerProfile: args.aiPlannerProfile || undefined,
2528
3010
  role: args.aiRole,
2529
3011
  runId: args.aiRunId || undefined,
2530
3012
  timeout: args.aiTimeout,
@@ -2541,6 +3023,8 @@ async function run(argv) {
2541
3023
  printPrompt: args.aiPrintPrompt,
2542
3024
  provider: args.aiProvider,
2543
3025
  providerExplicit: args.aiProviderExplicit,
3026
+ model: args.aiModel || undefined,
3027
+ plannerProfile: args.aiPlannerProfile || undefined,
2544
3028
  role: args.aiRole,
2545
3029
  runId: args.aiRunId || undefined,
2546
3030
  timeout: args.aiTimeout,
@@ -2570,6 +3054,9 @@ async function run(argv) {
2570
3054
  commit: args.aiCommit,
2571
3055
  context: args.aiContext || undefined,
2572
3056
  dryRun: args.dryRun,
3057
+ executorProfile: args.aiExecutorProfile || undefined,
3058
+ interactive: args.interactive,
3059
+ model: args.aiModel || undefined,
2573
3060
  provider: args.aiProvider,
2574
3061
  providerExplicit: args.aiProviderExplicit,
2575
3062
  role: args.aiRole,
@@ -2593,7 +3080,10 @@ async function run(argv) {
2593
3080
  context: args.aiContext || undefined,
2594
3081
  dryRun: args.dryRun,
2595
3082
  execute: args.aiExecute,
3083
+ executorProfile: args.aiExecutorProfile || undefined,
3084
+ interactive: args.interactive,
2596
3085
  json: args.json,
3086
+ model: args.aiModel || undefined,
2597
3087
  mode: args.aiExecutionMode,
2598
3088
  provider: args.aiProvider,
2599
3089
  providerExplicit: args.aiProviderExplicit,
@@ -2620,7 +3110,9 @@ async function run(argv) {
2620
3110
  create: args.aiCreate,
2621
3111
  dryRun: args.dryRun,
2622
3112
  input: args.aiInput || undefined,
3113
+ interactive: args.interactive,
2623
3114
  remote: args.aiRemote || undefined,
3115
+ review: args.review,
2624
3116
  sshHostAlias: args.aiSshHostAlias || undefined,
2625
3117
  identityFile: args.aiIdentityFile || undefined,
2626
3118
  title: args.aiTitle || undefined,
@@ -2689,6 +3181,9 @@ async function run(argv) {
2689
3181
  runDoctor(args.targetDir, {
2690
3182
  dryRun: args.dryRun,
2691
3183
  fix: args.doctorFix,
3184
+ json: args.json,
3185
+ noColor: args.noColor,
3186
+ unicode: args.unicode,
2692
3187
  });
2693
3188
  return;
2694
3189
  }
@@ -2760,10 +3255,14 @@ async function run(argv) {
2760
3255
 
2761
3256
  if (args.mode === 'spec') {
2762
3257
  if (args.specCommand === 'create') {
2763
- runCreateSpec(process.cwd(), {
3258
+ await runCreateSpec(process.cwd(), {
2764
3259
  dryRun: args.dryRun,
2765
3260
  input: args.aiInput || undefined,
3261
+ interactive: args.interactive,
3262
+ methodology: args.methodology || undefined,
3263
+ review: args.review,
2766
3264
  specSlug: args.specSlug || undefined,
3265
+ withPlanner: args.withPlanner,
2767
3266
  });
2768
3267
  return;
2769
3268
  }
@@ -2811,14 +3310,25 @@ async function run(argv) {
2811
3310
  const packageRoot = path.resolve(__dirname, '../..');
2812
3311
  const targetDir = resolveTargetRoot(process.cwd(), args.targetDir);
2813
3312
  const projectName = args.projectName || path.basename(targetDir) || 'Quiver Project';
3313
+ const initOptions = await resolveInteractiveInitOptions(args, targetDir, projectName);
3314
+ if (initOptions.action === 'doctor') {
3315
+ runDoctor(targetDir, {
3316
+ dryRun: args.dryRun,
3317
+ fix: false,
3318
+ json: args.json,
3319
+ noColor: args.noColor,
3320
+ unicode: args.unicode,
3321
+ });
3322
+ return;
3323
+ }
2814
3324
  const initLayout = buildInitLayout(targetDir, {
2815
3325
  compatibilityAlias: !args.explicitInit,
2816
3326
  dryRun: args.dryRun,
2817
- full: args.initFull,
2818
- includeTemplates: args.initIncludeTemplates,
2819
- legacyScripts: args.initLegacyScripts,
2820
- minimal: args.initMinimal,
2821
- projectName,
3327
+ full: initOptions.full,
3328
+ includeTemplates: initOptions.includeTemplates,
3329
+ legacyScripts: initOptions.legacyScripts,
3330
+ minimal: initOptions.minimal,
3331
+ projectName: initOptions.projectName,
2822
3332
  skipInstall: args.skipInstall,
2823
3333
  });
2824
3334
 
@@ -2836,9 +3346,9 @@ async function run(argv) {
2836
3346
  if (initLayout.profile === 'full') {
2837
3347
  exportTemplatesToLegacyRoot(templateRoot, targetDir);
2838
3348
  }
2839
- runInitDocs(targetDir, projectName, {
2840
- includeTemplates: args.initIncludeTemplates,
2841
- legacyScripts: args.initLegacyScripts,
3349
+ runInitDocs(targetDir, initOptions.projectName, {
3350
+ includeTemplates: initOptions.includeTemplates,
3351
+ legacyScripts: initOptions.legacyScripts,
2842
3352
  profile: initLayout.profile,
2843
3353
  templateRoot,
2844
3354
  });
@@ -2853,13 +3363,14 @@ async function run(argv) {
2853
3363
  }
2854
3364
 
2855
3365
  console.log(`Installed Quiver into ${targetDir}`);
2856
- printInitNextSteps(targetDir, projectName);
3366
+ printInitNextSteps(targetDir, initOptions.projectName);
2857
3367
  } finally {
2858
3368
  fs.rmSync(tempRoot, { recursive: true, force: true });
2859
3369
  }
2860
3370
  }
2861
3371
 
2862
3372
  module.exports = {
3373
+ resolveInteractiveInitOptions,
2863
3374
  runAnalyze,
2864
3375
  runDoctor,
2865
3376
  runFlow,