popeye-cli 1.8.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.
Files changed (68) hide show
  1. package/README.md +47 -3
  2. package/cheatsheet.md +33 -0
  3. package/dist/cli/commands/index.d.ts +1 -0
  4. package/dist/cli/commands/index.d.ts.map +1 -1
  5. package/dist/cli/commands/index.js +1 -0
  6. package/dist/cli/commands/index.js.map +1 -1
  7. package/dist/cli/commands/review.d.ts +31 -0
  8. package/dist/cli/commands/review.d.ts.map +1 -0
  9. package/dist/cli/commands/review.js +156 -0
  10. package/dist/cli/commands/review.js.map +1 -0
  11. package/dist/cli/index.d.ts.map +1 -1
  12. package/dist/cli/index.js +2 -1
  13. package/dist/cli/index.js.map +1 -1
  14. package/dist/cli/interactive.d.ts.map +1 -1
  15. package/dist/cli/interactive.js +122 -61
  16. package/dist/cli/interactive.js.map +1 -1
  17. package/dist/types/audit.d.ts +623 -0
  18. package/dist/types/audit.d.ts.map +1 -0
  19. package/dist/types/audit.js +240 -0
  20. package/dist/types/audit.js.map +1 -0
  21. package/dist/types/workflow.d.ts +15 -0
  22. package/dist/types/workflow.d.ts.map +1 -1
  23. package/dist/types/workflow.js +5 -0
  24. package/dist/types/workflow.js.map +1 -1
  25. package/dist/workflow/audit-analyzer.d.ts +58 -0
  26. package/dist/workflow/audit-analyzer.d.ts.map +1 -0
  27. package/dist/workflow/audit-analyzer.js +420 -0
  28. package/dist/workflow/audit-analyzer.js.map +1 -0
  29. package/dist/workflow/audit-mode.d.ts +28 -0
  30. package/dist/workflow/audit-mode.d.ts.map +1 -0
  31. package/dist/workflow/audit-mode.js +169 -0
  32. package/dist/workflow/audit-mode.js.map +1 -0
  33. package/dist/workflow/audit-recovery.d.ts +61 -0
  34. package/dist/workflow/audit-recovery.d.ts.map +1 -0
  35. package/dist/workflow/audit-recovery.js +242 -0
  36. package/dist/workflow/audit-recovery.js.map +1 -0
  37. package/dist/workflow/audit-reporter.d.ts +65 -0
  38. package/dist/workflow/audit-reporter.d.ts.map +1 -0
  39. package/dist/workflow/audit-reporter.js +301 -0
  40. package/dist/workflow/audit-reporter.js.map +1 -0
  41. package/dist/workflow/audit-scanner.d.ts +87 -0
  42. package/dist/workflow/audit-scanner.d.ts.map +1 -0
  43. package/dist/workflow/audit-scanner.js +768 -0
  44. package/dist/workflow/audit-scanner.js.map +1 -0
  45. package/dist/workflow/index.d.ts +5 -0
  46. package/dist/workflow/index.d.ts.map +1 -1
  47. package/dist/workflow/index.js +5 -0
  48. package/dist/workflow/index.js.map +1 -1
  49. package/package.json +1 -1
  50. package/src/cli/commands/index.ts +1 -0
  51. package/src/cli/commands/review.ts +187 -0
  52. package/src/cli/index.ts +2 -0
  53. package/src/cli/interactive.ts +72 -4
  54. package/src/types/audit.ts +294 -0
  55. package/src/types/workflow.ts +15 -0
  56. package/src/workflow/audit-analyzer.ts +491 -0
  57. package/src/workflow/audit-mode.ts +240 -0
  58. package/src/workflow/audit-recovery.ts +284 -0
  59. package/src/workflow/audit-reporter.ts +370 -0
  60. package/src/workflow/audit-scanner.ts +873 -0
  61. package/src/workflow/index.ts +5 -0
  62. package/tests/cli/commands/review.test.ts +52 -0
  63. package/tests/types/audit.test.ts +250 -0
  64. package/tests/workflow/audit-analyzer.test.ts +281 -0
  65. package/tests/workflow/audit-mode.test.ts +114 -0
  66. package/tests/workflow/audit-recovery.test.ts +237 -0
  67. package/tests/workflow/audit-reporter.test.ts +254 -0
  68. package/tests/workflow/audit-scanner.test.ts +270 -0
