create-quiver 0.13.0 → 0.14.1

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 +30 -0
  2. package/README.md +183 -511
  3. package/README_FOR_AI.md +36 -26
  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 +125 -0
  9. package/docs/COMMANDS.md.template +19 -4
  10. package/docs/GITFLOW_PR_GUIDE.md +70 -0
  11. package/docs/TROUBLESHOOTING.md.template +29 -0
  12. package/docs/WORKFLOW.md.template +13 -12
  13. package/docs/getting-started/linux.md +84 -0
  14. package/docs/getting-started/macos.md +85 -0
  15. package/docs/getting-started/windows-git-bash-wsl.md +78 -0
  16. package/docs/getting-started/windows-powershell.md +96 -0
  17. package/docs/reference/commands.md +94 -0
  18. package/docs/workflows/existing-project.md +131 -0
  19. package/docs/workflows/full-ai-spec-to-pr.md +311 -0
  20. package/docs/workflows/legacy-quiver-project.md +102 -0
  21. package/docs/workflows/new-project.md +76 -0
  22. package/package.json +5 -1
  23. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/COVERAGE_MATRIX.md +117 -0
  24. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/EVIDENCE_REPORT.md +200 -0
  25. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/EXECUTION_PLAN.md +60 -0
  26. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/SPEC.md +132 -0
  27. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/STATUS.md +36 -0
  28. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/pr.md +128 -0
  29. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/CLOSURE_BRIEF.md +44 -0
  30. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/EXECUTION_BRIEF.md +56 -0
  31. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/slice.json +71 -0
  32. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/CLOSURE_BRIEF.md +38 -0
  33. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/EXECUTION_BRIEF.md +53 -0
  34. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/slice.json +83 -0
  35. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/CLOSURE_BRIEF.md +33 -0
  36. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/EXECUTION_BRIEF.md +53 -0
  37. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/slice.json +85 -0
  38. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/CLOSURE_BRIEF.md +34 -0
  39. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/EXECUTION_BRIEF.md +52 -0
  40. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/slice.json +82 -0
  41. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/CLOSURE_BRIEF.md +32 -0
  42. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/EXECUTION_BRIEF.md +55 -0
  43. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/slice.json +85 -0
  44. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/CLOSURE_BRIEF.md +35 -0
  45. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/EXECUTION_BRIEF.md +59 -0
  46. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/slice.json +94 -0
  47. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/CLOSURE_BRIEF.md +40 -0
  48. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/EXECUTION_BRIEF.md +56 -0
  49. package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/slice.json +98 -0
  50. package/specs/quiver-v29-planner-prepare-context-cli-ux/EVIDENCE_REPORT.md +163 -0
  51. package/specs/quiver-v29-planner-prepare-context-cli-ux/EXECUTION_PLAN.md +72 -0
  52. package/specs/quiver-v29-planner-prepare-context-cli-ux/SPEC.md +173 -0
  53. package/specs/quiver-v29-planner-prepare-context-cli-ux/STATUS.md +34 -0
  54. package/specs/quiver-v29-planner-prepare-context-cli-ux/pr.md +95 -0
  55. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/CLOSURE_BRIEF.md +32 -0
  56. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/EXECUTION_BRIEF.md +45 -0
  57. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/slice.json +58 -0
  58. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/CLOSURE_BRIEF.md +33 -0
  59. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/EXECUTION_BRIEF.md +49 -0
  60. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/slice.json +75 -0
  61. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/CLOSURE_BRIEF.md +32 -0
  62. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/EXECUTION_BRIEF.md +47 -0
  63. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/slice.json +71 -0
  64. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/CLOSURE_BRIEF.md +33 -0
  65. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/EXECUTION_BRIEF.md +52 -0
  66. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/slice.json +82 -0
  67. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/CLOSURE_BRIEF.md +34 -0
  68. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/EXECUTION_BRIEF.md +46 -0
  69. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/slice.json +73 -0
  70. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/CLOSURE_BRIEF.md +34 -0
  71. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/EXECUTION_BRIEF.md +46 -0
  72. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/slice.json +83 -0
  73. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/CLOSURE_BRIEF.md +31 -0
  74. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/EXECUTION_BRIEF.md +50 -0
  75. package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/slice.json +95 -0
  76. package/src/create-quiver/commands/ai.js +938 -16
  77. package/src/create-quiver/commands/spec.js +74 -2
  78. package/src/create-quiver/index.js +91 -5
  79. package/src/create-quiver/lib/ai/context-packs.js +2 -2
  80. package/src/create-quiver/lib/ai/context-proposal.js +389 -0
  81. package/src/create-quiver/lib/ai/context-proposal.schema.js +31 -0
  82. package/src/create-quiver/lib/ai/export-state.js +52 -5
  83. package/src/create-quiver/lib/ai/github.js +14 -2
  84. package/src/create-quiver/lib/ai/plan-review.js +159 -0
  85. package/src/create-quiver/lib/ai/run-state.js +17 -2
  86. package/src/create-quiver/lib/ai/spec-generator.js +15 -0
  87. package/src/create-quiver/lib/cli/editor.js +118 -0
  88. package/src/create-quiver/lib/cli/theme.js +100 -0
  89. package/src/create-quiver/lib/cli/ux-flags.js +151 -0
  90. package/src/create-quiver/lib/cli/ux.js +130 -0
  91. package/src/create-quiver/lib/project-state-resolver.js +195 -1
  92. package/src/create-quiver/lib/spec-worktrees.js +50 -2
