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.
- package/CHANGELOG.md +30 -0
- package/README.md +183 -511
- package/README_FOR_AI.md +36 -26
- 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 +125 -0
- package/docs/COMMANDS.md.template +19 -4
- package/docs/GITFLOW_PR_GUIDE.md +70 -0
- package/docs/TROUBLESHOOTING.md.template +29 -0
- package/docs/WORKFLOW.md.template +13 -12
- 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 +94 -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-v28-pixel-quiver-feedback-reconciliation/COVERAGE_MATRIX.md +117 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/EVIDENCE_REPORT.md +200 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/EXECUTION_PLAN.md +60 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/SPEC.md +132 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/STATUS.md +36 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/pr.md +128 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/CLOSURE_BRIEF.md +44 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-00-reconciliation-and-evidence-freeze/slice.json +71 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/CLOSURE_BRIEF.md +38 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/EXECUTION_BRIEF.md +53 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-01-ai-run-state-approvals-and-clean-output/slice.json +83 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/EXECUTION_BRIEF.md +53 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-02-structured-technical-plan-contract-and-repair-flow/slice.json +85 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/EXECUTION_BRIEF.md +52 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-03-active-slice-reconciliation-and-ai-inspect/slice.json +82 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/EXECUTION_BRIEF.md +55 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-04-spec-validation-scope-and-worktree-reliability/slice.json +85 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/CLOSURE_BRIEF.md +35 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/EXECUTION_BRIEF.md +59 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-05-review-plan-closure-and-agent-dx/slice.json +94 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/CLOSURE_BRIEF.md +40 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v28-pixel-quiver-feedback-reconciliation/slices/slice-06-backward-compatibility-docs-and-release-readiness/slice.json +98 -0
- 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/src/create-quiver/commands/ai.js +938 -16
- package/src/create-quiver/commands/spec.js +74 -2
- package/src/create-quiver/index.js +91 -5
- package/src/create-quiver/lib/ai/context-packs.js +2 -2
- 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/export-state.js +52 -5
- package/src/create-quiver/lib/ai/github.js +14 -2
- package/src/create-quiver/lib/ai/plan-review.js +159 -0
- package/src/create-quiver/lib/ai/run-state.js +17 -2
- package/src/create-quiver/lib/ai/spec-generator.js +15 -0
- package/src/create-quiver/lib/cli/editor.js +118 -0
- package/src/create-quiver/lib/cli/theme.js +100 -0
- package/src/create-quiver/lib/cli/ux-flags.js +151 -0
- package/src/create-quiver/lib/cli/ux.js +130 -0
- package/src/create-quiver/lib/project-state-resolver.js +195 -1
- 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
|
|
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
|
|
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
|
|
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
|
|
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
|
|