steroids-api 0.2.7

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 (328) hide show
  1. package/dist/API/src/index.d.ts +10 -0
  2. package/dist/API/src/index.d.ts.map +1 -0
  3. package/dist/API/src/index.js +130 -0
  4. package/dist/API/src/index.js.map +1 -0
  5. package/dist/API/src/routes/activity.d.ts +7 -0
  6. package/dist/API/src/routes/activity.d.ts.map +1 -0
  7. package/dist/API/src/routes/activity.js +252 -0
  8. package/dist/API/src/routes/activity.js.map +1 -0
  9. package/dist/API/src/routes/config.d.ts +7 -0
  10. package/dist/API/src/routes/config.d.ts.map +1 -0
  11. package/dist/API/src/routes/config.js +521 -0
  12. package/dist/API/src/routes/config.js.map +1 -0
  13. package/dist/API/src/routes/health.d.ts +7 -0
  14. package/dist/API/src/routes/health.d.ts.map +1 -0
  15. package/dist/API/src/routes/health.js +172 -0
  16. package/dist/API/src/routes/health.js.map +1 -0
  17. package/dist/API/src/routes/incidents.d.ts +7 -0
  18. package/dist/API/src/routes/incidents.d.ts.map +1 -0
  19. package/dist/API/src/routes/incidents.js +117 -0
  20. package/dist/API/src/routes/incidents.js.map +1 -0
  21. package/dist/API/src/routes/projects.d.ts +7 -0
  22. package/dist/API/src/routes/projects.d.ts.map +1 -0
  23. package/dist/API/src/routes/projects.js +398 -0
  24. package/dist/API/src/routes/projects.js.map +1 -0
  25. package/dist/API/src/routes/runners.d.ts +7 -0
  26. package/dist/API/src/routes/runners.d.ts.map +1 -0
  27. package/dist/API/src/routes/runners.js +242 -0
  28. package/dist/API/src/routes/runners.js.map +1 -0
  29. package/dist/API/src/routes/tasks.d.ts +7 -0
  30. package/dist/API/src/routes/tasks.d.ts.map +1 -0
  31. package/dist/API/src/routes/tasks.js +1007 -0
  32. package/dist/API/src/routes/tasks.js.map +1 -0
  33. package/dist/API/src/utils/validation.d.ts +22 -0
  34. package/dist/API/src/utils/validation.d.ts.map +1 -0
  35. package/dist/API/src/utils/validation.js +50 -0
  36. package/dist/API/src/utils/validation.js.map +1 -0
  37. package/dist/index.d.ts +10 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +184 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/routes/activity.d.ts +7 -0
  42. package/dist/routes/activity.d.ts.map +1 -0
  43. package/dist/routes/activity.js +252 -0
  44. package/dist/routes/activity.js.map +1 -0
  45. package/dist/routes/config.d.ts +7 -0
  46. package/dist/routes/config.d.ts.map +1 -0
  47. package/dist/routes/config.js +647 -0
  48. package/dist/routes/config.js.map +1 -0
  49. package/dist/routes/credit-alerts.d.ts +2 -0
  50. package/dist/routes/credit-alerts.d.ts.map +1 -0
  51. package/dist/routes/credit-alerts.js +97 -0
  52. package/dist/routes/credit-alerts.js.map +1 -0
  53. package/dist/routes/health.d.ts +7 -0
  54. package/dist/routes/health.d.ts.map +1 -0
  55. package/dist/routes/health.js +200 -0
  56. package/dist/routes/health.js.map +1 -0
  57. package/dist/routes/incidents.d.ts +7 -0
  58. package/dist/routes/incidents.d.ts.map +1 -0
  59. package/dist/routes/incidents.js +117 -0
  60. package/dist/routes/incidents.js.map +1 -0
  61. package/dist/routes/projects.d.ts +7 -0
  62. package/dist/routes/projects.d.ts.map +1 -0
  63. package/dist/routes/projects.js +643 -0
  64. package/dist/routes/projects.js.map +1 -0
  65. package/dist/routes/runners.d.ts +7 -0
  66. package/dist/routes/runners.d.ts.map +1 -0
  67. package/dist/routes/runners.js +299 -0
  68. package/dist/routes/runners.js.map +1 -0
  69. package/dist/routes/skills.d.ts +3 -0
  70. package/dist/routes/skills.d.ts.map +1 -0
  71. package/dist/routes/skills.js +109 -0
  72. package/dist/routes/skills.js.map +1 -0
  73. package/dist/routes/storage.d.ts +7 -0
  74. package/dist/routes/storage.d.ts.map +1 -0
  75. package/dist/routes/storage.js +93 -0
  76. package/dist/routes/storage.js.map +1 -0
  77. package/dist/routes/tasks.d.ts +7 -0
  78. package/dist/routes/tasks.d.ts.map +1 -0
  79. package/dist/routes/tasks.js +1145 -0
  80. package/dist/routes/tasks.js.map +1 -0
  81. package/dist/src/cleanup/invocation-logs.d.ts +30 -0
  82. package/dist/src/cleanup/invocation-logs.d.ts.map +1 -0
  83. package/dist/src/cleanup/invocation-logs.js +66 -0
  84. package/dist/src/cleanup/invocation-logs.js.map +1 -0
  85. package/dist/src/commands/loop-phases.d.ts +11 -0
  86. package/dist/src/commands/loop-phases.d.ts.map +1 -0
  87. package/dist/src/commands/loop-phases.js +304 -0
  88. package/dist/src/commands/loop-phases.js.map +1 -0
  89. package/dist/src/config/loader.d.ts +160 -0
  90. package/dist/src/config/loader.d.ts.map +1 -0
  91. package/dist/src/config/loader.js +276 -0
  92. package/dist/src/config/loader.js.map +1 -0
  93. package/dist/src/database/connection.d.ts +35 -0
  94. package/dist/src/database/connection.d.ts.map +1 -0
  95. package/dist/src/database/connection.js +197 -0
  96. package/dist/src/database/connection.js.map +1 -0
  97. package/dist/src/database/queries.d.ts +220 -0
  98. package/dist/src/database/queries.d.ts.map +1 -0
  99. package/dist/src/database/queries.js +589 -0
  100. package/dist/src/database/queries.js.map +1 -0
  101. package/dist/src/database/schema.d.ts +8 -0
  102. package/dist/src/database/schema.d.ts.map +1 -0
  103. package/dist/src/database/schema.js +184 -0
  104. package/dist/src/database/schema.js.map +1 -0
  105. package/dist/src/git/push.d.ts +26 -0
  106. package/dist/src/git/push.d.ts.map +1 -0
  107. package/dist/src/git/push.js +91 -0
  108. package/dist/src/git/push.js.map +1 -0
  109. package/dist/src/git/status.d.ts +83 -0
  110. package/dist/src/git/status.d.ts.map +1 -0
  111. package/dist/src/git/status.js +315 -0
  112. package/dist/src/git/status.js.map +1 -0
  113. package/dist/src/health/stuck-task-detector.d.ts +131 -0
  114. package/dist/src/health/stuck-task-detector.d.ts.map +1 -0
  115. package/dist/src/health/stuck-task-detector.js +233 -0
  116. package/dist/src/health/stuck-task-detector.js.map +1 -0
  117. package/dist/src/health/stuck-task-recovery.d.ts +45 -0
  118. package/dist/src/health/stuck-task-recovery.d.ts.map +1 -0
  119. package/dist/src/health/stuck-task-recovery.js +309 -0
  120. package/dist/src/health/stuck-task-recovery.js.map +1 -0
  121. package/dist/src/index.d.ts +10 -0
  122. package/dist/src/index.d.ts.map +1 -0
  123. package/dist/src/index.js +130 -0
  124. package/dist/src/index.js.map +1 -0
  125. package/dist/src/locking/queries.d.ts +116 -0
  126. package/dist/src/locking/queries.d.ts.map +1 -0
  127. package/dist/src/locking/queries.js +232 -0
  128. package/dist/src/locking/queries.js.map +1 -0
  129. package/dist/src/locking/section-lock.d.ts +74 -0
  130. package/dist/src/locking/section-lock.d.ts.map +1 -0
  131. package/dist/src/locking/section-lock.js +196 -0
  132. package/dist/src/locking/section-lock.js.map +1 -0
  133. package/dist/src/locking/task-lock.d.ts +92 -0
  134. package/dist/src/locking/task-lock.d.ts.map +1 -0
  135. package/dist/src/locking/task-lock.js +233 -0
  136. package/dist/src/locking/task-lock.js.map +1 -0
  137. package/dist/src/migrations/index.d.ts +7 -0
  138. package/dist/src/migrations/index.d.ts.map +1 -0
  139. package/dist/src/migrations/index.js +9 -0
  140. package/dist/src/migrations/index.js.map +1 -0
  141. package/dist/src/migrations/manifest.d.ts +92 -0
  142. package/dist/src/migrations/manifest.d.ts.map +1 -0
  143. package/dist/src/migrations/manifest.js +255 -0
  144. package/dist/src/migrations/manifest.js.map +1 -0
  145. package/dist/src/migrations/runner.d.ts +84 -0
  146. package/dist/src/migrations/runner.d.ts.map +1 -0
  147. package/dist/src/migrations/runner.js +338 -0
  148. package/dist/src/migrations/runner.js.map +1 -0
  149. package/dist/src/orchestrator/coder.d.ts +32 -0
  150. package/dist/src/orchestrator/coder.d.ts.map +1 -0
  151. package/dist/src/orchestrator/coder.js +170 -0
  152. package/dist/src/orchestrator/coder.js.map +1 -0
  153. package/dist/src/orchestrator/coordinator.d.ts +28 -0
  154. package/dist/src/orchestrator/coordinator.d.ts.map +1 -0
  155. package/dist/src/orchestrator/coordinator.js +252 -0
  156. package/dist/src/orchestrator/coordinator.js.map +1 -0
  157. package/dist/src/orchestrator/fallback-handler.d.ts +24 -0
  158. package/dist/src/orchestrator/fallback-handler.d.ts.map +1 -0
  159. package/dist/src/orchestrator/fallback-handler.js +280 -0
  160. package/dist/src/orchestrator/fallback-handler.js.map +1 -0
  161. package/dist/src/orchestrator/invoke.d.ts +14 -0
  162. package/dist/src/orchestrator/invoke.d.ts.map +1 -0
  163. package/dist/src/orchestrator/invoke.js +76 -0
  164. package/dist/src/orchestrator/invoke.js.map +1 -0
  165. package/dist/src/orchestrator/post-coder.d.ts +10 -0
  166. package/dist/src/orchestrator/post-coder.d.ts.map +1 -0
  167. package/dist/src/orchestrator/post-coder.js +198 -0
  168. package/dist/src/orchestrator/post-coder.js.map +1 -0
  169. package/dist/src/orchestrator/post-reviewer.d.ts +10 -0
  170. package/dist/src/orchestrator/post-reviewer.d.ts.map +1 -0
  171. package/dist/src/orchestrator/post-reviewer.js +199 -0
  172. package/dist/src/orchestrator/post-reviewer.js.map +1 -0
  173. package/dist/src/orchestrator/reviewer.d.ts +35 -0
  174. package/dist/src/orchestrator/reviewer.d.ts.map +1 -0
  175. package/dist/src/orchestrator/reviewer.js +237 -0
  176. package/dist/src/orchestrator/reviewer.js.map +1 -0
  177. package/dist/src/orchestrator/schemas.d.ts +10 -0
  178. package/dist/src/orchestrator/schemas.d.ts.map +1 -0
  179. package/dist/src/orchestrator/schemas.js +81 -0
  180. package/dist/src/orchestrator/schemas.js.map +1 -0
  181. package/dist/src/orchestrator/task-selector.d.ts +102 -0
  182. package/dist/src/orchestrator/task-selector.d.ts.map +1 -0
  183. package/dist/src/orchestrator/task-selector.js +326 -0
  184. package/dist/src/orchestrator/task-selector.js.map +1 -0
  185. package/dist/src/orchestrator/types.d.ts +74 -0
  186. package/dist/src/orchestrator/types.d.ts.map +1 -0
  187. package/dist/src/orchestrator/types.js +5 -0
  188. package/dist/src/orchestrator/types.js.map +1 -0
  189. package/dist/src/prompts/coder.d.ts +36 -0
  190. package/dist/src/prompts/coder.d.ts.map +1 -0
  191. package/dist/src/prompts/coder.js +303 -0
  192. package/dist/src/prompts/coder.js.map +1 -0
  193. package/dist/src/prompts/prompt-helpers.d.ts +51 -0
  194. package/dist/src/prompts/prompt-helpers.d.ts.map +1 -0
  195. package/dist/src/prompts/prompt-helpers.js +299 -0
  196. package/dist/src/prompts/prompt-helpers.js.map +1 -0
  197. package/dist/src/prompts/reviewer.d.ts +40 -0
  198. package/dist/src/prompts/reviewer.d.ts.map +1 -0
  199. package/dist/src/prompts/reviewer.js +416 -0
  200. package/dist/src/prompts/reviewer.js.map +1 -0
  201. package/dist/src/providers/claude.d.ts +53 -0
  202. package/dist/src/providers/claude.d.ts.map +1 -0
  203. package/dist/src/providers/claude.js +227 -0
  204. package/dist/src/providers/claude.js.map +1 -0
  205. package/dist/src/providers/codex.d.ts +53 -0
  206. package/dist/src/providers/codex.d.ts.map +1 -0
  207. package/dist/src/providers/codex.js +253 -0
  208. package/dist/src/providers/codex.js.map +1 -0
  209. package/dist/src/providers/gemini.d.ts +58 -0
  210. package/dist/src/providers/gemini.d.ts.map +1 -0
  211. package/dist/src/providers/gemini.js +240 -0
  212. package/dist/src/providers/gemini.js.map +1 -0
  213. package/dist/src/providers/interface.d.ts +185 -0
  214. package/dist/src/providers/interface.d.ts.map +1 -0
  215. package/dist/src/providers/interface.js +92 -0
  216. package/dist/src/providers/interface.js.map +1 -0
  217. package/dist/src/providers/invocation-logger.d.ts +97 -0
  218. package/dist/src/providers/invocation-logger.d.ts.map +1 -0
  219. package/dist/src/providers/invocation-logger.js +378 -0
  220. package/dist/src/providers/invocation-logger.js.map +1 -0
  221. package/dist/src/providers/openai.d.ts +53 -0
  222. package/dist/src/providers/openai.d.ts.map +1 -0
  223. package/dist/src/providers/openai.js +230 -0
  224. package/dist/src/providers/openai.js.map +1 -0
  225. package/dist/src/providers/registry.d.ts +100 -0
  226. package/dist/src/providers/registry.d.ts.map +1 -0
  227. package/dist/src/providers/registry.js +170 -0
  228. package/dist/src/providers/registry.js.map +1 -0
  229. package/dist/src/routes/activity.d.ts +7 -0
  230. package/dist/src/routes/activity.d.ts.map +1 -0
  231. package/dist/src/routes/activity.js +252 -0
  232. package/dist/src/routes/activity.js.map +1 -0
  233. package/dist/src/routes/config.d.ts +7 -0
  234. package/dist/src/routes/config.d.ts.map +1 -0
  235. package/dist/src/routes/config.js +521 -0
  236. package/dist/src/routes/config.js.map +1 -0
  237. package/dist/src/routes/health.d.ts +7 -0
  238. package/dist/src/routes/health.d.ts.map +1 -0
  239. package/dist/src/routes/health.js +172 -0
  240. package/dist/src/routes/health.js.map +1 -0
  241. package/dist/src/routes/incidents.d.ts +7 -0
  242. package/dist/src/routes/incidents.d.ts.map +1 -0
  243. package/dist/src/routes/incidents.js +117 -0
  244. package/dist/src/routes/incidents.js.map +1 -0
  245. package/dist/src/routes/projects.d.ts +7 -0
  246. package/dist/src/routes/projects.d.ts.map +1 -0
  247. package/dist/src/routes/projects.js +398 -0
  248. package/dist/src/routes/projects.js.map +1 -0
  249. package/dist/src/routes/runners.d.ts +7 -0
  250. package/dist/src/routes/runners.d.ts.map +1 -0
  251. package/dist/src/routes/runners.js +242 -0
  252. package/dist/src/routes/runners.js.map +1 -0
  253. package/dist/src/routes/tasks.d.ts +7 -0
  254. package/dist/src/routes/tasks.d.ts.map +1 -0
  255. package/dist/src/routes/tasks.js +1007 -0
  256. package/dist/src/routes/tasks.js.map +1 -0
  257. package/dist/src/runners/activity-log.d.ts +65 -0
  258. package/dist/src/runners/activity-log.d.ts.map +1 -0
  259. package/dist/src/runners/activity-log.js +140 -0
  260. package/dist/src/runners/activity-log.js.map +1 -0
  261. package/dist/src/runners/cron.d.ts +30 -0
  262. package/dist/src/runners/cron.d.ts.map +1 -0
  263. package/dist/src/runners/cron.js +333 -0
  264. package/dist/src/runners/cron.js.map +1 -0
  265. package/dist/src/runners/daemon.d.ts +71 -0
  266. package/dist/src/runners/daemon.d.ts.map +1 -0
  267. package/dist/src/runners/daemon.js +233 -0
  268. package/dist/src/runners/daemon.js.map +1 -0
  269. package/dist/src/runners/global-db.d.ts +31 -0
  270. package/dist/src/runners/global-db.d.ts.map +1 -0
  271. package/dist/src/runners/global-db.js +220 -0
  272. package/dist/src/runners/global-db.js.map +1 -0
  273. package/dist/src/runners/hang-detector.d.ts +38 -0
  274. package/dist/src/runners/hang-detector.d.ts.map +1 -0
  275. package/dist/src/runners/hang-detector.js +130 -0
  276. package/dist/src/runners/hang-detector.js.map +1 -0
  277. package/dist/src/runners/heartbeat.d.ts +39 -0
  278. package/dist/src/runners/heartbeat.d.ts.map +1 -0
  279. package/dist/src/runners/heartbeat.js +71 -0
  280. package/dist/src/runners/heartbeat.js.map +1 -0
  281. package/dist/src/runners/lock.d.ts +47 -0
  282. package/dist/src/runners/lock.d.ts.map +1 -0
  283. package/dist/src/runners/lock.js +140 -0
  284. package/dist/src/runners/lock.js.map +1 -0
  285. package/dist/src/runners/orchestrator-loop.d.ts +20 -0
  286. package/dist/src/runners/orchestrator-loop.d.ts.map +1 -0
  287. package/dist/src/runners/orchestrator-loop.js +208 -0
  288. package/dist/src/runners/orchestrator-loop.js.map +1 -0
  289. package/dist/src/runners/projects.d.ts +96 -0
  290. package/dist/src/runners/projects.d.ts.map +1 -0
  291. package/dist/src/runners/projects.js +243 -0
  292. package/dist/src/runners/projects.js.map +1 -0
  293. package/dist/src/runners/wakeup.d.ts +37 -0
  294. package/dist/src/runners/wakeup.d.ts.map +1 -0
  295. package/dist/src/runners/wakeup.js +355 -0
  296. package/dist/src/runners/wakeup.js.map +1 -0
  297. package/dist/src/utils/validation.d.ts +22 -0
  298. package/dist/src/utils/validation.d.ts.map +1 -0
  299. package/dist/src/utils/validation.js +50 -0
  300. package/dist/src/utils/validation.js.map +1 -0
  301. package/dist/utils/sqlite.d.ts +17 -0
  302. package/dist/utils/sqlite.d.ts.map +1 -0
  303. package/dist/utils/sqlite.js +27 -0
  304. package/dist/utils/sqlite.js.map +1 -0
  305. package/dist/utils/storage-cache.d.ts +33 -0
  306. package/dist/utils/storage-cache.d.ts.map +1 -0
  307. package/dist/utils/storage-cache.js +81 -0
  308. package/dist/utils/storage-cache.js.map +1 -0
  309. package/dist/utils/validation.d.ts +22 -0
  310. package/dist/utils/validation.d.ts.map +1 -0
  311. package/dist/utils/validation.js +51 -0
  312. package/dist/utils/validation.js.map +1 -0
  313. package/package.json +39 -0
  314. package/src/index.ts +199 -0
  315. package/src/routes/activity.ts +302 -0
  316. package/src/routes/config.ts +723 -0
  317. package/src/routes/credit-alerts.ts +73 -0
  318. package/src/routes/health.ts +219 -0
  319. package/src/routes/incidents.ts +131 -0
  320. package/src/routes/projects.ts +854 -0
  321. package/src/routes/runners.ts +357 -0
  322. package/src/routes/skills.ts +127 -0
  323. package/src/routes/storage.ts +108 -0
  324. package/src/routes/tasks.ts +1372 -0
  325. package/src/utils/sqlite.ts +36 -0
  326. package/src/utils/storage-cache.ts +107 -0
  327. package/src/utils/validation.ts +61 -0
  328. package/tsconfig.json +20 -0
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Post-Reviewer Orchestrator
3
+ * Analyzes reviewer output and decides task outcome
4
+ */
5
+ /**
6
+ * Generate post-reviewer orchestrator prompt
7
+ */
8
+ export function buildPostReviewerPrompt(context) {
9
+ const { task, reviewer_output: { stdout, stderr, exit_code, timed_out, duration_ms }, git_context: { commit_sha, files_changed, additions, deletions } } = context;
10
+ const duration_seconds = (duration_ms / 1000).toFixed(1);
11
+ const stdout_tail = stdout.slice(-2000);
12
+ const stderr_tail = stderr.slice(-2000);
13
+ let stderrSection = '';
14
+ if (stderr) {
15
+ stderrSection = `
16
+ **Errors:**
17
+ \`\`\`
18
+ ${stderr_tail}
19
+ \`\`\`
20
+ `;
21
+ }
22
+ return `# POST-REVIEWER ORCHESTRATOR
23
+
24
+ You are a state machine that analyzes reviewer output and determines the next action.
25
+
26
+ **CRITICAL: You MUST respond ONLY with valid JSON. No markdown, no other text.**
27
+
28
+ ---
29
+
30
+ ## Task Context
31
+
32
+ **Task ID:** ${task.id}
33
+ **Task Title:** ${task.title}
34
+ **Rejection Count:** ${task.rejection_count}/15
35
+
36
+ ---
37
+
38
+ ## Reviewer Execution
39
+
40
+ **Exit Code:** ${exit_code}
41
+ **Timed Out:** ${timed_out}
42
+ **Duration:** ${duration_seconds}s
43
+
44
+ **Output (last 2000 chars):**
45
+ \`\`\`
46
+ ${stdout_tail}
47
+ \`\`\`
48
+ ${stderrSection}
49
+ ---
50
+
51
+ ## Git Diff
52
+
53
+ **Commit:** ${commit_sha}
54
+ **Files Changed:** ${files_changed.length}
55
+ **Lines:** +${additions} -${deletions}
56
+
57
+ ---
58
+
59
+ ## Decision Rules
60
+
61
+ ### 1. Clear Approval
62
+ - Output contains "APPROVE" / "LGTM" / "looks good" → \`approve\`
63
+ - Exit 0 + positive language + no rejection phrases → \`approve\`
64
+
65
+ ### 2. Clear Rejection
66
+ - Output contains "REJECT" / "needs work" / "issues found" → \`reject\`
67
+ - Output lists specific problems/feedback → \`reject\`
68
+
69
+ ### 3. Dispute
70
+ - Output contains "DISPUTE" / "fundamental disagreement" → \`dispute\`
71
+ - Rejection count >= 10 AND same issue repeated → \`dispute\`
72
+ - Output mentions "out of scope" / "architectural disagreement" → \`dispute\`
73
+
74
+ ### 4. Skip
75
+ - Output contains "SKIP" / "external setup required" → \`skip\`
76
+ - Output says "nothing to review" / "no code changes needed" → \`skip\`
77
+
78
+ ### 5. Unclear
79
+ - Exit 0 but no clear decision words → \`unclear\`
80
+ - Timeout → \`unclear\`
81
+ - Stderr has errors → \`unclear\`
82
+
83
+ ### 6. Rejection Threshold
84
+ - Rejection count = 15 → automatically \`dispute\` (prevent infinite loops)
85
+
86
+ ---
87
+
88
+ ## Output Format (JSON ONLY)
89
+
90
+ \`\`\`json
91
+ {
92
+ "decision": "approve" | "reject" | "dispute" | "skip" | "unclear",
93
+ "reasoning": "One sentence why (max 100 chars)",
94
+ "notes": "Feedback for coder (required if reject)",
95
+ "next_status": "completed" | "in_progress" | "disputed" | "skipped" | "review",
96
+ "metadata": {
97
+ "rejection_count": 0,
98
+ "confidence": "high" | "medium" | "low",
99
+ "push_to_remote": false,
100
+ "repeated_issue": false
101
+ }
102
+ }
103
+ \`\`\`
104
+
105
+ ### Field Rules
106
+
107
+ **decision:**
108
+ - \`approve\` → Work meets requirements, task complete
109
+ - \`reject\` → Issues found, send back to coder
110
+ - \`dispute\` → Fundamental disagreement or hit limit, needs human
111
+ - \`skip\` → Task requires external work, no code needed
112
+ - \`unclear\` → Couldn't determine decision, retry review
113
+
114
+ **next_status:**
115
+ - \`completed\` for approve
116
+ - \`in_progress\` for reject
117
+ - \`disputed\` for dispute
118
+ - \`skipped\` for skip
119
+ - \`review\` for unclear
120
+
121
+ **notes:** Required if reject (specific feedback for coder)
122
+
123
+ **metadata.push_to_remote:**
124
+ - \`true\` for approve, dispute, skip
125
+ - \`false\` for reject, unclear
126
+
127
+ ---
128
+
129
+ ## Examples
130
+
131
+ ### Example 1: Approval
132
+ \`\`\`json
133
+ {
134
+ "decision": "approve",
135
+ "reasoning": "Explicit approval signal",
136
+ "notes": "Implementation meets all requirements",
137
+ "next_status": "completed",
138
+ "metadata": {
139
+ "rejection_count": 0,
140
+ "confidence": "high",
141
+ "push_to_remote": true,
142
+ "repeated_issue": false
143
+ }
144
+ }
145
+ \`\`\`
146
+
147
+ ### Example 2: Rejection
148
+ \`\`\`json
149
+ {
150
+ "decision": "reject",
151
+ "reasoning": "Specific issues identified",
152
+ "notes": "1. Add error handling in parseConfig(). 2. Missing test for edge case. 3. Fix type error on line 42.",
153
+ "next_status": "in_progress",
154
+ "metadata": {
155
+ "rejection_count": 1,
156
+ "confidence": "high",
157
+ "push_to_remote": false,
158
+ "repeated_issue": false
159
+ }
160
+ }
161
+ \`\`\`
162
+
163
+ ### Example 3: Dispute (Repeated)
164
+ \`\`\`json
165
+ {
166
+ "decision": "dispute",
167
+ "reasoning": "Same issue repeated 4 times, hitting limit",
168
+ "notes": "Reviewer demanding global test coverage outside task scope. Human decision needed.",
169
+ "next_status": "disputed",
170
+ "metadata": {
171
+ "rejection_count": 11,
172
+ "confidence": "high",
173
+ "push_to_remote": true,
174
+ "repeated_issue": true
175
+ }
176
+ }
177
+ \`\`\`
178
+
179
+ ### Example 4: Unclear
180
+ \`\`\`json
181
+ {
182
+ "decision": "unclear",
183
+ "reasoning": "No decision statement in output",
184
+ "notes": "Reviewer did not complete analysis",
185
+ "next_status": "review",
186
+ "metadata": {
187
+ "rejection_count": 2,
188
+ "confidence": "low",
189
+ "push_to_remote": false,
190
+ "repeated_issue": false
191
+ }
192
+ }
193
+ \`\`\`
194
+
195
+ ---
196
+
197
+ Analyze the context above and respond with JSON:`;
198
+ }
199
+ //# sourceMappingURL=post-reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"post-reviewer.js","sourceRoot":"","sources":["../../../../src/orchestrator/post-reviewer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH;;GAEG;AACH,MAAM,UAAU,uBAAuB,CAAC,OAAwB;IAC9D,MAAM,EACJ,IAAI,EACJ,eAAe,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,EACtE,WAAW,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,SAAS,EAAE,SAAS,EAAE,EACjE,GAAG,OAAO,CAAC;IAEZ,MAAM,gBAAgB,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;IACzD,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IACxC,MAAM,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC;IAExC,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,MAAM,EAAE,CAAC;QACX,aAAa,GAAG;;;EAGlB,WAAW;;CAEZ,CAAC;IACA,CAAC;IAED,OAAO;;;;;;;;;;eAUM,IAAI,CAAC,EAAE;kBACJ,IAAI,CAAC,KAAK;uBACL,IAAI,CAAC,eAAe;;;;;;iBAM1B,SAAS;iBACT,SAAS;gBACV,gBAAgB;;;;EAI9B,WAAW;;EAEX,aAAa;;;;;cAKD,UAAU;qBACH,aAAa,CAAC,MAAM;cAC3B,SAAS,KAAK,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iDA8IY,CAAC;AAClD,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Reviewer invocation
3
+ * Uses AI provider system for flexible LLM support
4
+ */
5
+ import type { Task } from '../database/queries.js';
6
+ export interface ReviewerResult {
7
+ success: boolean;
8
+ exitCode: number;
9
+ stdout: string;
10
+ stderr: string;
11
+ duration: number;
12
+ timedOut: boolean;
13
+ decision?: 'approve' | 'reject' | 'dispute';
14
+ notes?: string;
15
+ }
16
+ export interface BatchReviewerResult {
17
+ success: boolean;
18
+ exitCode: number;
19
+ stdout: string;
20
+ stderr: string;
21
+ duration: number;
22
+ timedOut: boolean;
23
+ taskCount: number;
24
+ }
25
+ /**
26
+ * Invoke reviewer for a task
27
+ * @param coordinatorGuidance Optional guidance from coordinator after repeated rejections
28
+ * @param coordinatorDecision Optional decision type from coordinator
29
+ */
30
+ export declare function invokeReviewer(task: Task, projectPath: string, coordinatorGuidance?: string, coordinatorDecision?: string): Promise<ReviewerResult>;
31
+ /**
32
+ * Invoke reviewer for a batch of tasks
33
+ */
34
+ export declare function invokeReviewerBatch(tasks: Task[], sectionName: string, projectPath: string): Promise<BatchReviewerResult>;
35
+ //# sourceMappingURL=reviewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../../../../src/orchestrator/reviewer.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,wBAAwB,CAAC;AAqBnD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAiHD;;;;GAIG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,EACnB,mBAAmB,CAAC,EAAE,MAAM,EAC5B,mBAAmB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,cAAc,CAAC,CAsGzB;AAED;;GAEG;AACH,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,IAAI,EAAE,EACb,WAAW,EAAE,MAAM,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,mBAAmB,CAAC,CA8C9B"}
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Reviewer invocation
3
+ * Uses AI provider system for flexible LLM support
4
+ */
5
+ import { writeFileSync, readFileSync, unlinkSync, existsSync } from 'node:fs';
6
+ import { tmpdir } from 'node:os';
7
+ import { join } from 'node:path';
8
+ import { listTasks, getTaskRejections, getLatestSubmissionNotes } from '../database/queries.js';
9
+ import { openDatabase } from '../database/connection.js';
10
+ import { generateReviewerPrompt, generateBatchReviewerPrompt, } from '../prompts/reviewer.js';
11
+ import { getGitDiff, getModifiedFiles, findTaskCommit, getCommitDiff, getCommitFiles, } from '../git/status.js';
12
+ import { loadConfig } from '../config/loader.js';
13
+ import { getProviderRegistry } from '../providers/registry.js';
14
+ import { logInvocation } from '../providers/invocation-logger.js';
15
+ /**
16
+ * Write prompt to temp file
17
+ */
18
+ function writePromptToTempFile(prompt) {
19
+ const tempPath = join(tmpdir(), `steroids-reviewer-${Date.now()}.txt`);
20
+ writeFileSync(tempPath, prompt, 'utf-8');
21
+ return tempPath;
22
+ }
23
+ /**
24
+ * Parse reviewer output for decision
25
+ */
26
+ function parseReviewerDecision(output) {
27
+ const upperOutput = output.toUpperCase();
28
+ // Look for explicit decision markers
29
+ if (upperOutput.includes('DECISION: APPROVE') || upperOutput.includes('**APPROVE**') || /\bAPPROVE\b/.test(upperOutput)) {
30
+ // Extract notes if present
31
+ const notesMatch = output.match(/(?:notes?|feedback|comments?):\s*["']?([^"'\n]+)/i);
32
+ return { decision: 'approve', notes: notesMatch?.[1]?.trim() };
33
+ }
34
+ if (upperOutput.includes('DECISION: REJECT') || upperOutput.includes('**REJECT**') || /\bREJECT\b/.test(upperOutput)) {
35
+ // Extract rejection notes
36
+ const notesMatch = output.match(/(?:notes?|reason|feedback|issues?):\s*["']?([^"'\n]+)/i);
37
+ return { decision: 'reject', notes: notesMatch?.[1]?.trim() || 'See reviewer output for details' };
38
+ }
39
+ if (upperOutput.includes('DECISION: DISPUTE') || upperOutput.includes('**DISPUTE**') || /\bDISPUTE\b/.test(upperOutput)) {
40
+ const notesMatch = output.match(/(?:reason|notes?):\s*["']?([^"'\n]+)/i);
41
+ return { decision: 'dispute', notes: notesMatch?.[1]?.trim() };
42
+ }
43
+ return {};
44
+ }
45
+ /**
46
+ * Invoke AI provider with prompt
47
+ * Uses configuration to determine which provider to use
48
+ */
49
+ async function invokeProvider(promptFile, timeoutMs = 600_000, // 10 minutes default for reviewer
50
+ taskId, projectPath) {
51
+ // Load configuration to get reviewer provider settings
52
+ // Project config overrides global config
53
+ const config = loadConfig(projectPath);
54
+ const reviewerConfig = config.ai?.reviewer;
55
+ const providerName = reviewerConfig?.provider;
56
+ const modelName = reviewerConfig?.model;
57
+ if (!providerName || !modelName) {
58
+ throw new Error('Reviewer AI provider not configured. Run "steroids config ai reviewer" to configure.');
59
+ }
60
+ // Get the provider from registry
61
+ const registry = getProviderRegistry();
62
+ const provider = registry.get(providerName);
63
+ // Check if provider is available
64
+ if (!(await provider.isAvailable())) {
65
+ throw new Error(`Provider '${providerName}' is not available. ` +
66
+ `Ensure the CLI is installed and in PATH.`);
67
+ }
68
+ // Read prompt content
69
+ const promptContent = readFileSync(promptFile, 'utf-8');
70
+ const result = await logInvocation(promptContent, (ctx) => provider.invoke(promptContent, {
71
+ model: modelName,
72
+ timeout: timeoutMs,
73
+ cwd: process.cwd(),
74
+ promptFile,
75
+ role: 'reviewer',
76
+ streamOutput: true,
77
+ onActivity: ctx?.onActivity,
78
+ }), {
79
+ role: 'reviewer',
80
+ provider: providerName,
81
+ model: modelName,
82
+ taskId,
83
+ projectPath,
84
+ });
85
+ // Parse the decision from output
86
+ const { decision, notes } = parseReviewerDecision(result.stdout);
87
+ return {
88
+ success: result.success,
89
+ exitCode: result.exitCode,
90
+ stdout: result.stdout,
91
+ stderr: result.stderr,
92
+ duration: result.duration,
93
+ timedOut: result.timedOut,
94
+ decision,
95
+ notes,
96
+ };
97
+ }
98
+ /**
99
+ * Invoke reviewer for a task
100
+ * @param coordinatorGuidance Optional guidance from coordinator after repeated rejections
101
+ * @param coordinatorDecision Optional decision type from coordinator
102
+ */
103
+ export async function invokeReviewer(task, projectPath, coordinatorGuidance, coordinatorDecision) {
104
+ // Load config to show provider/model being used
105
+ const config = loadConfig(projectPath);
106
+ const reviewerConfig = config.ai?.reviewer;
107
+ console.log(`\n${'='.repeat(60)}`);
108
+ console.log(`REVIEWER: ${task.title}`);
109
+ console.log(`Task ID: ${task.id}`);
110
+ console.log(`Rejection count: ${task.rejection_count}/15`);
111
+ console.log(`Provider: ${reviewerConfig?.provider ?? 'not configured'}`);
112
+ console.log(`Model: ${reviewerConfig?.model ?? 'not configured'}`);
113
+ console.log(`${'='.repeat(60)}\n`);
114
+ // Try to find the specific commit for this task
115
+ let gitDiff;
116
+ let modifiedFiles;
117
+ const commitHash = findTaskCommit(projectPath, task.title);
118
+ if (commitHash) {
119
+ console.log(`Found task commit: ${commitHash}`);
120
+ gitDiff = getCommitDiff(projectPath, commitHash);
121
+ modifiedFiles = getCommitFiles(projectPath, commitHash);
122
+ }
123
+ else {
124
+ // Fallback to HEAD~1 if no matching commit found
125
+ console.log('No matching commit found, using HEAD~1 diff');
126
+ gitDiff = getGitDiff(projectPath, 'HEAD~1');
127
+ modifiedFiles = getModifiedFiles(projectPath);
128
+ }
129
+ // Fetch other tasks in the same section for context
130
+ let sectionTasks = [];
131
+ let rejectionHistory = [];
132
+ let submissionNotes = null;
133
+ try {
134
+ const { db, close } = openDatabase(projectPath);
135
+ // Get section tasks
136
+ if (task.section_id) {
137
+ const allSectionTasks = listTasks(db, { sectionId: task.section_id });
138
+ sectionTasks = allSectionTasks.map(t => ({
139
+ id: t.id,
140
+ title: t.title,
141
+ status: t.status,
142
+ }));
143
+ }
144
+ // Get rejection history - ALWAYS fetch this so reviewer can see past attempts
145
+ rejectionHistory = getTaskRejections(db, task.id);
146
+ if (rejectionHistory.length > 0) {
147
+ console.log(`Found ${rejectionHistory.length} previous rejection(s) for this task`);
148
+ }
149
+ // Get coder's submission notes (if any)
150
+ submissionNotes = getLatestSubmissionNotes(db, task.id);
151
+ if (submissionNotes) {
152
+ console.log(`Coder included notes with submission`);
153
+ }
154
+ close();
155
+ }
156
+ catch (error) {
157
+ console.warn('Could not fetch task context:', error);
158
+ }
159
+ // Reuse config loaded earlier, get reviewer model
160
+ const reviewerModel = reviewerConfig?.model || 'unknown';
161
+ const context = {
162
+ task,
163
+ projectPath,
164
+ reviewerModel,
165
+ gitDiff,
166
+ modifiedFiles,
167
+ sectionTasks,
168
+ rejectionHistory,
169
+ submissionNotes,
170
+ config,
171
+ coordinatorGuidance,
172
+ coordinatorDecision,
173
+ };
174
+ const prompt = generateReviewerPrompt(context);
175
+ // Write prompt to temp file
176
+ const promptFile = writePromptToTempFile(prompt);
177
+ try {
178
+ const result = await invokeProvider(promptFile, 600_000, task.id, projectPath);
179
+ console.log(`\n${'='.repeat(60)}`);
180
+ console.log(`REVIEWER COMPLETED`);
181
+ console.log(`Exit code: ${result.exitCode}`);
182
+ console.log(`Duration: ${(result.duration / 1000).toFixed(1)}s`);
183
+ console.log(`${'='.repeat(60)}\n`);
184
+ return result;
185
+ }
186
+ finally {
187
+ // Clean up temp file
188
+ if (existsSync(promptFile)) {
189
+ unlinkSync(promptFile);
190
+ }
191
+ }
192
+ }
193
+ /**
194
+ * Invoke reviewer for a batch of tasks
195
+ */
196
+ export async function invokeReviewerBatch(tasks, sectionName, projectPath) {
197
+ // Load config for quality settings and to show provider/model being used
198
+ const config = loadConfig(projectPath);
199
+ const reviewerConfig = config.ai?.reviewer;
200
+ console.log(`\n${'='.repeat(60)}`);
201
+ console.log(`BATCH REVIEWER: Section "${sectionName}"`);
202
+ console.log(`Tasks: ${tasks.length}`);
203
+ tasks.forEach((t, i) => console.log(` ${i + 1}. ${t.title} (${t.id})`));
204
+ console.log(`Provider: ${reviewerConfig?.provider ?? 'not configured'}`);
205
+ console.log(`Model: ${reviewerConfig?.model ?? 'not configured'}`);
206
+ console.log(`${'='.repeat(60)}\n`);
207
+ // Get combined git diff for all tasks (compare against base before batch started)
208
+ // We look for the earliest task's commit and diff from there
209
+ const gitDiff = getGitDiff(projectPath, 'HEAD~' + tasks.length);
210
+ const modifiedFiles = getModifiedFiles(projectPath);
211
+ const context = {
212
+ tasks,
213
+ projectPath,
214
+ sectionName,
215
+ gitDiff,
216
+ modifiedFiles,
217
+ config,
218
+ };
219
+ const prompt = generateBatchReviewerPrompt(context);
220
+ const promptFile = writePromptToTempFile(prompt);
221
+ try {
222
+ // Longer timeout for batch: base 20 minutes + 3 minutes per task
223
+ const timeoutMs = 20 * 60 * 1000 + tasks.length * 3 * 60 * 1000;
224
+ const result = await invokeProvider(promptFile, timeoutMs, undefined, projectPath);
225
+ console.log(`\n${'='.repeat(60)}`);
226
+ console.log(`BATCH REVIEWER COMPLETED`);
227
+ console.log(`Duration: ${(result.duration / 1000).toFixed(1)}s`);
228
+ console.log(`${'='.repeat(60)}\n`);
229
+ return { ...result, taskCount: tasks.length };
230
+ }
231
+ finally {
232
+ if (existsSync(promptFile)) {
233
+ unlinkSync(promptFile);
234
+ }
235
+ }
236
+ }
237
+ //# sourceMappingURL=reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.js","sourceRoot":"","sources":["../../../../src/orchestrator/reviewer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * JSON schema validation for orchestrator outputs
3
+ */
4
+ export declare const validateCoderResult: import("ajv").ValidateFunction<{
5
+ [x: string]: {};
6
+ }>;
7
+ export declare const validateReviewerResult: import("ajv").ValidateFunction<{
8
+ [x: string]: {};
9
+ }>;
10
+ //# sourceMappingURL=schemas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../../src/orchestrator/schemas.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgFH,eAAO,MAAM,mBAAmB;;EAA2B,CAAC;AAC5D,eAAO,MAAM,sBAAsB;;EAA8B,CAAC"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * JSON schema validation for orchestrator outputs
3
+ */
4
+ import Ajv from 'ajv';
5
+ const coderSchema = {
6
+ type: 'object',
7
+ required: ['action', 'reasoning', 'next_status', 'metadata'],
8
+ properties: {
9
+ action: {
10
+ type: 'string',
11
+ enum: ['submit', 'retry', 'stage_commit_submit', 'error']
12
+ },
13
+ reasoning: { type: 'string', minLength: 10, maxLength: 200 },
14
+ commits: {
15
+ oneOf: [
16
+ { type: 'array', items: { type: 'string' } },
17
+ { type: 'null' }
18
+ ]
19
+ },
20
+ commit_message: {
21
+ oneOf: [
22
+ { type: 'string', maxLength: 200 },
23
+ { type: 'null' }
24
+ ]
25
+ },
26
+ next_status: {
27
+ type: 'string',
28
+ enum: ['review', 'in_progress', 'failed']
29
+ },
30
+ metadata: {
31
+ type: 'object',
32
+ required: ['files_changed', 'confidence', 'exit_clean', 'has_commits'],
33
+ properties: {
34
+ files_changed: { type: 'number', minimum: 0 },
35
+ confidence: { type: 'string', enum: ['high', 'medium', 'low'] },
36
+ exit_clean: { type: 'boolean' },
37
+ has_commits: { type: 'boolean' }
38
+ }
39
+ }
40
+ }
41
+ };
42
+ const reviewerSchema = {
43
+ type: 'object',
44
+ required: ['decision', 'reasoning', 'next_status', 'metadata'],
45
+ properties: {
46
+ decision: {
47
+ type: 'string',
48
+ enum: ['approve', 'reject', 'dispute', 'skip', 'unclear']
49
+ },
50
+ reasoning: { type: 'string', minLength: 10, maxLength: 200 },
51
+ notes: {
52
+ oneOf: [
53
+ { type: 'string', maxLength: 1000 },
54
+ { type: 'null' }
55
+ ]
56
+ },
57
+ next_status: {
58
+ type: 'string',
59
+ enum: ['completed', 'in_progress', 'disputed', 'skipped', 'review']
60
+ },
61
+ metadata: {
62
+ type: 'object',
63
+ required: ['rejection_count', 'confidence', 'push_to_remote'],
64
+ properties: {
65
+ rejection_count: { type: 'number', minimum: 0 },
66
+ confidence: { type: 'string', enum: ['high', 'medium', 'low'] },
67
+ push_to_remote: { type: 'boolean' },
68
+ repeated_issue: {
69
+ oneOf: [
70
+ { type: 'boolean' },
71
+ { type: 'null' }
72
+ ]
73
+ }
74
+ }
75
+ }
76
+ }
77
+ };
78
+ const ajv = new Ajv();
79
+ export const validateCoderResult = ajv.compile(coderSchema);
80
+ export const validateReviewerResult = ajv.compile(reviewerSchema);
81
+ //# sourceMappingURL=schemas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schemas.js","sourceRoot":"","sources":["../../../../src/orchestrator/schemas.ts"],"names":[],"mappings":"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"}