@ttfw/envoi 1.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 (283) hide show
  1. package/README.md +238 -0
  2. package/dist/commands/app.d.ts +2 -0
  3. package/dist/commands/app.d.ts.map +1 -0
  4. package/dist/commands/app.js +31 -0
  5. package/dist/commands/app.js.map +1 -0
  6. package/dist/commands/autonomy.d.ts +6 -0
  7. package/dist/commands/autonomy.d.ts.map +1 -0
  8. package/dist/commands/autonomy.js +89 -0
  9. package/dist/commands/autonomy.js.map +1 -0
  10. package/dist/commands/builder.d.ts +13 -0
  11. package/dist/commands/builder.d.ts.map +1 -0
  12. package/dist/commands/builder.js +142 -0
  13. package/dist/commands/builder.js.map +1 -0
  14. package/dist/commands/idea.d.ts +12 -0
  15. package/dist/commands/idea.d.ts.map +1 -0
  16. package/dist/commands/idea.js +79 -0
  17. package/dist/commands/idea.js.map +1 -0
  18. package/dist/commands/init.d.ts +18 -0
  19. package/dist/commands/init.d.ts.map +1 -0
  20. package/dist/commands/init.js +423 -0
  21. package/dist/commands/init.js.map +1 -0
  22. package/dist/commands/mode.d.ts +13 -0
  23. package/dist/commands/mode.d.ts.map +1 -0
  24. package/dist/commands/mode.js +96 -0
  25. package/dist/commands/mode.js.map +1 -0
  26. package/dist/commands/onboard.d.ts +37 -0
  27. package/dist/commands/onboard.d.ts.map +1 -0
  28. package/dist/commands/onboard.js +743 -0
  29. package/dist/commands/onboard.js.map +1 -0
  30. package/dist/commands/pr-note.d.ts +8 -0
  31. package/dist/commands/pr-note.d.ts.map +1 -0
  32. package/dist/commands/pr-note.js +27 -0
  33. package/dist/commands/pr-note.js.map +1 -0
  34. package/dist/commands/undo.d.ts +7 -0
  35. package/dist/commands/undo.d.ts.map +1 -0
  36. package/dist/commands/undo.js +59 -0
  37. package/dist/commands/undo.js.map +1 -0
  38. package/dist/commands/update.d.ts +24 -0
  39. package/dist/commands/update.d.ts.map +1 -0
  40. package/dist/commands/update.js +248 -0
  41. package/dist/commands/update.js.map +1 -0
  42. package/dist/constants/report_codes.d.ts +29 -0
  43. package/dist/constants/report_codes.d.ts.map +1 -0
  44. package/dist/constants/report_codes.js +69 -0
  45. package/dist/constants/report_codes.js.map +1 -0
  46. package/dist/index.d.ts +3 -0
  47. package/dist/index.d.ts.map +1 -0
  48. package/dist/index.js +675 -0
  49. package/dist/index.js.map +1 -0
  50. package/dist/lib/autonomy.d.ts +16 -0
  51. package/dist/lib/autonomy.d.ts.map +1 -0
  52. package/dist/lib/autonomy.js +38 -0
  53. package/dist/lib/autonomy.js.map +1 -0
  54. package/dist/lib/blocked.d.ts +87 -0
  55. package/dist/lib/blocked.d.ts.map +1 -0
  56. package/dist/lib/blocked.js +134 -0
  57. package/dist/lib/blocked.js.map +1 -0
  58. package/dist/lib/branding.d.ts +13 -0
  59. package/dist/lib/branding.d.ts.map +1 -0
  60. package/dist/lib/branding.js +19 -0
  61. package/dist/lib/branding.js.map +1 -0
  62. package/dist/lib/claude.d.ts +42 -0
  63. package/dist/lib/claude.d.ts.map +1 -0
  64. package/dist/lib/claude.js +291 -0
  65. package/dist/lib/claude.js.map +1 -0
  66. package/dist/lib/config.d.ts +71 -0
  67. package/dist/lib/config.d.ts.map +1 -0
  68. package/dist/lib/config.js +410 -0
  69. package/dist/lib/config.js.map +1 -0
  70. package/dist/lib/diff.d.ts +150 -0
  71. package/dist/lib/diff.d.ts.map +1 -0
  72. package/dist/lib/diff.js +257 -0
  73. package/dist/lib/diff.js.map +1 -0
  74. package/dist/lib/doctor.d.ts +67 -0
  75. package/dist/lib/doctor.d.ts.map +1 -0
  76. package/dist/lib/doctor.js +211 -0
  77. package/dist/lib/doctor.js.map +1 -0
  78. package/dist/lib/fingerprint.d.ts +27 -0
  79. package/dist/lib/fingerprint.d.ts.map +1 -0
  80. package/dist/lib/fingerprint.js +116 -0
  81. package/dist/lib/fingerprint.js.map +1 -0
  82. package/dist/lib/fs.d.ts +93 -0
  83. package/dist/lib/fs.d.ts.map +1 -0
  84. package/dist/lib/fs.js +179 -0
  85. package/dist/lib/fs.js.map +1 -0
  86. package/dist/lib/git.d.ts +177 -0
  87. package/dist/lib/git.d.ts.map +1 -0
  88. package/dist/lib/git.js +355 -0
  89. package/dist/lib/git.js.map +1 -0
  90. package/dist/lib/git_branching.d.ts +84 -0
  91. package/dist/lib/git_branching.d.ts.map +1 -0
  92. package/dist/lib/git_branching.js +327 -0
  93. package/dist/lib/git_branching.js.map +1 -0
  94. package/dist/lib/gitignore.d.ts +26 -0
  95. package/dist/lib/gitignore.d.ts.map +1 -0
  96. package/dist/lib/gitignore.js +119 -0
  97. package/dist/lib/gitignore.js.map +1 -0
  98. package/dist/lib/guardrails.d.ts +232 -0
  99. package/dist/lib/guardrails.d.ts.map +1 -0
  100. package/dist/lib/guardrails.js +323 -0
  101. package/dist/lib/guardrails.js.map +1 -0
  102. package/dist/lib/history.d.ts +110 -0
  103. package/dist/lib/history.d.ts.map +1 -0
  104. package/dist/lib/history.js +236 -0
  105. package/dist/lib/history.js.map +1 -0
  106. package/dist/lib/index.d.ts +29 -0
  107. package/dist/lib/index.d.ts.map +1 -0
  108. package/dist/lib/index.js +29 -0
  109. package/dist/lib/index.js.map +1 -0
  110. package/dist/lib/json-extract.d.ts +42 -0
  111. package/dist/lib/json-extract.d.ts.map +1 -0
  112. package/dist/lib/json-extract.js +201 -0
  113. package/dist/lib/json-extract.js.map +1 -0
  114. package/dist/lib/judge.d.ts +237 -0
  115. package/dist/lib/judge.d.ts.map +1 -0
  116. package/dist/lib/judge.js +501 -0
  117. package/dist/lib/judge.js.map +1 -0
  118. package/dist/lib/lock.d.ts +79 -0
  119. package/dist/lib/lock.d.ts.map +1 -0
  120. package/dist/lib/lock.js +254 -0
  121. package/dist/lib/lock.js.map +1 -0
  122. package/dist/lib/migration.d.ts +9 -0
  123. package/dist/lib/migration.d.ts.map +1 -0
  124. package/dist/lib/migration.js +74 -0
  125. package/dist/lib/migration.js.map +1 -0
  126. package/dist/lib/paths.d.ts +18 -0
  127. package/dist/lib/paths.d.ts.map +1 -0
  128. package/dist/lib/paths.js +27 -0
  129. package/dist/lib/paths.js.map +1 -0
  130. package/dist/lib/preflight.d.ts +33 -0
  131. package/dist/lib/preflight.d.ts.map +1 -0
  132. package/dist/lib/preflight.js +177 -0
  133. package/dist/lib/preflight.js.map +1 -0
  134. package/dist/lib/prompt_budget.d.ts +18 -0
  135. package/dist/lib/prompt_budget.d.ts.map +1 -0
  136. package/dist/lib/prompt_budget.js +36 -0
  137. package/dist/lib/prompt_budget.js.map +1 -0
  138. package/dist/lib/report.d.ts +102 -0
  139. package/dist/lib/report.d.ts.map +1 -0
  140. package/dist/lib/report.js +347 -0
  141. package/dist/lib/report.js.map +1 -0
  142. package/dist/lib/reviewer-flow.d.ts +80 -0
  143. package/dist/lib/reviewer-flow.d.ts.map +1 -0
  144. package/dist/lib/reviewer-flow.js +138 -0
  145. package/dist/lib/reviewer-flow.js.map +1 -0
  146. package/dist/lib/reviewer.d.ts +53 -0
  147. package/dist/lib/reviewer.d.ts.map +1 -0
  148. package/dist/lib/reviewer.js +199 -0
  149. package/dist/lib/reviewer.js.map +1 -0
  150. package/dist/lib/risk.d.ts +127 -0
  151. package/dist/lib/risk.d.ts.map +1 -0
  152. package/dist/lib/risk.js +192 -0
  153. package/dist/lib/risk.js.map +1 -0
  154. package/dist/lib/rollback.d.ts +143 -0
  155. package/dist/lib/rollback.d.ts.map +1 -0
  156. package/dist/lib/rollback.js +244 -0
  157. package/dist/lib/rollback.js.map +1 -0
  158. package/dist/lib/schema.d.ts +47 -0
  159. package/dist/lib/schema.d.ts.map +1 -0
  160. package/dist/lib/schema.js +91 -0
  161. package/dist/lib/schema.js.map +1 -0
  162. package/dist/lib/scope.d.ts +89 -0
  163. package/dist/lib/scope.d.ts.map +1 -0
  164. package/dist/lib/scope.js +135 -0
  165. package/dist/lib/scope.js.map +1 -0
  166. package/dist/lib/self_update.d.ts +13 -0
  167. package/dist/lib/self_update.d.ts.map +1 -0
  168. package/dist/lib/self_update.js +172 -0
  169. package/dist/lib/self_update.js.map +1 -0
  170. package/dist/lib/state.d.ts +143 -0
  171. package/dist/lib/state.d.ts.map +1 -0
  172. package/dist/lib/state.js +258 -0
  173. package/dist/lib/state.js.map +1 -0
  174. package/dist/lib/tick.d.ts +310 -0
  175. package/dist/lib/tick.d.ts.map +1 -0
  176. package/dist/lib/tick.js +424 -0
  177. package/dist/lib/tick.js.map +1 -0
  178. package/dist/lib/transport.d.ts +145 -0
  179. package/dist/lib/transport.d.ts.map +1 -0
  180. package/dist/lib/transport.js +237 -0
  181. package/dist/lib/transport.js.map +1 -0
  182. package/dist/lib/verdict_labels.d.ts +5 -0
  183. package/dist/lib/verdict_labels.d.ts.map +1 -0
  184. package/dist/lib/verdict_labels.js +25 -0
  185. package/dist/lib/verdict_labels.js.map +1 -0
  186. package/dist/lib/verify-safety.d.ts +63 -0
  187. package/dist/lib/verify-safety.d.ts.map +1 -0
  188. package/dist/lib/verify-safety.js +123 -0
  189. package/dist/lib/verify-safety.js.map +1 -0
  190. package/dist/lib/verify.d.ts +139 -0
  191. package/dist/lib/verify.d.ts.map +1 -0
  192. package/dist/lib/verify.js +311 -0
  193. package/dist/lib/verify.js.map +1 -0
  194. package/dist/lib/workspace_state.d.ts +79 -0
  195. package/dist/lib/workspace_state.d.ts.map +1 -0
  196. package/dist/lib/workspace_state.js +283 -0
  197. package/dist/lib/workspace_state.js.map +1 -0
  198. package/dist/runner/builder.d.ts +58 -0
  199. package/dist/runner/builder.d.ts.map +1 -0
  200. package/dist/runner/builder.js +775 -0
  201. package/dist/runner/builder.js.map +1 -0
  202. package/dist/runner/builder_parse.d.ts +37 -0
  203. package/dist/runner/builder_parse.d.ts.map +1 -0
  204. package/dist/runner/builder_parse.js +76 -0
  205. package/dist/runner/builder_parse.js.map +1 -0
  206. package/dist/runner/index.d.ts +9 -0
  207. package/dist/runner/index.d.ts.map +1 -0
  208. package/dist/runner/index.js +7 -0
  209. package/dist/runner/index.js.map +1 -0
  210. package/dist/runner/loop.d.ts +51 -0
  211. package/dist/runner/loop.d.ts.map +1 -0
  212. package/dist/runner/loop.js +221 -0
  213. package/dist/runner/loop.js.map +1 -0
  214. package/dist/runner/orchestrator.d.ts +67 -0
  215. package/dist/runner/orchestrator.d.ts.map +1 -0
  216. package/dist/runner/orchestrator.js +376 -0
  217. package/dist/runner/orchestrator.js.map +1 -0
  218. package/dist/runner/tick.d.ts +10 -0
  219. package/dist/runner/tick.d.ts.map +1 -0
  220. package/dist/runner/tick.js +1639 -0
  221. package/dist/runner/tick.js.map +1 -0
  222. package/dist/types/blocked.d.ts +52 -0
  223. package/dist/types/blocked.d.ts.map +1 -0
  224. package/dist/types/blocked.js +8 -0
  225. package/dist/types/blocked.js.map +1 -0
  226. package/dist/types/builder.d.ts +25 -0
  227. package/dist/types/builder.d.ts.map +1 -0
  228. package/dist/types/builder.js +7 -0
  229. package/dist/types/builder.js.map +1 -0
  230. package/dist/types/claude.d.ts +86 -0
  231. package/dist/types/claude.d.ts.map +1 -0
  232. package/dist/types/claude.js +48 -0
  233. package/dist/types/claude.js.map +1 -0
  234. package/dist/types/config.d.ts +384 -0
  235. package/dist/types/config.d.ts.map +1 -0
  236. package/dist/types/config.js +7 -0
  237. package/dist/types/config.js.map +1 -0
  238. package/dist/types/index.d.ts +18 -0
  239. package/dist/types/index.d.ts.map +1 -0
  240. package/dist/types/index.js +8 -0
  241. package/dist/types/index.js.map +1 -0
  242. package/dist/types/lock.d.ts +21 -0
  243. package/dist/types/lock.d.ts.map +1 -0
  244. package/dist/types/lock.js +8 -0
  245. package/dist/types/lock.js.map +1 -0
  246. package/dist/types/preflight.d.ts +49 -0
  247. package/dist/types/preflight.d.ts.map +1 -0
  248. package/dist/types/preflight.js +8 -0
  249. package/dist/types/preflight.js.map +1 -0
  250. package/dist/types/report.d.ts +161 -0
  251. package/dist/types/report.d.ts.map +1 -0
  252. package/dist/types/report.js +8 -0
  253. package/dist/types/report.js.map +1 -0
  254. package/dist/types/reviewer.d.ts +66 -0
  255. package/dist/types/reviewer.d.ts.map +1 -0
  256. package/dist/types/reviewer.js +5 -0
  257. package/dist/types/reviewer.js.map +1 -0
  258. package/dist/types/state.d.ts +124 -0
  259. package/dist/types/state.d.ts.map +1 -0
  260. package/dist/types/state.js +20 -0
  261. package/dist/types/state.js.map +1 -0
  262. package/dist/types/task.d.ts +117 -0
  263. package/dist/types/task.d.ts.map +1 -0
  264. package/dist/types/task.js +7 -0
  265. package/dist/types/task.js.map +1 -0
  266. package/dist/types/workspace_state.d.ts +125 -0
  267. package/dist/types/workspace_state.d.ts.map +1 -0
  268. package/dist/types/workspace_state.js +10 -0
  269. package/dist/types/workspace_state.js.map +1 -0
  270. package/envoi.config.json +191 -0
  271. package/package.json +52 -0
  272. package/relais/prompts/.gitkeep +0 -0
  273. package/relais/prompts/builder.system.txt +13 -0
  274. package/relais/prompts/builder.user.txt +15 -0
  275. package/relais/prompts/orchestrator.system.txt +37 -0
  276. package/relais/prompts/orchestrator.user.txt +34 -0
  277. package/relais/prompts/reviewer.system.txt +33 -0
  278. package/relais/prompts/reviewer.user.txt +35 -0
  279. package/relais/schemas/.gitkeep +0 -0
  280. package/relais/schemas/builder_result.schema.json +29 -0
  281. package/relais/schemas/report.schema.json +195 -0
  282. package/relais/schemas/reviewer_result.schema.json +70 -0
  283. package/relais/schemas/task.schema.json +155 -0
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Reviewer flow integration for pre-builder risk checks.
3
+ *
4
+ * Integrates the reviewer into the tick flow to be called pre-builder when
5
+ * risk is detected. Handles reviewer decisions and returns appropriate stop
6
+ * codes or proceeds to builder.
7
+ */
8
+ import { join } from 'node:path';
9
+ import { readFile } from 'node:fs/promises';
10
+ import { invokeReviewer } from './reviewer.js';
11
+ import { shouldTriggerReviewer } from './risk.js';
12
+ /**
13
+ * Handles reviewer decision and returns appropriate stop code or null.
14
+ *
15
+ * @param decision - Reviewer decision object from parsed output
16
+ * @returns ReviewerFlowResult with stopCode or null (proceed)
17
+ */
18
+ export function handleReviewerDecision(decision) {
19
+ if (decision.decision === 'proceed') {
20
+ return { stopCode: null };
21
+ }
22
+ if (decision.decision === 'force_patch') {
23
+ return { stopCode: 'STOP_REVIEWER_FORCED_PATCH' };
24
+ }
25
+ if (decision.decision === 'ask_question') {
26
+ if (!decision.question) {
27
+ // Invalid decision - missing question, default to force_patch
28
+ return { stopCode: 'STOP_REVIEWER_FORCED_PATCH' };
29
+ }
30
+ return {
31
+ stopCode: 'STOP_REVIEWER_ASK_QUESTION',
32
+ question: {
33
+ prompt: decision.question.prompt,
34
+ choices: decision.question.choices,
35
+ },
36
+ };
37
+ }
38
+ // Unknown decision - default to force_patch for safety
39
+ return { stopCode: 'STOP_REVIEWER_FORCED_PATCH' };
40
+ }
41
+ /**
42
+ * Runs reviewer if needed based on risk flags and configuration.
43
+ *
44
+ * This function should be called pre-builder when risk is detected.
45
+ * It checks if reviewer should be triggered, invokes it if needed, and
46
+ * handles the decision.
47
+ *
48
+ * @param config - Envoi configuration
49
+ * @param context - Reviewer flow context
50
+ * @returns Promise resolving to ReviewerFlowResult
51
+ */
52
+ export async function runReviewerIfNeeded(config, context) {
53
+ // Reviewer must be configured
54
+ if (!config.reviewer) {
55
+ return { stopCode: null };
56
+ }
57
+ // Check if reviewer should be triggered
58
+ if (!shouldTriggerReviewer(config.reviewer, context.riskFlags)) {
59
+ return { stopCode: null };
60
+ }
61
+ // Check authentication
62
+ const authCheck = await import('./reviewer.js').then((m) => m.checkReviewerAuth());
63
+ if (!authCheck.authenticated) {
64
+ // Degrade gracefully - log error but proceed (or default to force_patch if pre-build)
65
+ return {
66
+ stopCode: 'STOP_REVIEWER_FORCED_PATCH',
67
+ reviewerError: `Reviewer authentication failed: ${authCheck.reason || 'unknown reason'}`,
68
+ };
69
+ }
70
+ // Build reviewer prompt
71
+ const reviewerConfig = config.reviewer;
72
+ const workspaceDir = config.workspace_dir;
73
+ const userPromptPath = join(workspaceDir, reviewerConfig.user_prompt_file);
74
+ const systemPromptPath = join(workspaceDir, reviewerConfig.system_prompt_file);
75
+ let userPrompt;
76
+ let systemPrompt;
77
+ try {
78
+ userPrompt = await readFile(userPromptPath, 'utf-8');
79
+ systemPrompt = await readFile(systemPromptPath, 'utf-8');
80
+ }
81
+ catch (error) {
82
+ return {
83
+ stopCode: 'STOP_REVIEWER_FORCED_PATCH',
84
+ reviewerError: `Failed to read reviewer prompt files: ${error instanceof Error ? error.message : String(error)}`,
85
+ };
86
+ }
87
+ // Interpolate placeholders in user prompt
88
+ const replacements = {
89
+ '{{RISK_FLAGS}}': context.riskFlags.join(', ') || 'none',
90
+ '{{TASK_JSON}}': context.task ? JSON.stringify(context.task, null, 2) : 'null',
91
+ '{{LAST_REPORT_MD}}': context.lastReportMd || '',
92
+ '{{DIFF_PATCH_OR_EMPTY}}': context.diffPatch || '',
93
+ '{{VERIFY_LOG_EXCERPT_OR_EMPTY}}': context.verifyLogExcerpt || '',
94
+ '{{TOUCHED_PATHS}}': context.touchedPaths.join('\n') || 'none',
95
+ };
96
+ for (const [placeholder, value] of Object.entries(replacements)) {
97
+ userPrompt = userPrompt.replace(new RegExp(placeholder.replace(/[{}]/g, '\\$&'), 'g'), value);
98
+ }
99
+ // Invoke reviewer
100
+ const invocationConfig = {
101
+ command: reviewerConfig.command,
102
+ model: reviewerConfig.model,
103
+ maxTurns: reviewerConfig.max_turns,
104
+ timeout: config.runner.max_tick_seconds * 1000, // Convert to milliseconds
105
+ };
106
+ const reviewerContext = {
107
+ prompt: userPrompt,
108
+ systemPrompt: systemPromptPath,
109
+ };
110
+ const invocationResult = await invokeReviewer(invocationConfig, reviewerContext);
111
+ if (!invocationResult.success) {
112
+ // Reviewer invocation failed - degrade gracefully
113
+ return {
114
+ stopCode: 'STOP_REVIEWER_FORCED_PATCH',
115
+ reviewerError: invocationResult.error,
116
+ };
117
+ }
118
+ // Parse and validate reviewer output
119
+ let decision;
120
+ try {
121
+ // The result should match reviewer_result.schema.json structure
122
+ const parsed = invocationResult.result;
123
+ if (!parsed.decision ||
124
+ !['proceed', 'force_patch', 'ask_question'].includes(parsed.decision)) {
125
+ throw new Error(`Invalid decision: ${parsed.decision}`);
126
+ }
127
+ decision = parsed;
128
+ }
129
+ catch (error) {
130
+ return {
131
+ stopCode: 'STOP_REVIEWER_FORCED_PATCH',
132
+ reviewerError: `Failed to parse reviewer decision: ${error instanceof Error ? error.message : String(error)}`,
133
+ };
134
+ }
135
+ // Handle the decision
136
+ return handleReviewerDecision(decision);
137
+ }
138
+ //# sourceMappingURL=reviewer-flow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer-flow.js","sourceRoot":"","sources":["../../src/lib/reviewer-flow.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Codex CLI wrapper for invoking reviewer with proper flags.
3
+ *
4
+ * Provides functions to invoke the reviewer, parse responses, and check authentication.
5
+ */
6
+ import type { ReviewerInvocationConfig, ReviewerContext, ReviewerInvocationResult } from '../types/reviewer.js';
7
+ /**
8
+ * Checks if reviewer authentication is configured.
9
+ *
10
+ * Checks for CODEX_API_KEY environment variable presence as a best-effort
11
+ * authentication check (V1 implementation).
12
+ *
13
+ * @returns Object with authentication status
14
+ */
15
+ export declare function checkReviewerAuth(): {
16
+ authenticated: boolean;
17
+ reason?: string;
18
+ };
19
+ /**
20
+ * Parses the JSON response from Codex CLI and extracts the result.
21
+ *
22
+ * Handles two formats:
23
+ * 1. Wrapper format: { result: 'JSON string', ... } - parses the .result field as JSON
24
+ * 2. Direct JSON format: { ... } - uses the parsed JSON directly
25
+ *
26
+ * @param stdout - Standard output from CLI process
27
+ * @returns Parsed result object
28
+ * @throws {Error} If JSON parsing fails
29
+ */
30
+ export declare function parseReviewerOutput(stdout: string): object;
31
+ /**
32
+ * Invokes Codex CLI reviewer with the given configuration and context.
33
+ *
34
+ * @param config - Codex CLI reviewer configuration
35
+ * @param context - Reviewer context including prompt and optional system prompt
36
+ * @returns Promise resolving to ReviewerInvocationResult (success or error)
37
+ *
38
+ * @example
39
+ * ```typescript
40
+ * const result = await invokeReviewer(config, {
41
+ * prompt: 'Review this code...',
42
+ * systemPrompt: '/path/to/system.txt'
43
+ * });
44
+ *
45
+ * if (result.success) {
46
+ * console.log('Review result:', result.result);
47
+ * } else {
48
+ * console.error('Review failed:', result.error);
49
+ * }
50
+ * ```
51
+ */
52
+ export declare function invokeReviewer(config: ReviewerInvocationConfig, context: ReviewerContext): Promise<ReviewerInvocationResult>;
53
+ //# sourceMappingURL=reviewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.d.ts","sourceRoot":"","sources":["../../src/lib/reviewer.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,KAAK,EAAE,wBAAwB,EAAE,eAAe,EAAE,wBAAwB,EAAiC,MAAM,sBAAsB,CAAC;AAE/I;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,CAe/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CA8B1D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,cAAc,CAClC,MAAM,EAAE,wBAAwB,EAChC,OAAO,EAAE,eAAe,GACvB,OAAO,CAAC,wBAAwB,CAAC,CAyHnC"}
@@ -0,0 +1,199 @@
1
+ /**
2
+ * Codex CLI wrapper for invoking reviewer with proper flags.
3
+ *
4
+ * Provides functions to invoke the reviewer, parse responses, and check authentication.
5
+ */
6
+ import { spawn } from 'node:child_process';
7
+ /**
8
+ * Checks if reviewer authentication is configured.
9
+ *
10
+ * Checks for CODEX_API_KEY environment variable presence as a best-effort
11
+ * authentication check (V1 implementation).
12
+ *
13
+ * @returns Object with authentication status
14
+ */
15
+ export function checkReviewerAuth() {
16
+ const apiKey = process.env.CODEX_API_KEY;
17
+ if (!apiKey) {
18
+ return {
19
+ authenticated: false,
20
+ reason: 'CODEX_API_KEY environment variable not set',
21
+ };
22
+ }
23
+ if (apiKey.trim().length === 0) {
24
+ return {
25
+ authenticated: false,
26
+ reason: 'CODEX_API_KEY environment variable is empty',
27
+ };
28
+ }
29
+ return { authenticated: true };
30
+ }
31
+ /**
32
+ * Parses the JSON response from Codex CLI and extracts the result.
33
+ *
34
+ * Handles two formats:
35
+ * 1. Wrapper format: { result: 'JSON string', ... } - parses the .result field as JSON
36
+ * 2. Direct JSON format: { ... } - uses the parsed JSON directly
37
+ *
38
+ * @param stdout - Standard output from CLI process
39
+ * @returns Parsed result object
40
+ * @throws {Error} If JSON parsing fails
41
+ */
42
+ export function parseReviewerOutput(stdout) {
43
+ let parsed;
44
+ try {
45
+ parsed = JSON.parse(stdout);
46
+ }
47
+ catch (error) {
48
+ throw new Error(`Failed to parse JSON response: ${error instanceof Error ? error.message : String(error)}`);
49
+ }
50
+ if (typeof parsed !== 'object' || parsed === null) {
51
+ throw new Error('Parsed response is not an object');
52
+ }
53
+ const obj = parsed;
54
+ // Check if it's a wrapper format with .result field
55
+ if (typeof obj.result === 'string') {
56
+ try {
57
+ // Parse the nested JSON string
58
+ const nestedParsed = JSON.parse(obj.result);
59
+ if (typeof nestedParsed === 'object' && nestedParsed !== null) {
60
+ return nestedParsed;
61
+ }
62
+ // If nested parse didn't yield an object, fall through to return wrapper
63
+ }
64
+ catch {
65
+ // If parsing .result fails, fall through to return wrapper
66
+ }
67
+ }
68
+ // Return direct JSON or wrapper object
69
+ return parsed;
70
+ }
71
+ /**
72
+ * Invokes Codex CLI reviewer with the given configuration and context.
73
+ *
74
+ * @param config - Codex CLI reviewer configuration
75
+ * @param context - Reviewer context including prompt and optional system prompt
76
+ * @returns Promise resolving to ReviewerInvocationResult (success or error)
77
+ *
78
+ * @example
79
+ * ```typescript
80
+ * const result = await invokeReviewer(config, {
81
+ * prompt: 'Review this code...',
82
+ * systemPrompt: '/path/to/system.txt'
83
+ * });
84
+ *
85
+ * if (result.success) {
86
+ * console.log('Review result:', result.result);
87
+ * } else {
88
+ * console.error('Review failed:', result.error);
89
+ * }
90
+ * ```
91
+ */
92
+ export async function invokeReviewer(config, context) {
93
+ const startTime = Date.now();
94
+ // Build CLI arguments
95
+ const args = [
96
+ '-p', // prompt mode (non-interactive)
97
+ '--model',
98
+ config.model,
99
+ '--max-turns',
100
+ config.maxTurns.toString(),
101
+ ];
102
+ // Add optional system-prompt flag
103
+ if (context.systemPrompt) {
104
+ args.push('--system-prompt', context.systemPrompt);
105
+ }
106
+ // Add the prompt as the last argument
107
+ args.push(context.prompt);
108
+ return new Promise((resolve) => {
109
+ let stdout = '';
110
+ let stderr = '';
111
+ let timeoutId = null;
112
+ // Spawn the process (shell: false for security)
113
+ const child = spawn(config.command, args, {
114
+ stdio: ['pipe', 'pipe', 'pipe'],
115
+ shell: false,
116
+ });
117
+ // Set up timeout
118
+ if (config.timeout > 0) {
119
+ timeoutId = setTimeout(() => {
120
+ child.kill('SIGTERM');
121
+ const durationMs = Date.now() - startTime;
122
+ resolve({
123
+ success: false,
124
+ error: `Codex CLI invocation timed out after ${config.timeout}ms`,
125
+ exitCode: 124, // Standard timeout exit code
126
+ stderr,
127
+ durationMs,
128
+ });
129
+ }, config.timeout);
130
+ }
131
+ // Capture stdout
132
+ child.stdout?.on('data', (data) => {
133
+ stdout += data.toString();
134
+ });
135
+ // Capture stderr
136
+ child.stderr?.on('data', (data) => {
137
+ stderr += data.toString();
138
+ });
139
+ // Handle process completion
140
+ child.on('close', (code) => {
141
+ if (timeoutId) {
142
+ clearTimeout(timeoutId);
143
+ }
144
+ const durationMs = Date.now() - startTime;
145
+ const exitCode = code ?? 0;
146
+ // If process was killed by timeout, error was already handled
147
+ if (code === null && timeoutId) {
148
+ return;
149
+ }
150
+ // Try to parse the output
151
+ try {
152
+ const parsed = parseReviewerOutput(stdout);
153
+ // Basic validation: ensure it's an object
154
+ // Full schema validation will be added in WP-072 when reviewer_result.schema.json exists
155
+ if (typeof parsed !== 'object' || parsed === null) {
156
+ resolve({
157
+ success: false,
158
+ error: 'Reviewer output is not a valid object',
159
+ exitCode,
160
+ stderr,
161
+ durationMs,
162
+ });
163
+ return;
164
+ }
165
+ resolve({
166
+ success: true,
167
+ result: parsed,
168
+ raw: JSON.parse(stdout), // Keep original wrapper if present
169
+ exitCode,
170
+ durationMs,
171
+ });
172
+ }
173
+ catch (error) {
174
+ resolve({
175
+ success: false,
176
+ error: `Failed to parse reviewer output: ${error instanceof Error ? error.message : String(error)}`,
177
+ exitCode,
178
+ stderr,
179
+ durationMs,
180
+ });
181
+ }
182
+ });
183
+ // Handle process errors
184
+ child.on('error', (error) => {
185
+ if (timeoutId) {
186
+ clearTimeout(timeoutId);
187
+ }
188
+ const durationMs = Date.now() - startTime;
189
+ resolve({
190
+ success: false,
191
+ error: `Failed to spawn Codex CLI process: ${error.message}`,
192
+ exitCode: 1,
193
+ stderr,
194
+ durationMs,
195
+ });
196
+ });
197
+ });
198
+ }
199
+ //# sourceMappingURL=reviewer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reviewer.js","sourceRoot":"","sources":["../../src/lib/reviewer.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Risk scoring and reviewer trigger logic.
3
+ *
4
+ * Determines when the reviewer should be invoked based on deterministic
5
+ * risk signals: high-risk file paths, diff fraction thresholds, repeated
6
+ * stops, verification failures, and budget warnings.
7
+ */
8
+ import type { DiffAnalysis } from './diff.js';
9
+ import type { ReviewerConfig, ReviewerTriggerConfig } from '../types/config.js';
10
+ import type { TaskScope, DiffLimits } from '../types/task.js';
11
+ import type { RiskFlags } from '../types/reviewer.js';
12
+ /**
13
+ * Stop history entry representing a single stop event.
14
+ */
15
+ export interface StopHistoryEntry {
16
+ /** Tick number when the stop occurred */
17
+ tick: number;
18
+ /** Verdict of the stop (should be 'stop') */
19
+ verdict: 'stop';
20
+ }
21
+ /**
22
+ * Checks if any paths match high-risk glob patterns.
23
+ *
24
+ * Uses micromatch to check paths against high_risk_globs patterns.
25
+ *
26
+ * @param paths - Array of file paths to check
27
+ * @param highRiskGlobs - Array of glob patterns for high-risk files
28
+ * @returns Array of paths that match high-risk patterns
29
+ *
30
+ * @example
31
+ * const riskyPaths = checkHighRiskGlobs(
32
+ * ['src/auth.ts', 'src/utils.ts'],
33
+ * ['src/auth*.ts', 'src/*secret*']
34
+ * );
35
+ */
36
+ export declare function checkHighRiskGlobs(paths: string[], highRiskGlobs: string[]): string[];
37
+ /**
38
+ * Checks if diff fraction exceeds threshold.
39
+ *
40
+ * Calculates files_touched/max_files_touched or lines_changed/max_lines_changed
41
+ * and checks if either fraction >= threshold.
42
+ *
43
+ * @param analysis - Diff analysis result
44
+ * @param limits - Diff limits from task
45
+ * @param threshold - Fraction threshold (0.0 to 1.0)
46
+ * @returns True if diff fraction >= threshold
47
+ *
48
+ * @example
49
+ * const analysis = { files_touched: 8, lines_changed: 300, ... };
50
+ * const limits = { max_files_touched: 10, max_lines_changed: 400 };
51
+ * const nearCap = checkDiffFraction(analysis, limits, 0.8);
52
+ */
53
+ export declare function checkDiffFraction(analysis: DiffAnalysis, limits: DiffLimits, threshold: number): boolean;
54
+ /**
55
+ * Checks if there are repeated stops within a time window.
56
+ *
57
+ * Counts STOP verdicts in stop_history within the specified window
58
+ * and checks if count >= maxStops.
59
+ *
60
+ * @param stopHistory - Array of stop history entries
61
+ * @param window - Time window in ticks
62
+ * @param maxStops - Maximum number of stops allowed in window
63
+ * @param currentTick - Current tick number
64
+ * @returns True if repeated stops detected
65
+ *
66
+ * @example
67
+ * const history = [
68
+ * { tick: 5, verdict: 'stop' },
69
+ * { tick: 8, verdict: 'stop' },
70
+ * { tick: 12, verdict: 'stop' }
71
+ * ];
72
+ * const repeated = checkRepeatedStops(history, 10, 2, 12);
73
+ */
74
+ export declare function checkRepeatedStops(stopHistory: StopHistoryEntry[], window: number, maxStops: number, currentTick: number): boolean;
75
+ /**
76
+ * Computes risk flags based on various risk signals.
77
+ *
78
+ * Returns an array of risk flag strings indicating which risk conditions
79
+ * have been triggered.
80
+ *
81
+ * @param params - Parameters for risk computation
82
+ * @param params.analysis - Diff analysis result
83
+ * @param params.limits - Diff limits from task
84
+ * @param params.scope - Task scope configuration
85
+ * @param params.trigger - Reviewer trigger configuration
86
+ * @param params.stopHistory - Array of stop history entries
87
+ * @param params.currentTick - Current tick number
88
+ * @param params.verifyFailed - Whether verification failed
89
+ * @param params.budgetWarning - Whether budget warning threshold reached
90
+ * @returns Array of risk flag strings
91
+ *
92
+ * @example
93
+ * const flags = computeRiskFlags({
94
+ * analysis,
95
+ * limits,
96
+ * scope,
97
+ * trigger,
98
+ * stopHistory: [],
99
+ * currentTick: 10,
100
+ * verifyFailed: false,
101
+ * budgetWarning: false
102
+ * });
103
+ */
104
+ export declare function computeRiskFlags(params: {
105
+ analysis: DiffAnalysis;
106
+ limits: DiffLimits;
107
+ scope: TaskScope;
108
+ trigger: ReviewerTriggerConfig;
109
+ stopHistory: StopHistoryEntry[];
110
+ currentTick: number;
111
+ verifyFailed: boolean;
112
+ budgetWarning: boolean;
113
+ }): RiskFlags[];
114
+ /**
115
+ * Determines if reviewer should be triggered based on risk flags and config.
116
+ *
117
+ * Returns true if reviewer is enabled and any trigger condition is met.
118
+ *
119
+ * @param config - Reviewer configuration
120
+ * @param riskFlags - Array of risk flags from computeRiskFlags
121
+ * @returns True if reviewer should be triggered
122
+ *
123
+ * @example
124
+ * const shouldTrigger = shouldTriggerReviewer(config, ['high_risk_path', 'diff_near_cap']);
125
+ */
126
+ export declare function shouldTriggerReviewer(config: ReviewerConfig, riskFlags: RiskFlags[]): boolean;
127
+ //# sourceMappingURL=risk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"risk.d.ts","sourceRoot":"","sources":["../../src/lib/risk.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AAChF,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEtD;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,6CAA6C;IAC7C,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,EAAE,MAAM,EAAE,GACtB,MAAM,EAAE,CAOV;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,YAAY,EACtB,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,MAAM,GAChB,OAAO,CAiBT;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,gBAAgB,EAAE,EAC/B,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,GAClB,OAAO,CAYT;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE;IACvC,QAAQ,EAAE,YAAY,CAAC;IACvB,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,EAAE,qBAAqB,CAAC;IAC/B,WAAW,EAAE,gBAAgB,EAAE,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,OAAO,CAAC;CACxB,GAAG,SAAS,EAAE,CAsFd;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,cAAc,EACtB,SAAS,EAAE,SAAS,EAAE,GACrB,OAAO,CAQT"}