popeye-cli 1.10.0 → 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.
Files changed (253) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/CONTRIBUTING.md +15 -1
  3. package/README.md +57 -0
  4. package/dist/pipeline/artifact-manager.d.ts +47 -0
  5. package/dist/pipeline/artifact-manager.d.ts.map +1 -0
  6. package/dist/pipeline/artifact-manager.js +251 -0
  7. package/dist/pipeline/artifact-manager.js.map +1 -0
  8. package/dist/pipeline/artifact-validators.d.ts +29 -0
  9. package/dist/pipeline/artifact-validators.d.ts.map +1 -0
  10. package/dist/pipeline/artifact-validators.js +173 -0
  11. package/dist/pipeline/artifact-validators.js.map +1 -0
  12. package/dist/pipeline/change-request.d.ts +47 -0
  13. package/dist/pipeline/change-request.d.ts.map +1 -0
  14. package/dist/pipeline/change-request.js +91 -0
  15. package/dist/pipeline/change-request.js.map +1 -0
  16. package/dist/pipeline/check-runner.d.ts +47 -0
  17. package/dist/pipeline/check-runner.d.ts.map +1 -0
  18. package/dist/pipeline/check-runner.js +417 -0
  19. package/dist/pipeline/check-runner.js.map +1 -0
  20. package/dist/pipeline/command-resolver.d.ts +9 -0
  21. package/dist/pipeline/command-resolver.d.ts.map +1 -0
  22. package/dist/pipeline/command-resolver.js +140 -0
  23. package/dist/pipeline/command-resolver.js.map +1 -0
  24. package/dist/pipeline/consensus/consensus-runner.d.ts +44 -0
  25. package/dist/pipeline/consensus/consensus-runner.d.ts.map +1 -0
  26. package/dist/pipeline/consensus/consensus-runner.js +212 -0
  27. package/dist/pipeline/consensus/consensus-runner.js.map +1 -0
  28. package/dist/pipeline/constitution.d.ts +45 -0
  29. package/dist/pipeline/constitution.d.ts.map +1 -0
  30. package/dist/pipeline/constitution.js +82 -0
  31. package/dist/pipeline/constitution.js.map +1 -0
  32. package/dist/pipeline/gate-engine.d.ts +55 -0
  33. package/dist/pipeline/gate-engine.d.ts.map +1 -0
  34. package/dist/pipeline/gate-engine.js +270 -0
  35. package/dist/pipeline/gate-engine.js.map +1 -0
  36. package/dist/pipeline/index.d.ts +26 -0
  37. package/dist/pipeline/index.d.ts.map +1 -0
  38. package/dist/pipeline/index.js +35 -0
  39. package/dist/pipeline/index.js.map +1 -0
  40. package/dist/pipeline/migration.d.ts +15 -0
  41. package/dist/pipeline/migration.d.ts.map +1 -0
  42. package/dist/pipeline/migration.js +76 -0
  43. package/dist/pipeline/migration.js.map +1 -0
  44. package/dist/pipeline/orchestrator.d.ts +28 -0
  45. package/dist/pipeline/orchestrator.d.ts.map +1 -0
  46. package/dist/pipeline/orchestrator.js +238 -0
  47. package/dist/pipeline/orchestrator.js.map +1 -0
  48. package/dist/pipeline/packets/audit-report-builder.d.ts +11 -0
  49. package/dist/pipeline/packets/audit-report-builder.d.ts.map +1 -0
  50. package/dist/pipeline/packets/audit-report-builder.js +32 -0
  51. package/dist/pipeline/packets/audit-report-builder.js.map +1 -0
  52. package/dist/pipeline/packets/consensus-packet-builder.d.ts +35 -0
  53. package/dist/pipeline/packets/consensus-packet-builder.d.ts.map +1 -0
  54. package/dist/pipeline/packets/consensus-packet-builder.js +80 -0
  55. package/dist/pipeline/packets/consensus-packet-builder.js.map +1 -0
  56. package/dist/pipeline/packets/index.d.ts +12 -0
  57. package/dist/pipeline/packets/index.d.ts.map +1 -0
  58. package/dist/pipeline/packets/index.js +8 -0
  59. package/dist/pipeline/packets/index.js.map +1 -0
  60. package/dist/pipeline/packets/plan-packet-builder.d.ts +21 -0
  61. package/dist/pipeline/packets/plan-packet-builder.d.ts.map +1 -0
  62. package/dist/pipeline/packets/plan-packet-builder.js +27 -0
  63. package/dist/pipeline/packets/plan-packet-builder.js.map +1 -0
  64. package/dist/pipeline/packets/rca-packet-builder.d.ts +19 -0
  65. package/dist/pipeline/packets/rca-packet-builder.d.ts.map +1 -0
  66. package/dist/pipeline/packets/rca-packet-builder.js +22 -0
  67. package/dist/pipeline/packets/rca-packet-builder.js.map +1 -0
  68. package/dist/pipeline/phases/architecture.d.ts +7 -0
  69. package/dist/pipeline/phases/architecture.d.ts.map +1 -0
  70. package/dist/pipeline/phases/architecture.js +60 -0
  71. package/dist/pipeline/phases/architecture.js.map +1 -0
  72. package/dist/pipeline/phases/audit.d.ts +8 -0
  73. package/dist/pipeline/phases/audit.d.ts.map +1 -0
  74. package/dist/pipeline/phases/audit.js +144 -0
  75. package/dist/pipeline/phases/audit.js.map +1 -0
  76. package/dist/pipeline/phases/consensus-architecture.d.ts +7 -0
  77. package/dist/pipeline/phases/consensus-architecture.d.ts.map +1 -0
  78. package/dist/pipeline/phases/consensus-architecture.js +84 -0
  79. package/dist/pipeline/phases/consensus-architecture.js.map +1 -0
  80. package/dist/pipeline/phases/consensus-master-plan.d.ts +7 -0
  81. package/dist/pipeline/phases/consensus-master-plan.d.ts.map +1 -0
  82. package/dist/pipeline/phases/consensus-master-plan.js +81 -0
  83. package/dist/pipeline/phases/consensus-master-plan.js.map +1 -0
  84. package/dist/pipeline/phases/consensus-role-plans.d.ts +7 -0
  85. package/dist/pipeline/phases/consensus-role-plans.d.ts.map +1 -0
  86. package/dist/pipeline/phases/consensus-role-plans.js +85 -0
  87. package/dist/pipeline/phases/consensus-role-plans.js.map +1 -0
  88. package/dist/pipeline/phases/done.d.ts +7 -0
  89. package/dist/pipeline/phases/done.d.ts.map +1 -0
  90. package/dist/pipeline/phases/done.js +45 -0
  91. package/dist/pipeline/phases/done.js.map +1 -0
  92. package/dist/pipeline/phases/implementation.d.ts +8 -0
  93. package/dist/pipeline/phases/implementation.d.ts.map +1 -0
  94. package/dist/pipeline/phases/implementation.js +42 -0
  95. package/dist/pipeline/phases/implementation.js.map +1 -0
  96. package/dist/pipeline/phases/index.d.ts +20 -0
  97. package/dist/pipeline/phases/index.d.ts.map +1 -0
  98. package/dist/pipeline/phases/index.js +19 -0
  99. package/dist/pipeline/phases/index.js.map +1 -0
  100. package/dist/pipeline/phases/intake.d.ts +8 -0
  101. package/dist/pipeline/phases/intake.d.ts.map +1 -0
  102. package/dist/pipeline/phases/intake.js +40 -0
  103. package/dist/pipeline/phases/intake.js.map +1 -0
  104. package/dist/pipeline/phases/phase-context.d.ts +30 -0
  105. package/dist/pipeline/phases/phase-context.d.ts.map +1 -0
  106. package/dist/pipeline/phases/phase-context.js +33 -0
  107. package/dist/pipeline/phases/phase-context.js.map +1 -0
  108. package/dist/pipeline/phases/production-gate.d.ts +8 -0
  109. package/dist/pipeline/phases/production-gate.d.ts.map +1 -0
  110. package/dist/pipeline/phases/production-gate.js +84 -0
  111. package/dist/pipeline/phases/production-gate.js.map +1 -0
  112. package/dist/pipeline/phases/qa-validation.d.ts +7 -0
  113. package/dist/pipeline/phases/qa-validation.d.ts.map +1 -0
  114. package/dist/pipeline/phases/qa-validation.js +50 -0
  115. package/dist/pipeline/phases/qa-validation.js.map +1 -0
  116. package/dist/pipeline/phases/recovery-loop.d.ts +7 -0
  117. package/dist/pipeline/phases/recovery-loop.d.ts.map +1 -0
  118. package/dist/pipeline/phases/recovery-loop.js +91 -0
  119. package/dist/pipeline/phases/recovery-loop.js.map +1 -0
  120. package/dist/pipeline/phases/review.d.ts +8 -0
  121. package/dist/pipeline/phases/review.d.ts.map +1 -0
  122. package/dist/pipeline/phases/review.js +127 -0
  123. package/dist/pipeline/phases/review.js.map +1 -0
  124. package/dist/pipeline/phases/role-planning.d.ts +7 -0
  125. package/dist/pipeline/phases/role-planning.d.ts.map +1 -0
  126. package/dist/pipeline/phases/role-planning.js +75 -0
  127. package/dist/pipeline/phases/role-planning.js.map +1 -0
  128. package/dist/pipeline/phases/stuck.d.ts +7 -0
  129. package/dist/pipeline/phases/stuck.d.ts.map +1 -0
  130. package/dist/pipeline/phases/stuck.js +51 -0
  131. package/dist/pipeline/phases/stuck.js.map +1 -0
  132. package/dist/pipeline/repo-snapshot.d.ts +24 -0
  133. package/dist/pipeline/repo-snapshot.d.ts.map +1 -0
  134. package/dist/pipeline/repo-snapshot.js +343 -0
  135. package/dist/pipeline/repo-snapshot.js.map +1 -0
  136. package/dist/pipeline/role-execution-adapter.d.ts +59 -0
  137. package/dist/pipeline/role-execution-adapter.d.ts.map +1 -0
  138. package/dist/pipeline/role-execution-adapter.js +159 -0
  139. package/dist/pipeline/role-execution-adapter.js.map +1 -0
  140. package/dist/pipeline/skill-loader.d.ts +34 -0
  141. package/dist/pipeline/skill-loader.d.ts.map +1 -0
  142. package/dist/pipeline/skill-loader.js +156 -0
  143. package/dist/pipeline/skill-loader.js.map +1 -0
  144. package/dist/pipeline/skills/defaults.d.ts +16 -0
  145. package/dist/pipeline/skills/defaults.d.ts.map +1 -0
  146. package/dist/pipeline/skills/defaults.js +189 -0
  147. package/dist/pipeline/skills/defaults.js.map +1 -0
  148. package/dist/pipeline/type-defs/artifacts.d.ts +202 -0
  149. package/dist/pipeline/type-defs/artifacts.d.ts.map +1 -0
  150. package/dist/pipeline/type-defs/artifacts.js +66 -0
  151. package/dist/pipeline/type-defs/artifacts.js.map +1 -0
  152. package/dist/pipeline/type-defs/audit.d.ts +256 -0
  153. package/dist/pipeline/type-defs/audit.d.ts.map +1 -0
  154. package/dist/pipeline/type-defs/audit.js +54 -0
  155. package/dist/pipeline/type-defs/audit.js.map +1 -0
  156. package/dist/pipeline/type-defs/checks.d.ts +81 -0
  157. package/dist/pipeline/type-defs/checks.d.ts.map +1 -0
  158. package/dist/pipeline/type-defs/checks.js +38 -0
  159. package/dist/pipeline/type-defs/checks.js.map +1 -0
  160. package/dist/pipeline/type-defs/enums.d.ts +43 -0
  161. package/dist/pipeline/type-defs/enums.d.ts.map +1 -0
  162. package/dist/pipeline/type-defs/enums.js +55 -0
  163. package/dist/pipeline/type-defs/enums.js.map +1 -0
  164. package/dist/pipeline/type-defs/index.d.ts +12 -0
  165. package/dist/pipeline/type-defs/index.d.ts.map +1 -0
  166. package/dist/pipeline/type-defs/index.js +12 -0
  167. package/dist/pipeline/type-defs/index.js.map +1 -0
  168. package/dist/pipeline/type-defs/packets.d.ts +806 -0
  169. package/dist/pipeline/type-defs/packets.d.ts.map +1 -0
  170. package/dist/pipeline/type-defs/packets.js +109 -0
  171. package/dist/pipeline/type-defs/packets.js.map +1 -0
  172. package/dist/pipeline/type-defs/snapshot.d.ts +52 -0
  173. package/dist/pipeline/type-defs/snapshot.d.ts.map +1 -0
  174. package/dist/pipeline/type-defs/snapshot.js +35 -0
  175. package/dist/pipeline/type-defs/snapshot.js.map +1 -0
  176. package/dist/pipeline/type-defs/state.d.ts +449 -0
  177. package/dist/pipeline/type-defs/state.d.ts.map +1 -0
  178. package/dist/pipeline/type-defs/state.js +88 -0
  179. package/dist/pipeline/type-defs/state.js.map +1 -0
  180. package/dist/pipeline/types.d.ts +16 -0
  181. package/dist/pipeline/types.d.ts.map +1 -0
  182. package/dist/pipeline/types.js +16 -0
  183. package/dist/pipeline/types.js.map +1 -0
  184. package/dist/types/audit.d.ts +6 -6
  185. package/dist/workflow/index.d.ts.map +1 -1
  186. package/dist/workflow/index.js +48 -0
  187. package/dist/workflow/index.js.map +1 -1
  188. package/package.json +1 -1
  189. package/skills/PHASE_GATE_ENGINE_SPEC.md +113 -20
  190. package/skills/POPEYE_FULL_AUTONOMY_PIPELINE.md +66 -13
  191. package/src/pipeline/artifact-manager.ts +339 -0
  192. package/src/pipeline/artifact-validators.ts +224 -0
  193. package/src/pipeline/change-request.ts +119 -0
  194. package/src/pipeline/check-runner.ts +504 -0
  195. package/src/pipeline/command-resolver.ts +168 -0
  196. package/src/pipeline/consensus/consensus-runner.ts +317 -0
  197. package/src/pipeline/constitution.ts +109 -0
  198. package/src/pipeline/gate-engine.ts +347 -0
  199. package/src/pipeline/index.ts +82 -0
  200. package/src/pipeline/migration.ts +91 -0
  201. package/src/pipeline/orchestrator.ts +314 -0
  202. package/src/pipeline/packets/audit-report-builder.ts +47 -0
  203. package/src/pipeline/packets/consensus-packet-builder.ts +112 -0
  204. package/src/pipeline/packets/index.ts +15 -0
  205. package/src/pipeline/packets/plan-packet-builder.ts +52 -0
  206. package/src/pipeline/packets/rca-packet-builder.ts +38 -0
  207. package/src/pipeline/phases/architecture.ts +73 -0
  208. package/src/pipeline/phases/audit.ts +193 -0
  209. package/src/pipeline/phases/consensus-architecture.ts +104 -0
  210. package/src/pipeline/phases/consensus-master-plan.ts +100 -0
  211. package/src/pipeline/phases/consensus-role-plans.ts +105 -0
  212. package/src/pipeline/phases/done.ts +68 -0
  213. package/src/pipeline/phases/implementation.ts +48 -0
  214. package/src/pipeline/phases/index.ts +21 -0
  215. package/src/pipeline/phases/intake.ts +54 -0
  216. package/src/pipeline/phases/phase-context.ts +86 -0
  217. package/src/pipeline/phases/production-gate.ts +113 -0
  218. package/src/pipeline/phases/qa-validation.ts +63 -0
  219. package/src/pipeline/phases/recovery-loop.ts +118 -0
  220. package/src/pipeline/phases/review.ts +149 -0
  221. package/src/pipeline/phases/role-planning.ts +92 -0
  222. package/src/pipeline/phases/stuck.ts +62 -0
  223. package/src/pipeline/repo-snapshot.ts +395 -0
  224. package/src/pipeline/role-execution-adapter.ts +238 -0
  225. package/src/pipeline/skill-loader.ts +192 -0
  226. package/src/pipeline/skills/defaults.ts +215 -0
  227. package/src/pipeline/type-defs/artifacts.ts +81 -0
  228. package/src/pipeline/type-defs/audit.ts +67 -0
  229. package/src/pipeline/type-defs/checks.ts +47 -0
  230. package/src/pipeline/type-defs/enums.ts +62 -0
  231. package/src/pipeline/type-defs/index.ts +12 -0
  232. package/src/pipeline/type-defs/packets.ts +131 -0
  233. package/src/pipeline/type-defs/snapshot.ts +55 -0
  234. package/src/pipeline/type-defs/state.ts +165 -0
  235. package/src/pipeline/types.ts +16 -0
  236. package/src/workflow/index.ts +48 -0
  237. package/tests/pipeline/artifact-manager.test.ts +183 -0
  238. package/tests/pipeline/artifact-validators.test.ts +207 -0
  239. package/tests/pipeline/change-request.test.ts +180 -0
  240. package/tests/pipeline/check-runner.test.ts +157 -0
  241. package/tests/pipeline/command-resolver.test.ts +159 -0
  242. package/tests/pipeline/consensus-runner.test.ts +206 -0
  243. package/tests/pipeline/consensus-scoring.test.ts +163 -0
  244. package/tests/pipeline/constitution.test.ts +122 -0
  245. package/tests/pipeline/gate-engine.test.ts +195 -0
  246. package/tests/pipeline/migration.test.ts +133 -0
  247. package/tests/pipeline/orchestrator.test.ts +614 -0
  248. package/tests/pipeline/packets/builders.test.ts +347 -0
  249. package/tests/pipeline/repo-snapshot.test.ts +189 -0
  250. package/tests/pipeline/role-execution-adapter.test.ts +299 -0
  251. package/tests/pipeline/skill-loader.test.ts +186 -0
  252. package/tests/pipeline/start-env-checks.test.ts +123 -0
  253. package/tests/pipeline/types.test.ts +156 -0
