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.
- package/CHANGELOG.md +27 -0
- package/README.md +187 -518
- package/README_FOR_AI.md +39 -27
- package/ROADMAP.md +11 -0
- package/assets/quiver-wordmark.svg +22 -0
- package/docs/AI_CONTEXT.md.template +2 -0
- package/docs/AI_ONBOARDING_PROMPT.md.template +9 -1
- package/docs/CLI_UX_GUIDE.md +185 -0
- package/docs/COMMANDS.md.template +22 -3
- package/docs/GITFLOW_PR_GUIDE.md +70 -0
- package/docs/getting-started/linux.md +84 -0
- package/docs/getting-started/macos.md +85 -0
- package/docs/getting-started/windows-git-bash-wsl.md +78 -0
- package/docs/getting-started/windows-powershell.md +96 -0
- package/docs/reference/commands.md +98 -0
- package/docs/workflows/existing-project.md +131 -0
- package/docs/workflows/full-ai-spec-to-pr.md +311 -0
- package/docs/workflows/legacy-quiver-project.md +102 -0
- package/docs/workflows/new-project.md +76 -0
- package/package.json +5 -1
- package/specs/quiver-v29-planner-prepare-context-cli-ux/EVIDENCE_REPORT.md +163 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/EXECUTION_PLAN.md +72 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/SPEC.md +173 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/STATUS.md +34 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/pr.md +95 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/EXECUTION_BRIEF.md +45 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/slice.json +58 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/EXECUTION_BRIEF.md +49 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/slice.json +75 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/EXECUTION_BRIEF.md +47 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/slice.json +71 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/EXECUTION_BRIEF.md +52 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/slice.json +82 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/EXECUTION_BRIEF.md +46 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/slice.json +73 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/EXECUTION_BRIEF.md +46 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/slice.json +83 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/EXECUTION_BRIEF.md +50 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/slice.json +95 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/EVIDENCE_REPORT.md +213 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/EXECUTION_PLAN.md +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/SPEC.md +213 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/STATUS.md +31 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/pr.md +103 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/slice.json +71 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/EXECUTION_BRIEF.md +54 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/slice.json +69 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/slice.json +81 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/EXECUTION_BRIEF.md +54 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/slice.json +75 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/EXECUTION_BRIEF.md +57 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/slice.json +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/EXECUTION_BRIEF.md +57 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/slice.json +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/CLOSURE_BRIEF.md +35 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/EXECUTION_BRIEF.md +55 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/slice.json +81 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/EXECUTION_BRIEF.md +55 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/slice.json +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/EXECUTION_BRIEF.md +59 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/slice.json +95 -0
- package/src/create-quiver/commands/ai.js +809 -71
- package/src/create-quiver/commands/spec.js +167 -5
- package/src/create-quiver/index.js +582 -71
- package/src/create-quiver/lib/agent-profiles.js +111 -10
- package/src/create-quiver/lib/ai/context-proposal.js +389 -0
- package/src/create-quiver/lib/ai/context-proposal.schema.js +31 -0
- package/src/create-quiver/lib/ai/execution-plan.js +106 -8
- package/src/create-quiver/lib/ai/executor.js +284 -28
- package/src/create-quiver/lib/ai/providers.js +71 -1
- package/src/create-quiver/lib/cli/editor.js +118 -0
- package/src/create-quiver/lib/cli/selectors.js +107 -0
- package/src/create-quiver/lib/cli/theme.js +103 -0
- package/src/create-quiver/lib/cli/ux-flags.js +169 -0
- 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
|
|
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 (
|
|
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:
|
|
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
|
|