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
@@ -2,6 +2,9 @@ const fs = require('node:fs');
2
2
  const path = require('node:path');
3
3
 
4
4
  const { checkHandoff } = require('../lib/handoff');
5
+ const { openEditor } = require('../lib/cli/editor');
6
+ const { selectOption } = require('../lib/cli/selectors');
7
+ const { createUx } = require('../lib/cli/ux');
5
8
  const { parseJsonWithComments } = require('../lib/json');
6
9
  const { assertPathInsideRoot, validateProjectRelativePaths } = require('../lib/paths');
7
10
  const { resolveReviewedTechnicalPlanInput } = require('../lib/ai/plan-review');
@@ -362,6 +365,10 @@ function formatSpecCreateDryRun(preview) {
362
365
  lines.push(`- ${file}`);
363
366
  }
364
367
 
368
+ if (preview.reviewRequested) {
369
+ lines.push('Review requested: yes (dry-run preview only; no editor opened and no files written).');
370
+ }
371
+
365
372
  lines.push(...formatNextCommands(preview.relativeSpecDir));
366
373
  lines.push('No files will be written in dry-run mode.');
367
374
  return `${lines.join('\n')}\n`;
@@ -384,11 +391,162 @@ function formatSpecCreateResult(result, repoRoot) {
384
391
  return `${lines.join('\n')}\n`;
385
392
  }
386
393
 