package/README.md CHANGED
@@ -26,7 +26,8 @@ Popeye is an autonomous software development agent that takes a simple project i
26
26
  9. **Scans** generated website files for placeholder fingerprints (TODO comments, lorem ipsum, default tiers) and reports quality warnings
27
27
  10. **Styles** the application with a professional design system and component library
28
28
  11. **Tests** the implementation and fixes issues automatically with Tester-driven fix plans
29
- 12. **Delivers** a complete, working project with polished UI
29
+ 12. **Reviews** the completed project with a post-build audit that scores code quality, detects wiring issues, and generates recovery tasks
30
+ 13. **Delivers** a complete, working project with polished UI
30
31
 
31
32
  ## How It Works
32
33
 
@@ -435,6 +436,7 @@ Popeye provides real-time feedback:
435
436
  - How to run (development, tests, production)
436
437
  - Project structure overview
437
438
  - **Project Type Upgrade**: Upgrade projects in-place (e.g., python to fullstack, fullstack to all) with automatic file restructuring, scaffolding, and planning integration
439
+ - **Post-Build Audit/Review**: Run `popeye review` to scan your completed project, score it across 8 categories, detect FE-BE wiring issues, and auto-generate recovery milestones for critical findings
438
440
  - **Flexible Model Switching**: Use any AI model name for OpenAI, Gemini, or Grok providers -- not limited to a predefined list
439
441
 
440
442
  ### Automatic UI/UX Design
@@ -895,6 +897,40 @@ popeye config set consensus.threshold 90
895
897
  popeye config reset
