create-quiver 0.10.0 → 0.12.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/BACKLOG.md +16 -17
- package/CHANGELOG.md +34 -0
- package/README.md +174 -39
- package/README_FOR_AI.md +48 -24
- package/ROADMAP.md +22 -11
- package/docs/AI_CONTEXT.md.template +2 -0
- package/docs/AI_ONBOARDING_PROMPT.md.template +25 -18
- package/docs/COMMANDS.md.template +59 -11
- package/docs/CONTEXTO.md.template +2 -0
- package/docs/DECISIONS.md.template +1 -0
- package/docs/INDEX.md.template +20 -18
- package/docs/STATUS.md.template +1 -0
- package/docs/SUPPORT_MATRIX.md.template +2 -2
- package/docs/TROUBLESHOOTING.md.template +50 -0
- package/docs/WORKFLOW.md.template +25 -17
- package/package.json +19 -2
- package/package.template.json +13 -1
- package/scripts/init-docs.sh +11 -4
- package/scripts/package-quiver.sh +18 -2
- package/specs/quiver-v22-guided-ai-workflow/EVIDENCE_REPORT.md +58 -0
- package/specs/quiver-v22-guided-ai-workflow/EXECUTION_PLAN.md +88 -0
- package/specs/quiver-v22-guided-ai-workflow/SPEC.md +228 -0
- package/specs/quiver-v22-guided-ai-workflow/STATUS.md +42 -0
- package/specs/quiver-v22-guided-ai-workflow/pr.md +104 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +35 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +61 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-00-spec-foundation/slice.json +51 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/EXECUTION_BRIEF.md +58 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-01-docs-source-of-truth-sync/slice.json +55 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/CLOSURE_BRIEF.md +30 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/EXECUTION_BRIEF.md +57 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-02-prepare-command-diagnostics/slice.json +57 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-03-context-doc-refresh/slice.json +56 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-04-planner-approval-state/slice.json +58 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-05-spec-worktree-lifecycle/slice.json +54 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/EXECUTION_BRIEF.md +58 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-06-executor-commit-recovery/slice.json +57 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/EXECUTION_BRIEF.md +58 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-07-execution-waves-delegation/slice.json +55 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/EXECUTION_BRIEF.md +58 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-08-pr-create-gh-ssh/slice.json +53 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/EXECUTION_BRIEF.md +59 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-09-post-merge-cleanup-release-safety/slice.json +59 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +58 -0
- package/specs/quiver-v22-guided-ai-workflow/slices/slice-10-docs-smokes-release-readiness/slice.json +60 -0
- package/specs/quiver-v23-guided-flow-productization/EVIDENCE_REPORT.md +80 -0
- package/specs/quiver-v23-guided-flow-productization/EXECUTION_PLAN.md +80 -0
- package/specs/quiver-v23-guided-flow-productization/SPEC.md +203 -0
- package/specs/quiver-v23-guided-flow-productization/STATUS.md +39 -0
- package/specs/quiver-v23-guided-flow-productization/pr.md +119 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +30 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +61 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-00-spec-foundation/slice.json +51 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/EXECUTION_BRIEF.md +35 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-01-short-command-and-flow-entrypoint/slice.json +56 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/EXECUTION_BRIEF.md +29 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-02-flow-status-wizard/slice.json +55 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/EXECUTION_BRIEF.md +29 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-03-agent-profiles/slice.json +54 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/EXECUTION_BRIEF.md +30 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-04-context-preparation-onboarding/slice.json +59 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/EXECUTION_BRIEF.md +29 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-05-planner-iteration-history/slice.json +53 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/EXECUTION_BRIEF.md +30 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-06-production-plan-review/slice.json +54 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/EXECUTION_BRIEF.md +30 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-07-spec-create-experience/slice.json +55 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/EXECUTION_BRIEF.md +30 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-08-executor-prompt-generation/slice.json +55 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/EXECUTION_BRIEF.md +34 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-09-delegated-slice-execution/slice.json +57 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +32 -0
- package/specs/quiver-v23-guided-flow-productization/slices/slice-10-docs-smokes-release-readiness/slice.json +63 -0
- package/specs/quiver-v24-dx-onboarding-hardening/EVIDENCE_REPORT.md +55 -0
- package/specs/quiver-v24-dx-onboarding-hardening/EXECUTION_PLAN.md +43 -0
- package/specs/quiver-v24-dx-onboarding-hardening/SPEC.md +149 -0
- package/specs/quiver-v24-dx-onboarding-hardening/STATUS.md +31 -0
- package/specs/quiver-v24-dx-onboarding-hardening/pr.md +76 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +52 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-00-spec-foundation/slice.json +51 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/CLOSURE_BRIEF.md +38 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/EXECUTION_BRIEF.md +53 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-01-init-template-hygiene/slice.json +55 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/EXECUTION_BRIEF.md +50 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-02-cli-command-routing-version-errors/slice.json +52 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/EXECUTION_BRIEF.md +50 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-03-doctor-fix-doc-link-checks/slice.json +53 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/EXECUTION_BRIEF.md +50 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-04-prepare-output-ai-context-drafts/slice.json +70 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/CLOSURE_BRIEF.md +36 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/EXECUTION_BRIEF.md +49 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-05-local-slice-validation-base-guidance/slice.json +52 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/CLOSURE_BRIEF.md +43 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/EXECUTION_BRIEF.md +53 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-06-plan-graph-next-history-views/slice.json +60 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/EXECUTION_BRIEF.md +50 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-07-analyzer-command-map-hardening/slice.json +51 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/EXECUTION_BRIEF.md +52 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-08-evidence-run-command/slice.json +54 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/EXECUTION_BRIEF.md +51 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-09-spec-viewer-demo-scaffolding/slice.json +59 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/EXECUTION_BRIEF.md +54 -0
- package/specs/quiver-v24-dx-onboarding-hardening/slices/slice-10-docs-smokes-release-readiness/slice.json +76 -0
- package/src/create-quiver/commands/ai.js +508 -35
- package/src/create-quiver/commands/demo.js +22 -0
- package/src/create-quiver/commands/evidence.js +37 -0
- package/src/create-quiver/commands/flow.js +561 -0
- package/src/create-quiver/commands/graph.js +14 -1
- package/src/create-quiver/commands/next.js +28 -0
- package/src/create-quiver/commands/plan.js +6 -3
- package/src/create-quiver/commands/prepare.js +236 -0
- package/src/create-quiver/commands/spec.js +133 -0
- package/src/create-quiver/index.js +688 -25
- package/src/create-quiver/lib/agent-profiles.js +148 -0
- package/src/create-quiver/lib/ai/context-packs.js +12 -0
- package/src/create-quiver/lib/ai/execution-plan.js +370 -10
- package/src/create-quiver/lib/ai/executor.js +376 -17
- package/src/create-quiver/lib/ai/github.js +196 -0
- package/src/create-quiver/lib/ai/onboarding-template.js +365 -0
- package/src/create-quiver/lib/ai/plan-review.js +283 -0
- package/src/create-quiver/lib/ai/providers.js +1 -0
- package/src/create-quiver/lib/ai/safety.js +5 -0
- package/src/create-quiver/lib/ai/spec-templates.js +2 -2
- package/src/create-quiver/lib/approvals.js +350 -0
- package/src/create-quiver/lib/demo.js +657 -0
- package/src/create-quiver/lib/doctor.js +234 -0
- package/src/create-quiver/lib/evidence.js +115 -0
- package/src/create-quiver/lib/init-docs.js +284 -17
- package/src/create-quiver/lib/init-layout.js +26 -1
- package/src/create-quiver/lib/lifecycle.js +6 -0
- package/src/create-quiver/lib/package-safety.js +117 -0
- package/src/create-quiver/lib/readiness.js +85 -18
- package/src/create-quiver/lib/slice-graph.js +1 -0
- package/src/create-quiver/lib/slice.js +8 -8
- package/src/create-quiver/lib/spec-worktrees.js +349 -0
|
@@ -205,6 +205,57 @@ function writeFrontMatter(filePath, fields) {
|
|
|
205
205
|
return nextContent;
|
|
206
206
|
}
|
|
207
207
|
|
|
208
|
+
const ROOT_GITIGNORE_DEFAULTS = [
|
|
209
|
+
'node_modules/',
|
|
210
|
+
'.DS_Store',
|
|
211
|
+
'dist/',
|
|
212
|
+
'coverage/',
|
|
213
|
+
];
|
|
214
|
+
|
|
215
|
+
function normalizeGitignorePattern(line) {
|
|
216
|
+
const trimmed = line.trim();
|
|
217
|
+
if (!trimmed || trimmed.startsWith('#')) {
|
|
218
|
+
return trimmed;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
return trimmed.replace(/\/+$/g, '');
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function mergeLineList(existingText, defaults) {
|
|
225
|
+
const existingLines = existingText
|
|
226
|
+
.split(/\r?\n/)
|
|
227
|
+
.filter((line, index, lines) => line.length > 0 || index < lines.length - 1);
|
|
228
|
+
const seen = new Set(existingLines.map(normalizeGitignorePattern).filter(Boolean));
|
|
229
|
+
const nextLines = [...existingLines];
|
|
230
|
+
|
|
231
|
+
for (const line of defaults) {
|
|
232
|
+
const normalized = normalizeGitignorePattern(line);
|
|
233
|
+
if (!seen.has(normalized)) {
|
|
234
|
+
nextLines.push(line);
|
|
235
|
+
seen.add(normalized);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return `${nextLines.join('\n').replace(/\s+$/g, '')}\n`;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
function mergeRootGitignore(projectRoot) {
|
|
243
|
+
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
244
|
+
const exists = fs.existsSync(gitignorePath);
|
|
245
|
+
const existingText = exists
|
|
246
|
+
? fs.readFileSync(gitignorePath, 'utf8')
|
|
247
|
+
: '';
|
|
248
|
+
|
|
249
|
+
ensureDir(path.dirname(gitignorePath));
|
|
250
|
+
fs.writeFileSync(gitignorePath, mergeLineList(existingText, ROOT_GITIGNORE_DEFAULTS));
|
|
251
|
+
return exists ? 'merged' : 'created';
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
function resolvePackageName(projectRoot, options = {}) {
|
|
255
|
+
return options.projectSlug
|
|
256
|
+
|| toProjectSlug(options.projectName || path.basename(projectRoot) || 'Quiver Project');
|
|
257
|
+
}
|
|
258
|
+
|
|
208
259
|
function mergePackageJson(projectRoot, templateRoot, options = {}) {
|
|
209
260
|
const packageTemplate = path.join(templateRoot, 'package.template.json');
|
|
210
261
|
const packageJsonPath = path.join(projectRoot, 'package.json');
|
|
@@ -218,13 +269,17 @@ function mergePackageJson(projectRoot, templateRoot, options = {}) {
|
|
|
218
269
|
|
|
219
270
|
if (!fs.existsSync(packageJsonPath)) {
|
|
220
271
|
const template = JSON.parse(fs.readFileSync(packageTemplate, 'utf8'));
|
|
272
|
+
template.name = resolvePackageName(projectRoot, options);
|
|
221
273
|
template.scripts = scripts;
|
|
222
274
|
fs.writeFileSync(packageJsonPath, `${JSON.stringify(template, null, 2)}\n`);
|
|
223
275
|
return 'created';
|
|
224
276
|
}
|
|
225
277
|
|
|
226
278
|
const existing = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
227
|
-
|
|
279
|
+
|
|
280
|
+
if (typeof existing.name !== 'string' || existing.name.trim().length === 0) {
|
|
281
|
+
existing.name = resolvePackageName(projectRoot, options);
|
|
282
|
+
}
|
|
228
283
|
|
|
229
284
|
existing.scripts = {
|
|
230
285
|
...(existing.scripts || {}),
|
|
@@ -259,16 +314,22 @@ npx create-quiver next
|
|
|
259
314
|
Use \`AGENTS.md\` first, then \`docs/AI_CONTEXT.md\` and \`docs/AI_ONBOARDING_PROMPT.md\` for the working contract.
|
|
260
315
|
|
|
261
316
|
\`\`\`bash
|
|
317
|
+
npm run quiver:prepare -- --dry-run
|
|
262
318
|
npm run quiver:ai:onboard -- --dry-run
|
|
263
319
|
npm run quiver:ai:plan -- --phase acceptance --input requirements.md --dry-run
|
|
264
|
-
npm run quiver:ai:
|
|
265
|
-
npm run quiver:ai:plan -- --phase
|
|
320
|
+
npm run quiver:ai:approve -- --phase acceptance --input acceptance-approved.md
|
|
321
|
+
npm run quiver:ai:plan -- --phase technical-plan --dry-run
|
|
322
|
+
npm run quiver:ai:review-plan -- --dry-run
|
|
323
|
+
npm run quiver:ai:approve -- --phase technical-plan --version <n>
|
|
324
|
+
npm run quiver:spec:create -- --dry-run
|
|
266
325
|
\`\`\`
|
|
267
326
|
|
|
268
327
|
When a real spec exists, execute one approved slice at a time:
|
|
269
328
|
|
|
270
329
|
\`\`\`bash
|
|
271
|
-
npm run quiver:ai:
|
|
330
|
+
npm run quiver:ai:prompt-slice -- --slice specs/<spec-slug>/slices/<slice-id>/slice.json --dry-run
|
|
331
|
+
npm run quiver:ai:execute-slice -- --slice specs/<spec-slug>/slices/<slice-id>/slice.json --dry-run --commit
|
|
332
|
+
npm run quiver:ai:execute-plan -- --dry-run --commit --mode delegated
|
|
272
333
|
\`\`\`
|
|
273
334
|
|
|
274
335
|
## Documentation
|
|
@@ -302,21 +363,27 @@ After \`analyze\`, use \`docs/PROJECT_MAP.md\` for the detected stack, package m
|
|
|
302
363
|
|
|
303
364
|
## AI-First Workflow
|
|
304
365
|
|
|
305
|
-
Quiver keeps the visible contract small: start with \`README.md\`, \`AGENTS.md\`, and \`docs/\`. Specs and slices should be created only after a real requirement and
|
|
366
|
+
Quiver keeps the visible contract small: start with \`README.md\`, \`AGENTS.md\`, and \`docs/\`. Specs and slices should be created only after a real requirement and a reviewed, approved technical plan.
|
|
306
367
|
|
|
307
368
|
Use dry-runs before spending model tokens:
|
|
308
369
|
|
|
309
370
|
\`\`\`bash
|
|
371
|
+
npm run quiver:prepare -- --dry-run
|
|
310
372
|
npm run quiver:ai:onboard -- --dry-run
|
|
311
373
|
npm run quiver:ai:plan -- --phase acceptance --input requirements.md --dry-run
|
|
312
|
-
npm run quiver:ai:
|
|
313
|
-
npm run quiver:ai:plan -- --phase
|
|
374
|
+
npm run quiver:ai:approve -- --phase acceptance --input acceptance-approved.md
|
|
375
|
+
npm run quiver:ai:plan -- --phase technical-plan --dry-run
|
|
376
|
+
npm run quiver:ai:review-plan -- --dry-run
|
|
377
|
+
npm run quiver:ai:approve -- --phase technical-plan --version <n>
|
|
378
|
+
npm run quiver:spec:create -- --dry-run
|
|
314
379
|
\`\`\`
|
|
315
380
|
|
|
316
381
|
When a real spec exists, execute one approved slice at a time:
|
|
317
382
|
|
|
318
383
|
\`\`\`bash
|
|
319
|
-
npm run quiver:ai:
|
|
384
|
+
npm run quiver:ai:prompt-slice -- --slice specs/<spec-slug>/slices/<slice-id>/slice.json --dry-run
|
|
385
|
+
npm run quiver:ai:execute-slice -- --slice specs/<spec-slug>/slices/<slice-id>/slice.json --dry-run --commit
|
|
386
|
+
npm run quiver:ai:execute-plan -- --dry-run --commit --mode delegated
|
|
320
387
|
\`\`\`
|
|
321
388
|
|
|
322
389
|
## Project NPM Scripts
|
|
@@ -325,13 +392,25 @@ The generated project includes \`quiver:*\` npm scripts that call the Node CLI:
|
|
|
325
392
|
|
|
326
393
|
\`\`\`bash
|
|
327
394
|
npm run quiver:analyze
|
|
395
|
+
npm run quiver:prepare -- --dry-run
|
|
328
396
|
npm run quiver:plan
|
|
329
397
|
npm run quiver:graph
|
|
330
398
|
npm run quiver:next
|
|
331
399
|
npm run quiver:doctor
|
|
332
400
|
npm run quiver:ai:onboard -- --dry-run
|
|
333
401
|
npm run quiver:ai:plan -- --phase acceptance --input requirements.md --dry-run
|
|
334
|
-
npm run quiver:ai:
|
|
402
|
+
npm run quiver:ai:approve -- --phase acceptance --input acceptance-approved.md
|
|
403
|
+
npm run quiver:ai:plan -- --phase technical-plan --dry-run
|
|
404
|
+
npm run quiver:ai:review-plan -- --dry-run
|
|
405
|
+
npm run quiver:ai:approve -- --phase technical-plan --version <n>
|
|
406
|
+
npm run quiver:spec:create -- --dry-run
|
|
407
|
+
npm run quiver:ai:prompt-slice -- --slice specs/<spec-slug>/slices/<slice-id>/slice.json --dry-run
|
|
408
|
+
npm run quiver:ai:execute-slice -- --slice specs/<spec-slug>/slices/<slice-id>/slice.json --dry-run --commit
|
|
409
|
+
npm run quiver:ai:execute-plan -- --dry-run --commit --mode delegated
|
|
410
|
+
npm run quiver:ai:pr -- --dry-run --input specs/<spec-slug>/pr.md --ssh-host-alias github-work --identity-file ~/.ssh/github-work
|
|
411
|
+
npm run quiver:spec:start -- specs/<spec-slug>
|
|
412
|
+
npm run quiver:spec:status -- specs/<spec-slug>
|
|
413
|
+
npm run quiver:spec:close -- specs/<spec-slug> --dry-run
|
|
335
414
|
\`\`\`
|
|
336
415
|
|
|
337
416
|
## Documentation
|
|
@@ -388,12 +467,19 @@ Quiver is designed for an AI-first workflow: a planner agent reads the project c
|
|
|
388
467
|
Start with dry-runs so you can inspect the provider, role, context pack, and invocation before spending model tokens:
|
|
389
468
|
|
|
390
469
|
\`\`\`bash
|
|
470
|
+
npm run quiver:prepare -- --dry-run
|
|
391
471
|
npm run quiver:ai:onboard -- --dry-run
|
|
392
472
|
npm run quiver:ai:plan -- --phase acceptance --input requirements.md --dry-run
|
|
393
|
-
npm run quiver:ai:
|
|
394
|
-
npm run quiver:ai:plan -- --phase
|
|
395
|
-
npm run quiver:ai:
|
|
396
|
-
npm run quiver:ai:
|
|
473
|
+
npm run quiver:ai:approve -- --phase acceptance --input acceptance-approved.md
|
|
474
|
+
npm run quiver:ai:plan -- --phase technical-plan --dry-run
|
|
475
|
+
npm run quiver:ai:review-plan -- --dry-run
|
|
476
|
+
npm run quiver:ai:approve -- --phase technical-plan --version <n>
|
|
477
|
+
npm run quiver:spec:create -- --dry-run
|
|
478
|
+
npm run quiver:spec:start -- specs/${projectSlug}
|
|
479
|
+
npm run quiver:ai:prompt-slice -- --slice specs/${projectSlug}/slices/slice-01/slice.json --dry-run
|
|
480
|
+
npm run quiver:ai:execute-slice -- --slice specs/${projectSlug}/slices/slice-01/slice.json --dry-run --commit
|
|
481
|
+
npm run quiver:ai:execute-plan -- --dry-run --commit --mode delegated
|
|
482
|
+
npm run quiver:ai:pr -- --dry-run --input specs/${projectSlug}/pr.md --ssh-host-alias github-work --identity-file ~/.ssh/github-work
|
|
397
483
|
\`\`\`
|
|
398
484
|
|
|
399
485
|
Remove \`--dry-run\` only after the phase output is approved and the local provider CLI is ready.
|
|
@@ -404,15 +490,26 @@ The generated project includes \`quiver:*\` npm scripts that call the Node CLI a
|
|
|
404
490
|
|
|
405
491
|
\`\`\`bash
|
|
406
492
|
npm run quiver:analyze
|
|
493
|
+
npm run quiver:prepare -- --dry-run
|
|
407
494
|
npm run quiver:plan
|
|
408
495
|
npm run quiver:graph
|
|
409
496
|
npm run quiver:next
|
|
410
497
|
npm run quiver:doctor
|
|
411
498
|
npm run quiver:ai:onboard -- --dry-run
|
|
412
499
|
npm run quiver:ai:plan -- --phase acceptance --input requirements.md --dry-run
|
|
413
|
-
npm run quiver:ai:
|
|
500
|
+
npm run quiver:ai:approve -- --phase acceptance --input acceptance-approved.md
|
|
501
|
+
npm run quiver:ai:plan -- --phase technical-plan --dry-run
|
|
502
|
+
npm run quiver:ai:review-plan -- --dry-run
|
|
503
|
+
npm run quiver:ai:approve -- --phase technical-plan --version <n>
|
|
504
|
+
npm run quiver:spec:create -- --dry-run
|
|
505
|
+
npm run quiver:ai:prompt-slice -- --slice specs/${projectSlug}/slices/slice-01/slice.json --dry-run
|
|
506
|
+
npm run quiver:ai:execute-slice -- --slice specs/${projectSlug}/slices/slice-01/slice.json --dry-run --commit
|
|
507
|
+
npm run quiver:ai:execute-plan -- --dry-run --commit --mode delegated
|
|
414
508
|
npm run quiver:ai:doctor -- --dry-run --ssh-host-alias github-work --identity-file ~/.ssh/github-work
|
|
415
|
-
npm run quiver:ai:pr -- --dry-run --ssh-host-alias github-work --identity-file ~/.ssh/github-work
|
|
509
|
+
npm run quiver:ai:pr -- --dry-run --input specs/${projectSlug}/pr.md --ssh-host-alias github-work --identity-file ~/.ssh/github-work
|
|
510
|
+
npm run quiver:spec:start -- specs/${projectSlug}
|
|
511
|
+
npm run quiver:spec:status -- specs/${projectSlug}
|
|
512
|
+
npm run quiver:spec:close -- specs/${projectSlug} --dry-run
|
|
416
513
|
npm run quiver:migrate
|
|
417
514
|
npm run quiver:start-slice -- specs/${projectSlug}/slices/slice-01/slice.json
|
|
418
515
|
npm run quiver:check-slice -- specs/${projectSlug}/slices/slice-01/slice.json
|
|
@@ -425,7 +522,8 @@ npm run quiver:refresh-active-slices
|
|
|
425
522
|
|
|
426
523
|
The \`quiver:graph\` script prints the tree view by default; use \`npx create-quiver graph --format mermaid\` for PR-ready Markdown and \`--format dot\` when you want Graphviz source.
|
|
427
524
|
The \`quiver:next\` script points to the next ready slice and can auto-start it behind a confirmation prompt.
|
|
428
|
-
The \`quiver:ai:*\` scripts standardize planner/executor AI flows. Use dry-run first: onboarding and planning dry-runs do not require provider auth,
|
|
525
|
+
The \`quiver:ai:*\` scripts standardize planner/executor AI flows. Use dry-run first: onboarding and planning dry-runs do not require provider auth, \`quiver:ai:execute-plan -- --dry-run --commit --mode manual\` prints manual prompts, \`--mode delegated\` prints safe waves, and \`quiver:ai:pr -- --dry-run\` validates \`gh\`, GitFlow docs, branch/worktree state, SSH inputs, and \`pr.md\` without creating a PR. Add \`--create\` only after reviewing the plan.
|
|
526
|
+
Use \`quiver:spec:create\`, \`quiver:spec:start\`, \`quiver:spec:status\`, and \`quiver:spec:close\` for one spec generation and worktree per spec.
|
|
429
527
|
Use \`npx create-quiver next --all-ready\` when you want the full ready level instead of a single suggestion.
|
|
430
528
|
The legacy Bash wrappers remain in \`tools/scripts/\` for compatibility, but new project-level automation should prefer the \`quiver:*\` scripts and the direct \`npx create-quiver ...\` commands below.
|
|
431
529
|
\`npm run quiver:migrate\` is only for projects that were already initialized by Quiver.
|
|
@@ -502,7 +600,7 @@ Record durable decisions in \`docs/DECISIONS.md\` so future AI agents do not re-
|
|
|
502
600
|
|
|
503
601
|
## First Slice Workflow
|
|
504
602
|
|
|
505
|
-
Use this section only for projects generated with the full compatibility layout. In the default AI-first layout, create real specs and slices with \`npx create-quiver
|
|
603
|
+
Use this section only for projects generated with the full compatibility layout. In the default AI-first layout, create real specs and slices with \`npx create-quiver spec create\` after acceptance criteria are approved and the technical plan is reviewed and approved.
|
|
506
604
|
|
|
507
605
|
1. Review or refine specs/${projectSlug}/SPEC.md.
|
|
508
606
|
2. Create the first slice from specs/${projectSlug}/slices/slice-template/slice.json.
|
|
@@ -541,6 +639,19 @@ Use this section only for projects generated with the full compatibility layout.
|
|
|
541
639
|
`;
|
|
542
640
|
}
|
|
543
641
|
|
|
642
|
+
function buildFullProfileIndexAppendix(projectSlug) {
|
|
643
|
+
return `## Full Profile Extras
|
|
644
|
+
|
|
645
|
+
- **Multi-agent workflow** - \`./MULTI_AGENT_WORKFLOW.md\`
|
|
646
|
+
- **Quick AI context** - \`./ai/QUICK.md\`
|
|
647
|
+
- **Standard AI context** - \`./ai/STANDARD.md\`
|
|
648
|
+
- **Deep AI context** - \`./ai/DEEP.md\`
|
|
649
|
+
- **Spec starter assets** - \`../specs/${projectSlug}/\`
|
|
650
|
+
- **Tool notes** - \`./tools/\`
|
|
651
|
+
- **Archive** - \`./archive/\`
|
|
652
|
+
`;
|
|
653
|
+
}
|
|
654
|
+
|
|
544
655
|
function initializeProjectDocs(options) {
|
|
545
656
|
const {
|
|
546
657
|
projectRoot,
|
|
@@ -598,6 +709,9 @@ function initializeProjectDocs(options) {
|
|
|
598
709
|
fs.writeFileSync(internalPaths.gitignorePath, buildQuiverInternalGitignore());
|
|
599
710
|
operations.push({ source: 'Quiver internal gitignore', destination: '.quiver/.gitignore', result: 'updated' });
|
|
600
711
|
|
|
712
|
+
const rootGitignoreResult = mergeRootGitignore(projectRoot);
|
|
713
|
+
operations.push({ source: 'root gitignore defaults', destination: '.gitignore', result: rootGitignoreResult });
|
|
714
|
+
|
|
601
715
|
if (includeTemplates) {
|
|
602
716
|
fs.mkdirSync(internalPaths.templatesDir, { recursive: true });
|
|
603
717
|
fs.cpSync(templateRoot, internalPaths.templatesDir, {
|
|
@@ -691,6 +805,17 @@ function initializeProjectDocs(options) {
|
|
|
691
805
|
operations.push({ source, destination, result });
|
|
692
806
|
}
|
|
693
807
|
|
|
808
|
+
const indexPath = path.join(projectRoot, 'docs', 'INDEX.md');
|
|
809
|
+
const indexWasCreated = operations.some((operation) => (
|
|
810
|
+
operation.destination === 'docs/INDEX.md'
|
|
811
|
+
&& (operation.result === 'created' || operation.result === 'created-with-frontmatter')
|
|
812
|
+
));
|
|
813
|
+
if (profile === 'full' && indexWasCreated && fs.existsSync(indexPath)) {
|
|
814
|
+
const currentIndex = fs.readFileSync(indexPath, 'utf8').replace(/\s+$/g, '');
|
|
815
|
+
fs.writeFileSync(indexPath, `${currentIndex}\n\n${buildFullProfileIndexAppendix(replacements.projectSlug)}`);
|
|
816
|
+
operations.push({ source: 'full profile index appendix', destination: 'docs/INDEX.md', result: 'updated' });
|
|
817
|
+
}
|
|
818
|
+
|
|
694
819
|
const binaryCopies = [
|
|
695
820
|
['docs/UI_STANDARDS.md', 'docs/UI_STANDARDS.md'],
|
|
696
821
|
['docs/MOCK_DATA_GUIDE.md', 'docs/MOCK_DATA_GUIDE.md'],
|
|
@@ -765,6 +890,8 @@ function initializeProjectDocs(options) {
|
|
|
765
890
|
legacyScripts,
|
|
766
891
|
migrateMode,
|
|
767
892
|
profile,
|
|
893
|
+
projectName,
|
|
894
|
+
projectSlug: replacements.projectSlug,
|
|
768
895
|
});
|
|
769
896
|
operations.push({ source: 'package.template.json', destination: 'package.json', result: packageResult });
|
|
770
897
|
|
|
@@ -963,8 +1090,148 @@ function installSelfAsDevDep(projectRoot, version) {
|
|
|
963
1090
|
}
|
|
964
1091
|
}
|
|
965
1092
|
|
|
1093
|
+
function normalizeSkippedReason(reason) {
|
|
1094
|
+
if (!reason) {
|
|
1095
|
+
return 'excluded path';
|
|
1096
|
+
}
|
|
1097
|
+
|
|
1098
|
+
if (reason === 'env-file') {
|
|
1099
|
+
return 'env files';
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
if (reason === 'git-metadata') {
|
|
1103
|
+
return '.git metadata';
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
if (reason === 'hidden-directory') {
|
|
1107
|
+
return 'hidden directories';
|
|
1108
|
+
}
|
|
1109
|
+
|
|
1110
|
+
if (reason.startsWith('secret-file:')) {
|
|
1111
|
+
return 'secret files';
|
|
1112
|
+
}
|
|
1113
|
+
|
|
1114
|
+
if (reason.startsWith('unsafe-segment:')) {
|
|
1115
|
+
const segment = reason.slice('unsafe-segment:'.length);
|
|
1116
|
+
const dependencySegments = new Set(['node_modules', '.pnpm-store', '.npm', '.yarn']);
|
|
1117
|
+
const outputSegments = new Set(['dist', 'build', 'coverage', 'out', 'tmp', 'temp', 'cache', '.cache', '.turbo', '.next', '.nuxt', '.parcel-cache', 'generated', 'gen', 'artifacts', 'reports', 'vendor', 'target']);
|
|
1118
|
+
|
|
1119
|
+
if (segment === '.quiver') {
|
|
1120
|
+
return 'local AI state';
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
if (dependencySegments.has(segment)) {
|
|
1124
|
+
return 'dependency folders';
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
if (outputSegments.has(segment)) {
|
|
1128
|
+
return 'generated/output/cache folders';
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
return segment;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
return reason;
|
|
1135
|
+
}
|
|
1136
|
+
|
|
1137
|
+
function summarizeSkippedPaths(skippedPathDetails = [], skippedPaths = []) {
|
|
1138
|
+
const counts = new Map();
|
|
1139
|
+
|
|
1140
|
+
const items = Array.isArray(skippedPathDetails) && skippedPathDetails.length > 0
|
|
1141
|
+
? skippedPathDetails
|
|
1142
|
+
: skippedPaths.map((item) => ({ path: item, reason: 'excluded path' }));
|
|
1143
|
+
|
|
1144
|
+
for (const item of items) {
|
|
1145
|
+
const label = normalizeSkippedReason(item.reason);
|
|
1146
|
+
counts.set(label, (counts.get(label) || 0) + 1);
|
|
1147
|
+
}
|
|
1148
|
+
|
|
1149
|
+
return Array.from(counts.entries()).map(([label, count]) => ({ label, count }));
|
|
1150
|
+
}
|
|
1151
|
+
|
|
1152
|
+
function renderAiContextDoc(scan, options = {}) {
|
|
1153
|
+
const projectName = scan?.project?.name || 'Quiver Project';
|
|
1154
|
+
const projectSlug = options.projectSlug || toProjectSlug(projectName);
|
|
1155
|
+
const stack = scan?.stack || {};
|
|
1156
|
+
const commands = scan?.commands || {};
|
|
1157
|
+
const common = commands.common || {};
|
|
1158
|
+
const summaries = summarizeSkippedPaths(scan?.skipped_path_details, scan?.skipped_paths);
|
|
1159
|
+
const risks = Array.isArray(scan?.risks) ? scan.risks : [];
|
|
1160
|
+
const hasReadme = scan?.docs?.has_readme ? 'yes' : 'no';
|
|
1161
|
+
const hasWorkflow = scan?.ci?.has_ci ? 'yes' : 'no';
|
|
1162
|
+
const sourceDirs = Array.isArray(scan?.structure?.source_directories) ? scan.structure.source_directories : [];
|
|
1163
|
+
|
|
1164
|
+
const lines = [];
|
|
1165
|
+
lines.push(`# ${projectName} AI Context`);
|
|
1166
|
+
lines.push('');
|
|
1167
|
+
lines.push('This file is refreshed by `npx create-quiver analyze`.');
|
|
1168
|
+
lines.push('Use `docs/PROJECT_MAP.md` for stack and command details, and `.quiver/scans/PROJECT_SCAN.json` only when raw analyzer data is needed.');
|
|
1169
|
+
lines.push('');
|
|
1170
|
+
lines.push('## Snapshot');
|
|
1171
|
+
lines.push(`- Primary stack: ${stack.primary || 'unknown'}`);
|
|
1172
|
+
lines.push('- Package manager source: `docs/PROJECT_MAP.md`');
|
|
1173
|
+
lines.push(`- Install: ${commands.install || 'not defined'}`);
|
|
1174
|
+
lines.push(`- Dev: ${common.dev || 'not defined'}`);
|
|
1175
|
+
lines.push(`- Build: ${common.build || 'not defined'}`);
|
|
1176
|
+
lines.push(`- Test: ${common.test || 'not defined'}`);
|
|
1177
|
+
lines.push(`- README present: ${hasReadme}`);
|
|
1178
|
+
lines.push(`- GitHub Actions workflows: ${hasWorkflow}`);
|
|
1179
|
+
lines.push(`- Source directories: ${sourceDirs.length > 0 ? sourceDirs.join(', ') : 'none detected'}`);
|
|
1180
|
+
lines.push('');
|
|
1181
|
+
lines.push('## Read First');
|
|
1182
|
+
lines.push('- `docs/PROJECT_MAP.md`');
|
|
1183
|
+
lines.push('- `docs/WORKFLOW.md`');
|
|
1184
|
+
lines.push('- `docs/AI_ONBOARDING_PROMPT.md`');
|
|
1185
|
+
lines.push('- `docs/CONTEXTO.md`');
|
|
1186
|
+
lines.push('- `docs/DECISIONS.md`');
|
|
1187
|
+
lines.push(`- specs/${projectSlug}/SPEC.md`);
|
|
1188
|
+
lines.push('');
|
|
1189
|
+
lines.push('## Assumptions and Missing Info');
|
|
1190
|
+
if (risks.length > 0) {
|
|
1191
|
+
for (const risk of risks) {
|
|
1192
|
+
lines.push(`- ${risk}`);
|
|
1193
|
+
}
|
|
1194
|
+
} else {
|
|
1195
|
+
lines.push('- No major repository signals are missing.');
|
|
1196
|
+
}
|
|
1197
|
+
lines.push('- Do not infer product or business rules that are not present in the repository.');
|
|
1198
|
+
lines.push('');
|
|
1199
|
+
lines.push('## Exclusions');
|
|
1200
|
+
if (summaries.length > 0) {
|
|
1201
|
+
for (const item of summaries) {
|
|
1202
|
+
lines.push(`- ${item.label}: ${item.count}`);
|
|
1203
|
+
}
|
|
1204
|
+
} else {
|
|
1205
|
+
lines.push('- No exclusions were needed.');
|
|
1206
|
+
}
|
|
1207
|
+
lines.push('');
|
|
1208
|
+
lines.push('## Internal Artifacts');
|
|
1209
|
+
lines.push('- Visible source: `docs/PROJECT_MAP.md`');
|
|
1210
|
+
lines.push('- Internal raw scan: `.quiver/scans/PROJECT_SCAN.json`');
|
|
1211
|
+
lines.push('');
|
|
1212
|
+
const body = lines.join('\n');
|
|
1213
|
+
const frontMatter = serializeFrontMatter(buildFrontMatterFields({
|
|
1214
|
+
purpose: 'Agent-facing project context pack',
|
|
1215
|
+
appliesWhen: 'after analyze, onboarding, implementation, review',
|
|
1216
|
+
body,
|
|
1217
|
+
currentDate: options.currentDate || new Date().toISOString().slice(0, 10),
|
|
1218
|
+
}));
|
|
1219
|
+
|
|
1220
|
+
return `${frontMatter}\n\n${body}`;
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1223
|
+
function refreshAiContextDoc(projectRoot, scan, options = {}) {
|
|
1224
|
+
const destinationPath = path.join(projectRoot, 'docs', 'AI_CONTEXT.md');
|
|
1225
|
+
fs.mkdirSync(path.dirname(destinationPath), { recursive: true });
|
|
1226
|
+
fs.writeFileSync(destinationPath, `${renderAiContextDoc(scan, options)}\n`);
|
|
1227
|
+
return destinationPath;
|
|
1228
|
+
}
|
|
1229
|
+
|
|
966
1230
|
module.exports = {
|
|
967
1231
|
initializeProjectDocs,
|
|
1232
|
+
refreshAiContextDoc,
|
|
1233
|
+
renderAiContextDoc,
|
|
1234
|
+
summarizeSkippedPaths,
|
|
968
1235
|
writeFrontMatter,
|
|
969
1236
|
toProjectSlug,
|
|
970
1237
|
detectPackageManager,
|
|
@@ -22,6 +22,7 @@ const CORE_VISIBLE_DIRECTORIES = ['docs', 'docs/ai', '.quiver', '.quiver/scans']
|
|
|
22
22
|
const MINIMAL_VISIBLE_FILES = [
|
|
23
23
|
'README.md',
|
|
24
24
|
'AGENTS.md',
|
|
25
|
+
'.gitignore',
|
|
25
26
|
'docs/AI_CONTEXT.md',
|
|
26
27
|
'docs/AI_ONBOARDING_PROMPT.md',
|
|
27
28
|
'docs/COMMANDS.md',
|
|
@@ -92,6 +93,7 @@ function quiverInternalPaths(projectRoot) {
|
|
|
92
93
|
function buildQuiverInternalGitignore() {
|
|
93
94
|
return [
|
|
94
95
|
'cache/',
|
|
96
|
+
'evidence/',
|
|
95
97
|
'runs/',
|
|
96
98
|
'worktrees/',
|
|
97
99
|
'',
|
|
@@ -178,15 +180,28 @@ function resolveInitPackageScripts(profile, options = {}) {
|
|
|
178
180
|
const baseScripts = {
|
|
179
181
|
'quiver:migrate': 'npx create-quiver migrate',
|
|
180
182
|
'quiver:analyze': 'npx create-quiver analyze',
|
|
183
|
+
'quiver:flow': 'npx create-quiver flow',
|
|
184
|
+
'quiver:prepare': 'npx create-quiver prepare',
|
|
181
185
|
'quiver:plan': 'npx create-quiver plan',
|
|
182
186
|
'quiver:graph': 'npx create-quiver graph',
|
|
183
187
|
'quiver:next': 'npx create-quiver next',
|
|
184
188
|
'quiver:doctor': 'npx create-quiver doctor',
|
|
189
|
+
'quiver:evidence': 'npx create-quiver evidence',
|
|
190
|
+
'quiver:ai:agent': 'npx create-quiver ai agent',
|
|
185
191
|
'quiver:ai:onboard': 'npx create-quiver ai onboard',
|
|
192
|
+
'quiver:ai:prepare-context': 'npx create-quiver ai prepare-context',
|
|
186
193
|
'quiver:ai:plan': 'npx create-quiver ai plan',
|
|
194
|
+
'quiver:ai:review-plan': 'npx create-quiver ai review-plan',
|
|
195
|
+
'quiver:ai:approve': 'npx create-quiver ai approve',
|
|
196
|
+
'quiver:ai:prompt-slice': 'npx create-quiver ai prompt-slice',
|
|
187
197
|
'quiver:ai:execute-slice': 'npx create-quiver ai execute-slice',
|
|
198
|
+
'quiver:ai:execute-plan': 'npx create-quiver ai execute-plan',
|
|
188
199
|
'quiver:ai:pr': 'npx create-quiver ai pr',
|
|
189
200
|
'quiver:ai:doctor': 'npx create-quiver ai doctor',
|
|
201
|
+
'quiver:spec:create': 'npx create-quiver spec create',
|
|
202
|
+
'quiver:spec:start': 'npx create-quiver spec start',
|
|
203
|
+
'quiver:spec:status': 'npx create-quiver spec status',
|
|
204
|
+
'quiver:spec:close': 'npx create-quiver spec close',
|
|
190
205
|
'quiver:start-slice': 'npx create-quiver start-slice',
|
|
191
206
|
'quiver:check-slice': 'npx create-quiver check-slice',
|
|
192
207
|
'quiver:check-pr': 'npx create-quiver check-pr',
|
|
@@ -259,7 +274,17 @@ function buildInitLayout(projectRoot, options = {}) {
|
|
|
259
274
|
}
|
|
260
275
|
|
|
261
276
|
for (const file of visibleFiles) {
|
|
262
|
-
|
|
277
|
+
const updateMode = file === 'package.json' || file === '.gitignore';
|
|
278
|
+
pushPlannedOperation(
|
|
279
|
+
operations,
|
|
280
|
+
projectRoot,
|
|
281
|
+
file,
|
|
282
|
+
'file',
|
|
283
|
+
updateMode ? 'update' : 'create',
|
|
284
|
+
updateMode ? 'prepare project metadata or ignored paths' : 'core visible contract file',
|
|
285
|
+
profile,
|
|
286
|
+
'visible',
|
|
287
|
+
);
|
|
263
288
|
}
|
|
264
289
|
|
|
265
290
|
if (profile === 'full') {
|
|
@@ -4,6 +4,7 @@ const { branchDelete, catFileExists, currentBranch, fetchBranch, fetchRemote, ha
|
|
|
4
4
|
const { parseJsonWithComments } = require('./json');
|
|
5
5
|
const { writeFrontMatter } = require('./init-docs');
|
|
6
6
|
const { relativePosixPath, resolveTargetRoot } = require('./paths');
|
|
7
|
+
const { ensureSpecSliceZeroComplete } = require('./spec-worktrees');
|
|
7
8
|
const { activeSlicePath, renderActiveSlice, resolveSliceContext, safeBranchName, toAlias, validateSliceMetaForStart, worktreesRootForRepo } = require('./slice');
|
|
8
9
|
|
|
9
10
|
function ensureDir(dirPath) {
|
|
@@ -299,6 +300,11 @@ function startSlice(sliceInput, options = {}) {
|
|
|
299
300
|
const repoRoot = runGit(['rev-parse', '--show-toplevel'], process.cwd());
|
|
300
301
|
const slice = resolveSliceContext(repoRoot, sliceInput);
|
|
301
302
|
slice.repoRoot = repoRoot;
|
|
303
|
+
|
|
304
|
+
if (!slice.isBaseline) {
|
|
305
|
+
ensureSpecSliceZeroComplete(repoRoot, slice.specDirAbs);
|
|
306
|
+
}
|
|
307
|
+
|
|
302
308
|
validateSliceMetaForStart(slice);
|
|
303
309
|
|
|
304
310
|
if (slice.status === 'blocked') {
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
const PACKAGE_PREFIX = 'package/';
|
|
2
|
+
|
|
3
|
+
const SAFETY_RULES = [
|
|
4
|
+
{
|
|
5
|
+
code: 'env-file',
|
|
6
|
+
match(relativePath) {
|
|
7
|
+
return /(^|\/)\.env($|[./])/.test(relativePath);
|
|
8
|
+
},
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
code: 'npm-credentials',
|
|
12
|
+
match(relativePath) {
|
|
13
|
+
return /(^|\/)\.npmrc$/.test(relativePath) || /(^|\/)\.npm(\/|$)/.test(relativePath);
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
code: 'ai-tool-state',
|
|
18
|
+
match(relativePath) {
|
|
19
|
+
return /(^|\/)\.(claude|codex|quiver)(\/|$)/.test(relativePath);
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
code: 'worktree-state',
|
|
24
|
+
match(relativePath) {
|
|
25
|
+
return /(^|\/)\.worktrees(\/|$)/.test(relativePath);
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
code: 'worktree-context',
|
|
30
|
+
match(relativePath) {
|
|
31
|
+
return /(^|\/)WORKTREE_CONTEXT\.md$/.test(relativePath);
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
code: 'demo-output',
|
|
36
|
+
match(relativePath) {
|
|
37
|
+
return relativePath === 'quiver-spec-viewer' || relativePath.startsWith('quiver-spec-viewer/');
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
];
|
|
41
|
+
|
|
42
|
+
function normalizeTarballPath(inputPath) {
|
|
43
|
+
return String(inputPath || '')
|
|
44
|
+
.trim()
|
|
45
|
+
.replace(/\\/g, '/')
|
|
46
|
+
.replace(/^\.\//, '')
|
|
47
|
+
.replace(/\/{2,}/g, '/');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function stripPackagePrefix(inputPath) {
|
|
51
|
+
const normalizedPath = normalizeTarballPath(inputPath);
|
|
52
|
+
|
|
53
|
+
if (normalizedPath.startsWith(PACKAGE_PREFIX)) {
|
|
54
|
+
return normalizedPath.slice(PACKAGE_PREFIX.length);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return normalizedPath;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function collectPackageSafetyViolations(paths) {
|
|
61
|
+
const violations = [];
|
|
62
|
+
const seen = new Set();
|
|
63
|
+
|
|
64
|
+
for (const rawPath of paths || []) {
|
|
65
|
+
const normalizedPath = normalizeTarballPath(rawPath);
|
|
66
|
+
const relativePath = stripPackagePrefix(normalizedPath);
|
|
67
|
+
|
|
68
|
+
for (const rule of SAFETY_RULES) {
|
|
69
|
+
if (!rule.match(relativePath)) {
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const key = `${rule.code}:${normalizedPath}`;
|
|
74
|
+
if (seen.has(key)) {
|
|
75
|
+
continue;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
seen.add(key);
|
|
79
|
+
violations.push({
|
|
80
|
+
code: rule.code,
|
|
81
|
+
path: normalizedPath,
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return violations;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function formatPackageSafetyViolations(violations) {
|
|
90
|
+
return violations
|
|
91
|
+
.map((violation) => `${violation.path} [${violation.code}]`)
|
|
92
|
+
.join(', ');
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function assertPackageSafety(paths) {
|
|
96
|
+
const violations = collectPackageSafetyViolations(paths);
|
|
97
|
+
|
|
98
|
+
if (violations.length === 0) {
|
|
99
|
+
return {
|
|
100
|
+
ok: true,
|
|
101
|
+
violations,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const error = new Error(`PACKAGE_SAFETY_FAILED: unsafe tarball contents detected: ${formatPackageSafetyViolations(violations)}`);
|
|
106
|
+
error.code = 'PACKAGE_SAFETY_FAILED';
|
|
107
|
+
error.violations = violations;
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
module.exports = {
|
|
112
|
+
assertPackageSafety,
|
|
113
|
+
collectPackageSafetyViolations,
|
|
114
|
+
formatPackageSafetyViolations,
|
|
115
|
+
normalizeTarballPath,
|
|
116
|
+
stripPackagePrefix,
|
|
117
|
+
};
|