387
- function runCreateSpec(repoRoot, options = {}) {
394
+ function createSpecReviewFile(preview, options = {}) {
395
+ const os = require('node:os');
396
+ const reviewDir = options.reviewDir || fs.mkdtempSync(path.join(os.tmpdir(), 'quiver-spec-create-review-'));
397
+ const reviewPath = path.join(reviewDir, 'spec-create-preview.md');
398
+ fs.mkdirSync(reviewDir, { recursive: true });
399
+ fs.writeFileSync(reviewPath, formatSpecCreateDryRun({ ...preview, reviewRequested: false }));
400
+ return reviewPath;
401
+ }
402
+
403
+ const SPEC_METHODOLOGY_OPTIONS = Object.freeze([
404
+ {
405
+ label: 'WDD + SDD',
406
+ value: 'wdd-sdd',
407
+ hint: 'Workflow Driven Development + Spec Driven Development',
408
+ default: true,
409
+ },
410
+ ]);
411
+
412
+ async function resolveInteractiveSpecCreateOptions(repoRoot, preview, options = {}) {
413
+ if (options.interactive !== true) {
414
+ return options;
415
+ }
416
+
417
+ const ux = options.ux || createUx({
418
+ interactive: true,
419
+ promptConfirm: options.promptConfirm,
420
+ stdinIsTTY: options.stdinIsTTY,
421
+ stdoutIsTTY: options.stdoutIsTTY,
422
+ stderrIsTTY: options.stderrIsTTY,
423
+ write: options.write,
424
+ });
425
+
426
+ if (!ux.mode.usePrompts) {
427
+ throw new Error(formatError('spec create --interactive requires an interactive TTY. Use --input, --spec, --review, and --dry-run for non-interactive automation.'));
428
+ }
429
+
430
+ const selectorOptions = {
431
+ env: options.env,
432
+ input: options.inputStream,
433
+ interactive: true,
434
+ noColor: options.noColor,
435
+ output: options.output,
436
+ prompts: options.prompts,
437
+ promptSelect: options.promptSelect,
438
+ stderrIsTTY: options.stderrIsTTY,
439
+ stdinIsTTY: options.stdinIsTTY,
440
+ stdoutIsTTY: options.stdoutIsTTY,
441
+ };
442
+ const selectedMethodology = await selectOption('¿Qué metodología aplica esta spec?', SPEC_METHODOLOGY_OPTIONS, {
443
+ ...selectorOptions,
444
+ defaultValue: 'wdd-sdd',
445
+ flag: '--methodology',
446
+ name: 'methodology',
447
+ value: options.methodology || '',
448
+ });
449
+ const selectedInput = await selectOption('¿Qué plan aprobado querés usar?', [
450
+ {
451
+ label: preview.inputPath,
452
+ value: preview.inputPath,
453
+ hint: 'Plan técnico revisado y aprobado',
454
+ default: true,
455
+ },
456
+ ], {
457
+ ...selectorOptions,
458
+ defaultValue: preview.inputPath,
459
+ flag: '--input',
460
+ name: 'approved technical plan input',
461
+ value: options.input || '',
462
+ });
463
+ const selectedReview = await selectOption('¿Cómo querés revisar antes de escribir?', [
464
+ {
465
+ label: 'Crear despues de confirmar',
466
+ value: 'direct',
467
+ hint: 'Muestra resumen y pide aprobacion final',
468
+ default: options.review !== true,
469
+ },
470
+ {
471
+ label: 'Abrir preview de review',
472
+ value: 'review',
473
+ hint: 'Usa $VISUAL o $EDITOR antes de escribir',
474
+ default: options.review === true,
475
+ },
476
+ ], {
477
+ ...selectorOptions,
478
+ defaultValue: options.review === true ? 'review' : 'direct',
479
+ flag: '--review',
480
+ name: 'spec create review mode',
481
+ });
482
+
483
+ ux.summary([
484
+ { label: 'Spec', value: preview.manifest.slug },
485
+ { label: 'Metodologia', value: selectedMethodology.label },
486
+ { label: 'Input', value: selectedInput.value },
487
+ { label: 'Target', value: preview.relativeSpecDir },
488
+ { label: 'Archivos planificados', value: preview.preview.files.length },
489
+ { label: 'Revision', value: selectedReview.value === 'review' ? 'abrir preview' : 'confirmacion directa' },
490
+ ], { title: 'Spec create' });
491
+
492
+ return {
493
+ ...options,
494
+ input: selectedInput.value,
495
+ methodology: selectedMethodology.value,
496
+ review: selectedReview.value === 'review',
497
+ ux,
498
+ };
499
+ }
500
+
501
+ async function confirmSpecCreate(message, options = {}) {
502
+ if (options.interactive !== true) {
503
+ return;
504
+ }
505
+
506
+ const ux = options.ux || createUx({
507
+ interactive: true,
508
+ promptConfirm: options.promptConfirm,
509
+ stdinIsTTY: options.stdinIsTTY,
510
+ stdoutIsTTY: options.stdoutIsTTY,
511
+ stderrIsTTY: options.stderrIsTTY,
512
+ write: options.write,
513
+ });
514
+ const confirmed = await ux.promptConfirm(message, { initialValue: false });
515
+ if (!confirmed) {
516
+ throw new Error(formatError('spec create interactive approval declined. No files were written.'));
517
+ }
518
+ }
519
+
520
+ async function reviewSpecCreatePreview(repoRoot, preview, options = {}) {
521
+ if (options.review !== true) {
522
+ return '';
523
+ }
524
+
525
+ const reviewPath = createSpecReviewFile(preview, options);
526
+ const hasEditorRunner = typeof options.openEditorFn === 'function';
527
+ const canOpenEditor = hasEditorRunner || options.stdinIsTTY === true || (options.stdinIsTTY !== false && Boolean(process.stdin.isTTY));
528
+
529
+ if (!canOpenEditor) {
530
+ throw new Error(formatError(`spec create --review requires an interactive terminal or an injected editor runner.\nReview artifact: ${reviewPath}`));
531
+ }
532
+
533
+ const editorResult = hasEditorRunner
534
+ ? options.openEditorFn(reviewPath, { cwd: repoRoot, env: options.env || process.env })
535
+ : openEditor(reviewPath, { cwd: repoRoot, env: options.env || process.env });
536
+
537
+ if (!editorResult || editorResult.ok !== true) {
538
+ throw new Error(formatError(`${editorResult?.reason || 'spec create review was canceled.'}\nReview artifact: ${reviewPath}`));
539
+ }
540
+
541
+ return reviewPath;
542
+ }
543
+
544
+ async function runCreateSpec(repoRoot, options = {}) {
388
545
  const preview = buildSpecCreatePreview(repoRoot, options);
546
+ const resolvedOptions = await resolveInteractiveSpecCreateOptions(repoRoot, preview, options);
389
547
 
390
- if (options.dryRun) {
391
- process.stdout.write(formatSpecCreateDryRun(preview));
548
+ if (resolvedOptions.dryRun) {
549
+ process.stdout.write(formatSpecCreateDryRun({ ...preview, reviewRequested: resolvedOptions.review === true }));
392
550
  return {
393
551
  task: 'spec-create',
394
552
  dryRun: true,
@@ -398,9 +556,12 @@ function runCreateSpec(repoRoot, options = {}) {
398
556
  };
399
557
  }
400
558
 
559
+ const reviewPath = await reviewSpecCreatePreview(repoRoot, preview, resolvedOptions);
560
+ await confirmSpecCreate(`Create spec '${preview.manifest.slug}'?`, resolvedOptions);
561
+
401
562
  const result = generateSpecArtifacts(repoRoot, {
402
- input: preview.inputPath,
403
- specSlug: options.specSlug,
563
+ input: resolvedOptions.input || preview.inputPath,
564
+ specSlug: resolvedOptions.specSlug,
404
565
  });
405
566
  process.stdout.write(formatSpecCreateResult(result, repoRoot));
406
567
 
@@ -411,6 +572,7 @@ function runCreateSpec(repoRoot, options = {}) {
411
572
  specDir: toRelativePosix(repoRoot, result.specDir),
412
573
  files: result.files.map((filePath) => toRelativePosix(repoRoot, filePath)),
413
574
  manifest: result.manifest,
575
+ reviewPath,
414
576
  };
415
577
  }
416
578