896
898
  ```
897
899
 
900
+ ### `popeye review` (alias: `audit`)
901
+
902
+ Run a post-build audit/review of the project. Scans the codebase, produces a structured report with findings and scores, and optionally generates recovery milestones.
903
+
904
+ ```bash
905
+ # Standard audit
906
+ popeye review ./my-project
907
+
908
+ # Deep audit with strict mode
909
+ popeye review ./my-project --depth 3 --strict
910
+
911
+ # JSON only, no auto-recovery
912
+ popeye review ./my-project --format json --no-recover
913
+
914
+ # Audit only the frontend component
915
+ popeye review ./my-project --target frontend
916
+ ```
917
+
918
+ **Options:**
919
+ | Option | Description | Default |
920
+ |--------|-------------|---------|
921
+ | `-d, --depth <level>` | Audit depth: `1`=shallow, `2`=standard, `3`=deep | `2` |
922
+ | `-s, --strict` | Enable strict mode (higher standards) | `false` |
923
+ | `-f, --format <type>` | Output format: `json`, `md`, `both` | `both` |
924
+ | `--no-recover` | Skip auto-injection of recovery milestones | Recovery on |
925
+ | `-t, --target <kind>` | Audit target: `all`, `frontend`, `backend`, `website` | `all` |
926
+
927
+ The audit runs three stages:
928
+ 1. **Scan** -- Deterministic filesystem scan (files, LOC, dependencies, FE-BE wiring matrix)
929
+ 2. **Analyze** -- AI-powered analysis producing scored findings across 8 categories
930
+ 3. **Recovery** -- Evidence-based recovery plan generation when critical/major findings exist
931
+
932
+ Reports are written to `.popeye/popeye.audit.md`, `.popeye/popeye.audit.json`, and optionally `.popeye/popeye.recovery.md`/`.json`. Recovery milestones are injected into the project state and can be executed with `popeye resume`.
933
+
898
934
  ### Interactive Mode
899
935
 
900
936
  Launch an interactive REPL session:
@@ -922,6 +958,7 @@ popeye
922
958
  /overview [fix] Project review with analysis; fix to auto-discover docs
923
959
  /db [action] Database management (status/configure/apply)
924
960
  /doctor Run database and project readiness checks
961
+ /review Run post-build audit with findings and recovery
925
962
  /info Show system info (Claude CLI status, API keys, etc.)
926
963
  /clear Clear screen
927
964
  /exit Exit interactive mode
@@ -1522,7 +1559,8 @@ src/
1522
1559
  │ ├── interactive.ts # REPL mode (with /model, /upgrade, /overview, /db, /doctor commands)
1523
1560
  │ └── commands/ # Individual commands
1524
1561
  │ ├── db.ts # Database management CLI (status/configure/apply)
1525
- └── doctor.ts # Readiness checks (8 checks for DB and project health)
1562
+ ├── doctor.ts # Readiness checks (8 checks for DB and project health)
1563
+ │ └── review.ts # Post-build audit/review CLI command
1526
1564
  ├── adapters/ # AI service adapters
1527
1565
  │ ├── claude.ts # Claude Agent SDK (with rate limiting)
1528
1566
  │ ├── openai.ts # OpenAI API (default reviewer, marketing persona for websites)
@@ -1590,12 +1628,18 @@ src/
1590
1628
  │ ├── project-verification.ts # Project quality checks
1591
1629
  │ ├── project-structure.ts # Project directory scanner
1592
1630
  │ ├── remediation.ts # Consensus-driven failure recovery
1593
- └── auto-fix.ts # Automatic error fixing (enhanced ENOENT tracking)
1631
+ ├── auto-fix.ts # Automatic error fixing (enhanced ENOENT tracking)
1632
+ │ ├── audit-scanner.ts # Deterministic project scanning (components, wiring, docs)
1633
+ │ ├── audit-analyzer.ts # AI-powered analysis with Serena-first search
1634
+ │ ├── audit-reporter.ts # Markdown + JSON report generation
1635
+ │ ├── audit-recovery.ts # Evidence-based recovery plan generation
1636
+ │ └── audit-mode.ts # Audit orchestrator (scan -> analyze -> recover)
1594
1637
  └── types/ # TypeScript types
1595
1638
  ├── project.ts # OutputLanguage, isWorkspace(), flexible OpenAIModelSchema
1596
1639
  ├── workflow.ts # ProjectStateSchema (qaEnabled, dbConfig, qa* task fields)
1597
1640
  ├── consensus.ts # GeminiModelSchema, GrokModelSchema, reviewerPersona, testPlanThreshold
1598
1641
  ├── tester.ts # TestVerdict, TestPlanOutput, TestRunReview, TestFixPlan
1642
+ ├── audit.ts # Audit system schemas (findings, recovery, wiring, scores)
1599
1643
  ├── database.ts # DbStatus, DbMode, DbConfig, DbSetupStep Zod schemas
1600
1644
  ├── database-runtime.ts # SetupStepResult, ReadinessCheck runtime schemas
1601
1645
  └── website-strategy.ts # WebsiteStrategyDocument, BrandAssetsContract, DesignTokens
package/cheatsheet.md CHANGED
@@ -203,6 +203,34 @@ popeye-cli doctor ./my-project
203
203
 
204
204
  ---
205
205
 
206
+ ### `popeye-cli review [directory]` (alias: `audit`)
207
+
208
+ Run a post-build audit/review of the project. Scans the codebase, produces a structured report with findings, and optionally generates recovery milestones.
209
+
210
+ | Option | Description | Default |
211
+ |--------|-------------|---------|
212
+ | `-d, --depth <level>` | Audit depth: `1`=shallow, `2`=standard, `3`=deep | `2` |
213
+ | `-s, --strict` | Enable strict mode (higher standards, stricter recovery triggers) | `false` |
214
+ | `-f, --format <type>` | Output format: `json`, `md`, `both` | `both` |
215
+ | `--no-recover` | Skip auto-injection of recovery milestones | Recovery enabled by default |
216
+ | `-t, --target <kind>` | Audit target: `all`, `frontend`, `backend`, `website` | `all` |
217
+
218
+ The audit runs three stages:
219
+ 1. **Scan** -- Deterministic filesystem scan (files, LOC, deps, wiring matrix)
220
+ 2. **Analyze** -- AI-powered analysis producing scored findings
221
+ 3. **Recovery** -- Evidence-based recovery plan generation (if critical/major findings exist)
222
+
223
+ Reports are written to `.popeye/popeye.audit.md`, `.popeye/popeye.audit.json`, and optionally `.popeye/popeye.recovery.md`/`.json`.
224
+
225
+ ```bash
226
+ popeye-cli review ./my-project
227
+ popeye-cli review ./my-project --depth 3 --strict
228
+ popeye-cli review ./my-project --format json --no-recover
229
+ popeye-cli audit ./my-project --target frontend
230
+ ```
231
+
232
+ ---
233
+
206
234
  ## Interactive Mode Slash Commands
207
235
 
208
236
  Enter these commands during an interactive session (started via `popeye-cli interactive`).
@@ -287,6 +315,7 @@ Available upgrade paths depend on the current project type:
287
315
  | `/db configure` | Configure database (redirects to CLI) |
288
316
  | `/db apply` | Apply database setup (redirects to CLI) |
289
317
  | `/doctor` | Run all readiness checks inline |
318
+ | `/review`, `/audit` | Run a post-build audit with findings and optional recovery |
290
319
 
291
320
  ### Session Control
292
321
 
@@ -402,6 +431,10 @@ popeye-cli db apply ./taskmaster
402
431
  # Resume after interruption
403
432
  popeye-cli resume ./taskmaster
404
433
 
434
+ # Audit the project after build
435
+ popeye-cli review ./taskmaster
436
+ popeye-cli review ./taskmaster --depth 3 --strict
437
+
405
438
  # Reset and re-plan
406
439
  popeye-cli reset ./taskmaster --phase plan
407
440
  ```
