create-quiver 0.14.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/README.md +187 -518
- package/README_FOR_AI.md +39 -27
- package/ROADMAP.md +11 -0
- package/assets/quiver-wordmark.svg +22 -0
- package/docs/AI_CONTEXT.md.template +2 -0
- package/docs/AI_ONBOARDING_PROMPT.md.template +9 -1
- package/docs/CLI_UX_GUIDE.md +185 -0
- package/docs/COMMANDS.md.template +22 -3
- package/docs/GITFLOW_PR_GUIDE.md +70 -0
- package/docs/getting-started/linux.md +84 -0
- package/docs/getting-started/macos.md +85 -0
- package/docs/getting-started/windows-git-bash-wsl.md +78 -0
- package/docs/getting-started/windows-powershell.md +96 -0
- package/docs/reference/commands.md +98 -0
- package/docs/workflows/existing-project.md +131 -0
- package/docs/workflows/full-ai-spec-to-pr.md +311 -0
- package/docs/workflows/legacy-quiver-project.md +102 -0
- package/docs/workflows/new-project.md +76 -0
- package/package.json +5 -1
- package/specs/quiver-v29-planner-prepare-context-cli-ux/EVIDENCE_REPORT.md +163 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/EXECUTION_PLAN.md +72 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/SPEC.md +173 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/STATUS.md +34 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/pr.md +95 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/EXECUTION_BRIEF.md +45 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-00-cli-ux-spec-foundation/slice.json +58 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/EXECUTION_BRIEF.md +49 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-01-cli-ux-primitives-theme/slice.json +75 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/EXECUTION_BRIEF.md +47 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-02-planner-context-proposal-contract/slice.json +71 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/EXECUTION_BRIEF.md +52 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-03-prepare-context-planner-review-flow/slice.json +82 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/EXECUTION_BRIEF.md +46 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-04-ux-flag-matrix-compatibility/slice.json +73 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/EXECUTION_BRIEF.md +46 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-05-progressive-command-adoption/slice.json +83 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/EXECUTION_BRIEF.md +50 -0
- package/specs/quiver-v29-planner-prepare-context-cli-ux/slices/slice-06-docs-tests-smoke-readiness/slice.json +95 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/EVIDENCE_REPORT.md +213 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/EXECUTION_PLAN.md +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/SPEC.md +213 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/STATUS.md +31 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/pr.md +103 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-00-spec-foundation/slice.json +71 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/CLOSURE_BRIEF.md +31 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/EXECUTION_BRIEF.md +54 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-01-cli-ux-runtime-progress-engine/slice.json +69 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/EXECUTION_BRIEF.md +56 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-02-agent-profile-selection-selectors/slice.json +81 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/EXECUTION_BRIEF.md +54 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-03-provider-model-selection-contract/slice.json +75 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/CLOSURE_BRIEF.md +32 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/EXECUTION_BRIEF.md +57 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-04-planner-ia-progress-flows/slice.json +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/CLOSURE_BRIEF.md +33 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/EXECUTION_BRIEF.md +57 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-05-executor-pr-progress-flows/slice.json +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/CLOSURE_BRIEF.md +35 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/EXECUTION_BRIEF.md +55 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-06-doctor-visual-json-contract/slice.json +81 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/EXECUTION_BRIEF.md +55 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-07-interactive-init-spec-create/slice.json +85 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/CLOSURE_BRIEF.md +34 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/EXECUTION_BRIEF.md +59 -0
- package/specs/quiver-v30-interactive-cli-ux-agent-selection/slices/slice-08-tests-docs-cross-platform-release/slice.json +95 -0
- package/src/create-quiver/commands/ai.js +809 -71
- package/src/create-quiver/commands/spec.js +167 -5
- package/src/create-quiver/index.js +582 -71
- package/src/create-quiver/lib/agent-profiles.js +111 -10
- package/src/create-quiver/lib/ai/context-proposal.js +389 -0
- package/src/create-quiver/lib/ai/context-proposal.schema.js +31 -0
- package/src/create-quiver/lib/ai/execution-plan.js +106 -8
- package/src/create-quiver/lib/ai/executor.js +284 -28
- package/src/create-quiver/lib/ai/providers.js +71 -1
- package/src/create-quiver/lib/cli/editor.js +118 -0
- package/src/create-quiver/lib/cli/selectors.js +107 -0
- package/src/create-quiver/lib/cli/theme.js +103 -0
- package/src/create-quiver/lib/cli/ux-flags.js +169 -0
- package/src/create-quiver/lib/cli/ux.js +225 -0
|
@@ -53,6 +53,9 @@ const { checkPrReadiness, checkScope, checkSliceReadiness } = require('./lib/rea
|
|
|
53
53
|
const { cleanupSlice, refreshActiveSlicesBoard, startSlice } = require('./lib/lifecycle');
|
|
54
54
|
const { buildSpecStatus, closeSpecWorktree, formatSpecCloseResult, formatSpecStartResult, formatSpecStatus, startSpecWorktree } = require('./lib/spec-worktrees');
|
|
55
55
|
const { getContextPathExclusionReason } = require('./lib/ai/safety');
|
|
56
|
+
const { selectOption } = require('./lib/cli/selectors');
|
|
57
|
+
const { createUx } = require('./lib/cli/ux');
|
|
58
|
+
const { validateUxFlags } = require('./lib/cli/ux-flags');
|
|
56
59
|
const { relativePosixPath, resolveTargetRoot } = require('./lib/paths');
|
|
57
60
|
const {
|
|
58
61
|
CURRENT_SCAN_RELATIVE_PATH,
|
|
@@ -306,6 +309,11 @@ Options:
|
|
|
306
309
|
--include-templates Export packaged templates in init profile
|
|
307
310
|
--dry-run Preview init, analyze, migrate, prepare, spec create/start/close, demo, ai agent set, or AI work without executing writes/providers
|
|
308
311
|
--print-prompt Print the exact AI prompt and exit without executing provider CLIs
|
|
312
|
+
--with-planner Enable planner-assisted behavior on commands that explicitly support it
|
|
313
|
+
--interactive Enable prompts on commands that explicitly support interactive choices
|
|
314
|
+
--review Open or prepare human review before persistent writes where supported
|
|
315
|
+
--methodology <name> Select methodology where supported (currently wdd-sdd)
|
|
316
|
+
--no-color Disable ANSI colors in human output
|
|
309
317
|
--fix For doctor, apply safe non-destructive repairs
|
|
310
318
|
--execute For ai execute-plan, run the planned slices instead of printing commands
|
|
311
319
|
--create For ai pr, create the PR after preflight instead of printing the plan only
|
|
@@ -329,6 +337,7 @@ Options:
|
|
|
329
337
|
|
|
330
338
|
Examples:
|
|
331
339
|
npx create-quiver init --name "My Project"
|
|
340
|
+
npx create-quiver init --interactive
|
|
332
341
|
npx create-quiver init --name "My Project" --dry-run
|
|
333
342
|
npx create-quiver --name "My Project"
|
|
334
343
|
npx create-quiver --name "My Project" --dir ./my-project
|
|
@@ -417,6 +426,10 @@ function parseArgs(argv) {
|
|
|
417
426
|
strict: false,
|
|
418
427
|
strictOverlap: false,
|
|
419
428
|
json: false,
|
|
429
|
+
noColor: false,
|
|
430
|
+
withPlanner: false,
|
|
431
|
+
interactive: false,
|
|
432
|
+
review: false,
|
|
420
433
|
includeCompleted: false,
|
|
421
434
|
onlyReady: false,
|
|
422
435
|
allReady: false,
|
|
@@ -425,6 +438,7 @@ function parseArgs(argv) {
|
|
|
425
438
|
format: 'tree',
|
|
426
439
|
formatExplicit: false,
|
|
427
440
|
showConflicts: false,
|
|
441
|
+
methodology: '',
|
|
428
442
|
level: null,
|
|
429
443
|
unicode: false,
|
|
430
444
|
aiCommand: '',
|
|
@@ -647,6 +661,26 @@ function parseArgs(argv) {
|
|
|
647
661
|
continue;
|
|
648
662
|
}
|
|
649
663
|
|
|
664
|
+
if (arg === '--no-color') {
|
|
665
|
+
result.noColor = true;
|
|
666
|
+
continue;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
if (arg === '--with-planner') {
|
|
670
|
+
result.withPlanner = true;
|
|
671
|
+
continue;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
if (arg === '--interactive') {
|
|
675
|
+
result.interactive = true;
|
|
676
|
+
continue;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (arg === '--review') {
|
|
680
|
+
result.review = true;
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
683
|
+
|
|
650
684
|
if (arg === '--include-completed') {
|
|
651
685
|
result.includeCompleted = true;
|
|
652
686
|
continue;
|
|
@@ -720,6 +754,74 @@ function parseArgs(argv) {
|
|
|
720
754
|
continue;
|
|
721
755
|
}
|
|
722
756
|
|
|
757
|
+
if (arg === '--id') {
|
|
758
|
+
const value = args[++index];
|
|
759
|
+
if (!value) {
|
|
760
|
+
throw new Error(formatError('missing value for --id'));
|
|
761
|
+
}
|
|
762
|
+
result.aiProfileId = value;
|
|
763
|
+
continue;
|
|
764
|
+
}
|
|
765
|
+
|
|
766
|
+
if (arg === '--display-name') {
|
|
767
|
+
const value = args[++index];
|
|
768
|
+
if (!value) {
|
|
769
|
+
throw new Error(formatError('missing value for --display-name'));
|
|
770
|
+
}
|
|
771
|
+
result.aiDisplayName = value;
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
if (arg === '--default') {
|
|
776
|
+
result.aiDefaultProfile = true;
|
|
777
|
+
continue;
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
if (arg === '--planner') {
|
|
781
|
+
const value = args[++index];
|
|
782
|
+
if (!value) {
|
|
783
|
+
throw new Error(formatError('missing value for --planner'));
|
|
784
|
+
}
|
|
785
|
+
result.aiPlannerProfile = value;
|
|
786
|
+
continue;
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
if (arg === '--executor') {
|
|
790
|
+
const value = args[++index];
|
|
791
|
+
if (!value) {
|
|
792
|
+
throw new Error(formatError('missing value for --executor'));
|
|
793
|
+
}
|
|
794
|
+
result.aiExecutorProfile = value;
|
|
795
|
+
continue;
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
if (arg === '--reviewer') {
|
|
799
|
+
const value = args[++index];
|
|
800
|
+
if (!value) {
|
|
801
|
+
throw new Error(formatError('missing value for --reviewer'));
|
|
802
|
+
}
|
|
803
|
+
result.aiReviewerProfile = value;
|
|
804
|
+
continue;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
if (arg === '--doctor') {
|
|
808
|
+
const value = args[++index];
|
|
809
|
+
if (!value) {
|
|
810
|
+
throw new Error(formatError('missing value for --doctor'));
|
|
811
|
+
}
|
|
812
|
+
result.aiDoctorProfile = value;
|
|
813
|
+
continue;
|
|
814
|
+
}
|
|
815
|
+
|
|
816
|
+
if (arg === '--methodology') {
|
|
817
|
+
const value = args[++index];
|
|
818
|
+
if (!value) {
|
|
819
|
+
throw new Error(formatError('missing value for --methodology'));
|
|
820
|
+
}
|
|
821
|
+
result.methodology = value;
|
|
822
|
+
continue;
|
|
823
|
+
}
|
|
824
|
+
|
|
723
825
|
if (arg === '--label') {
|
|
724
826
|
const value = args[++index];
|
|
725
827
|
if (!value) {
|
|
@@ -2145,28 +2247,21 @@ function runMigrate(targetDir, options = {}) {
|
|
|
2145
2247
|
}
|
|
2146
2248
|
}
|
|
2147
2249
|
|
|
2148
|
-
function
|
|
2149
|
-
const
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
if (!hasQuiverInitializationEvidence(projectRoot)) {
|
|
2156
|
-
throw new Error(formatError('doctor requires a project previously initialized by Quiver.\nRun init first: npx create-quiver --name "Project Name"'));
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
const fixPlan = buildDoctorFixPlan(projectRoot);
|
|
2160
|
-
if (options.fix) {
|
|
2161
|
-
if (options.dryRun) {
|
|
2162
|
-
console.log(formatDoctorFixPlan(fixPlan, { dryRun: true }));
|
|
2163
|
-
return;
|
|
2250
|
+
function uniqueLines(lines) {
|
|
2251
|
+
const seen = new Set();
|
|
2252
|
+
const unique = [];
|
|
2253
|
+
for (const line of lines) {
|
|
2254
|
+
const value = String(line || '').trim();
|
|
2255
|
+
if (!value || seen.has(value)) {
|
|
2256
|
+
continue;
|
|
2164
2257
|
}
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
console.log(formatDoctorFixPlan(fixPlan));
|
|
2258
|
+
seen.add(value);
|
|
2259
|
+
unique.push(value);
|
|
2168
2260
|
}
|
|
2261
|
+
return unique;
|
|
2262
|
+
}
|
|
2169
2263
|
|
|
2264
|
+
function buildDoctorCommandReport(projectRoot) {
|
|
2170
2265
|
const doctorReport = collectDoctorReport(projectRoot);
|
|
2171
2266
|
const specSlugs = doctorReport.specSlugs;
|
|
2172
2267
|
const doctorExampleTarget = doctorReport.exampleTarget || {
|
|
@@ -2253,65 +2348,425 @@ function runDoctor(targetDir, options = {}) {
|
|
|
2253
2348
|
...nonExecutableScripts.map((file) => `missing executable bit: ${file}`),
|
|
2254
2349
|
...missingScripts.map((name) => `missing package.json script: ${name}`),
|
|
2255
2350
|
];
|
|
2256
|
-
const
|
|
2351
|
+
const checks = [];
|
|
2352
|
+
|
|
2353
|
+
const addCheck = (id, status, message, details = {}) => {
|
|
2354
|
+
checks.push({
|
|
2355
|
+
id,
|
|
2356
|
+
status,
|
|
2357
|
+
message,
|
|
2358
|
+
...details,
|
|
2359
|
+
});
|
|
2360
|
+
};
|
|
2257
2361
|
|
|
2258
|
-
|
|
2259
|
-
|
|
2260
|
-
|
|
2362
|
+
addCheck('project-root', 'ok', `Quiver doctor passed for ${projectRoot}`);
|
|
2363
|
+
addCheck(
|
|
2364
|
+
'layout',
|
|
2365
|
+
doctorReport.layout === 'incomplete' ? 'error' : 'ok',
|
|
2366
|
+
`Layout: ${doctorReport.layout}`,
|
|
2367
|
+
);
|
|
2368
|
+
addCheck('specs', 'ok', specSlugs.length > 0 ? `Specs: ${specSlugs.join(', ')}` : 'Specs: none yet');
|
|
2261
2369
|
|
|
2262
|
-
console.log(`Quiver doctor passed for ${projectRoot}`);
|
|
2263
|
-
console.log(`Layout: ${doctorReport.layout}`);
|
|
2264
|
-
if (specSlugs.length > 0) {
|
|
2265
|
-
console.log(`Specs: ${specSlugs.join(', ')}`);
|
|
2266
|
-
} else {
|
|
2267
|
-
console.log('Specs: none yet');
|
|
2268
|
-
}
|
|
2269
2370
|
if (doctorReport.legacySignals.length > 0) {
|
|
2270
|
-
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
|
|
2274
|
-
|
|
2275
|
-
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
|
|
2371
|
+
addCheck('legacy-signals', doctorReport.layout === 'legacy' || doctorReport.layout === 'hybrid' ? 'warning' : 'ok', `Legacy signals: ${doctorReport.legacySignals.join(', ')}`);
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
addCheck(
|
|
2375
|
+
'required-files',
|
|
2376
|
+
missingFiles.length > 0 ? 'error' : 'ok',
|
|
2377
|
+
missingFiles.length > 0 ? `Missing required files: ${missingFiles.join(', ')}` : 'Required files found',
|
|
2378
|
+
{ missing: missingFiles },
|
|
2379
|
+
);
|
|
2380
|
+
|
|
2381
|
+
if (requiredExecutables.length > 0 || nonExecutableScripts.length > 0) {
|
|
2382
|
+
addCheck(
|
|
2383
|
+
'legacy-executables',
|
|
2384
|
+
nonExecutableScripts.length > 0 ? 'error' : 'ok',
|
|
2385
|
+
nonExecutableScripts.length > 0 ? `Missing executable bit: ${nonExecutableScripts.join(', ')}` : 'Legacy executable scripts are runnable',
|
|
2386
|
+
{ missing: nonExecutableScripts },
|
|
2387
|
+
);
|
|
2388
|
+
}
|
|
2389
|
+
|
|
2390
|
+
addCheck(
|
|
2391
|
+
'workflow-scripts',
|
|
2392
|
+
missingScripts.length > 0 ? 'error' : 'ok',
|
|
2393
|
+
missingScripts.length > 0 ? `Missing package.json workflow scripts: ${missingScripts.join(', ')}` : 'Workflow scripts available',
|
|
2394
|
+
{ missing: missingScripts },
|
|
2395
|
+
);
|
|
2396
|
+
|
|
2397
|
+
addCheck(
|
|
2398
|
+
'state',
|
|
2399
|
+
hasQuiverState ? 'ok' : 'warning',
|
|
2400
|
+
hasQuiverState ? 'Quiver state metadata found' : 'Warning: missing Quiver state metadata: .quiver/state.json',
|
|
2401
|
+
);
|
|
2402
|
+
|
|
2403
|
+
addCheck(
|
|
2404
|
+
'project-scan',
|
|
2405
|
+
hasScanArtifacts ? 'ok' : 'warning',
|
|
2406
|
+
hasScanArtifacts ? 'Project analysis artifacts found' : 'Warning: project analysis artifacts not found; run analyze when you need the visible project map',
|
|
2407
|
+
);
|
|
2408
|
+
|
|
2279
2409
|
for (const scriptName of missingNodeNativeScripts) {
|
|
2280
|
-
|
|
2410
|
+
addCheck(`node-script:${scriptName}`, 'warning', `Warning: missing Node-native script: ${scriptName}`);
|
|
2281
2411
|
}
|
|
2412
|
+
|
|
2282
2413
|
for (const scriptName of missingAiScripts) {
|
|
2283
|
-
|
|
2414
|
+
addCheck(`ai-script:${scriptName}`, 'warning', `Warning: missing AI orchestration script: ${scriptName}`);
|
|
2284
2415
|
}
|
|
2416
|
+
|
|
2285
2417
|
if (legacyOnlyScripts.length > 0) {
|
|
2286
|
-
|
|
2418
|
+
addCheck(
|
|
2419
|
+
'legacy-only-scripts',
|
|
2420
|
+
'warning',
|
|
2421
|
+
`Warning: legacy Bash workflow scripts detected for ${legacyOnlyScripts.join(', ')}. Run npx create-quiver migrate to add quiver:* npm scripts.`,
|
|
2422
|
+
);
|
|
2287
2423
|
}
|
|
2424
|
+
|
|
2288
2425
|
for (const script of unsupportedCreateQuiverScripts) {
|
|
2289
|
-
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2295
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
2299
|
-
|
|
2300
|
-
|
|
2301
|
-
|
|
2426
|
+
addCheck(
|
|
2427
|
+
`unsupported-script:${script.scriptName}`,
|
|
2428
|
+
'warning',
|
|
2429
|
+
`Warning: package.json script ${script.scriptName} targets ${script.reason}: \`${script.command}\`. Update create-quiver or regenerate scripts with npx create-quiver migrate.`,
|
|
2430
|
+
{ script_name: script.scriptName, command: script.command, reason: script.reason },
|
|
2431
|
+
);
|
|
2432
|
+
}
|
|
2433
|
+
|
|
2434
|
+
for (const warning of doctorReport.warnings) {
|
|
2435
|
+
addCheck(`warning:${checks.length + 1}`, 'warning', `Warning: ${warning}`);
|
|
2436
|
+
}
|
|
2437
|
+
|
|
2438
|
+
const suggestedFixes = [
|
|
2439
|
+
...doctorReport.recommendations,
|
|
2440
|
+
!hasQuiverState
|
|
2441
|
+
? 'Run migration first: npx create-quiver migrate'
|
|
2442
|
+
: !hasScanArtifacts
|
|
2443
|
+
? 'Analyze the project first: npx create-quiver analyze'
|
|
2444
|
+
: 'Ask your AI agent: Read AGENTS.md, then docs/AI_ONBOARDING_PROMPT.md and execute it.',
|
|
2445
|
+
'Check the next ready slice: npx create-quiver next',
|
|
2446
|
+
];
|
|
2447
|
+
|
|
2302
2448
|
if (specSlugs.length > 0) {
|
|
2303
2449
|
const projectSlug = doctorExampleTarget.specSlug;
|
|
2304
2450
|
const sliceId = doctorExampleTarget.sliceId || '<slice-id>';
|
|
2305
2451
|
if (doctorExampleTarget.source === 'active-slice') {
|
|
2306
|
-
|
|
2452
|
+
suggestedFixes.push(`Example target: ${projectSlug}/${sliceId} (${doctorExampleTarget.status})`);
|
|
2307
2453
|
} else if (doctorExampleTarget.source === 'generic-multiple-specs') {
|
|
2308
|
-
|
|
2454
|
+
suggestedFixes.push('Example target: specs/<spec-slug>/slices/<slice-id>/slice.json (generic because no active slice is obvious)');
|
|
2455
|
+
}
|
|
2456
|
+
suggestedFixes.push(`Start a slice: npx create-quiver start-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
|
|
2457
|
+
suggestedFixes.push(`Validate a slice: npx create-quiver check-slice specs/${projectSlug}/slices/${sliceId}/slice.json`);
|
|
2458
|
+
suggestedFixes.push(`Validate the PR gate: npx create-quiver check-pr specs/${projectSlug}/slices/${sliceId}/slice.json`);
|
|
2459
|
+
} else {
|
|
2460
|
+
suggestedFixes.push('Create real specs and slices only after acceptance criteria are approved and the technical plan is reviewed and approved.');
|
|
2461
|
+
}
|
|
2462
|
+
|
|
2463
|
+
const errors = checks.filter((check) => check.status === 'error').map((check) => check.message);
|
|
2464
|
+
const warnings = checks.filter((check) => check.status === 'warning').map((check) => check.message);
|
|
2465
|
+
const status = errors.length > 0 ? 'error' : warnings.length > 0 ? 'warning' : 'ok';
|
|
2466
|
+
|
|
2467
|
+
return {
|
|
2468
|
+
schema_version: 1,
|
|
2469
|
+
command: 'doctor',
|
|
2470
|
+
project_root: projectRoot,
|
|
2471
|
+
status,
|
|
2472
|
+
exit_code: errors.length > 0 ? 1 : 0,
|
|
2473
|
+
layout: doctorReport.layout,
|
|
2474
|
+
specs: specSlugs,
|
|
2475
|
+
legacy_signals: doctorReport.legacySignals,
|
|
2476
|
+
checks,
|
|
2477
|
+
suggested_fixes: uniqueLines(suggestedFixes),
|
|
2478
|
+
warnings,
|
|
2479
|
+
errors: migrationProblems.length > 0 ? uniqueLines([...migrationProblems, ...errors]) : errors,
|
|
2480
|
+
};
|
|
2481
|
+
}
|
|
2482
|
+
|
|
2483
|
+
function formatDoctorHumanReport(report, options = {}) {
|
|
2484
|
+
const lines = [];
|
|
2485
|
+
const ux = createUx({
|
|
2486
|
+
...options,
|
|
2487
|
+
spinner: false,
|
|
2488
|
+
write: (text) => lines.push(String(text)),
|
|
2489
|
+
});
|
|
2490
|
+
const symbolForStatus = (status) => {
|
|
2491
|
+
if (status === 'ok') return ux.theme.symbols.success;
|
|
2492
|
+
if (status === 'error') return ux.theme.symbols.error;
|
|
2493
|
+
return ux.theme.symbols.warning;
|
|
2494
|
+
};
|
|
2495
|
+
const colorForStatus = (status) => {
|
|
2496
|
+
if (status === 'ok') return 'success';
|
|
2497
|
+
if (status === 'error') return 'error';
|
|
2498
|
+
return 'warning';
|
|
2499
|
+
};
|
|
2500
|
+
|
|
2501
|
+
ux.section('Quiver Doctor');
|
|
2502
|
+
ux.line('');
|
|
2503
|
+
ux.line('Checks');
|
|
2504
|
+
for (const check of report.checks) {
|
|
2505
|
+
const line = ` ${symbolForStatus(check.status)} ${check.message}`;
|
|
2506
|
+
ux.line(ux.mode.decoration ? ux.theme.status(colorForStatus(check.status), line) : line);
|
|
2507
|
+
}
|
|
2508
|
+
|
|
2509
|
+
ux.line('');
|
|
2510
|
+
ux.line('Suggested fixes');
|
|
2511
|
+
for (const fix of report.suggested_fixes) {
|
|
2512
|
+
const line = ` ${ux.theme.symbols.bullet} ${fix}`;
|
|
2513
|
+
ux.line(ux.mode.decoration ? ux.theme.status('command', line) : line);
|
|
2514
|
+
}
|
|
2515
|
+
|
|
2516
|
+
return lines.join('');
|
|
2517
|
+
}
|
|
2518
|
+
|
|
2519
|
+
const METHODOLOGY_OPTIONS = Object.freeze([
|
|
2520
|
+
{
|
|
2521
|
+
label: 'WDD + SDD',
|
|
2522
|
+
value: 'wdd-sdd',
|
|
2523
|
+
hint: 'Workflow Driven Development + Spec Driven Development',
|
|
2524
|
+
default: true,
|
|
2525
|
+
},
|
|
2526
|
+
]);
|
|
2527
|
+
|
|
2528
|
+
const INIT_MODE_OPTIONS = Object.freeze([
|
|
2529
|
+
{
|
|
2530
|
+
label: 'Proyecto existente',
|
|
2531
|
+
value: 'existing',
|
|
2532
|
+
hint: 'Agrega Quiver sin sobrescribir archivos existentes',
|
|
2533
|
+
default: true,
|
|
2534
|
+
},
|
|
2535
|
+
{
|
|
2536
|
+
label: 'Proyecto nuevo',
|
|
2537
|
+
value: 'new',
|
|
2538
|
+
hint: 'Crea el contrato base en una carpeta nueva o vacia',
|
|
2539
|
+
},
|
|
2540
|
+
{
|
|
2541
|
+
label: 'Solo validar estructura',
|
|
2542
|
+
value: 'validate',
|
|
2543
|
+
hint: 'Ejecuta Doctor en lugar de escribir archivos',
|
|
2544
|
+
},
|
|
2545
|
+
]);
|
|
2546
|
+
|
|
2547
|
+
const INIT_PROFILE_OPTIONS = Object.freeze([
|
|
2548
|
+
{
|
|
2549
|
+
label: 'Default',
|
|
2550
|
+
value: 'default',
|
|
2551
|
+
hint: 'Contrato AI-first recomendado',
|
|
2552
|
+
default: true,
|
|
2553
|
+
},
|
|
2554
|
+
{
|
|
2555
|
+
label: 'Minimal',
|
|
2556
|
+
value: 'minimal',
|
|
2557
|
+
hint: 'Solo documentos esenciales',
|
|
2558
|
+
},
|
|
2559
|
+
{
|
|
2560
|
+
label: 'Full compatibility',
|
|
2561
|
+
value: 'full',
|
|
2562
|
+
hint: 'Incluye compatibilidad historica y templates visibles',
|
|
2563
|
+
},
|
|
2564
|
+
]);
|
|
2565
|
+
|
|
2566
|
+
function hasDirectoryContent(dirPath) {
|
|
2567
|
+
return fs.existsSync(dirPath)
|
|
2568
|
+
&& fs.statSync(dirPath).isDirectory()
|
|
2569
|
+
&& fs.readdirSync(dirPath).length > 0;
|
|
2570
|
+
}
|
|
2571
|
+
|
|
2572
|
+
function assertSupportedMethodology(value) {
|
|
2573
|
+
const normalized = String(value || '').trim();
|
|
2574
|
+
if (!normalized) {
|
|
2575
|
+
return 'wdd-sdd';
|
|
2576
|
+
}
|
|
2577
|
+
if (normalized !== 'wdd-sdd') {
|
|
2578
|
+
throw new Error(formatError(`unsupported methodology '${normalized}'. Supported methodologies: wdd-sdd.`));
|
|
2579
|
+
}
|
|
2580
|
+
return normalized;
|
|
2581
|
+
}
|
|
2582
|
+
|
|
2583
|
+
async function resolveInteractiveInitOptions(args, targetDir, projectName, options = {}) {
|
|
2584
|
+
const explicitMethodology = assertSupportedMethodology(args.methodology);
|
|
2585
|
+
|
|
2586
|
+
if (args.interactive !== true) {
|
|
2587
|
+
return {
|
|
2588
|
+
action: 'init',
|
|
2589
|
+
full: args.initFull,
|
|
2590
|
+
includeTemplates: args.initIncludeTemplates,
|
|
2591
|
+
legacyScripts: args.initLegacyScripts,
|
|
2592
|
+
methodology: explicitMethodology,
|
|
2593
|
+
minimal: args.initMinimal,
|
|
2594
|
+
projectName,
|
|
2595
|
+
};
|
|
2596
|
+
}
|
|
2597
|
+
|
|
2598
|
+
const ux = createUx({
|
|
2599
|
+
env: options.env,
|
|
2600
|
+
input: options.input,
|
|
2601
|
+
interactive: true,
|
|
2602
|
+
noColor: args.noColor,
|
|
2603
|
+
output: options.output,
|
|
2604
|
+
promptConfirm: options.promptConfirm,
|
|
2605
|
+
stderrIsTTY: options.stderrIsTTY,
|
|
2606
|
+
stdinIsTTY: options.stdinIsTTY,
|
|
2607
|
+
stdoutIsTTY: options.stdoutIsTTY,
|
|
2608
|
+
write: options.write,
|
|
2609
|
+
});
|
|
2610
|
+
|
|
2611
|
+
if (!ux.mode.usePrompts) {
|
|
2612
|
+
throw new Error(formatError('init --interactive requires an interactive TTY. Use explicit flags such as --name, --minimal, --full, --legacy-scripts, --include-templates, or run doctor to validate structure.'));
|
|
2613
|
+
}
|
|
2614
|
+
|
|
2615
|
+
const selectorOptions = {
|
|
2616
|
+
env: options.env,
|
|
2617
|
+
input: options.input,
|
|
2618
|
+
interactive: true,
|
|
2619
|
+
noColor: args.noColor,
|
|
2620
|
+
output: options.output,
|
|
2621
|
+
prompts: options.prompts,
|
|
2622
|
+
promptSelect: options.promptSelect,
|
|
2623
|
+
stderrIsTTY: options.stderrIsTTY,
|
|
2624
|
+
stdinIsTTY: options.stdinIsTTY,
|
|
2625
|
+
stdoutIsTTY: options.stdoutIsTTY,
|
|
2626
|
+
};
|
|
2627
|
+
|
|
2628
|
+
ux.heading('Bienvenido a Quiver');
|
|
2629
|
+
const selectedMode = await selectOption('¿Qué querés configurar?', INIT_MODE_OPTIONS, {
|
|
2630
|
+
...selectorOptions,
|
|
2631
|
+
defaultValue: hasDirectoryContent(targetDir) ? 'existing' : 'new',
|
|
2632
|
+
flag: 'init|doctor',
|
|
2633
|
+
name: 'init mode',
|
|
2634
|
+
});
|
|
2635
|
+
const selectedMethodology = await selectOption('¿Qué metodología vas a usar?', METHODOLOGY_OPTIONS, {
|
|
2636
|
+
...selectorOptions,
|
|
2637
|
+
defaultValue: explicitMethodology,
|
|
2638
|
+
flag: '--methodology',
|
|
2639
|
+
name: 'methodology',
|
|
2640
|
+
value: args.methodology || '',
|
|
2641
|
+
});
|
|
2642
|
+
|
|
2643
|
+
assertSupportedMethodology(selectedMethodology.value);
|
|
2644
|
+
|
|
2645
|
+
if (selectedMode.value === 'validate') {
|
|
2646
|
+
ux.summary([
|
|
2647
|
+
{ label: 'Modo', value: 'Solo validar estructura' },
|
|
2648
|
+
{ label: 'Metodologia', value: selectedMethodology.label },
|
|
2649
|
+
{ label: 'Comando equivalente', value: 'npx create-quiver doctor' },
|
|
2650
|
+
], { title: 'Configuracion elegida' });
|
|
2651
|
+
if (!args.force && !args.dryRun) {
|
|
2652
|
+
const confirmed = await ux.promptConfirm('Ejecutar Doctor ahora?', { initialValue: true });
|
|
2653
|
+
if (!confirmed) {
|
|
2654
|
+
throw new Error(formatError('init interactive validation declined. No files were written.'));
|
|
2655
|
+
}
|
|
2309
2656
|
}
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2657
|
+
return {
|
|
2658
|
+
action: 'doctor',
|
|
2659
|
+
methodology: selectedMethodology.value,
|
|
2660
|
+
projectName,
|
|
2661
|
+
};
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
const defaultProfile = args.initFull ? 'full' : args.initMinimal ? 'minimal' : 'default';
|
|
2665
|
+
const selectedProfile = await selectOption('¿Qué contrato inicial querés crear?', INIT_PROFILE_OPTIONS, {
|
|
2666
|
+
...selectorOptions,
|
|
2667
|
+
defaultValue: defaultProfile,
|
|
2668
|
+
flag: '--minimal|--full',
|
|
2669
|
+
name: 'init profile',
|
|
2670
|
+
});
|
|
2671
|
+
const agentGuidance = await selectOption('¿Querés ver el próximo paso para perfiles de agentes?', [
|
|
2672
|
+
{
|
|
2673
|
+
label: 'Mostrar comandos sugeridos',
|
|
2674
|
+
value: 'show',
|
|
2675
|
+
hint: 'No guarda credenciales ni ejecuta proveedores',
|
|
2676
|
+
default: true,
|
|
2677
|
+
},
|
|
2678
|
+
{
|
|
2679
|
+
label: 'Omitir por ahora',
|
|
2680
|
+
value: 'skip',
|
|
2681
|
+
},
|
|
2682
|
+
], {
|
|
2683
|
+
...selectorOptions,
|
|
2684
|
+
defaultValue: 'show',
|
|
2685
|
+
flag: 'ai agent set',
|
|
2686
|
+
name: 'agent profile guidance',
|
|
2687
|
+
});
|
|
2688
|
+
const nextFlags = {
|
|
2689
|
+
full: selectedProfile.value === 'full',
|
|
2690
|
+
includeTemplates: args.initIncludeTemplates || selectedProfile.value === 'full',
|
|
2691
|
+
legacyScripts: args.initLegacyScripts,
|
|
2692
|
+
methodology: selectedMethodology.value,
|
|
2693
|
+
minimal: selectedProfile.value === 'minimal',
|
|
2694
|
+
projectName,
|
|
2695
|
+
};
|
|
2696
|
+
|
|
2697
|
+
ux.summary([
|
|
2698
|
+
{ label: 'Proyecto', value: projectName },
|
|
2699
|
+
{ label: 'Modo', value: selectedMode.label },
|
|
2700
|
+
{ label: 'Metodologia', value: selectedMethodology.label },
|
|
2701
|
+
{ label: 'Perfil', value: selectedProfile.label },
|
|
2702
|
+
{ label: 'Perfiles de agentes', value: agentGuidance.value === 'show' ? 'mostrar proximo paso' : 'omitir' },
|
|
2703
|
+
], { title: 'Configuracion elegida' });
|
|
2704
|
+
|
|
2705
|
+
if (agentGuidance.value === 'show') {
|
|
2706
|
+
ux.nextSteps([
|
|
2707
|
+
'npx create-quiver ai agent set planner --provider codex --model "<modelo-planner>" --dry-run',
|
|
2708
|
+
'npx create-quiver ai agent set executor --provider claude --model "<modelo-executor>" --dry-run',
|
|
2709
|
+
], { title: 'Despues de inicializar' });
|
|
2710
|
+
}
|
|
2711
|
+
|
|
2712
|
+
if (!args.force && !args.dryRun) {
|
|
2713
|
+
const confirmed = await ux.promptConfirm(`Inicializar Quiver en ${targetDir}?`, { initialValue: true });
|
|
2714
|
+
if (!confirmed) {
|
|
2715
|
+
throw new Error(formatError('init interactive approval declined. No files were written.'));
|
|
2716
|
+
}
|
|
2717
|
+
}
|
|
2718
|
+
|
|
2719
|
+
return {
|
|
2720
|
+
action: 'init',
|
|
2721
|
+
...nextFlags,
|
|
2722
|
+
};
|
|
2723
|
+
}
|
|
2724
|
+
|
|
2725
|
+
function runDoctor(targetDir, options = {}) {
|
|
2726
|
+
const projectRoot = resolveTargetRoot(process.cwd(), targetDir);
|
|
2727
|
+
|
|
2728
|
+
if (!fs.existsSync(projectRoot)) {
|
|
2729
|
+
throw new Error(formatError(`target directory does not exist: ${projectRoot}`));
|
|
2730
|
+
}
|
|
2731
|
+
|
|
2732
|
+
if (!hasQuiverInitializationEvidence(projectRoot)) {
|
|
2733
|
+
throw new Error(formatError('doctor requires a project previously initialized by Quiver.\nRun init first: npx create-quiver --name "Project Name"'));
|
|
2734
|
+
}
|
|
2735
|
+
|
|
2736
|
+
const fixPlan = buildDoctorFixPlan(projectRoot);
|
|
2737
|
+
if (options.fix) {
|
|
2738
|
+
if (options.dryRun) {
|
|
2739
|
+
if (options.json) {
|
|
2740
|
+
console.log(JSON.stringify({
|
|
2741
|
+
schema_version: 1,
|
|
2742
|
+
command: 'doctor fix',
|
|
2743
|
+
dry_run: true,
|
|
2744
|
+
fixes: fixPlan,
|
|
2745
|
+
}, null, 2));
|
|
2746
|
+
return;
|
|
2747
|
+
}
|
|
2748
|
+
console.log(formatDoctorFixPlan(fixPlan, { dryRun: true }));
|
|
2749
|
+
return;
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2752
|
+
applyDoctorFixPlan(projectRoot, fixPlan);
|
|
2753
|
+
if (!options.json) {
|
|
2754
|
+
console.log(formatDoctorFixPlan(fixPlan));
|
|
2755
|
+
}
|
|
2756
|
+
}
|
|
2757
|
+
|
|
2758
|
+
const commandReport = buildDoctorCommandReport(projectRoot);
|
|
2759
|
+
if (options.json) {
|
|
2760
|
+
console.log(JSON.stringify(commandReport, null, 2));
|
|
2313
2761
|
} else {
|
|
2314
|
-
|
|
2762
|
+
process.stdout.write(formatDoctorHumanReport(commandReport, {
|
|
2763
|
+
noColor: options.noColor,
|
|
2764
|
+
unicode: options.unicode,
|
|
2765
|
+
}));
|
|
2766
|
+
}
|
|
2767
|
+
|
|
2768
|
+
if (commandReport.exit_code !== 0) {
|
|
2769
|
+
process.exitCode = commandReport.exit_code;
|
|
2315
2770
|
}
|
|
2316
2771
|
}
|
|
2317
2772
|
|
|
@@ -2342,6 +2797,8 @@ async function run(argv) {
|
|
|
2342
2797
|
return;
|
|
2343
2798
|
}
|
|
2344
2799
|
|
|
2800
|
+
validateUxFlags(args);
|
|
2801
|
+
|
|
2345
2802
|
if (args.mode === 'analyze') {
|
|
2346
2803
|
runAnalyze(args.targetDir, {
|
|
2347
2804
|
dryRun: args.dryRun,
|
|
@@ -2456,6 +2913,9 @@ async function run(argv) {
|
|
|
2456
2913
|
runAiAgent(process.cwd(), {
|
|
2457
2914
|
command: args.aiAgentCommand,
|
|
2458
2915
|
context: args.aiContext || undefined,
|
|
2916
|
+
defaultProfile: args.aiDefaultProfile,
|
|
2917
|
+
displayName: args.aiDisplayName || undefined,
|
|
2918
|
+
id: args.aiProfileId || undefined,
|
|
2459
2919
|
label: args.aiLabel || undefined,
|
|
2460
2920
|
model: args.aiModel || undefined,
|
|
2461
2921
|
provider: args.aiProviderExplicit ? args.aiProvider : undefined,
|
|
@@ -2473,6 +2933,8 @@ async function run(argv) {
|
|
|
2473
2933
|
printPrompt: args.aiPrintPrompt,
|
|
2474
2934
|
provider: args.aiProvider,
|
|
2475
2935
|
providerExplicit: args.aiProviderExplicit,
|
|
2936
|
+
model: args.aiModel || undefined,
|
|
2937
|
+
plannerProfile: args.aiPlannerProfile || undefined,
|
|
2476
2938
|
role: args.aiRole,
|
|
2477
2939
|
timeout: args.aiTimeout,
|
|
2478
2940
|
});
|
|
@@ -2481,8 +2943,19 @@ async function run(argv) {
|
|
|
2481
2943
|
|
|
2482
2944
|
if (args.aiCommand === 'prepare-context') {
|
|
2483
2945
|
await runAiPrepareContext(process.cwd(), {
|
|
2946
|
+
context: args.aiContext || undefined,
|
|
2484
2947
|
dryRun: args.dryRun,
|
|
2948
|
+
interactive: args.interactive,
|
|
2949
|
+
printPrompt: args.aiPrintPrompt,
|
|
2950
|
+
provider: args.aiProvider,
|
|
2951
|
+
providerExplicit: args.aiProviderExplicit,
|
|
2952
|
+
model: args.aiModel || undefined,
|
|
2953
|
+
plannerProfile: args.aiPlannerProfile || undefined,
|
|
2954
|
+
review: args.review,
|
|
2955
|
+
role: args.aiRole,
|
|
2485
2956
|
runId: args.aiRunId || undefined,
|
|
2957
|
+
timeout: args.aiTimeout,
|
|
2958
|
+
withPlanner: args.withPlanner,
|
|
2486
2959
|
});
|
|
2487
2960
|
return;
|
|
2488
2961
|
}
|
|
@@ -2496,10 +2969,15 @@ async function run(argv) {
|
|
|
2496
2969
|
printPrompt: args.aiPrintPrompt,
|
|
2497
2970
|
provider: args.aiProvider,
|
|
2498
2971
|
providerExplicit: args.aiProviderExplicit,
|
|
2972
|
+
model: args.aiModel || undefined,
|
|
2973
|
+
plannerProfile: args.aiPlannerProfile || undefined,
|
|
2974
|
+
interactive: args.interactive,
|
|
2975
|
+
review: args.review,
|
|
2499
2976
|
role: args.aiRole,
|
|
2500
2977
|
runId: args.aiRunId || undefined,
|
|
2501
2978
|
specSlug: args.specSlug || undefined,
|
|
2502
2979
|
timeout: args.aiTimeout,
|
|
2980
|
+
withPlanner: args.withPlanner,
|
|
2503
2981
|
});
|
|
2504
2982
|
return;
|
|
2505
2983
|
}
|
|
@@ -2512,6 +2990,8 @@ async function run(argv) {
|
|
|
2512
2990
|
printPrompt: args.aiPrintPrompt,
|
|
2513
2991
|
provider: args.aiProvider,
|
|
2514
2992
|
providerExplicit: args.aiProviderExplicit,
|
|
2993
|
+
model: args.aiModel || undefined,
|
|
2994
|
+
reviewerProfile: args.aiReviewerProfile || undefined,
|
|
2515
2995
|
timeout: args.aiTimeout,
|
|
2516
2996
|
});
|
|
2517
2997
|
return;
|
|
@@ -2525,6 +3005,8 @@ async function run(argv) {
|
|
|
2525
3005
|
printPrompt: args.aiPrintPrompt,
|
|
2526
3006
|
provider: args.aiProvider,
|
|
2527
3007
|
providerExplicit: args.aiProviderExplicit,
|
|
3008
|
+
model: args.aiModel || undefined,
|
|
3009
|
+
plannerProfile: args.aiPlannerProfile || undefined,
|
|
2528
3010
|
role: args.aiRole,
|
|
2529
3011
|
runId: args.aiRunId || undefined,
|
|
2530
3012
|
timeout: args.aiTimeout,
|
|
@@ -2541,6 +3023,8 @@ async function run(argv) {
|
|
|
2541
3023
|
printPrompt: args.aiPrintPrompt,
|
|
2542
3024
|
provider: args.aiProvider,
|
|
2543
3025
|
providerExplicit: args.aiProviderExplicit,
|
|
3026
|
+
model: args.aiModel || undefined,
|
|
3027
|
+
plannerProfile: args.aiPlannerProfile || undefined,
|
|
2544
3028
|
role: args.aiRole,
|
|
2545
3029
|
runId: args.aiRunId || undefined,
|
|
2546
3030
|
timeout: args.aiTimeout,
|
|
@@ -2570,6 +3054,9 @@ async function run(argv) {
|
|
|
2570
3054
|
commit: args.aiCommit,
|
|
2571
3055
|
context: args.aiContext || undefined,
|
|
2572
3056
|
dryRun: args.dryRun,
|
|
3057
|
+
executorProfile: args.aiExecutorProfile || undefined,
|
|
3058
|
+
interactive: args.interactive,
|
|
3059
|
+
model: args.aiModel || undefined,
|
|
2573
3060
|
provider: args.aiProvider,
|
|
2574
3061
|
providerExplicit: args.aiProviderExplicit,
|
|
2575
3062
|
role: args.aiRole,
|
|
@@ -2593,7 +3080,10 @@ async function run(argv) {
|
|
|
2593
3080
|
context: args.aiContext || undefined,
|
|
2594
3081
|
dryRun: args.dryRun,
|
|
2595
3082
|
execute: args.aiExecute,
|
|
3083
|
+
executorProfile: args.aiExecutorProfile || undefined,
|
|
3084
|
+
interactive: args.interactive,
|
|
2596
3085
|
json: args.json,
|
|
3086
|
+
model: args.aiModel || undefined,
|
|
2597
3087
|
mode: args.aiExecutionMode,
|
|
2598
3088
|
provider: args.aiProvider,
|
|
2599
3089
|
providerExplicit: args.aiProviderExplicit,
|
|
@@ -2620,7 +3110,9 @@ async function run(argv) {
|
|
|
2620
3110
|
create: args.aiCreate,
|
|
2621
3111
|
dryRun: args.dryRun,
|
|
2622
3112
|
input: args.aiInput || undefined,
|
|
3113
|
+
interactive: args.interactive,
|
|
2623
3114
|
remote: args.aiRemote || undefined,
|
|
3115
|
+
review: args.review,
|
|
2624
3116
|
sshHostAlias: args.aiSshHostAlias || undefined,
|
|
2625
3117
|
identityFile: args.aiIdentityFile || undefined,
|
|
2626
3118
|
title: args.aiTitle || undefined,
|
|
@@ -2689,6 +3181,9 @@ async function run(argv) {
|
|
|
2689
3181
|
runDoctor(args.targetDir, {
|
|
2690
3182
|
dryRun: args.dryRun,
|
|
2691
3183
|
fix: args.doctorFix,
|
|
3184
|
+
json: args.json,
|
|
3185
|
+
noColor: args.noColor,
|
|
3186
|
+
unicode: args.unicode,
|
|
2692
3187
|
});
|
|
2693
3188
|
return;
|
|
2694
3189
|
}
|
|
@@ -2760,10 +3255,14 @@ async function run(argv) {
|
|
|
2760
3255
|
|
|
2761
3256
|
if (args.mode === 'spec') {
|
|
2762
3257
|
if (args.specCommand === 'create') {
|
|
2763
|
-
runCreateSpec(process.cwd(), {
|
|
3258
|
+
await runCreateSpec(process.cwd(), {
|
|
2764
3259
|
dryRun: args.dryRun,
|
|
2765
3260
|
input: args.aiInput || undefined,
|
|
3261
|
+
interactive: args.interactive,
|
|
3262
|
+
methodology: args.methodology || undefined,
|
|
3263
|
+
review: args.review,
|
|
2766
3264
|
specSlug: args.specSlug || undefined,
|
|
3265
|
+
withPlanner: args.withPlanner,
|
|
2767
3266
|
});
|
|
2768
3267
|
return;
|
|
2769
3268
|
}
|
|
@@ -2811,14 +3310,25 @@ async function run(argv) {
|
|
|
2811
3310
|
const packageRoot = path.resolve(__dirname, '../..');
|
|
2812
3311
|
const targetDir = resolveTargetRoot(process.cwd(), args.targetDir);
|
|
2813
3312
|
const projectName = args.projectName || path.basename(targetDir) || 'Quiver Project';
|
|
3313
|
+
const initOptions = await resolveInteractiveInitOptions(args, targetDir, projectName);
|
|
3314
|
+
if (initOptions.action === 'doctor') {
|
|
3315
|
+
runDoctor(targetDir, {
|
|
3316
|
+
dryRun: args.dryRun,
|
|
3317
|
+
fix: false,
|
|
3318
|
+
json: args.json,
|
|
3319
|
+
noColor: args.noColor,
|
|
3320
|
+
unicode: args.unicode,
|
|
3321
|
+
});
|
|
3322
|
+
return;
|
|
3323
|
+
}
|
|
2814
3324
|
const initLayout = buildInitLayout(targetDir, {
|
|
2815
3325
|
compatibilityAlias: !args.explicitInit,
|
|
2816
3326
|
dryRun: args.dryRun,
|
|
2817
|
-
full:
|
|
2818
|
-
includeTemplates:
|
|
2819
|
-
legacyScripts:
|
|
2820
|
-
minimal:
|
|
2821
|
-
projectName,
|
|
3327
|
+
full: initOptions.full,
|
|
3328
|
+
includeTemplates: initOptions.includeTemplates,
|
|
3329
|
+
legacyScripts: initOptions.legacyScripts,
|
|
3330
|
+
minimal: initOptions.minimal,
|
|
3331
|
+
projectName: initOptions.projectName,
|
|
2822
3332
|
skipInstall: args.skipInstall,
|
|
2823
3333
|
});
|
|
2824
3334
|
|
|
@@ -2836,9 +3346,9 @@ async function run(argv) {
|
|
|
2836
3346
|
if (initLayout.profile === 'full') {
|
|
2837
3347
|
exportTemplatesToLegacyRoot(templateRoot, targetDir);
|
|
2838
3348
|
}
|
|
2839
|
-
runInitDocs(targetDir, projectName, {
|
|
2840
|
-
includeTemplates:
|
|
2841
|
-
legacyScripts:
|
|
3349
|
+
runInitDocs(targetDir, initOptions.projectName, {
|
|
3350
|
+
includeTemplates: initOptions.includeTemplates,
|
|
3351
|
+
legacyScripts: initOptions.legacyScripts,
|
|
2842
3352
|
profile: initLayout.profile,
|
|
2843
3353
|
templateRoot,
|
|
2844
3354
|
});
|
|
@@ -2853,13 +3363,14 @@ async function run(argv) {
|
|
|
2853
3363
|
}
|
|
2854
3364
|
|
|
2855
3365
|
console.log(`Installed Quiver into ${targetDir}`);
|
|
2856
|
-
printInitNextSteps(targetDir, projectName);
|
|
3366
|
+
printInitNextSteps(targetDir, initOptions.projectName);
|
|
2857
3367
|
} finally {
|
|
2858
3368
|
fs.rmSync(tempRoot, { recursive: true, force: true });
|
|
2859
3369
|
}
|
|
2860
3370
|
}
|
|
2861
3371
|
|
|
2862
3372
|
module.exports = {
|
|
3373
|
+
resolveInteractiveInitOptions,
|
|
2863
3374
|
runAnalyze,
|
|
2864
3375
|
runDoctor,
|
|
2865
3376
|
runFlow,
|