popeye-cli 1.9.5 → 2.0.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 +59 -0
- package/CONTRIBUTING.md +15 -1
- package/README.md +57 -0
- package/cheatsheet.md +65 -0
- package/dist/cli/commands/debug-context.d.ts +64 -0
- package/dist/cli/commands/debug-context.d.ts.map +1 -0
- package/dist/cli/commands/debug-context.js +221 -0
- package/dist/cli/commands/debug-context.js.map +1 -0
- package/dist/cli/commands/debug-prompts.d.ts +25 -0
- package/dist/cli/commands/debug-prompts.d.ts.map +1 -0
- package/dist/cli/commands/debug-prompts.js +80 -0
- package/dist/cli/commands/debug-prompts.js.map +1 -0
- package/dist/cli/commands/debug.d.ts +68 -0
- package/dist/cli/commands/debug.d.ts.map +1 -0
- package/dist/cli/commands/debug.js +543 -0
- package/dist/cli/commands/debug.js.map +1 -0
- package/dist/cli/commands/index.d.ts +1 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +1 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +2 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/interactive.d.ts.map +1 -1
- package/dist/cli/interactive.js +25 -0
- package/dist/cli/interactive.js.map +1 -1
- package/dist/generators/all.d.ts.map +1 -1
- package/dist/generators/all.js +2 -0
- package/dist/generators/all.js.map +1 -1
- package/dist/generators/templates/database-docker.d.ts.map +1 -1
- package/dist/generators/templates/database-docker.js +10 -0
- package/dist/generators/templates/database-docker.js.map +1 -1
- package/dist/generators/templates/fullstack.d.ts +4 -1
- package/dist/generators/templates/fullstack.d.ts.map +1 -1
- package/dist/generators/templates/fullstack.js +6 -2
- package/dist/generators/templates/fullstack.js.map +1 -1
- package/dist/pipeline/artifact-manager.d.ts +47 -0
- package/dist/pipeline/artifact-manager.d.ts.map +1 -0
- package/dist/pipeline/artifact-manager.js +251 -0
- package/dist/pipeline/artifact-manager.js.map +1 -0
- package/dist/pipeline/artifact-validators.d.ts +29 -0
- package/dist/pipeline/artifact-validators.d.ts.map +1 -0
- package/dist/pipeline/artifact-validators.js +173 -0
- package/dist/pipeline/artifact-validators.js.map +1 -0
- package/dist/pipeline/change-request.d.ts +47 -0
- package/dist/pipeline/change-request.d.ts.map +1 -0
- package/dist/pipeline/change-request.js +91 -0
- package/dist/pipeline/change-request.js.map +1 -0
- package/dist/pipeline/check-runner.d.ts +47 -0
- package/dist/pipeline/check-runner.d.ts.map +1 -0
- package/dist/pipeline/check-runner.js +417 -0
- package/dist/pipeline/check-runner.js.map +1 -0
- package/dist/pipeline/command-resolver.d.ts +9 -0
- package/dist/pipeline/command-resolver.d.ts.map +1 -0
- package/dist/pipeline/command-resolver.js +140 -0
- package/dist/pipeline/command-resolver.js.map +1 -0
- package/dist/pipeline/consensus/consensus-runner.d.ts +44 -0
- package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -0
- package/dist/pipeline/consensus/consensus-runner.js +212 -0
- package/dist/pipeline/consensus/consensus-runner.js.map +1 -0
- package/dist/pipeline/constitution.d.ts +45 -0
- package/dist/pipeline/constitution.d.ts.map +1 -0
- package/dist/pipeline/constitution.js +82 -0
- package/dist/pipeline/constitution.js.map +1 -0
- package/dist/pipeline/gate-engine.d.ts +55 -0
- package/dist/pipeline/gate-engine.d.ts.map +1 -0
- package/dist/pipeline/gate-engine.js +270 -0
- package/dist/pipeline/gate-engine.js.map +1 -0
- package/dist/pipeline/index.d.ts +26 -0
- package/dist/pipeline/index.d.ts.map +1 -0
- package/dist/pipeline/index.js +35 -0
- package/dist/pipeline/index.js.map +1 -0
- package/dist/pipeline/migration.d.ts +15 -0
- package/dist/pipeline/migration.d.ts.map +1 -0
- package/dist/pipeline/migration.js +76 -0
- package/dist/pipeline/migration.js.map +1 -0
- package/dist/pipeline/orchestrator.d.ts +28 -0
- package/dist/pipeline/orchestrator.d.ts.map +1 -0
- package/dist/pipeline/orchestrator.js +238 -0
- package/dist/pipeline/orchestrator.js.map +1 -0
- package/dist/pipeline/packets/audit-report-builder.d.ts +11 -0
- package/dist/pipeline/packets/audit-report-builder.d.ts.map +1 -0
- package/dist/pipeline/packets/audit-report-builder.js +32 -0
- package/dist/pipeline/packets/audit-report-builder.js.map +1 -0
- package/dist/pipeline/packets/consensus-packet-builder.d.ts +35 -0
- package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -0
- package/dist/pipeline/packets/consensus-packet-builder.js +80 -0
- package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -0
- package/dist/pipeline/packets/index.d.ts +12 -0
- package/dist/pipeline/packets/index.d.ts.map +1 -0
- package/dist/pipeline/packets/index.js +8 -0
- package/dist/pipeline/packets/index.js.map +1 -0
- package/dist/pipeline/packets/plan-packet-builder.d.ts +21 -0
- package/dist/pipeline/packets/plan-packet-builder.d.ts.map +1 -0
- package/dist/pipeline/packets/plan-packet-builder.js +27 -0
- package/dist/pipeline/packets/plan-packet-builder.js.map +1 -0
- package/dist/pipeline/packets/rca-packet-builder.d.ts +19 -0
- package/dist/pipeline/packets/rca-packet-builder.d.ts.map +1 -0
- package/dist/pipeline/packets/rca-packet-builder.js +22 -0
- package/dist/pipeline/packets/rca-packet-builder.js.map +1 -0
- package/dist/pipeline/phases/architecture.d.ts +7 -0
- package/dist/pipeline/phases/architecture.d.ts.map +1 -0
- package/dist/pipeline/phases/architecture.js +60 -0
- package/dist/pipeline/phases/architecture.js.map +1 -0
- package/dist/pipeline/phases/audit.d.ts +8 -0
- package/dist/pipeline/phases/audit.d.ts.map +1 -0
- package/dist/pipeline/phases/audit.js +144 -0
- package/dist/pipeline/phases/audit.js.map +1 -0
- package/dist/pipeline/phases/consensus-architecture.d.ts +7 -0
- package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -0
- package/dist/pipeline/phases/consensus-architecture.js +84 -0
- package/dist/pipeline/phases/consensus-architecture.js.map +1 -0
- package/dist/pipeline/phases/consensus-master-plan.d.ts +7 -0
- package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -0
- package/dist/pipeline/phases/consensus-master-plan.js +81 -0
- package/dist/pipeline/phases/consensus-master-plan.js.map +1 -0
- package/dist/pipeline/phases/consensus-role-plans.d.ts +7 -0
- package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -0
- package/dist/pipeline/phases/consensus-role-plans.js +85 -0
- package/dist/pipeline/phases/consensus-role-plans.js.map +1 -0
- package/dist/pipeline/phases/done.d.ts +7 -0
- package/dist/pipeline/phases/done.d.ts.map +1 -0
- package/dist/pipeline/phases/done.js +45 -0
- package/dist/pipeline/phases/done.js.map +1 -0
- package/dist/pipeline/phases/implementation.d.ts +8 -0
- package/dist/pipeline/phases/implementation.d.ts.map +1 -0
- package/dist/pipeline/phases/implementation.js +42 -0
- package/dist/pipeline/phases/implementation.js.map +1 -0
- package/dist/pipeline/phases/index.d.ts +20 -0
- package/dist/pipeline/phases/index.d.ts.map +1 -0
- package/dist/pipeline/phases/index.js +19 -0
- package/dist/pipeline/phases/index.js.map +1 -0
- package/dist/pipeline/phases/intake.d.ts +8 -0
- package/dist/pipeline/phases/intake.d.ts.map +1 -0
- package/dist/pipeline/phases/intake.js +40 -0
- package/dist/pipeline/phases/intake.js.map +1 -0
- package/dist/pipeline/phases/phase-context.d.ts +30 -0
- package/dist/pipeline/phases/phase-context.d.ts.map +1 -0
- package/dist/pipeline/phases/phase-context.js +33 -0
- package/dist/pipeline/phases/phase-context.js.map +1 -0
- package/dist/pipeline/phases/production-gate.d.ts +8 -0
- package/dist/pipeline/phases/production-gate.d.ts.map +1 -0
- package/dist/pipeline/phases/production-gate.js +84 -0
- package/dist/pipeline/phases/production-gate.js.map +1 -0
- package/dist/pipeline/phases/qa-validation.d.ts +7 -0
- package/dist/pipeline/phases/qa-validation.d.ts.map +1 -0
- package/dist/pipeline/phases/qa-validation.js +50 -0
- package/dist/pipeline/phases/qa-validation.js.map +1 -0
- package/dist/pipeline/phases/recovery-loop.d.ts +7 -0
- package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -0
- package/dist/pipeline/phases/recovery-loop.js +91 -0
- package/dist/pipeline/phases/recovery-loop.js.map +1 -0
- package/dist/pipeline/phases/review.d.ts +8 -0
- package/dist/pipeline/phases/review.d.ts.map +1 -0
- package/dist/pipeline/phases/review.js +127 -0
- package/dist/pipeline/phases/review.js.map +1 -0
- package/dist/pipeline/phases/role-planning.d.ts +7 -0
- package/dist/pipeline/phases/role-planning.d.ts.map +1 -0
- package/dist/pipeline/phases/role-planning.js +75 -0
- package/dist/pipeline/phases/role-planning.js.map +1 -0
- package/dist/pipeline/phases/stuck.d.ts +7 -0
- package/dist/pipeline/phases/stuck.d.ts.map +1 -0
- package/dist/pipeline/phases/stuck.js +51 -0
- package/dist/pipeline/phases/stuck.js.map +1 -0
- package/dist/pipeline/repo-snapshot.d.ts +24 -0
- package/dist/pipeline/repo-snapshot.d.ts.map +1 -0
- package/dist/pipeline/repo-snapshot.js +343 -0
- package/dist/pipeline/repo-snapshot.js.map +1 -0
- package/dist/pipeline/role-execution-adapter.d.ts +59 -0
- package/dist/pipeline/role-execution-adapter.d.ts.map +1 -0
- package/dist/pipeline/role-execution-adapter.js +159 -0
- package/dist/pipeline/role-execution-adapter.js.map +1 -0
- package/dist/pipeline/skill-loader.d.ts +34 -0
- package/dist/pipeline/skill-loader.d.ts.map +1 -0
- package/dist/pipeline/skill-loader.js +156 -0
- package/dist/pipeline/skill-loader.js.map +1 -0
- package/dist/pipeline/skills/defaults.d.ts +16 -0
- package/dist/pipeline/skills/defaults.d.ts.map +1 -0
- package/dist/pipeline/skills/defaults.js +189 -0
- package/dist/pipeline/skills/defaults.js.map +1 -0
- package/dist/pipeline/type-defs/artifacts.d.ts +202 -0
- package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -0
- package/dist/pipeline/type-defs/artifacts.js +66 -0
- package/dist/pipeline/type-defs/artifacts.js.map +1 -0
- package/dist/pipeline/type-defs/audit.d.ts +256 -0
- package/dist/pipeline/type-defs/audit.d.ts.map +1 -0
- package/dist/pipeline/type-defs/audit.js +54 -0
- package/dist/pipeline/type-defs/audit.js.map +1 -0
- package/dist/pipeline/type-defs/checks.d.ts +81 -0
- package/dist/pipeline/type-defs/checks.d.ts.map +1 -0
- package/dist/pipeline/type-defs/checks.js +38 -0
- package/dist/pipeline/type-defs/checks.js.map +1 -0
- package/dist/pipeline/type-defs/enums.d.ts +43 -0
- package/dist/pipeline/type-defs/enums.d.ts.map +1 -0
- package/dist/pipeline/type-defs/enums.js +55 -0
- package/dist/pipeline/type-defs/enums.js.map +1 -0
- package/dist/pipeline/type-defs/index.d.ts +12 -0
- package/dist/pipeline/type-defs/index.d.ts.map +1 -0
- package/dist/pipeline/type-defs/index.js +12 -0
- package/dist/pipeline/type-defs/index.js.map +1 -0
- package/dist/pipeline/type-defs/packets.d.ts +806 -0
- package/dist/pipeline/type-defs/packets.d.ts.map +1 -0
- package/dist/pipeline/type-defs/packets.js +109 -0
- package/dist/pipeline/type-defs/packets.js.map +1 -0
- package/dist/pipeline/type-defs/snapshot.d.ts +52 -0
- package/dist/pipeline/type-defs/snapshot.d.ts.map +1 -0
- package/dist/pipeline/type-defs/snapshot.js +35 -0
- package/dist/pipeline/type-defs/snapshot.js.map +1 -0
- package/dist/pipeline/type-defs/state.d.ts +449 -0
- package/dist/pipeline/type-defs/state.d.ts.map +1 -0
- package/dist/pipeline/type-defs/state.js +88 -0
- package/dist/pipeline/type-defs/state.js.map +1 -0
- package/dist/pipeline/types.d.ts +16 -0
- package/dist/pipeline/types.d.ts.map +1 -0
- package/dist/pipeline/types.js +16 -0
- package/dist/pipeline/types.js.map +1 -0
- package/dist/types/audit.d.ts +6 -6
- package/dist/workflow/index.d.ts.map +1 -1
- package/dist/workflow/index.js +48 -0
- package/dist/workflow/index.js.map +1 -1
- package/package.json +1 -1
- package/skills/ARBITRATOR.md +137 -0
- package/skills/ARCHITECT.md +167 -0
- package/skills/AUDITOR.md +128 -0
- package/skills/AUDIT_REPORT_SCHEMA.md +20 -0
- package/skills/BACKEND_PROGRAMMER.md +95 -0
- package/skills/CONSENSUS_PACKET_SCHEMA.md +166 -0
- package/skills/DB_EXPERT.md +106 -0
- package/skills/DEBUGGER.md +286 -0
- package/skills/DISPATCHER.md +157 -0
- package/skills/FRONTEND_PROGRAMMER.md +84 -0
- package/skills/JOURNALIST.md +247 -0
- package/skills/MARKETING_EXPERT.md +23 -0
- package/skills/PHASE_GATE_ENGINE_SPEC.md +171 -0
- package/skills/PLAN_PACKET_SCHEMA.md +222 -0
- package/skills/POPEYE_CONSTITUTION.md +177 -0
- package/skills/POPEYE_FULL_AUTONOMY_PIPELINE.md +537 -0
- package/skills/PRODUCTION_READINESS_SCHEMA.md +19 -0
- package/skills/QA_TESTER.md +40 -0
- package/skills/RCA_PACKET_SCHEMA.md +22 -0
- package/skills/RELEASE_MANAGER.md +60 -0
- package/skills/REVIEWER.md +133 -0
- package/skills/SOCIAL_EXPERT.md +22 -0
- package/skills/UI_UX_SPECIALIST.md +22 -0
- package/skills/WEBSITE_PROGRAMMER.md +37 -0
- package/src/cli/commands/debug-context.ts +265 -0
- package/src/cli/commands/debug-prompts.ts +91 -0
- package/src/cli/commands/debug.ts +662 -0
- package/src/cli/commands/index.ts +1 -0
- package/src/cli/index.ts +2 -0
- package/src/cli/interactive.ts +27 -0
- package/src/generators/all.ts +2 -0
- package/src/generators/templates/database-docker.ts +10 -0
- package/src/generators/templates/fullstack.ts +6 -2
- package/src/pipeline/artifact-manager.ts +339 -0
- package/src/pipeline/artifact-validators.ts +224 -0
- package/src/pipeline/change-request.ts +119 -0
- package/src/pipeline/check-runner.ts +504 -0
- package/src/pipeline/command-resolver.ts +168 -0
- package/src/pipeline/consensus/consensus-runner.ts +317 -0
- package/src/pipeline/constitution.ts +109 -0
- package/src/pipeline/gate-engine.ts +347 -0
- package/src/pipeline/index.ts +82 -0
- package/src/pipeline/migration.ts +91 -0
- package/src/pipeline/orchestrator.ts +314 -0
- package/src/pipeline/packets/audit-report-builder.ts +47 -0
- package/src/pipeline/packets/consensus-packet-builder.ts +112 -0
- package/src/pipeline/packets/index.ts +15 -0
- package/src/pipeline/packets/plan-packet-builder.ts +52 -0
- package/src/pipeline/packets/rca-packet-builder.ts +38 -0
- package/src/pipeline/phases/architecture.ts +73 -0
- package/src/pipeline/phases/audit.ts +193 -0
- package/src/pipeline/phases/consensus-architecture.ts +104 -0
- package/src/pipeline/phases/consensus-master-plan.ts +100 -0
- package/src/pipeline/phases/consensus-role-plans.ts +105 -0
- package/src/pipeline/phases/done.ts +68 -0
- package/src/pipeline/phases/implementation.ts +48 -0
- package/src/pipeline/phases/index.ts +21 -0
- package/src/pipeline/phases/intake.ts +54 -0
- package/src/pipeline/phases/phase-context.ts +86 -0
- package/src/pipeline/phases/production-gate.ts +113 -0
- package/src/pipeline/phases/qa-validation.ts +63 -0
- package/src/pipeline/phases/recovery-loop.ts +118 -0
- package/src/pipeline/phases/review.ts +149 -0
- package/src/pipeline/phases/role-planning.ts +92 -0
- package/src/pipeline/phases/stuck.ts +62 -0
- package/src/pipeline/repo-snapshot.ts +395 -0
- package/src/pipeline/role-execution-adapter.ts +238 -0
- package/src/pipeline/skill-loader.ts +192 -0
- package/src/pipeline/skills/defaults.ts +215 -0
- package/src/pipeline/type-defs/artifacts.ts +81 -0
- package/src/pipeline/type-defs/audit.ts +67 -0
- package/src/pipeline/type-defs/checks.ts +47 -0
- package/src/pipeline/type-defs/enums.ts +62 -0
- package/src/pipeline/type-defs/index.ts +12 -0
- package/src/pipeline/type-defs/packets.ts +131 -0
- package/src/pipeline/type-defs/snapshot.ts +55 -0
- package/src/pipeline/type-defs/state.ts +165 -0
- package/src/pipeline/types.ts +16 -0
- package/src/workflow/index.ts +48 -0
- package/tests/cli/commands/debug.test.ts +376 -0
- package/tests/pipeline/artifact-manager.test.ts +183 -0
- package/tests/pipeline/artifact-validators.test.ts +207 -0
- package/tests/pipeline/change-request.test.ts +180 -0
- package/tests/pipeline/check-runner.test.ts +157 -0
- package/tests/pipeline/command-resolver.test.ts +159 -0
- package/tests/pipeline/consensus-runner.test.ts +206 -0
- package/tests/pipeline/consensus-scoring.test.ts +163 -0
- package/tests/pipeline/constitution.test.ts +122 -0
- package/tests/pipeline/gate-engine.test.ts +195 -0
- package/tests/pipeline/migration.test.ts +133 -0
- package/tests/pipeline/orchestrator.test.ts +614 -0
- package/tests/pipeline/packets/builders.test.ts +347 -0
- package/tests/pipeline/repo-snapshot.test.ts +189 -0
- package/tests/pipeline/role-execution-adapter.test.ts +299 -0
- package/tests/pipeline/skill-loader.test.ts +186 -0
- package/tests/pipeline/start-env-checks.test.ts +123 -0
- package/tests/pipeline/types.test.ts +156 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# PRODUCTION READINESS SCHEMA
|
|
2
|
+
|
|
3
|
+
Required Fields:
|
|
4
|
+
|
|
5
|
+
- production_id
|
|
6
|
+
- timestamp
|
|
7
|
+
- build_status
|
|
8
|
+
- test_status
|
|
9
|
+
- lint_status
|
|
10
|
+
- migration_status
|
|
11
|
+
- audit_status
|
|
12
|
+
- security_status
|
|
13
|
+
- unresolved_blockers[]
|
|
14
|
+
- final_verdict (PASS/FAIL)
|
|
15
|
+
|
|
16
|
+
PASS allowed only if:
|
|
17
|
+
- All statuses green
|
|
18
|
+
- No unresolved blockers
|
|
19
|
+
- Audit PASS
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Skill: QA TESTER
|
|
2
|
+
Role Type: Quality Authority
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Objective
|
|
7
|
+
|
|
8
|
+
Design and enforce test coverage BEFORE and AFTER implementation.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Responsibilities
|
|
13
|
+
|
|
14
|
+
- Create test plan from Master Plan
|
|
15
|
+
- Define critical paths
|
|
16
|
+
- Define integration tests
|
|
17
|
+
- Define regression suite
|
|
18
|
+
- Validate build
|
|
19
|
+
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
## Required Outputs
|
|
23
|
+
|
|
24
|
+
- Test plan document
|
|
25
|
+
- Unit test requirements
|
|
26
|
+
- Integration test requirements
|
|
27
|
+
- Edge case list
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Anti-Shortcut Rules
|
|
32
|
+
|
|
33
|
+
- No generic "write tests"
|
|
34
|
+
- Must reference exact endpoints/components
|
|
35
|
+
- Must define expected behavior
|
|
36
|
+
|
|
37
|
+
---
|
|
38
|
+
|
|
39
|
+
Definition of Done:
|
|
40
|
+
All critical paths covered and validated.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# RCA PACKET SCHEMA
|
|
2
|
+
Purpose: Machine-verifiable root cause analysis artifact.
|
|
3
|
+
|
|
4
|
+
Required Fields:
|
|
5
|
+
|
|
6
|
+
- rca_id (UUID)
|
|
7
|
+
- timestamp
|
|
8
|
+
- incident_type
|
|
9
|
+
- severity
|
|
10
|
+
- reproduction_steps
|
|
11
|
+
- affected_files[]
|
|
12
|
+
- execution_trace
|
|
13
|
+
- root_cause_statement
|
|
14
|
+
- responsible_layer
|
|
15
|
+
- origin_phase
|
|
16
|
+
- governance_gap
|
|
17
|
+
- recommended_fix_owner
|
|
18
|
+
- requires_consensus (boolean)
|
|
19
|
+
- requires_change_request (boolean)
|
|
20
|
+
|
|
21
|
+
No vague root cause allowed.
|
|
22
|
+
Must identify structural origin.
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# Skill: RELEASE MANAGER
|
|
2
|
+
Role Type: Production Readiness Authority
|
|
3
|
+
Authority Level: Final Deployment Validator
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Objective
|
|
8
|
+
|
|
9
|
+
Ensure system is ready for deployment and produce final release artifacts.
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Responsibilities
|
|
14
|
+
|
|
15
|
+
- Validate Production Gate results
|
|
16
|
+
- Generate Release Notes
|
|
17
|
+
- Generate Deployment Instructions
|
|
18
|
+
- Verify versioning
|
|
19
|
+
- Verify changelog
|
|
20
|
+
- Tag release version (conceptually)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## Required Inputs
|
|
25
|
+
|
|
26
|
+
- Production Readiness Report
|
|
27
|
+
- Audit Report
|
|
28
|
+
- Repo Snapshot
|
|
29
|
+
- Final Plan Packet
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Output
|
|
34
|
+
|
|
35
|
+
# RELEASE PACKAGE
|
|
36
|
+
|
|
37
|
+
## Version
|
|
38
|
+
Semantic version increment
|
|
39
|
+
|
|
40
|
+
## Included Features
|
|
41
|
+
List from Master Plan
|
|
42
|
+
|
|
43
|
+
## Known Risks
|
|
44
|
+
Must be empty for PASS
|
|
45
|
+
|
|
46
|
+
## Deployment Steps
|
|
47
|
+
- Build commands
|
|
48
|
+
- Env var setup
|
|
49
|
+
- DB migration command
|
|
50
|
+
- Start commands
|
|
51
|
+
|
|
52
|
+
## Rollback Plan
|
|
53
|
+
Clear rollback steps
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Definition of Done
|
|
58
|
+
|
|
59
|
+
Release package stored under:
|
|
60
|
+
`/docs/release/`
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# Skill: REVIEWER (PLAN CONSENSUS REVIEWER)
|
|
2
|
+
Role Type: Independent Plan Auditor
|
|
3
|
+
Authority Level: Gatekeeper for Consensus Approval
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## Objective
|
|
8
|
+
|
|
9
|
+
Review a proposed plan produced by Dispatcher/Popeye using an independent LLM perspective,
|
|
10
|
+
detect gaps/hallucinations/shortcuts, and issue a structured vote that can be used for consensus.
|
|
11
|
+
|
|
12
|
+
Reviewer is NOT an implementer.
|
|
13
|
+
Reviewer is NOT a co-author (unless explicitly requested by Arbitrator to propose minimal corrections).
|
|
14
|
+
Reviewer is an evidence-based plan auditor.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Required Input: PLAN PACKET (Mandatory)
|
|
19
|
+
|
|
20
|
+
Reviewer only operates on a "Plan Packet" containing:
|
|
21
|
+
|
|
22
|
+
1) **Master Plan (approved version)**
|
|
23
|
+
2) **Proposed Plan** (the artifact under review)
|
|
24
|
+
3) **Repo Snapshot Summary** (what exists now)
|
|
25
|
+
4) **Constraints** (tech stack, env, policies)
|
|
26
|
+
5) **Constitution** (governing rules)
|
|
27
|
+
6) **Acceptance Criteria / Definition of Done**
|
|
28
|
+
|
|
29
|
+
If any component is missing → Reviewer must return **BLOCKED: Missing Inputs**.
|
|
30
|
+
|
|
31
|
+
---
|
|
32
|
+
|
|
33
|
+
## Primary Responsibilities
|
|
34
|
+
|
|
35
|
+
- Validate alignment with the Master Plan and Constitution
|
|
36
|
+
- Validate completeness: all scenarios, edge cases, and integration paths addressed
|
|
37
|
+
- Validate feasibility: steps are implementable in the repo as it exists
|
|
38
|
+
- Detect hallucinations: invented files, APIs, schema, env vars, services
|
|
39
|
+
- Detect shortcuts: mocks, TODOs, “later” wiring, vague testing
|
|
40
|
+
- Verify roles are correctly assigned and synchronized
|
|
41
|
+
- Verify artifacts + phase gates are present (architecture, DB, QA, review)
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Non-Responsibilities
|
|
46
|
+
|
|
47
|
+
- Does NOT implement
|
|
48
|
+
- Does NOT rewrite the whole plan
|
|
49
|
+
- Does NOT change scope without a Change Request
|
|
50
|
+
- Does NOT relax consensus rules
|
|
51
|
+
|
|
52
|
+
---
|
|
53
|
+
|
|
54
|
+
## Review Method (Must Follow)
|
|
55
|
+
|
|
56
|
+
1) **Coverage Scan**
|
|
57
|
+
- Does the plan cover 100% of Master Plan deliverables?
|
|
58
|
+
- Are all roles accounted for (Architect/DB/BE/FE/QA/etc.)?
|
|
59
|
+
|
|
60
|
+
2) **Integration Scan**
|
|
61
|
+
- FE↔BE wiring explicit?
|
|
62
|
+
- DB↔BE wiring explicit?
|
|
63
|
+
- Auth, env vars, migrations, deployment accounted for?
|
|
64
|
+
|
|
65
|
+
3) **Evidence Scan**
|
|
66
|
+
- Does it reference repo paths and existing modules accurately?
|
|
67
|
+
- Does it specify new files to be created deterministically?
|
|
68
|
+
|
|
69
|
+
4) **Risk & Scenario Scan**
|
|
70
|
+
- Failure modes covered? (timeouts, validation errors, empty states, rate limits, migrations fail, etc.)
|
|
71
|
+
- “Same resolution” comparisons, backward compat, rollback?
|
|
72
|
+
|
|
73
|
+
5) **Testability Scan**
|
|
74
|
+
- Are tests specified as executable steps? (not “write tests”)
|
|
75
|
+
- Are critical paths and integration tests listed?
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Output: REVIEW VOTE (Strict Format)
|
|
80
|
+
|
|
81
|
+
Reviewer MUST output the following structure:
|
|
82
|
+
|
|
83
|
+
### 1) Verdict
|
|
84
|
+
- **APPROVE**
|
|
85
|
+
- **APPROVE WITH MINOR CHANGES**
|
|
86
|
+
- **REJECT**
|
|
87
|
+
- **BLOCKED: MISSING INPUTS**
|
|
88
|
+
|
|
89
|
+
### 2) Score (0–100)
|
|
90
|
+
A numeric score representing confidence the plan can be executed without shortcuts/hallucinations.
|
|
91
|
+
|
|
92
|
+
### 3) Blocking Issues (if any)
|
|
93
|
+
Each blocking issue must include:
|
|
94
|
+
- **ID**
|
|
95
|
+
- **Problem**
|
|
96
|
+
- **Why it violates Master Plan/Constitution**
|
|
97
|
+
- **Exact fix requirement**
|
|
98
|
+
- **Where it should be fixed (which artifact/role)**
|
|
99
|
+
|
|
100
|
+
### 4) Non-Blocking Improvements
|
|
101
|
+
Concrete improvements that strengthen the plan.
|
|
102
|
+
|
|
103
|
+
### 5) Evidence & Consistency Notes
|
|
104
|
+
List any suspected hallucinations or ambiguous references.
|
|
105
|
+
|
|
106
|
+
### 6) Minimal Patch Suggestions (Optional)
|
|
107
|
+
If "Approve with minor changes", provide minimal diffs / bullet edits.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Automatic Rejection Triggers
|
|
112
|
+
|
|
113
|
+
Return **REJECT** if any exist:
|
|
114
|
+
|
|
115
|
+
- Implementation begins before architecture/DB/QA plans are gated
|
|
116
|
+
- Any plan step relies on "mock", "placeholder", "TODO" without explicit approval
|
|
117
|
+
- Unowned decisions (e.g. schema by BE, architecture by FE)
|
|
118
|
+
- Missing end-to-end integration steps
|
|
119
|
+
- Vague test plan (no named tests, no commands, no expected outcomes)
|
|
120
|
+
- Invented repo state (files/routes/env vars that don’t exist)
|
|
121
|
+
|
|
122
|
+
---
|
|
123
|
+
|
|
124
|
+
## Definition of Done
|
|
125
|
+
|
|
126
|
+
Reviewer is done when:
|
|
127
|
+
- A valid structured vote is returned
|
|
128
|
+
- Issues are categorized as blocking vs non-blocking
|
|
129
|
+
- Fix directives are precise enough for Dispatcher/Arbitrator to act on
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
End of Skill.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Skill: SOCIAL EXPERT
|
|
2
|
+
Role Type: Distribution Strategist
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Objective
|
|
7
|
+
|
|
8
|
+
Translate product and marketing strategy into platform-native content.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Responsibilities
|
|
13
|
+
|
|
14
|
+
- Platform strategy
|
|
15
|
+
- Content formats
|
|
16
|
+
- Community guidelines alignment
|
|
17
|
+
- Engagement loops
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
Definition of Done:
|
|
22
|
+
Distribution plan aligned with marketing strategy.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# Skill: UI/UX SPECIALIST
|
|
2
|
+
Role Type: Experience Authority
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Objective
|
|
7
|
+
|
|
8
|
+
Ensure usability, clarity, accessibility, and design coherence.
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Responsibilities
|
|
13
|
+
|
|
14
|
+
- UX flows
|
|
15
|
+
- Design system alignment
|
|
16
|
+
- Accessibility review
|
|
17
|
+
- Interaction validation
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
Anti-Shortcut:
|
|
22
|
+
No cosmetic-only review — must evaluate usability.
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Skill: WEBSITE PROGRAMMER
|
|
2
|
+
Role Type: Marketing Site Implementer
|
|
3
|
+
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
## Objective
|
|
7
|
+
|
|
8
|
+
Implement production-grade website aligned with:
|
|
9
|
+
|
|
10
|
+
- Brand
|
|
11
|
+
- Product positioning
|
|
12
|
+
- Architecture (if integrated)
|
|
13
|
+
- Marketing strategy
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## Responsibilities
|
|
18
|
+
|
|
19
|
+
- Landing pages
|
|
20
|
+
- Pricing pages
|
|
21
|
+
- Documentation pages
|
|
22
|
+
- SEO structure
|
|
23
|
+
- Analytics integration
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Anti-Shortcut Rules
|
|
28
|
+
|
|
29
|
+
- No generic template text
|
|
30
|
+
- No placeholder copy
|
|
31
|
+
- No mismatched branding
|
|
32
|
+
- No default theme if brand colors defined
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
Definition of Done:
|
|
37
|
+
Website reflects actual product capabilities and branding.
|
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Debug context helpers
|
|
3
|
+
* Deterministic functions for error analysis and smart file selection.
|
|
4
|
+
* Pure functions, easily testable.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import path from 'node:path';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Entry in the lightweight file index (paths + metadata, no content).
|
|
11
|
+
*/
|
|
12
|
+
export interface FileIndexEntry {
|
|
13
|
+
relativePath: string;
|
|
14
|
+
size: number;
|
|
15
|
+
mtime: number;
|
|
16
|
+
isConfig: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/** Config file patterns that are always considered relevant */
|
|
20
|
+
const CONFIG_PATTERNS = [
|
|
21
|
+
'package.json', 'package-lock.json', 'tsconfig.json', 'vite.config',
|
|
22
|
+
'pyproject.toml', 'requirements.txt', 'Pipfile',
|
|
23
|
+
'docker-compose.yml', 'docker-compose.yaml', 'Dockerfile',
|
|
24
|
+
'.env.example', '.env.local', 'alembic.ini',
|
|
25
|
+
'next.config', 'tailwind.config', 'postcss.config',
|
|
26
|
+
'jest.config', 'vitest.config', 'pytest.ini', 'setup.cfg',
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Check if a file path matches a config pattern.
|
|
31
|
+
*
|
|
32
|
+
* @param filePath - Relative path to check.
|
|
33
|
+
* @returns True if the file is a known config file.
|
|
34
|
+
*/
|
|
35
|
+
export function isConfigFile(filePath: string): boolean {
|
|
36
|
+
const basename = path.basename(filePath);
|
|
37
|
+
return CONFIG_PATTERNS.some((p) => basename.startsWith(p));
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Extract file paths mentioned in stack traces.
|
|
42
|
+
* Supports Python tracebacks, TypeScript/JS errors, and generic path patterns.
|
|
43
|
+
*
|
|
44
|
+
* @param text - Error text or stack trace.
|
|
45
|
+
* @returns Deduplicated array of file paths found in the text.
|
|
46
|
+
*/
|
|
47
|
+
export function extractPathsFromError(text: string): string[] {
|
|
48
|
+
const paths = new Set<string>();
|
|
49
|
+
|
|
50
|
+
// Python traceback: File "/app/src/module/file.py", line 42
|
|
51
|
+
const pyPattern = /File "([^"]+\.py[cw]?)", line \d+/g;
|
|
52
|
+
for (const match of text.matchAll(pyPattern)) {
|
|
53
|
+
paths.add(normalizePath(match[1]));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// TS/JS errors: src/components/App.tsx(15,3) or src/components/App.tsx:15:3
|
|
57
|
+
const tsPattern = /([a-zA-Z0-9_./\\-]+\.(?:ts|tsx|js|jsx|mjs|cjs))[\s:(]/g;
|
|
58
|
+
for (const match of text.matchAll(tsPattern)) {
|
|
59
|
+
paths.add(normalizePath(match[1]));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Docker / generic paths: /app/src/..., ./src/...
|
|
63
|
+
const genericPattern = /(?:\/app\/|\.\/)((?:src|app|lib|tests?|config)\/[a-zA-Z0-9_./-]+\.\w+)/g;
|
|
64
|
+
for (const match of text.matchAll(genericPattern)) {
|
|
65
|
+
paths.add(normalizePath(match[1]));
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Module not found patterns: Cannot find module './foo/bar'
|
|
69
|
+
const modulePattern = /Cannot find module ['"]([^'"]+)['"]/g;
|
|
70
|
+
for (const match of text.matchAll(modulePattern)) {
|
|
71
|
+
const mod = match[1];
|
|
72
|
+
if (mod.startsWith('.') || mod.startsWith('/')) {
|
|
73
|
+
paths.add(normalizePath(mod));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ModuleNotFoundError: No module named 'src.foo.bar'
|
|
78
|
+
const pyModulePattern = /No module named ['"]([^'"]+)['"]/g;
|
|
79
|
+
for (const match of text.matchAll(pyModulePattern)) {
|
|
80
|
+
const dotPath = match[1].replace(/\./g, '/');
|
|
81
|
+
paths.add(dotPath);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
return Array.from(paths);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/** Tech keyword map: keyword -> tags */
|
|
88
|
+
const TECH_KEYWORDS: Record<string, string[]> = {
|
|
89
|
+
'alembic': ['alembic', 'database', 'migration'],
|
|
90
|
+
'sqlalchemy': ['sqlalchemy', 'database', 'orm'],
|
|
91
|
+
'prisma': ['prisma', 'database', 'orm'],
|
|
92
|
+
'docker': ['docker', 'container'],
|
|
93
|
+
'docker-compose': ['docker', 'container', 'compose'],
|
|
94
|
+
'vite': ['vite', 'bundler', 'frontend'],
|
|
95
|
+
'webpack': ['webpack', 'bundler', 'frontend'],
|
|
96
|
+
'next': ['nextjs', 'react', 'frontend'],
|
|
97
|
+
'fastapi': ['fastapi', 'backend', 'python'],
|
|
98
|
+
'flask': ['flask', 'backend', 'python'],
|
|
99
|
+
'express': ['express', 'backend', 'node'],
|
|
100
|
+
'postgres': ['postgres', 'database'],
|
|
101
|
+
'redis': ['redis', 'cache'],
|
|
102
|
+
'tailwind': ['tailwind', 'css', 'frontend'],
|
|
103
|
+
'pytest': ['pytest', 'testing', 'python'],
|
|
104
|
+
'jest': ['jest', 'testing', 'node'],
|
|
105
|
+
'vitest': ['vitest', 'testing', 'node'],
|
|
106
|
+
'nginx': ['nginx', 'proxy'],
|
|
107
|
+
'cors': ['cors', 'api'],
|
|
108
|
+
'migration': ['migration', 'database'],
|
|
109
|
+
'celery': ['celery', 'queue', 'python'],
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Detect framework/tech keywords from error text.
|
|
114
|
+
*
|
|
115
|
+
* @param text - Error text or stack trace.
|
|
116
|
+
* @returns Object with deduplicated tags array.
|
|
117
|
+
*/
|
|
118
|
+
export function detectTechFromError(text: string): { tags: string[] } {
|
|
119
|
+
const tags = new Set<string>();
|
|
120
|
+
const lower = text.toLowerCase();
|
|
121
|
+
|
|
122
|
+
for (const [keyword, keywordTags] of Object.entries(TECH_KEYWORDS)) {
|
|
123
|
+
if (lower.includes(keyword)) {
|
|
124
|
+
for (const tag of keywordTags) {
|
|
125
|
+
tags.add(tag);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return { tags: Array.from(tags) };
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Select relevant files from the project index based on error paths and tech tags.
|
|
135
|
+
* Returns file paths sorted by relevance (direct matches first, then config, then nearby).
|
|
136
|
+
*
|
|
137
|
+
* @param fileIndex - Lightweight file index.
|
|
138
|
+
* @param errorPaths - Paths extracted from the error.
|
|
139
|
+
* @param tags - Tech tags detected from the error.
|
|
140
|
+
* @returns Array of relative paths to load.
|
|
141
|
+
*/
|
|
142
|
+
export function selectRelevantFiles(
|
|
143
|
+
fileIndex: FileIndexEntry[],
|
|
144
|
+
errorPaths: string[],
|
|
145
|
+
tags: string[]
|
|
146
|
+
): string[] {
|
|
147
|
+
if (fileIndex.length === 0) return [];
|
|
148
|
+
|
|
149
|
+
const selected = new Set<string>();
|
|
150
|
+
const MAX_FILES = 15;
|
|
151
|
+
|
|
152
|
+
// 1. Direct matches: files mentioned in the error
|
|
153
|
+
for (const errorPath of errorPaths) {
|
|
154
|
+
for (const entry of fileIndex) {
|
|
155
|
+
if (
|
|
156
|
+
entry.relativePath.endsWith(errorPath) ||
|
|
157
|
+
entry.relativePath === errorPath ||
|
|
158
|
+
entry.relativePath.includes(errorPath)
|
|
159
|
+
) {
|
|
160
|
+
selected.add(entry.relativePath);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// 2. Sibling files: files in the same directory as matches
|
|
166
|
+
const matchedDirs = new Set<string>();
|
|
167
|
+
for (const sel of selected) {
|
|
168
|
+
matchedDirs.add(path.dirname(sel));
|
|
169
|
+
}
|
|
170
|
+
for (const dir of matchedDirs) {
|
|
171
|
+
for (const entry of fileIndex) {
|
|
172
|
+
if (path.dirname(entry.relativePath) === dir && selected.size < MAX_FILES) {
|
|
173
|
+
selected.add(entry.relativePath);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// 3. Tag-based: config files related to detected tech
|
|
179
|
+
if (tags.includes('database') || tags.includes('migration')) {
|
|
180
|
+
for (const entry of fileIndex) {
|
|
181
|
+
if (
|
|
182
|
+
entry.relativePath.includes('alembic') ||
|
|
183
|
+
entry.relativePath.includes('migration') ||
|
|
184
|
+
entry.relativePath.includes('prisma') ||
|
|
185
|
+
entry.relativePath.includes('schema.sql')
|
|
186
|
+
) {
|
|
187
|
+
if (selected.size < MAX_FILES) selected.add(entry.relativePath);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
if (tags.includes('docker') || tags.includes('compose')) {
|
|
192
|
+
for (const entry of fileIndex) {
|
|
193
|
+
if (
|
|
194
|
+
entry.relativePath.includes('docker') ||
|
|
195
|
+
entry.relativePath.includes('Dockerfile')
|
|
196
|
+
) {
|
|
197
|
+
if (selected.size < MAX_FILES) selected.add(entry.relativePath);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// 4. Fallback: always include config files if we have few matches
|
|
203
|
+
if (selected.size < 5) {
|
|
204
|
+
for (const entry of fileIndex) {
|
|
205
|
+
if (entry.isConfig && selected.size < MAX_FILES) {
|
|
206
|
+
selected.add(entry.relativePath);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
return Array.from(selected).slice(0, MAX_FILES);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/** Image file extensions that Claude can read via the Read tool */
|
|
215
|
+
const IMAGE_EXTENSIONS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.webp', '.bmp', '.svg']);
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Extract image/screenshot file paths from user input text.
|
|
219
|
+
* Detects both quoted and unquoted absolute/relative paths ending in image extensions.
|
|
220
|
+
*
|
|
221
|
+
* @param text - User input text.
|
|
222
|
+
* @returns Array of image file paths found in the text.
|
|
223
|
+
*/
|
|
224
|
+
export function extractImagePaths(text: string): string[] {
|
|
225
|
+
const paths = new Set<string>();
|
|
226
|
+
|
|
227
|
+
// Quoted paths: '/path/to/image.png' or "/path/to/image.png"
|
|
228
|
+
const quotedPattern = /['"]([^'"]+\.(?:png|jpg|jpeg|gif|webp|bmp|svg))['"]/gi;
|
|
229
|
+
for (const match of text.matchAll(quotedPattern)) {
|
|
230
|
+
paths.add(match[1]);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
// Unquoted absolute paths: /path/to/image.png (no spaces allowed in unquoted)
|
|
234
|
+
const absolutePattern = /(\/[^\s'"]+\.(?:png|jpg|jpeg|gif|webp|bmp|svg))/gi;
|
|
235
|
+
for (const match of text.matchAll(absolutePattern)) {
|
|
236
|
+
paths.add(match[1]);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return Array.from(paths);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
/**
|
|
243
|
+
* Check if a file path points to an image file.
|
|
244
|
+
*
|
|
245
|
+
* @param filePath - File path to check.
|
|
246
|
+
* @returns True if the file has an image extension.
|
|
247
|
+
*/
|
|
248
|
+
export function isImageFile(filePath: string): boolean {
|
|
249
|
+
const ext = path.extname(filePath).toLowerCase();
|
|
250
|
+
return IMAGE_EXTENSIONS.has(ext);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Normalize a file path by stripping common prefixes (/app/, ./, etc.).
|
|
255
|
+
*
|
|
256
|
+
* @param p - Raw file path from error text.
|
|
257
|
+
* @returns Normalized relative path.
|
|
258
|
+
*/
|
|
259
|
+
function normalizePath(p: string): string {
|
|
260
|
+
let normalized = p.replace(/\\/g, '/');
|
|
261
|
+
// Strip common container prefixes
|
|
262
|
+
normalized = normalized.replace(/^\/app\//, '');
|
|
263
|
+
normalized = normalized.replace(/^\.\//, '');
|
|
264
|
+
return normalized;
|
|
265
|
+
}
|