@@ -9,4 +9,5 @@ export { createResumeCommand, createResetCommand, createCancelCommand } from './
9
9
  export { createConfigCommand } from './config.js';
10
10
  export { createDbCommand } from './db.js';
11
11
  export { createDoctorCommand } from './doctor.js';
12
+ export { createReviewCommand } from './review.js';
12
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
@@ -9,4 +9,5 @@ export { createResumeCommand, createResetCommand, createCancelCommand } from './
9
9
  export { createConfigCommand } from './config.js';
10
10
  export { createDbCommand } from './db.js';
11
11
  export { createDoctorCommand } from './doctor.js';
12
+ export { createReviewCommand } from './review.js';
12
13
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAC/F,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,31 @@
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 type { AuditModeResult } from '../../types/audit.js';
11
+ /**
12
+ * Execute the audit and print results to the console.
13
+ *
14
+ * @param projectDir - Absolute path to the project directory.
15
+ * @param options - CLI options.
16
+ * @returns The audit result.
17
+ */
18
+ export declare function runReview(projectDir: string, options?: {
19
+ depth?: number;
20
+ strict?: boolean;
21
+ format?: 'json' | 'md' | 'both';
22
+ recover?: boolean;
23
+ target?: string;
24
+ }): Promise<AuditModeResult>;
25
+ /**
26
+ * Create the `popeye review` CLI command.
27
+ *
28
+ * @returns Commander command instance.
29
+ */
30
+ export declare function createReviewCommand(): Command;
31
+ //# sourceMappingURL=review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/review.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAYpC,OAAO,KAAK,EAAE,eAAe,EAAiB,MAAM,sBAAsB,CAAC;AAM3E;;;;;;GAMG;AACH,wBAAsB,SAAS,CAC7B,UAAU,EAAE,MAAM,EAClB,OAAO,GAAE;IACP,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,GACL,OAAO,CAAC,eAAe,CAAC,CAoG1B;AAMD;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,OAAO,CAgC7C"}
@@ -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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"}
@@ -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;AAmBpC,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,CAyCvC;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CASzE"}
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, createDbCommand, createDoctorCommand, } 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
@@ -40,6 +40,7 @@ export function createProgram() {
40
40
  program.addCommand(createConfigCommand());
41
41
  program.addCommand(createDbCommand());
42
42
  program.addCommand(createDoctorCommand());
43
+ program.addCommand(createReviewCommand());
43
44
  // Interactive mode command
44
45
  program
45
46
  .command('interactive')
@@ -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;AAo0EH;;;;;;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"}
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"}
@@ -699,6 +699,7 @@ function showHelp() {
699
699
  ['/overview [fix]', 'Project review with analysis; fix to auto-discover docs'],
700
700
  ['/db [action]', 'Database management (status/configure/apply)'],
701
701
  ['/doctor', 'Run database and project readiness checks'],
702
+ ['/review', 'Run post-build audit/review with findings and recovery'],
702
703
  ['/clear', 'Clear screen'],
703
704
  ['/exit', 'Exit Popeye'],
704
705
  ];
@@ -846,6 +847,10 @@ async function handleInput(input, state) {
846
847
  case '/doctor':
847
848
  await handleDoctorSlashCommand(state);
848
849
  break;
850
+ case '/review':
851
+ case '/audit':
852
+ await handleReviewSlashCommand(state, args);
853
+ break;
849
854
  default:
850
855
  printError(`Unknown command: ${cmd}`);
851
856
  printInfo('Type /help for available commands');
@@ -968,6 +973,46 @@ async function handleDoctorSlashCommand(state) {
968
973
  printError(err instanceof Error ? err.message : 'Doctor checks failed');
969
974
  }
970
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
+ }
971
1016
  /**
972
1017
  * Handle /overview command - full project plan and milestone review
973
1018
  */
@@ -1564,73 +1609,89 @@ async function handleResume(state, args) {
1564
1609
  printError('Authentication required. Run /auth first.');
1565
1610
  return;
1566
1611
  }
1567
- // Discover all projects (registered + scanned in current directory)
1568
- console.log();
1569
- printInfo('Scanning for projects...');
1570
- const { all: allProjects } = await discoverProjects(state.projectDir || process.cwd());
1571
- // If projects found, let user select one
1572
- if (allProjects.length > 0) {
1573
- console.log();
1574
- console.log(theme.primary.bold(' Found Projects:'));
1575
- console.log();
1576
- // Show project list with numbers
1577
- const displayProjects = allProjects.slice(0, 10); // Limit to 10
1578
- for (let i = 0; i < displayProjects.length; i++) {
1579
- const project = displayProjects[i];
1580
- const info = formatProjectForDisplay(project);
1581
- const statusColor = project.status === 'complete' ? theme.success :
1582
- project.status === 'failed' ? theme.error :
1583
- project.status === 'in-progress' ? theme.warning : theme.dim;
1584
- console.log(` ${theme.primary(`${i + 1}.`)} ${theme.secondary(info.name)}`);
1585
- console.log(` ${statusColor(info.status)} ${theme.dim('|')} ${info.age}`);
1586
- console.log(` ${theme.dim(info.path)}`);
1587
- if (project.idea) {
1588
- 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)
1589
1622
  }
1590
- console.log();
1591
1623
  }
1592
- if (allProjects.length > 10) {
1593
- console.log(theme.dim(` ... and ${allProjects.length - 10} more projects`));
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) {
1594
1633
  console.log();
1595
- }
1596
- // Let user select
1597
- const selection = await promptSelection('Select a project to resume:', [
1598
- ...displayProjects.map((p, i) => ({
1599
- value: String(i),
1600
- label: `${p.name} (${formatProjectForDisplay(p).age})`,
1601
- })),
1602
- { value: 'scan', label: 'Scan for more projects...' },
1603
- { value: 'cancel', label: 'Cancel' },
1604
- ], '0');
1605
- if (selection === 'cancel') {
1606
- printInfo('Cancelled');
1607
- return;
1608
- }
1609
- if (selection === 'scan') {
1610
- // Scan deeper in current directory
1611
- printInfo('Scanning subdirectories...');
1612
- const { all: deepScan } = await discoverProjects(state.projectDir || process.cwd());
1613
- if (deepScan.length === allProjects.length) {
1614
- 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();
1615
1651
  }
1616
- else {
1617
- printSuccess(`Found ${deepScan.length - allProjects.length} additional projects`);
1652
+ if (allProjects.length > 10) {
1653
+ console.log(theme.dim(` ... and ${allProjects.length - 10} more projects`));
1654
+ console.log();
1618
1655
  }
1619
- // Recursively call handleResume to show updated list
1620
- await handleResume(state, args);
1621
- return;
1622
- }
1623
- const selectedIndex = parseInt(selection, 10);
1624
- const selectedProject = displayProjects[selectedIndex];
1625
- if (!selectedProject) {
1626
- printError('Invalid selection');
1627
- return;
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}`);
1628
1693
  }
1629
- // Set the project directory and continue
1630
- state.projectDir = selectedProject.path;
1631
- console.log();
1632
- printInfo(`Selected: ${selectedProject.name}`);
1633
- }
1694
+ } // end: project discovery block
1634
1695
  // Now check for formal project state at the selected/current directory
1635
1696
  if (!state.projectDir) {
1636
1697
  printError('No project directory set');