@@ -2,6 +2,8 @@ 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 { createUx } = require('../lib/cli/ux');
5
7
  const { parseJsonWithComments } = require('../lib/json');
6
8
  const { assertPathInsideRoot, validateProjectRelativePaths } = require('../lib/paths');
7
9
  const { resolveReviewedTechnicalPlanInput } = require('../lib/ai/plan-review');
@@ -129,6 +131,12 @@ function detectCycle(nodes) {
129
131
  return null;
130
132
  }
131
133
 
134
+ function missingGitFields(git) {
135
+ const data = git && typeof git === 'object' ? git : {};
136
+ return ['branch_type', 'base_branch', 'branch_slug', 'branch_name']
137
+ .filter((field) => !String(data[field] || '').trim());
138
+ }
139
+
132
140
  function buildSpecValidationReport(repoRoot, specInput, options = {}) {
133
141
  const strict = options.strict === true;
134
142
  const specDir = resolveSpecDir(repoRoot, specInput);
@@ -190,6 +198,10 @@ function buildSpecValidationReport(repoRoot, specInput, options = {}) {
190
198
  if (!Array.isArray(writeScope) || writeScope.length === 0) {
191
199
  errors.push(`${relativeSliceFile} must declare files or allowed_write_paths`);
192
200
  }
201
+ const missingGit = missingGitFields(json.git);
202
+ if (missingGit.length > 0) {
203
+ errors.push(`${relativeSliceFile} must declare git.branch_type, git.base_branch, git.branch_slug, and git.branch_name for local execution (missing: ${missingGit.join(', ')}).`);
204
+ }
193
205
  try {
194
206
  validateProjectRelativePaths(writeScope, `${relativeSliceFile} write scope`);
195
207
  validateProjectRelativePaths(json.expected_read_paths, `${relativeSliceFile} expected_read_paths`);
@@ -352,6 +364,10 @@ function formatSpecCreateDryRun(preview) {
352
364
  lines.push(`- ${file}`);
353
365
  }
354
366
 
367
+ if (preview.reviewRequested) {
368
+ lines.push('Review requested: yes (dry-run preview only; no editor opened and no files written).');
369
+ }
370
+
355
371
  lines.push(...formatNextCommands(preview.relativeSpecDir));
356
372
  lines.push('No files will be written in dry-run mode.');
357
373
  return `${lines.join('\n')}\n`;
@@ -374,11 +390,63 @@ function formatSpecCreateResult(result, repoRoot) {
374
390
  return `${lines.join('\n')}\n`;
375
391
  }
376
392
 
377
- function runCreateSpec(repoRoot, options = {}) {
393
+ function createSpecReviewFile(preview, options = {}) {
394
+ const os = require('node:os');
395
+ const reviewDir = options.reviewDir || fs.mkdtempSync(path.join(os.tmpdir(), 'quiver-spec-create-review-'));
396
+ const reviewPath = path.join(reviewDir, 'spec-create-preview.md');
397
+ fs.mkdirSync(reviewDir, { recursive: true });
398
+ fs.writeFileSync(reviewPath, formatSpecCreateDryRun({ ...preview, reviewRequested: false }));
399
+ return reviewPath;
400
+ }
401
+
402
+ async function confirmSpecCreate(message, options = {}) {
403
+ if (options.interactive !== true) {
404
+ return;
405
+ }
406
+
407
+ const ux = options.ux || createUx({
408
+ interactive: true,
409
+ promptConfirm: options.promptConfirm,
410
+ stdinIsTTY: options.stdinIsTTY,
411
+ stdoutIsTTY: options.stdoutIsTTY,
412
+ stderrIsTTY: options.stderrIsTTY,
413
+ write: options.write,
414
+ });
415
+ const confirmed = await ux.promptConfirm(message, { initialValue: false });
416
+ if (!confirmed) {
417
+ throw new Error(formatError('spec create interactive approval declined. No files were written.'));
418
+ }
419
+ }
420
+
421
+ async function reviewSpecCreatePreview(repoRoot, preview, options = {}) {
422
+ if (options.review !== true) {
423
+ return '';
424
+ }
425
+
426
+ const reviewPath = createSpecReviewFile(preview, options);
427
+ const hasEditorRunner = typeof options.openEditorFn === 'function';
428
+ const canOpenEditor = hasEditorRunner || options.stdinIsTTY === true || (options.stdinIsTTY !== false && Boolean(process.stdin.isTTY));
429
+
430
+ if (!canOpenEditor) {
431
+ throw new Error(formatError(`spec create --review requires an interactive terminal or an injected editor runner.\nReview artifact: ${reviewPath}`));
432
+ }
433
+
434
+ const editorResult = hasEditorRunner
435
+ ? options.openEditorFn(reviewPath, { cwd: repoRoot, env: options.env || process.env })
436
+ : openEditor(reviewPath, { cwd: repoRoot, env: options.env || process.env });
437
+
438
+ if (!editorResult || editorResult.ok !== true) {
439
+ throw new Error(formatError(`${editorResult?.reason || 'spec create review was canceled.'}\nReview artifact: ${reviewPath}`));
440
+ }
441
+
442
+ return reviewPath;
443
+ }
444
+
445
+ async function runCreateSpec(repoRoot, options = {}) {
378
446
  const preview = buildSpecCreatePreview(repoRoot, options);
379
447
 
380
448
  if (options.dryRun) {
381
- process.stdout.write(formatSpecCreateDryRun(preview));
449
+ process.stdout.write(formatSpecCreateDryRun({ ...preview, reviewRequested: options.review === true }));
382
450
  return {
383
451
  task: 'spec-create',
384
452
  dryRun: true,
@@ -388,6 +456,9 @@ function runCreateSpec(repoRoot, options = {}) {
388
456
  };
389
457
  }
390
458
 
459
+ const reviewPath = await reviewSpecCreatePreview(repoRoot, preview, options);
460
+ await confirmSpecCreate(`Create spec '${preview.manifest.slug}'?`, options);
461
+
391
462
  const result = generateSpecArtifacts(repoRoot, {
392
463
  input: preview.inputPath,
393
464
  specSlug: options.specSlug,
@@ -401,6 +472,7 @@ function runCreateSpec(repoRoot, options = {}) {
401
472
  specDir: toRelativePosix(repoRoot, result.specDir),
402
473
  files: result.files.map((filePath) => toRelativePosix(repoRoot, filePath)),
403
474
  manifest: result.manifest,
475
+ reviewPath,
404
476
  };
405
477
  }
406
478
 
@@ -10,6 +10,7 @@ const {
10
10
  formatDoctorFixPlan,
11
11
  } = require('./lib/doctor');
12
12
  const {
13
+ runActiveSlice: runAiActiveSlice,
13
14
  runAgent: runAiAgent,
14
15
  runApprovalStatus: runAiApprovalStatus,
15
16
  runApprove: runAiApprove,
@@ -25,6 +26,7 @@ const {
25
26
  runPlan: runAiPlan,
26
27
  runPrepareContext: runAiPrepareContext,
27
28
  runPr: runAiPr,
29
+ runRepairPlan: runAiRepairPlan,
28
30
  runPromptSlice: runAiPromptSlice,
29
31
  runReviewPlan: runAiReviewPlan,
30
32
  runRevise: runAiRevise,
@@ -51,6 +53,7 @@ const { checkPrReadiness, checkScope, checkSliceReadiness } = require('./lib/rea
51
53
  const { cleanupSlice, refreshActiveSlicesBoard, startSlice } = require('./lib/lifecycle');
52
54
  const { buildSpecStatus, closeSpecWorktree, formatSpecCloseResult, formatSpecStartResult, formatSpecStatus, startSpecWorktree } = require('./lib/spec-worktrees');
53
55
  const { getContextPathExclusionReason } = require('./lib/ai/safety');
56
+ const { validateUxFlags } = require('./lib/cli/ux-flags');
54
57
  const { relativePosixPath, resolveTargetRoot } = require('./lib/paths');
55
58
  const {
56
59
  CURRENT_SCAN_RELATIVE_PATH,
@@ -99,6 +102,7 @@ const SUPPORTED_COMMAND_MODES = new Set([
99
102
  ]);
100
103
 
101
104
  const SUPPORTED_AI_COMMANDS = new Set([
105
+ 'active-slice',
102
106
  'agent',
103
107
  'approve',
104
108
  'approval-status',
@@ -114,6 +118,7 @@ const SUPPORTED_AI_COMMANDS = new Set([
114
118
  'prepare-context',
115
119
  'pr',
116
120
  'prompt-slice',
121
+ 'repair-plan',
117
122
  'review-plan',
118
123
  'revise',
119
124
  'resume',
@@ -159,7 +164,8 @@ const COMMAND_HELP_GROUPS = [
159
164
  {
160
165
  title: 'AI lifecycle',
161
166
  commands: [
162
- ['ai run create', 'Create a durable AI lifecycle run from a requirements file.'],
167
+ ['ai run create|close', 'Create a durable AI lifecycle run or close/archive a completed or stale run without deleting evidence.'],
168
+ ['ai active-slice status|reconcile', 'Inspect or dry-run reconcile local active-slice state from every supported source.'],
163
169
  ['ai status', 'Show current AI lifecycle phase, approved versions, blockers, and next command.'],
164
170
  ['ai resume', 'Resume guidance from the last valid lifecycle phase without chat memory.'],
165
171
  ['ai onboard', 'Run or print the planner onboarding prompt with a token-aware context pack.'],
@@ -167,6 +173,7 @@ const COMMAND_HELP_GROUPS = [
167
173
  ['ai agent set|list|show', 'Manage planner, executor, reviewer, and doctor provider profiles without secrets; use set --dry-run to preview.'],
168
174
  ['ai plan', 'Generate versioned planner drafts for acceptance criteria, technical plan, or spec phase.'],
169
175
  ['ai revise', 'Create a new planner draft from human feedback without approving it.'],
176
+ ['ai repair-plan', 'Repair an approved technical plan into a new structured draft without mutating the approved artifact.'],
170
177
  ['ai review-plan', 'Review the technical-plan draft for production readiness before approval.'],
171
178
  ['ai approve', 'Approve a concrete saved draft version for the next planner phase.'],
172
179
  ['ai approvals', 'Inspect approval status and saved planner drafts.'],
@@ -243,6 +250,8 @@ function printUsage() {
243
250
  npx create-quiver plan [options]
244
251
  npx create-quiver ai <task> [options]
245
252
  npx create-quiver ai run create --input <requirements.md>
253
+ npx create-quiver ai run close --run <id>
254
+ npx create-quiver ai active-slice reconcile --dry-run
246
255
  npx create-quiver ai status [options]
247
256
  npx create-quiver ai resume [options]
248
257
  npx create-quiver ai inspect [options]
@@ -253,6 +262,7 @@ function printUsage() {
253
262
  npx create-quiver ai agent <set|list|show> [role] [options]
254
263
  npx create-quiver ai prepare-context [options]
255
264
  npx create-quiver ai revise [options]
265
+ npx create-quiver ai repair-plan [options]
256
266
  npx create-quiver graph [options]
257
267
  npx create-quiver next [options]
258
268
  npx create-quiver migrate [options]
@@ -297,6 +307,10 @@ Options:
297
307
  --include-templates Export packaged templates in init profile
298
308
  --dry-run Preview init, analyze, migrate, prepare, spec create/start/close, demo, ai agent set, or AI work without executing writes/providers
299
309
  --print-prompt Print the exact AI prompt and exit without executing provider CLIs
310
+ --with-planner Enable planner-assisted behavior on commands that explicitly support it
311
+ --interactive Enable prompts on commands that explicitly support interactive choices
312
+ --review Open or prepare human review before persistent writes where supported
313
+ --no-color Disable ANSI colors in human output
300
314
  --fix For doctor, apply safe non-destructive repairs
301
315
  --execute For ai execute-plan, run the planned slices instead of printing commands
302
316
  --create For ai pr, create the PR after preflight instead of printing the plan only
@@ -330,6 +344,7 @@ Examples:
330
344
  cd ./my-project && npx create-quiver ai onboard --print-prompt
331
345
  cd ./my-project && npx create-quiver ai prepare-context --dry-run
332
346
  cd ./my-project && npx create-quiver ai run create --input requirements.md
347
+ cd ./my-project && npx create-quiver ai active-slice reconcile --dry-run
333
348
  cd ./my-project && npx create-quiver ai status
334
349
  cd ./my-project && npx create-quiver ai resume
335
350
  cd ./my-project && npx create-quiver ai inspect
@@ -345,12 +360,14 @@ Examples:
345
360
  cd ./my-project && npx create-quiver ai revise --phase acceptance --input feedback.md --dry-run
346
361
  cd ./my-project && npx create-quiver ai approve --phase acceptance --version 1
347
362
  cd ./my-project && npx create-quiver ai plan --phase technical-plan --dry-run
363
+ cd ./my-project && npx create-quiver ai repair-plan --dry-run
348
364
  cd ./my-project && npx create-quiver ai review-plan --dry-run
349
365
  cd ./my-project && npx create-quiver ai approve --phase technical-plan --version 1
350
366
  cd ./my-project && npx create-quiver spec create --dry-run
351
367
  cd ./my-project && npx create-quiver spec start specs/my-project --dry-run
352
368
  cd ./my-project && npx create-quiver ai approvals
353
369
  cd ./my-project && npx create-quiver ai prompt-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
370
+ cd ./my-project && npx --yes create-quiver@${CLI_VERSION} ai prompt-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
354
371
  cd ./my-project && npx create-quiver ai execute-slice --slice specs/my-project/slices/slice-01/slice.json --dry-run
355
372
  cd ./my-project && npx create-quiver ai execute-slice --slice specs/my-project/slices/slice-01/slice.json --commit
356
373
  cd ./my-project && npx create-quiver ai execute-plan --dry-run --commit
@@ -405,6 +422,10 @@ function parseArgs(argv) {
405
422
  strict: false,
406
423
  strictOverlap: false,
407
424
  json: false,
425
+ noColor: false,
426
+ withPlanner: false,
427
+ interactive: false,
428
+ review: false,
408
429
  includeCompleted: false,
409
430
  onlyReady: false,
410
431
  allReady: false,
@@ -635,6 +656,26 @@ function parseArgs(argv) {
635
656
  continue;
636
657
  }
637
658
 
659
+ if (arg === '--no-color') {
660
+ result.noColor = true;
661
+ continue;
662
+ }
663
+
664
+ if (arg === '--with-planner') {
665
+ result.withPlanner = true;
666
+ continue;
667
+ }
668
+
669
+ if (arg === '--interactive') {
670
+ result.interactive = true;
671
+ continue;
672
+ }
673
+
674
+ if (arg === '--review') {
675
+ result.review = true;
676
+ continue;
677
+ }
678
+
638
679
  if (arg === '--include-completed') {
639
680
  result.includeCompleted = true;
640
681
  continue;
@@ -936,7 +977,7 @@ function parseArgs(argv) {
936
977
  if (result.aiCommand === 'run' && !result.aiRunCommand && positional.length > 0) {
937
978
  result.aiRunCommand = positional.shift();
938
979
  }
939
- if ((result.aiCommand === 'specs' || result.aiCommand === 'slices' || result.aiCommand === 'trace') && !result.aiSecondaryCommand && positional.length > 0) {
980
+ if ((result.aiCommand === 'specs' || result.aiCommand === 'slices' || result.aiCommand === 'trace' || result.aiCommand === 'active-slice') && !result.aiSecondaryCommand && positional.length > 0) {
940
981
  result.aiSecondaryCommand = positional.shift();
941
982
  }
942
983
  if ((result.aiCommand === 'specs' || result.aiCommand === 'slices') && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'list') {
@@ -945,6 +986,9 @@ function parseArgs(argv) {
945
986
  if (result.aiCommand === 'trace' && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'report') {
946
987
  throw new Error(formatError(`unsupported ai trace subcommand: ${result.aiSecondaryCommand}. Supported tasks: report`));
947
988
  }
989
+ if (result.aiCommand === 'active-slice' && result.aiSecondaryCommand && result.aiSecondaryCommand !== 'status' && result.aiSecondaryCommand !== 'reconcile') {
990
+ throw new Error(formatError(`unsupported ai active-slice subcommand: ${result.aiSecondaryCommand}. Supported tasks: status, reconcile`));
991
+ }
948
992
  if (positional.length > 0) {
949
993
  throw new Error(formatError('ai does not accept extra positional arguments'));
950
994
  }
@@ -2327,6 +2371,8 @@ async function run(argv) {
2327
2371
  return;
2328
2372
  }
2329
2373
 
2374
+ validateUxFlags(args);
2375
+
2330
2376
  if (args.mode === 'analyze') {
2331
2377
  runAnalyze(args.targetDir, {
2332
2378
  dryRun: args.dryRun,
@@ -2364,7 +2410,7 @@ async function run(argv) {
2364
2410
 
2365
2411
  if (args.mode === 'ai') {
2366
2412
  if (!args.aiCommand) {
2367
- throw new Error(formatError('missing ai subcommand. Use: npx create-quiver ai onboard | prepare-context | run | status | resume | inspect | export | specs | slices | trace | plan | revise | review-plan | approve | approvals | agent | prompt-slice | execute-slice | execute-plan | doctor | pr'));
2413
+ throw new Error(formatError('missing ai subcommand. Use: npx create-quiver ai onboard | prepare-context | run | active-slice | status | resume | inspect | export | specs | slices | trace | plan | revise | repair-plan | review-plan | approve | approvals | agent | prompt-slice | execute-slice | execute-plan | doctor | pr'));
2368
2414
  }
2369
2415
 
2370
2416
  if (args.aiCommand === 'run') {
@@ -2377,6 +2423,14 @@ async function run(argv) {
2377
2423
  return;
2378
2424
  }
2379
2425
 
2426
+ if (args.aiCommand === 'active-slice') {
2427
+ runAiActiveSlice(process.cwd(), {
2428
+ command: args.aiSecondaryCommand || 'status',
2429
+ dryRun: args.dryRun,
2430
+ });
2431
+ return;
2432
+ }
2433
+
2380
2434
  if (args.aiCommand === 'status') {
2381
2435
  runAiLifecycleStatus(process.cwd(), {
2382
2436
  runId: args.aiRunId || undefined,
@@ -2458,8 +2512,17 @@ async function run(argv) {
2458
2512
 
2459
2513
  if (args.aiCommand === 'prepare-context') {
2460
2514
  await runAiPrepareContext(process.cwd(), {
2515
+ context: args.aiContext || undefined,
2461
2516
  dryRun: args.dryRun,
2517
+ interactive: args.interactive,
2518
+ printPrompt: args.aiPrintPrompt,
2519
+ provider: args.aiProvider,
2520
+ providerExplicit: args.aiProviderExplicit,
2521
+ review: args.review,
2522
+ role: args.aiRole,
2462
2523
  runId: args.aiRunId || undefined,
2524
+ timeout: args.aiTimeout,
2525
+ withPlanner: args.withPlanner,
2463
2526
  });
2464
2527
  return;
2465
2528
  }
@@ -2473,10 +2536,13 @@ async function run(argv) {
2473
2536
  printPrompt: args.aiPrintPrompt,
2474
2537
  provider: args.aiProvider,
2475
2538
  providerExplicit: args.aiProviderExplicit,
2539
+ interactive: args.interactive,
2540
+ review: args.review,
2476
2541
  role: args.aiRole,
2477
2542
  runId: args.aiRunId || undefined,
2478
2543
  specSlug: args.specSlug || undefined,
2479
2544
  timeout: args.aiTimeout,
2545
+ withPlanner: args.withPlanner,
2480
2546
  });
2481
2547
  return;
2482
2548
  }
@@ -2494,6 +2560,21 @@ async function run(argv) {
2494
2560
  return;
2495
2561
  }
2496
2562
 
2563
+ if (args.aiCommand === 'repair-plan') {
2564
+ await runAiRepairPlan(process.cwd(), {
2565
+ context: args.aiContext || undefined,
2566
+ dryRun: args.dryRun,
2567
+ input: args.aiInput || undefined,
2568
+ printPrompt: args.aiPrintPrompt,
2569
+ provider: args.aiProvider,
2570
+ providerExplicit: args.aiProviderExplicit,
2571
+ role: args.aiRole,
2572
+ runId: args.aiRunId || undefined,
2573
+ timeout: args.aiTimeout,
2574
+ });
2575
+ return;
2576
+ }
2577
+
2497
2578
  if (args.aiCommand === 'revise') {
2498
2579
  await runAiRevise(process.cwd(), {
2499
2580
  context: args.aiContext || undefined,
@@ -2582,7 +2663,9 @@ async function run(argv) {
2582
2663
  create: args.aiCreate,
2583
2664
  dryRun: args.dryRun,
2584
2665
  input: args.aiInput || undefined,
2666
+ interactive: args.interactive,
2585
2667
  remote: args.aiRemote || undefined,
2668
+ review: args.review,
2586
2669
  sshHostAlias: args.aiSshHostAlias || undefined,
2587
2670
  identityFile: args.aiIdentityFile || undefined,
2588
2671
  title: args.aiTitle || undefined,
@@ -2590,7 +2673,7 @@ async function run(argv) {
2590
2673
  return;
2591
2674
  }
2592
2675
 
2593
- throw new Error(formatError(`unsupported ai subcommand: ${args.aiCommand}. Supported tasks: onboard, prepare-context, run, status, resume, inspect, export, specs, slices, trace, plan, revise, review-plan, approve, approvals, agent, prompt-slice, execute-slice, execute-plan, doctor, pr`));
2676
+ throw new Error(formatError(`unsupported ai subcommand: ${args.aiCommand}. Supported tasks: onboard, prepare-context, run, active-slice, status, resume, inspect, export, specs, slices, trace, plan, revise, repair-plan, review-plan, approve, approvals, agent, prompt-slice, execute-slice, execute-plan, doctor, pr`));
2594
2677
  }
2595
2678
 
2596
2679
  if (args.mode === 'graph') {
@@ -2722,10 +2805,13 @@ async function run(argv) {
2722
2805
 
2723
2806
  if (args.mode === 'spec') {
2724
2807
  if (args.specCommand === 'create') {
2725
- runCreateSpec(process.cwd(), {
2808
+ await runCreateSpec(process.cwd(), {
2726
2809
  dryRun: args.dryRun,
2727
2810
  input: args.aiInput || undefined,
2811
+ interactive: args.interactive,
2812
+ review: args.review,
2728
2813
  specSlug: args.specSlug || undefined,
2814
+ withPlanner: args.withPlanner,
2729
2815
  });
2730
2816
  return;
2731
2817
  }
@@ -27,14 +27,14 @@ const CONTEXT_PACKS = Object.freeze({
27
27
  description: 'Executor context for a single slice handoff.',
28
28
  role: ROLES.EXECUTOR,
29
29
  tokenBudgetHint: 3200,
30
- roleGuidance: 'Use slice handoff, allowed files, acceptance criteria, and validation commands only.',
30
+ roleGuidance: 'Use the slice.json, EXECUTION_BRIEF, CLOSURE_BRIEF, allowed files, acceptance criteria, and validation commands only. Do not request the full spec unless the slice brief explicitly requires it.',
31
31
  }),
32
32
  minimal: Object.freeze({
33
33
  name: 'minimal',
34
34
  description: 'Smallest executor context for narrowly-scoped tasks.',
35
35
  role: ROLES.EXECUTOR,
36
36
  tokenBudgetHint: 1200,
37
- roleGuidance: 'Use the smallest safe set of slice details and avoid onboarding context.',
37
+ roleGuidance: 'Use the smallest safe set of slice details, avoid onboarding context, and avoid full-spec context by default.',
38
38
  }),
39
39
  });
40
40