popeye-cli 1.7.0 → 1.9.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/README.md +148 -7
- package/cheatsheet.md +440 -0
- package/dist/cli/commands/db.d.ts +10 -0
- package/dist/cli/commands/db.d.ts.map +1 -0
- package/dist/cli/commands/db.js +240 -0
- package/dist/cli/commands/db.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +18 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +255 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/index.d.ts +3 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +3 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/review.d.ts +31 -0
- package/dist/cli/commands/review.d.ts.map +1 -0
- package/dist/cli/commands/review.js +156 -0
- package/dist/cli/commands/review.js.map +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +4 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +218 -61
- package/dist/cli/interactive.js.map +1 -1
- package/dist/generators/admin-wizard.d.ts +25 -0
- package/dist/generators/admin-wizard.d.ts.map +1 -0
- package/dist/generators/admin-wizard.js +123 -0
- package/dist/generators/admin-wizard.js.map +1 -0
- package/dist/generators/all.d.ts.map +1 -1
- package/dist/generators/all.js +10 -3
- package/dist/generators/all.js.map +1 -1
- package/dist/generators/database.d.ts +58 -0
- package/dist/generators/database.d.ts.map +1 -0
- package/dist/generators/database.js +229 -0
- package/dist/generators/database.js.map +1 -0
- package/dist/generators/fullstack.d.ts.map +1 -1
- package/dist/generators/fullstack.js +23 -7
- package/dist/generators/fullstack.js.map +1 -1
- package/dist/generators/index.d.ts +2 -0
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +2 -0
- package/dist/generators/index.js.map +1 -1
- package/dist/generators/templates/admin-wizard-python.d.ts +32 -0
- package/dist/generators/templates/admin-wizard-python.d.ts.map +1 -0
- package/dist/generators/templates/admin-wizard-python.js +425 -0
- package/dist/generators/templates/admin-wizard-python.js.map +1 -0
- package/dist/generators/templates/admin-wizard-react.d.ts +48 -0
- package/dist/generators/templates/admin-wizard-react.d.ts.map +1 -0
- package/dist/generators/templates/admin-wizard-react.js +554 -0
- package/dist/generators/templates/admin-wizard-react.js.map +1 -0
- package/dist/generators/templates/database-docker.d.ts +23 -0
- package/dist/generators/templates/database-docker.d.ts.map +1 -0
- package/dist/generators/templates/database-docker.js +221 -0
- package/dist/generators/templates/database-docker.js.map +1 -0
- package/dist/generators/templates/database-python.d.ts +54 -0
- package/dist/generators/templates/database-python.d.ts.map +1 -0
- package/dist/generators/templates/database-python.js +723 -0
- package/dist/generators/templates/database-python.js.map +1 -0
- package/dist/generators/templates/database-typescript.d.ts +34 -0
- package/dist/generators/templates/database-typescript.d.ts.map +1 -0
- package/dist/generators/templates/database-typescript.js +232 -0
- package/dist/generators/templates/database-typescript.js.map +1 -0
- package/dist/generators/templates/fullstack.d.ts.map +1 -1
- package/dist/generators/templates/fullstack.js +29 -0
- package/dist/generators/templates/fullstack.js.map +1 -1
- package/dist/generators/templates/index.d.ts +5 -0
- package/dist/generators/templates/index.d.ts.map +1 -1
- package/dist/generators/templates/index.js +5 -0
- package/dist/generators/templates/index.js.map +1 -1
- package/dist/state/index.d.ts +10 -0
- package/dist/state/index.d.ts.map +1 -1
- package/dist/state/index.js +21 -0
- package/dist/state/index.js.map +1 -1
- package/dist/types/audit.d.ts +623 -0
- package/dist/types/audit.d.ts.map +1 -0
- package/dist/types/audit.js +240 -0
- package/dist/types/audit.js.map +1 -0
- package/dist/types/database-runtime.d.ts +86 -0
- package/dist/types/database-runtime.d.ts.map +1 -0
- package/dist/types/database-runtime.js +61 -0
- package/dist/types/database-runtime.js.map +1 -0
- package/dist/types/database.d.ts +85 -0
- package/dist/types/database.d.ts.map +1 -0
- package/dist/types/database.js +71 -0
- package/dist/types/database.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +4 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/workflow.d.ts +36 -0
- package/dist/types/workflow.d.ts.map +1 -1
- package/dist/types/workflow.js +7 -0
- package/dist/types/workflow.js.map +1 -1
- package/dist/workflow/audit-analyzer.d.ts +58 -0
- package/dist/workflow/audit-analyzer.d.ts.map +1 -0
- package/dist/workflow/audit-analyzer.js +420 -0
- package/dist/workflow/audit-analyzer.js.map +1 -0
- package/dist/workflow/audit-mode.d.ts +28 -0
- package/dist/workflow/audit-mode.d.ts.map +1 -0
- package/dist/workflow/audit-mode.js +169 -0
- package/dist/workflow/audit-mode.js.map +1 -0
- package/dist/workflow/audit-recovery.d.ts +61 -0
- package/dist/workflow/audit-recovery.d.ts.map +1 -0
- package/dist/workflow/audit-recovery.js +242 -0
- package/dist/workflow/audit-recovery.js.map +1 -0
- package/dist/workflow/audit-reporter.d.ts +65 -0
- package/dist/workflow/audit-reporter.d.ts.map +1 -0
- package/dist/workflow/audit-reporter.js +301 -0
- package/dist/workflow/audit-reporter.js.map +1 -0
- package/dist/workflow/audit-scanner.d.ts +87 -0
- package/dist/workflow/audit-scanner.d.ts.map +1 -0
- package/dist/workflow/audit-scanner.js +768 -0
- package/dist/workflow/audit-scanner.js.map +1 -0
- package/dist/workflow/db-setup-runner.d.ts +63 -0
- package/dist/workflow/db-setup-runner.d.ts.map +1 -0
- package/dist/workflow/db-setup-runner.js +336 -0
- package/dist/workflow/db-setup-runner.js.map +1 -0
- package/dist/workflow/db-state-machine.d.ts +30 -0
- package/dist/workflow/db-state-machine.d.ts.map +1 -0
- package/dist/workflow/db-state-machine.js +51 -0
- package/dist/workflow/db-state-machine.js.map +1 -0
- package/dist/workflow/index.d.ts +7 -0
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +7 -0
- package/dist/workflow/index.js.map +1 -1
- package/package.json +1 -1
- package/src/cli/commands/db.ts +281 -0
- package/src/cli/commands/doctor.ts +273 -0
- package/src/cli/commands/index.ts +3 -0
- package/src/cli/commands/review.ts +187 -0
- package/src/cli/index.ts +6 -0
- package/src/cli/interactive.ts +174 -4
- package/src/generators/admin-wizard.ts +146 -0
- package/src/generators/all.ts +10 -3
- package/src/generators/database.ts +286 -0
- package/src/generators/fullstack.ts +26 -9
- package/src/generators/index.ts +12 -0
- package/src/generators/templates/admin-wizard-python.ts +431 -0
- package/src/generators/templates/admin-wizard-react.ts +560 -0
- package/src/generators/templates/database-docker.ts +227 -0
- package/src/generators/templates/database-python.ts +734 -0
- package/src/generators/templates/database-typescript.ts +238 -0
- package/src/generators/templates/fullstack.ts +29 -0
- package/src/generators/templates/index.ts +5 -0
- package/src/state/index.ts +28 -0
- package/src/types/audit.ts +294 -0
- package/src/types/database-runtime.ts +69 -0
- package/src/types/database.ts +84 -0
- package/src/types/index.ts +29 -0
- package/src/types/workflow.ts +20 -0
- package/src/workflow/audit-analyzer.ts +491 -0
- package/src/workflow/audit-mode.ts +240 -0
- package/src/workflow/audit-recovery.ts +284 -0
- package/src/workflow/audit-reporter.ts +370 -0
- package/src/workflow/audit-scanner.ts +873 -0
- package/src/workflow/db-setup-runner.ts +391 -0
- package/src/workflow/db-state-machine.ts +58 -0
- package/src/workflow/index.ts +7 -0
- package/tests/cli/commands/review.test.ts +52 -0
- package/tests/generators/admin-wizard-orchestrator.test.ts +64 -0
- package/tests/generators/admin-wizard-templates.test.ts +366 -0
- package/tests/generators/cross-phase-integration.test.ts +383 -0
- package/tests/generators/database.test.ts +456 -0
- package/tests/generators/fe-be-db-integration.test.ts +613 -0
- package/tests/types/audit.test.ts +250 -0
- package/tests/types/database-runtime.test.ts +158 -0
- package/tests/types/database.test.ts +187 -0
- package/tests/workflow/audit-analyzer.test.ts +281 -0
- package/tests/workflow/audit-mode.test.ts +114 -0
- package/tests/workflow/audit-recovery.test.ts +237 -0
- package/tests/workflow/audit-reporter.test.ts +254 -0
- package/tests/workflow/audit-scanner.test.ts +270 -0
- package/tests/workflow/db-setup-runner.test.ts +211 -0
- package/tests/workflow/db-state-machine.test.ts +117 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CLI command: popeye review
|
|
3
|
+
*
|
|
4
|
+
* Runs a post-build audit/review of the project, producing a structured
|
|
5
|
+
* report with findings and optional recovery tasks.
|
|
6
|
+
*
|
|
7
|
+
* Pattern follows doctor.ts command factory.
|
|
8
|
+
*/
|
|
9
|
+
import { Command } from 'commander';
|
|
10
|
+
import path from 'node:path';
|
|
11
|
+
import { printHeader, printSuccess, printError, printWarning, printInfo, printKeyValue, printSection, } from '../output.js';
|
|
12
|
+
import { runAuditMode } from '../../workflow/audit-mode.js';
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// Run audit (exported for testability + slash command reuse)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Execute the audit and print results to the console.
|
|
18
|
+
*
|
|
19
|
+
* @param projectDir - Absolute path to the project directory.
|
|
20
|
+
* @param options - CLI options.
|
|
21
|
+
* @returns The audit result.
|
|
22
|
+
*/
|
|
23
|
+
export async function runReview(projectDir, options = {}) {
|
|
24
|
+
printHeader('Project Audit / Review');
|
|
25
|
+
const auditOptions = {
|
|
26
|
+
projectDir,
|
|
27
|
+
depth: options.depth ?? 2,
|
|
28
|
+
runTests: true,
|
|
29
|
+
strict: options.strict ?? false,
|
|
30
|
+
format: options.format ?? 'both',
|
|
31
|
+
autoRecover: options.recover ?? true,
|
|
32
|
+
target: (options.target ?? 'all'),
|
|
33
|
+
onProgress: (stage, message) => {
|
|
34
|
+
printInfo(`[${stage}] ${message}`);
|
|
35
|
+
},
|
|
36
|
+
};
|
|
37
|
+
const result = await runAuditMode(auditOptions);
|
|
38
|
+
if (!result.success) {
|
|
39
|
+
printError(`Audit failed: ${result.error}`);
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
// Print summary
|
|
43
|
+
console.log();
|
|
44
|
+
printSection('Summary');
|
|
45
|
+
printKeyValue('Project', result.summary.projectName);
|
|
46
|
+
printKeyValue('Language', result.summary.language);
|
|
47
|
+
printKeyValue('Source files', result.summary.totalSourceFiles);
|
|
48
|
+
printKeyValue('Test files', result.summary.totalTestFiles);
|
|
49
|
+
printKeyValue('Lines of code', result.summary.totalLinesOfCode);
|
|
50
|
+
printKeyValue('Components', result.summary.componentCount);
|
|
51
|
+
// Print score
|
|
52
|
+
console.log();
|
|
53
|
+
printSection('Audit Score');
|
|
54
|
+
const score = result.audit.overallScore;
|
|
55
|
+
if (score >= 80) {
|
|
56
|
+
printSuccess(`Overall: ${score}/100`);
|
|
57
|
+
}
|
|
58
|
+
else if (score >= 60) {
|
|
59
|
+
printWarning(`Overall: ${score}/100`);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
printError(`Overall: ${score}/100`);
|
|
63
|
+
}
|
|
64
|
+
// Print finding counts
|
|
65
|
+
if (result.audit.criticalCount > 0) {
|
|
66
|
+
printError(`Critical: ${result.audit.criticalCount}`);
|
|
67
|
+
}
|
|
68
|
+
if (result.audit.majorCount > 0) {
|
|
69
|
+
printWarning(`Major: ${result.audit.majorCount}`);
|
|
70
|
+
}
|
|
71
|
+
if (result.audit.minorCount > 0) {
|
|
72
|
+
printInfo(`Minor: ${result.audit.minorCount}`);
|
|
73
|
+
}
|
|
74
|
+
if (result.audit.infoCount > 0) {
|
|
75
|
+
printInfo(`Info: ${result.audit.infoCount}`);
|
|
76
|
+
}
|
|
77
|
+
// Recommendation
|
|
78
|
+
console.log();
|
|
79
|
+
const rec = result.audit.recommendation;
|
|
80
|
+
if (rec === 'pass') {
|
|
81
|
+
printSuccess(`Recommendation: ${rec}`);
|
|
82
|
+
}
|
|
83
|
+
else if (rec === 'fix-and-recheck') {
|
|
84
|
+
printWarning(`Recommendation: ${rec}`);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
printError(`Recommendation: ${rec}`);
|
|
88
|
+
}
|
|
89
|
+
// Report paths
|
|
90
|
+
if (Object.keys(result.reportPaths).length > 0) {
|
|
91
|
+
console.log();
|
|
92
|
+
printSection('Reports');
|
|
93
|
+
if (result.reportPaths.auditMd) {
|
|
94
|
+
printInfo(`Markdown: ${result.reportPaths.auditMd}`);
|
|
95
|
+
}
|
|
96
|
+
if (result.reportPaths.auditJson) {
|
|
97
|
+
printInfo(`JSON: ${result.reportPaths.auditJson}`);
|
|
98
|
+
}
|
|
99
|
+
if (result.reportPaths.recoveryMd) {
|
|
100
|
+
printWarning(`Recovery plan: ${result.reportPaths.recoveryMd}`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// Recovery info
|
|
104
|
+
if (result.recovery) {
|
|
105
|
+
console.log();
|
|
106
|
+
printSection('Recovery Plan');
|
|
107
|
+
printWarning(`${result.recovery.milestones.length} recovery milestone(s), estimated ${result.recovery.estimatedEffort}`);
|
|
108
|
+
if (auditOptions.autoRecover) {
|
|
109
|
+
printSuccess('Recovery milestones injected — run /resume to execute.');
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
printInfo('Run without --no-recover to auto-inject recovery milestones.');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
}
|
|
117
|
+
// ---------------------------------------------------------------------------
|
|
118
|
+
// Commander command factory
|
|
119
|
+
// ---------------------------------------------------------------------------
|
|
120
|
+
/**
|
|
121
|
+
* Create the `popeye review` CLI command.
|
|
122
|
+
*
|
|
123
|
+
* @returns Commander command instance.
|
|
124
|
+
*/
|
|
125
|
+
export function createReviewCommand() {
|
|
126
|
+
const cmd = new Command('review')
|
|
127
|
+
.alias('audit')
|
|
128
|
+
.description('Run a post-build audit/review of the project')
|
|
129
|
+
.argument('[directory]', 'Project directory', '.')
|
|
130
|
+
.option('-d, --depth <level>', 'Audit depth: 1=shallow, 2=standard, 3=deep', '2')
|
|
131
|
+
.option('-s, --strict', 'Enable strict mode (higher standards)', false)
|
|
132
|
+
.option('-f, --format <type>', 'Output format: json, md, both', 'both')
|
|
133
|
+
.option('--no-recover', 'Skip auto-injection of recovery milestones')
|
|
134
|
+
.option('-t, --target <kind>', 'Audit target: all, frontend, backend, website', 'all')
|
|
135
|
+
.action(async (directory, opts) => {
|
|
136
|
+
const projectDir = path.resolve(directory);
|
|
137
|
+
try {
|
|
138
|
+
const result = await runReview(projectDir, {
|
|
139
|
+
depth: parseInt(opts.depth, 10),
|
|
140
|
+
strict: opts.strict,
|
|
141
|
+
format: opts.format,
|
|
142
|
+
recover: opts.recover,
|
|
143
|
+
target: opts.target,
|
|
144
|
+
});
|
|
145
|
+
if (!result.success) {
|
|
146
|
+
process.exit(1);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
catch (err) {
|
|
150
|
+
printError(err instanceof Error ? err.message : 'Audit failed');
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
});
|
|
154
|
+
return cmd;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review.js","sourceRoot":"","sources":["../../../src/cli/commands/review.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,qBAAqB,CAAC;AAOpC,eAAO,MAAM,OAAO,EAAE,MAA4B,CAAC;AAEnD;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CA0CvC;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CASzE"}
|
package/dist/cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import { Command } from 'commander';
|
|
6
6
|
import { createRequire } from 'node:module';
|
|
7
|
-
import { createAuthCommand, createCreateCommand, createStatusCommand, createValidateCommand, createSummaryCommand, createResumeCommand, createResetCommand, createCancelCommand, createConfigCommand, } from './commands/index.js';
|
|
7
|
+
import { createAuthCommand, createCreateCommand, createStatusCommand, createValidateCommand, createSummaryCommand, createResumeCommand, createResetCommand, createCancelCommand, createConfigCommand, createDbCommand, createDoctorCommand, createReviewCommand, } from './commands/index.js';
|
|
8
8
|
import { startInteractiveMode } from './interactive.js';
|
|
9
9
|
import { printError } from './output.js';
|
|
10
10
|
// Re-export
|
|
@@ -38,6 +38,9 @@ export function createProgram() {
|
|
|
38
38
|
program.addCommand(createResetCommand());
|
|
39
39
|
program.addCommand(createCancelCommand());
|
|
40
40
|
program.addCommand(createConfigCommand());
|
|
41
|
+
program.addCommand(createDbCommand());
|
|
42
|
+
program.addCommand(createDoctorCommand());
|
|
43
|
+
program.addCommand(createReviewCommand());
|
|
41
44
|
// Interactive mode command
|
|
42
45
|
program
|
|
43
46
|
.command('interactive')
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"interactive.d.ts","sourceRoot":"","sources":["../../src/cli/interactive.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAw4EH;;;;;;GAMG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CA2B7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA0BrF;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA4EhE;AAiVD;;GAEG;AACH,wBAAsB,oBAAoB,IAAI,OAAO,CAAC,IAAI,CAAC,CA4E1D"}
|
package/dist/cli/interactive.js
CHANGED
|
@@ -697,6 +697,9 @@ function showHelp() {
|
|
|
697
697
|
['/new <idea>', 'Force start a new project (skips existing check)'],
|
|
698
698
|
['/resume', 'Resume interrupted project'],
|
|
699
699
|
['/overview [fix]', 'Project review with analysis; fix to auto-discover docs'],
|
|
700
|
+
['/db [action]', 'Database management (status/configure/apply)'],
|
|
701
|
+
['/doctor', 'Run database and project readiness checks'],
|
|
702
|
+
['/review', 'Run post-build audit/review with findings and recovery'],
|
|
700
703
|
['/clear', 'Clear screen'],
|
|
701
704
|
['/exit', 'Exit Popeye'],
|
|
702
705
|
];
|
|
@@ -838,6 +841,16 @@ async function handleInput(input, state) {
|
|
|
838
841
|
await handleNewProject(args.join(' '), state);
|
|
839
842
|
}
|
|
840
843
|
break;
|
|
844
|
+
case '/db':
|
|
845
|
+
await handleDbSlashCommand(state, args);
|
|
846
|
+
break;
|
|
847
|
+
case '/doctor':
|
|
848
|
+
await handleDoctorSlashCommand(state);
|
|
849
|
+
break;
|
|
850
|
+
case '/review':
|
|
851
|
+
case '/audit':
|
|
852
|
+
await handleReviewSlashCommand(state, args);
|
|
853
|
+
break;
|
|
841
854
|
default:
|
|
842
855
|
printError(`Unknown command: ${cmd}`);
|
|
843
856
|
printInfo('Type /help for available commands');
|
|
@@ -872,6 +885,134 @@ async function handleStatus(state) {
|
|
|
872
885
|
const summary = await getWorkflowSummary(state.projectDir);
|
|
873
886
|
console.log(summary);
|
|
874
887
|
}
|
|
888
|
+
/**
|
|
889
|
+
* Handle /db slash command - database management
|
|
890
|
+
*/
|
|
891
|
+
async function handleDbSlashCommand(state, args) {
|
|
892
|
+
if (!state.projectDir) {
|
|
893
|
+
printError('No active project. Create or resume a project first.');
|
|
894
|
+
return;
|
|
895
|
+
}
|
|
896
|
+
const action = args[0] || 'status';
|
|
897
|
+
switch (action) {
|
|
898
|
+
case 'status': {
|
|
899
|
+
try {
|
|
900
|
+
const { loadProject } = await import('../state/index.js');
|
|
901
|
+
const { DEFAULT_DB_CONFIG } = await import('../types/database.js');
|
|
902
|
+
const projectState = await loadProject(state.projectDir);
|
|
903
|
+
const dbConfig = projectState.dbConfig || { ...DEFAULT_DB_CONFIG, designed: false };
|
|
904
|
+
console.log();
|
|
905
|
+
printInfo('Database Status:');
|
|
906
|
+
console.log(` Designed: ${dbConfig.designed ? 'Yes' : 'No'}`);
|
|
907
|
+
console.log(` Status: ${dbConfig.status}`);
|
|
908
|
+
console.log(` Mode: ${dbConfig.mode || 'not set'}`);
|
|
909
|
+
console.log(` Vector: ${dbConfig.vectorRequired ? 'Yes' : 'No'}`);
|
|
910
|
+
console.log(` Migrations: ${dbConfig.migrationsApplied}`);
|
|
911
|
+
if (dbConfig.lastError) {
|
|
912
|
+
printError(` Last Error: ${dbConfig.lastError}`);
|
|
913
|
+
}
|
|
914
|
+
console.log();
|
|
915
|
+
}
|
|
916
|
+
catch (err) {
|
|
917
|
+
printError(err instanceof Error ? err.message : 'Failed to load project state');
|
|
918
|
+
}
|
|
919
|
+
break;
|
|
920
|
+
}
|
|
921
|
+
case 'configure': {
|
|
922
|
+
printInfo('Use "popeye db configure" from the CLI for interactive configuration.');
|
|
923
|
+
printInfo('Or set DATABASE_URL in apps/backend/.env manually.');
|
|
924
|
+
break;
|
|
925
|
+
}
|
|
926
|
+
case 'apply': {
|
|
927
|
+
printInfo('Use "popeye db apply" from the CLI to run the setup pipeline.');
|
|
928
|
+
break;
|
|
929
|
+
}
|
|
930
|
+
default:
|
|
931
|
+
printError(`Unknown db action: ${action}`);
|
|
932
|
+
printInfo('Usage: /db [status|configure|apply]');
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
/**
|
|
936
|
+
* Handle /doctor slash command - readiness checks
|
|
937
|
+
*/
|
|
938
|
+
async function handleDoctorSlashCommand(state) {
|
|
939
|
+
if (!state.projectDir) {
|
|
940
|
+
printError('No active project. Create or resume a project first.');
|
|
941
|
+
return;
|
|
942
|
+
}
|
|
943
|
+
try {
|
|
944
|
+
const { runDoctorChecks } = await import('./commands/doctor.js');
|
|
945
|
+
console.log();
|
|
946
|
+
printInfo('Running readiness checks...');
|
|
947
|
+
console.log();
|
|
948
|
+
const result = await runDoctorChecks(state.projectDir);
|
|
949
|
+
for (const check of result.checks) {
|
|
950
|
+
const label = check.passed ? '[PASS]' : check.severity === 'info' ? '[SKIP]' : '[FAIL]';
|
|
951
|
+
if (check.passed) {
|
|
952
|
+
printSuccess(` ${label} ${check.name}: ${check.message}`);
|
|
953
|
+
}
|
|
954
|
+
else if (check.severity === 'info') {
|
|
955
|
+
printInfo(` ${label} ${check.name}: ${check.message}`);
|
|
956
|
+
}
|
|
957
|
+
else if (check.severity === 'warning') {
|
|
958
|
+
printWarning(` ${label} ${check.name}: ${check.message}`);
|
|
959
|
+
}
|
|
960
|
+
else {
|
|
961
|
+
printError(` ${label} ${check.name}: ${check.message}`);
|
|
962
|
+
}
|
|
963
|
+
}
|
|
964
|
+
console.log();
|
|
965
|
+
if (result.healthy) {
|
|
966
|
+
printSuccess('All critical checks passed.');
|
|
967
|
+
}
|
|
968
|
+
else {
|
|
969
|
+
printWarning('Some critical checks failed. See above for details.');
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
catch (err) {
|
|
973
|
+
printError(err instanceof Error ? err.message : 'Doctor checks failed');
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
/**
|
|
977
|
+
* Handle /review or /audit slash command - post-build project audit
|
|
978
|
+
*/
|
|
979
|
+
async function handleReviewSlashCommand(state, args = []) {
|
|
980
|
+
if (!state.projectDir) {
|
|
981
|
+
printError('No active project. Create or resume a project first.');
|
|
982
|
+
return;
|
|
983
|
+
}
|
|
984
|
+
// Parse CLI-style flags from args
|
|
985
|
+
const options = {};
|
|
986
|
+
for (let i = 0; i < args.length; i++) {
|
|
987
|
+
const arg = args[i];
|
|
988
|
+
if ((arg === '--depth' || arg === '-d') && args[i + 1]) {
|
|
989
|
+
options.depth = parseInt(args[++i], 10);
|
|
990
|
+
}
|
|
991
|
+
else if (arg === '--strict' || arg === '-s') {
|
|
992
|
+
options.strict = true;
|
|
993
|
+
}
|
|
994
|
+
else if ((arg === '--format' || arg === '-f') && args[i + 1]) {
|
|
995
|
+
options.format = args[++i];
|
|
996
|
+
}
|
|
997
|
+
else if (arg === '--no-recover') {
|
|
998
|
+
options.recover = false;
|
|
999
|
+
}
|
|
1000
|
+
else if (arg === '--recover') {
|
|
1001
|
+
options.recover = true;
|
|
1002
|
+
}
|
|
1003
|
+
else if ((arg === '--target' || arg === '-t') && args[i + 1]) {
|
|
1004
|
+
options.target = args[++i];
|
|
1005
|
+
}
|
|
1006
|
+
}
|
|
1007
|
+
try {
|
|
1008
|
+
const { runReview } = await import('./commands/review.js');
|
|
1009
|
+
console.log();
|
|
1010
|
+
await runReview(state.projectDir, options);
|
|
1011
|
+
}
|
|
1012
|
+
catch (err) {
|
|
1013
|
+
printError(err instanceof Error ? err.message : 'Audit failed');
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
875
1016
|
/**
|
|
876
1017
|
* Handle /overview command - full project plan and milestone review
|
|
877
1018
|
*/
|
|
@@ -1468,73 +1609,89 @@ async function handleResume(state, args) {
|
|
|
1468
1609
|
printError('Authentication required. Run /auth first.');
|
|
1469
1610
|
return;
|
|
1470
1611
|
}
|
|
1471
|
-
//
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
const displayProjects = allProjects.slice(0, 10); // Limit to 10
|
|
1482
|
-
for (let i = 0; i < displayProjects.length; i++) {
|
|
1483
|
-
const project = displayProjects[i];
|
|
1484
|
-
const info = formatProjectForDisplay(project);
|
|
1485
|
-
const statusColor = project.status === 'complete' ? theme.success :
|
|
1486
|
-
project.status === 'failed' ? theme.error :
|
|
1487
|
-
project.status === 'in-progress' ? theme.warning : theme.dim;
|
|
1488
|
-
console.log(` ${theme.primary(`${i + 1}.`)} ${theme.secondary(info.name)}`);
|
|
1489
|
-
console.log(` ${statusColor(info.status)} ${theme.dim('|')} ${info.age}`);
|
|
1490
|
-
console.log(` ${theme.dim(info.path)}`);
|
|
1491
|
-
if (project.idea) {
|
|
1492
|
-
console.log(` ${theme.dim(project.idea.slice(0, 60))}${project.idea.length > 60 ? '...' : ''}`);
|
|
1612
|
+
// Reason: If there's already an active project with pending work (e.g., from /review recovery),
|
|
1613
|
+
// skip project discovery and go straight to resuming.
|
|
1614
|
+
if (state.projectDir) {
|
|
1615
|
+
const activeStatus = await getWorkflowStatus(state.projectDir);
|
|
1616
|
+
if (activeStatus.exists && activeStatus.state) {
|
|
1617
|
+
const { phase, status: pStatus } = activeStatus.state;
|
|
1618
|
+
const hasPendingWork = phase !== 'complete' || pStatus !== 'complete';
|
|
1619
|
+
if (hasPendingWork) {
|
|
1620
|
+
printInfo(`Resuming active project: ${activeStatus.state.name}`);
|
|
1621
|
+
// Fall through to the resume logic below (skip discovery)
|
|
1493
1622
|
}
|
|
1494
|
-
console.log();
|
|
1495
1623
|
}
|
|
1496
|
-
|
|
1497
|
-
|
|
1624
|
+
}
|
|
1625
|
+
// Only discover projects if no active project with pending work
|
|
1626
|
+
if (!state.projectDir || (await getWorkflowStatus(state.projectDir)).state?.phase === 'complete') {
|
|
1627
|
+
// Discover all projects (registered + scanned in current directory)
|
|
1628
|
+
console.log();
|
|
1629
|
+
printInfo('Scanning for projects...');
|
|
1630
|
+
const { all: allProjects } = await discoverProjects(state.projectDir || process.cwd());
|
|
1631
|
+
// If projects found, let user select one
|
|
1632
|
+
if (allProjects.length > 0) {
|
|
1498
1633
|
console.log();
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
const { all: deepScan } = await discoverProjects(state.projectDir || process.cwd());
|
|
1517
|
-
if (deepScan.length === allProjects.length) {
|
|
1518
|
-
printWarning('No additional projects found');
|
|
1634
|
+
console.log(theme.primary.bold(' Found Projects:'));
|
|
1635
|
+
console.log();
|
|
1636
|
+
// Show project list with numbers
|
|
1637
|
+
const displayProjects = allProjects.slice(0, 10); // Limit to 10
|
|
1638
|
+
for (let i = 0; i < displayProjects.length; i++) {
|
|
1639
|
+
const project = displayProjects[i];
|
|
1640
|
+
const info = formatProjectForDisplay(project);
|
|
1641
|
+
const statusColor = project.status === 'complete' ? theme.success :
|
|
1642
|
+
project.status === 'failed' ? theme.error :
|
|
1643
|
+
project.status === 'in-progress' ? theme.warning : theme.dim;
|
|
1644
|
+
console.log(` ${theme.primary(`${i + 1}.`)} ${theme.secondary(info.name)}`);
|
|
1645
|
+
console.log(` ${statusColor(info.status)} ${theme.dim('|')} ${info.age}`);
|
|
1646
|
+
console.log(` ${theme.dim(info.path)}`);
|
|
1647
|
+
if (project.idea) {
|
|
1648
|
+
console.log(` ${theme.dim(project.idea.slice(0, 60))}${project.idea.length > 60 ? '...' : ''}`);
|
|
1649
|
+
}
|
|
1650
|
+
console.log();
|
|
1519
1651
|
}
|
|
1520
|
-
|
|
1521
|
-
|
|
1652
|
+
if (allProjects.length > 10) {
|
|
1653
|
+
console.log(theme.dim(` ... and ${allProjects.length - 10} more projects`));
|
|
1654
|
+
console.log();
|
|
1522
1655
|
}
|
|
1523
|
-
//
|
|
1524
|
-
await
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1656
|
+
// Let user select
|
|
1657
|
+
const selection = await promptSelection('Select a project to resume:', [
|
|
1658
|
+
...displayProjects.map((p, i) => ({
|
|
1659
|
+
value: String(i),
|
|
1660
|
+
label: `${p.name} (${formatProjectForDisplay(p).age})`,
|
|
1661
|
+
})),
|
|
1662
|
+
{ value: 'scan', label: 'Scan for more projects...' },
|
|
1663
|
+
{ value: 'cancel', label: 'Cancel' },
|
|
1664
|
+
], '0');
|
|
1665
|
+
if (selection === 'cancel') {
|
|
1666
|
+
printInfo('Cancelled');
|
|
1667
|
+
return;
|
|
1668
|
+
}
|
|
1669
|
+
if (selection === 'scan') {
|
|
1670
|
+
// Scan deeper in current directory
|
|
1671
|
+
printInfo('Scanning subdirectories...');
|
|
1672
|
+
const { all: deepScan } = await discoverProjects(state.projectDir || process.cwd());
|
|
1673
|
+
if (deepScan.length === allProjects.length) {
|
|
1674
|
+
printWarning('No additional projects found');
|
|
1675
|
+
}
|
|
1676
|
+
else {
|
|
1677
|
+
printSuccess(`Found ${deepScan.length - allProjects.length} additional projects`);
|
|
1678
|
+
}
|
|
1679
|
+
// Recursively call handleResume to show updated list
|
|
1680
|
+
await handleResume(state, args);
|
|
1681
|
+
return;
|
|
1682
|
+
}
|
|
1683
|
+
const selectedIndex = parseInt(selection, 10);
|
|
1684
|
+
const selectedProject = displayProjects[selectedIndex];
|
|
1685
|
+
if (!selectedProject) {
|
|
1686
|
+
printError('Invalid selection');
|
|
1687
|
+
return;
|
|
1688
|
+
}
|
|
1689
|
+
// Set the project directory and continue
|
|
1690
|
+
state.projectDir = selectedProject.path;
|
|
1691
|
+
console.log();
|
|
1692
|
+
printInfo(`Selected: ${selectedProject.name}`);
|
|
1532
1693
|
}
|
|
1533
|
-
|
|
1534
|
-
state.projectDir = selectedProject.path;
|
|
1535
|
-
console.log();
|
|
1536
|
-
printInfo(`Selected: ${selectedProject.name}`);
|
|
1537
|
-
}
|
|
1694
|
+
} // end: project discovery block
|
|
1538
1695
|
// Now check for formal project state at the selected/current directory
|
|
1539
1696
|
if (!state.projectDir) {
|
|
1540
1697
|
printError('No project directory set');
|