@@ -0,0 +1,417 @@
1
+ /**
2
+ * Check Runner — executes build/test/lint/typecheck commands
3
+ * and produces GateCheckResult artifacts.
4
+ *
5
+ * Safety: command sanitization, cwd enforcement, stream caps,
6
+ * configurable timeouts (P2-G).
7
+ */
8
+ import { exec } from 'node:child_process';
9
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
10
+ import { join, extname } from 'node:path';
11
+ // ─── Constants ───────────────────────────────────────────
12
+ /** Default timeout per check type in milliseconds */
13
+ const DEFAULT_TIMEOUTS = {
14
+ build: 20 * 60 * 1000, // 20 minutes
15
+ test: 10 * 60 * 1000, // 10 minutes
16
+ lint: 5 * 60 * 1000, // 5 minutes
17
+ typecheck: 5 * 60 * 1000, // 5 minutes
18
+ migration: 5 * 60 * 1000, // 5 minutes
19
+ };
20
+ /** Max stdout/stderr capture in bytes */
21
+ const MAX_OUTPUT_SIZE = 1024 * 1024; // 1 MB
22
+ /** Dangerous command patterns to reject */
23
+ const DANGEROUS_PATTERNS = [
24
+ /rm\s+-rf\s+\//,
25
+ /sudo\s+/,
26
+ />\s*\/dev\//,
27
+ />\s*\/etc\//,
28
+ />\s*\/usr\//,
29
+ /;\s*rm\s/,
30
+ /&&\s*rm\s/,
31
+ /\|\s*sh$/,
32
+ /\|\s*bash$/,
33
+ ];
34
+ /** Placeholder patterns for scanning */
35
+ const PLACEHOLDER_PATTERNS = [
36
+ /\bTODO\b/i,
37
+ /\bFIXME\b/i,
38
+ /\bHACK\b/i,
39
+ /\bXXX\b/i,
40
+ /placeholder/i,
41
+ /\bmock\b(?!\.)/i, // 'mock' but not 'mock.' (import paths)
42
+ /\btemp\b(?!late)/i, // 'temp' but not 'template'
43
+ /lorem ipsum/i,
44
+ /example\.com/i,
45
+ ];
46
+ // ─── Command Sanitization ────────────────────────────────
47
+ function sanitizeCommand(command) {
48
+ for (const pattern of DANGEROUS_PATTERNS) {
49
+ if (pattern.test(command)) {
50
+ return { safe: false, reason: `Matches dangerous pattern: ${pattern.source}` };
51
+ }
52
+ }
53
+ return { safe: true };
54
+ }
55
+ // ─── Check Execution ─────────────────────────────────────
56
+ /** Execute a single check command */
57
+ export async function runCheck(checkType, command, projectDir, timeoutOverride) {
58
+ const startTime = Date.now();
59
+ // Sanitize command
60
+ const { safe, reason } = sanitizeCommand(command);
61
+ if (!safe) {
62
+ return {
63
+ check_type: checkType,
64
+ status: 'fail',
65
+ command,
66
+ exit_code: -1,
67
+ stderr_summary: `Command rejected: ${reason}`,
68
+ duration_ms: 0,
69
+ timestamp: new Date().toISOString(),
70
+ };
71
+ }
72
+ const timeout = timeoutOverride ?? DEFAULT_TIMEOUTS[checkType] ?? 5 * 60 * 1000;
73
+ return new Promise((resolve) => {
74
+ const proc = exec(command, {
75
+ cwd: projectDir,
76
+ timeout,
77
+ maxBuffer: MAX_OUTPUT_SIZE,
78
+ env: {
79
+ ...process.env,
80
+ NODE_ENV: 'test',
81
+ CI: 'true',
82
+ },
83
+ }, (error, _stdout, stderr) => {
84
+ const duration = Date.now() - startTime;
85
+ const exitCode = error ? error.code ?? 1 : 0;
86
+ // Truncate output for summary
87
+ const stderrSummary = stderr
88
+ ? stderr.slice(0, 2000) + (stderr.length > 2000 ? '\n... (truncated)' : '')
89
+ : undefined;
90
+ resolve({
91
+ check_type: checkType,
92
+ status: exitCode === 0 ? 'pass' : 'fail',
93
+ command,
94
+ exit_code: typeof exitCode === 'number' ? exitCode : 1,
95
+ stdout_artifact: undefined, // Filled by storeCheckResults if needed
96
+ stderr_summary: stderrSummary,
97
+ duration_ms: duration,
98
+ timestamp: new Date().toISOString(),
99
+ });
100
+ });
101
+ // Safety: kill after timeout (backup for exec timeout)
102
+ setTimeout(() => {
103
+ try {
104
+ proc.kill('SIGTERM');
105
+ }
106
+ catch { /* already dead */ }
107
+ }, timeout + 5000);
108
+ });
109
+ }
110
+ /** Run all applicable checks based on resolved commands */
111
+ export async function runAllChecks(resolvedCommands, projectDir) {
112
+ const results = [];
113
+ const checkMap = [
114
+ ['build', resolvedCommands.build],
115
+ ['test', resolvedCommands.test],
116
+ ['lint', resolvedCommands.lint],
117
+ ['typecheck', resolvedCommands.typecheck],
118
+ ['migration', resolvedCommands.migrations],
119
+ ];
120
+ for (const [checkType, command] of checkMap) {
121
+ if (!command) {
122
+ results.push({
123
+ check_type: checkType,
124
+ status: 'skip',
125
+ command: '',
126
+ exit_code: 0,
127
+ duration_ms: 0,
128
+ timestamp: new Date().toISOString(),
129
+ });
130
+ continue;
131
+ }
132
+ const result = await runCheck(checkType, command, projectDir);
133
+ results.push(result);
134
+ }
135
+ return results;
136
+ }
137
+ /** Store check results as artifacts */
138
+ export function storeCheckResults(results, artifactManager, phase) {
139
+ const artifacts = [];
140
+ for (const result of results) {
141
+ if (result.status === 'skip')
142
+ continue;
143
+ // Only store meaningful output
144
+ const content = JSON.stringify(result, null, 2);
145
+ if (content.length > 100) {
146
+ const entry = artifactManager.createAndStoreJson(mapCheckTypeToArtifactType(result.check_type), result, phase);
147
+ artifacts.push(entry);
148
+ }
149
+ }
150
+ return artifacts;
151
+ }
152
+ function mapCheckTypeToArtifactType(checkType) {
153
+ switch (checkType) {
154
+ case 'build': return 'build_check';
155
+ case 'test': return 'test_check';
156
+ case 'lint': return 'lint_check';
157
+ case 'typecheck': return 'typecheck_check';
158
+ case 'placeholder_scan': return 'placeholder_scan';
159
+ default: return 'build_check';
160
+ }
161
+ }
162
+ // ─── Placeholder Scanner (P2-2) ──────────────────────────
163
+ /** Scan project for placeholder/TODO/mock content */
164
+ export function runPlaceholderScan(projectDir, allowlistPath) {
165
+ const startTime = Date.now();
166
+ const findings = [];
167
+ // Load allowlist if present
168
+ const allowlist = loadAllowlist(allowlistPath ?? join(projectDir, '.popeye-placeholder-allowlist'));
169
+ // Scan source directories
170
+ const scanDirs = ['src', 'app', 'pages', 'components', 'lib', 'server', 'api'];
171
+ for (const dir of scanDirs) {
172
+ const fullDir = join(projectDir, dir);
173
+ if (!existsSync(fullDir))
174
+ continue;
175
+ scanDirForPlaceholders(fullDir, projectDir, allowlist, findings);
176
+ }
177
+ const duration = Date.now() - startTime;
178
+ return {
179
+ check_type: 'placeholder_scan',
180
+ status: findings.length > 0 ? 'fail' : 'pass',
181
+ command: 'placeholder-scan',
182
+ exit_code: findings.length > 0 ? 1 : 0,
183
+ stderr_summary: findings.length > 0
184
+ ? `Found ${findings.length} placeholder(s):\n${findings.slice(0, 20).join('\n')}`
185
+ : undefined,
186
+ duration_ms: duration,
187
+ timestamp: new Date().toISOString(),
188
+ };
189
+ }
190
+ function scanDirForPlaceholders(dir, projectDir, allowlist, findings) {
191
+ const codeExts = new Set(['.ts', '.tsx', '.js', '.jsx', '.py', '.go', '.rs']);
192
+ try {
193
+ const entries = readdirSync(dir, { withFileTypes: true });
194
+ for (const entry of entries) {
195
+ if (entry.name.startsWith('.') || entry.name === 'node_modules')
196
+ continue;
197
+ const fullPath = join(dir, entry.name);
198
+ if (entry.isDirectory()) {
199
+ scanDirForPlaceholders(fullPath, projectDir, allowlist, findings);
200
+ }
201
+ else if (codeExts.has(extname(entry.name))) {
202
+ const relativePath = fullPath.replace(projectDir + '/', '');
203
+ if (allowlist.has(relativePath))
204
+ continue;
205
+ try {
206
+ const content = readFileSync(fullPath, 'utf-8');
207
+ const lines = content.split('\n');
208
+ for (let i = 0; i < lines.length; i++) {
209
+ for (const pattern of PLACEHOLDER_PATTERNS) {
210
+ if (pattern.test(lines[i])) {
211
+ findings.push(`${relativePath}:${i + 1}: ${lines[i].trim().slice(0, 80)}`);
212
+ break; // One finding per line
213
+ }
214
+ }
215
+ }
216
+ }
217
+ catch {
218
+ // Skip unreadable files
219
+ }
220
+ }
221
+ }
222
+ }
223
+ catch {
224
+ // Skip unreadable directories
225
+ }
226
+ }
227
+ function loadAllowlist(path) {
228
+ if (!existsSync(path))
229
+ return new Set();
230
+ try {
231
+ const content = readFileSync(path, 'utf-8');
232
+ return new Set(content.split('\n').map((l) => l.trim()).filter((l) => l && !l.startsWith('#')));
233
+ }
234
+ catch {
235
+ return new Set();
236
+ }
237
+ }
238
+ // ─── Start Check (v1.1 Gap #5) ──────────────────────────
239
+ /**
240
+ * Attempt to start the application and verify it does not crash immediately.
241
+ * Optionally checks a health endpoint if a port is detected.
242
+ *
243
+ * Args:
244
+ * startCommand: The command to start the app (e.g., "npm run start").
245
+ * projectDir: Project root directory.
246
+ * options: Optional port, health path, and timeout.
247
+ *
248
+ * Returns:
249
+ * GateCheckResult with pass/fail status.
250
+ */
251
+ export async function runStartCheck(startCommand, projectDir, options) {
252
+ const startTime = Date.now();
253
+ const timeout = options?.timeoutMs ?? 15000;
254
+ // Sanitize command
255
+ const { safe, reason } = sanitizeCommand(startCommand);
256
+ if (!safe) {
257
+ return {
258
+ check_type: 'start',
259
+ status: 'fail',
260
+ command: startCommand,
261
+ exit_code: -1,
262
+ stderr_summary: `Command rejected: ${reason}`,
263
+ duration_ms: 0,
264
+ timestamp: new Date().toISOString(),
265
+ };
266
+ }
267
+ return new Promise((resolve) => {
268
+ let stderr = '';
269
+ let resolved = false;
270
+ const proc = exec(startCommand, {
271
+ cwd: projectDir,
272
+ timeout: timeout + 5000,
273
+ maxBuffer: MAX_OUTPUT_SIZE,
274
+ env: { ...process.env, NODE_ENV: 'production' },
275
+ }, (error, _stdout, stderrOutput) => {
276
+ if (resolved)
277
+ return;
278
+ resolved = true;
279
+ const duration = Date.now() - startTime;
280
+ stderr = stderrOutput ?? '';
281
+ // Process exited — if it exited within timeout, it crashed
282
+ resolve({
283
+ check_type: 'start',
284
+ status: 'fail',
285
+ command: startCommand,
286
+ exit_code: error ? (typeof error.code === 'number'
287
+ ? error.code
288
+ : 1) : 0,
289
+ stderr_summary: stderr ? stderr.slice(0, 2000) : 'Process exited prematurely',
290
+ duration_ms: duration,
291
+ timestamp: new Date().toISOString(),
292
+ });
293
+ });
294
+ // If process survives for the timeout period, consider it passing
295
+ setTimeout(() => {
296
+ if (resolved)
297
+ return;
298
+ resolved = true;
299
+ // Kill the process
300
+ try {
301
+ proc.kill('SIGTERM');
302
+ }
303
+ catch { /* already dead */ }
304
+ const duration = Date.now() - startTime;
305
+ resolve({
306
+ check_type: 'start',
307
+ status: 'pass',
308
+ command: startCommand,
309
+ exit_code: 0,
310
+ stderr_summary: stderr ? stderr.slice(0, 500) : undefined,
311
+ duration_ms: duration,
312
+ timestamp: new Date().toISOString(),
313
+ });
314
+ }, timeout);
315
+ });
316
+ }
317
+ // ─── Env Check (v1.1 Gap #5) ────────────────────────────
318
+ /**
319
+ * Validate that required environment variables exist.
320
+ * Reads .env.example for required var names and checks .env has them set.
321
+ *
322
+ * Args:
323
+ * projectDir: Project root directory.
324
+ * _snapshot: Repo snapshot (for future use).
325
+ *
326
+ * Returns:
327
+ * GateCheckResult with pass/fail status.
328
+ */
329
+ export function runEnvCheck(projectDir, _snapshot) {
330
+ const startTime = Date.now();
331
+ const examplePath = join(projectDir, '.env.example');
332
+ const envPath = join(projectDir, '.env');
333
+ const missingVars = [];
334
+ const emptyVars = [];
335
+ // If no .env.example, skip check
336
+ if (!existsSync(examplePath)) {
337
+ return {
338
+ check_type: 'env_check',
339
+ status: 'pass',
340
+ command: 'env-check',
341
+ exit_code: 0,
342
+ stderr_summary: 'No .env.example found — skipping env validation',
343
+ duration_ms: Date.now() - startTime,
344
+ timestamp: new Date().toISOString(),
345
+ };
346
+ }
347
+ // Parse .env.example for required var names
348
+ const exampleContent = readFileSync(examplePath, 'utf-8');
349
+ const requiredVars = parseEnvVarNames(exampleContent);
350
+ // Check .env exists
351
+ if (!existsSync(envPath)) {
352
+ return {
353
+ check_type: 'env_check',
354
+ status: 'fail',
355
+ command: 'env-check',
356
+ exit_code: 1,
357
+ stderr_summary: `.env file not found. Required vars from .env.example: ${requiredVars.join(', ')}`,
358
+ duration_ms: Date.now() - startTime,
359
+ timestamp: new Date().toISOString(),
360
+ };
361
+ }
362
+ // Parse .env and check all required vars are present and non-empty
363
+ const envContent = readFileSync(envPath, 'utf-8');
364
+ const envVars = parseEnvVarValues(envContent);
365
+ for (const varName of requiredVars) {
366
+ if (!(varName in envVars)) {
367
+ missingVars.push(varName);
368
+ }
369
+ else if (!envVars[varName]) {
370
+ emptyVars.push(varName);
371
+ }
372
+ }
373
+ const duration = Date.now() - startTime;
374
+ const hasFail = missingVars.length > 0;
375
+ const summaryParts = [];
376
+ if (missingVars.length > 0) {
377
+ summaryParts.push(`Missing vars: ${missingVars.join(', ')}`);
378
+ }
379
+ if (emptyVars.length > 0) {
380
+ summaryParts.push(`Empty vars (warning): ${emptyVars.join(', ')}`);
381
+ }
382
+ return {
383
+ check_type: 'env_check',
384
+ status: hasFail ? 'fail' : 'pass',
385
+ command: 'env-check',
386
+ exit_code: hasFail ? 1 : 0,
387
+ stderr_summary: summaryParts.length > 0 ? summaryParts.join('; ') : undefined,
388
+ duration_ms: duration,
389
+ timestamp: new Date().toISOString(),
390
+ };
391
+ }
392
+ /** Parse env var names from .env.example (lines like KEY=value or KEY=) */
393
+ function parseEnvVarNames(content) {
394
+ return content
395
+ .split('\n')
396
+ .map((line) => line.trim())
397
+ .filter((line) => line && !line.startsWith('#'))
398
+ .map((line) => line.split('=')[0].trim())
399
+ .filter((name) => name.length > 0);
400
+ }
401
+ /** Parse env vars into key-value map from .env content */
402
+ function parseEnvVarValues(content) {
403
+ const vars = {};
404
+ for (const line of content.split('\n')) {
405
+ const trimmed = line.trim();
406
+ if (!trimmed || trimmed.startsWith('#'))
407
+ continue;
408
+ const eqIndex = trimmed.indexOf('=');
409
+ if (eqIndex === -1)
410
+ continue;
411
+ const key = trimmed.slice(0, eqIndex).trim();
412
+ const value = trimmed.slice(eqIndex + 1).trim().replace(/^["']|["']$/g, '');
413
+ vars[key] = value;
414
+ }
415
+ return vars;
416
+ }
417
+ //# sourceMappingURL=check-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-runner.js","sourceRoot":"","sources":["../../src/pipeline/check-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Command Resolver — detects project-type-specific build/test/lint/typecheck
3
+ * commands from a RepoSnapshot. Used by CheckRunner and ProductionGate.
4
+ */
5
+ import type { RepoSnapshot, ResolvedCommands } from './types.js';
6
+ export type ProjectType = 'node' | 'python' | 'mixed' | 'unknown';
7
+ export declare function detectProjectType(snapshot: RepoSnapshot): ProjectType;
8
+ export declare function resolveCommands(snapshot: RepoSnapshot, overrides?: Partial<ResolvedCommands>): ResolvedCommands;
9
+ //# sourceMappingURL=command-resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-resolver.d.ts","sourceRoot":"","sources":["../../src/pipeline/command-resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAIjE,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,CAAC;AAElE,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,WAAW,CAUrE;AAID,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,YAAY,EACtB,SAAS,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,GACpC,gBAAgB,CAqClB"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Command Resolver — detects project-type-specific build/test/lint/typecheck
3
+ * commands from a RepoSnapshot. Used by CheckRunner and ProductionGate.
4
+ */
5
+ export function detectProjectType(snapshot) {
6
+ const hasNode = snapshot.config_files.some((c) => c.type === 'package.json');
7
+ const hasPython = snapshot.config_files.some((c) => c.type === 'pyproject.toml' || c.type === 'requirements.txt' || c.type === 'setup.py');
8
+ if (hasNode && hasPython)
9
+ return 'mixed';
10
+ if (hasNode)
11
+ return 'node';
12
+ if (hasPython)
13
+ return 'python';
14
+ return 'unknown';
15
+ }
16
+ // ─── Command Resolution ──────────────────────────────────
17
+ export function resolveCommands(snapshot, overrides) {
18
+ const projectType = detectProjectType(snapshot);
19
+ const pm = snapshot.package_manager ?? 'npm';
20
+ const scripts = snapshot.scripts;
21
+ let resolved;
22
+ switch (projectType) {
23
+ case 'node':
24
+ resolved = resolveNodeCommands(pm, scripts, snapshot);
25
+ break;
26
+ case 'python':
27
+ resolved = resolvePythonCommands(snapshot);
28
+ break;
29
+ case 'mixed':
30
+ // Prefer Node commands, augment with Python where Node is missing
31
+ resolved = resolveNodeCommands(pm, scripts, snapshot);
32
+ if (!resolved.test) {
33
+ const pyResolved = resolvePythonCommands(snapshot);
34
+ resolved.test = pyResolved.test;
35
+ }
36
+ break;
37
+ default:
38
+ resolved = { resolved_from: 'none' };
39
+ }
40
+ // Apply overrides
41
+ if (overrides) {
42
+ if (overrides.build)
43
+ resolved.build = overrides.build;
44
+ if (overrides.test)
45
+ resolved.test = overrides.test;
46
+ if (overrides.lint)
47
+ resolved.lint = overrides.lint;
48
+ if (overrides.typecheck)
49
+ resolved.typecheck = overrides.typecheck;
50
+ if (overrides.migrations)
51
+ resolved.migrations = overrides.migrations;
52
+ if (overrides.start)
53
+ resolved.start = overrides.start;
54
+ }
55
+ return resolved;
56
+ }
57
+ // ─── Node Resolution ─────────────────────────────────────
58
+ function resolveNodeCommands(pm, scripts, snapshot) {
59
+ const run = pm === 'yarn' ? 'yarn' : pm === 'pnpm' ? 'pnpm' : `${pm} run`;
60
+ const npx = pm === 'pnpm' ? 'pnpm exec' : pm === 'yarn' ? 'yarn' : 'npx';
61
+ const resolved = {
62
+ resolved_from: 'package.json',
63
+ };
64
+ // Build
65
+ if (scripts.build) {
66
+ resolved.build = `${run} build`;
67
+ }
68
+ // Test
69
+ if (scripts.test) {
70
+ resolved.test = `${run} test`;
71
+ }
72
+ else if (snapshot.test_framework === 'vitest') {
73
+ resolved.test = `${npx} vitest run`;
74
+ }
75
+ else if (snapshot.test_framework === 'jest') {
76
+ resolved.test = `${npx} jest`;
77
+ }
78
+ // Lint
79
+ if (scripts.lint) {
80
+ resolved.lint = `${run} lint`;
81
+ }
82
+ // Typecheck
83
+ if (scripts.typecheck) {
84
+ resolved.typecheck = `${run} typecheck`;
85
+ }
86
+ else if (snapshot.languages_detected.includes('typescript')) {
87
+ resolved.typecheck = `${npx} tsc --noEmit`;
88
+ }
89
+ // Migrations
90
+ const hasPrisma = snapshot.config_files.some((c) => c.type === 'prisma/schema.prisma');
91
+ if (hasPrisma) {
92
+ resolved.migrations = `${npx} prisma migrate deploy`;
93
+ }
94
+ // Start
95
+ if (scripts.start) {
96
+ resolved.start = `${run} start`;
97
+ }
98
+ else if (scripts.dev) {
99
+ resolved.start = `${run} dev`;
100
+ }
101
+ return resolved;
102
+ }
103
+ // ─── Python Resolution ───────────────────────────────────
104
+ function resolvePythonCommands(snapshot) {
105
+ const resolved = {
106
+ resolved_from: snapshot.config_files
107
+ .find((c) => c.type === 'pyproject.toml' || c.type === 'requirements.txt')
108
+ ?.path ?? 'python-defaults',
109
+ };
110
+ // Test
111
+ if (snapshot.test_framework === 'pytest') {
112
+ resolved.test = 'pytest tests/';
113
+ }
114
+ else {
115
+ resolved.test = 'pytest tests/'; // default for Python
116
+ }
117
+ // Lint
118
+ const hasPyproject = snapshot.config_files.some((c) => c.type === 'pyproject.toml');
119
+ if (hasPyproject) {
120
+ resolved.lint = 'ruff check .';
121
+ }
122
+ else {
123
+ resolved.lint = 'flake8 src/';
124
+ }
125
+ // Typecheck
126
+ if (snapshot.languages_detected.includes('python')) {
127
+ resolved.typecheck = 'mypy src/';
128
+ }
129
+ // Build
130
+ resolved.build = 'python -m build';
131
+ // Migrations
132
+ const hasAlembic = snapshot.config_files.some((c) => c.type === 'alembic.ini');
133
+ if (hasAlembic) {
134
+ resolved.migrations = 'alembic upgrade head';
135
+ }
136
+ // Start
137
+ resolved.start = 'uvicorn main:app --host 0.0.0.0 --port 8000';
138
+ return resolved;
139
+ }
140
+ //# sourceMappingURL=command-resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command-resolver.js","sourceRoot":"","sources":["../../src/pipeline/command-resolver.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Consensus Runner — adapter layer between structured packets
3
+ * and existing consensus machinery.
4
+ *
5
+ * Two modes (P1-D):
6
+ * 1. Independent Review (DEFAULT): N reviewers review simultaneously,
7
+ * no reviewer sees other reviewers' output.
8
+ * 2. Iterative Consensus (optional): for recovery plan iteration.
9
+ */
10
+ import type { PlanPacket, ConsensusPacket, ReviewerVote } from '../types.js';
11
+ import type { GateDefinition } from '../gate-engine.js';
12
+ import type { ConsensusConfig } from '../../types/consensus.js';
13
+ export interface ConsensusRunnerConfig {
14
+ mode: 'independent' | 'iterative';
15
+ minReviewers: number;
16
+ threshold: number;
17
+ quorum: number;
18
+ projectDir: string;
19
+ consensusConfig?: Partial<ConsensusConfig>;
20
+ /** Provider configurations for multi-LLM review */
21
+ reviewerProviders?: ReviewerProviderConfig[];
22
+ }
23
+ export interface ReviewerProviderConfig {
24
+ provider: string;
25
+ model: string;
26
+ temperature: number;
27
+ }
28
+ export declare class ConsensusRunner {
29
+ private readonly config;
30
+ constructor(config: ConsensusRunnerConfig);
31
+ /** Run structured consensus on a plan packet */
32
+ runStructuredConsensus(planPacket: PlanPacket, gateDefinition: GateDefinition): Promise<ConsensusPacket>;
33
+ /** Independent review: spawn N reviewers, each reviews independently */
34
+ runIndependentReview(planPacket: PlanPacket): Promise<ReviewerVote[]>;
35
+ /** Iterative review: wraps existing iterateUntilConsensus */
36
+ runIterativeReview(planPacket: PlanPacket): Promise<ReviewerVote[]>;
37
+ /** Spawn a single independent reviewer */
38
+ private spawnSingleReviewer;
39
+ /** Call the appropriate provider adapter for a review */
40
+ private callProviderForReview;
41
+ }
42
+ export declare function buildReviewPrompt(planPacket: PlanPacket): string;
43
+ export declare function createConsensusRunner(projectDir: string, consensusConfig?: Partial<ConsensusConfig>): ConsensusRunner;
44
+ //# sourceMappingURL=consensus-runner.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consensus-runner.d.ts","sourceRoot":"","sources":["../../../src/pipeline/consensus/consensus-runner.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EACV,UAAU,EACV,eAAe,EACf,YAAY,EACb,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAMxD,OAAO,KAAK,EAAE,eAAe,EAAmB,MAAM,0BAA0B,CAAC;AAIjF,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,aAAa,GAAG,WAAW,CAAC;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAC3C,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,sBAAsB,EAAE,CAAC;CAC9C;AAED,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AASD,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAwB;gBAEnC,MAAM,EAAE,qBAAqB;IAIzC,gDAAgD;IAC1C,sBAAsB,CAC1B,UAAU,EAAE,UAAU,EACtB,cAAc,EAAE,cAAc,GAC7B,OAAO,CAAC,eAAe,CAAC;IA+B3B,wEAAwE;IAClE,oBAAoB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IA4B3E,6DAA6D;IACvD,kBAAkB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IA4CzE,0CAA0C;YAC5B,mBAAmB;IAqCjC,yDAAyD;YAC3C,qBAAqB;CAiCpC;AAsBD,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,UAAU,GAAG,MAAM,CAuChE;AAID,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,eAAe,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,GACzC,eAAe,CASjB"}