@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,237 @@
1
+ /**
2
+ * Transport layer utilities for Claude invocations.
3
+ *
4
+ * Provides stall detection and timeout wrapper for reliable
5
+ * handling of connection issues, timeouts, and transport failures.
6
+ */
7
+ import { ClaudeError } from '../types/claude.js';
8
+ import { invokeClaudeCode } from './claude.js';
9
+ /**
10
+ * Maximum length for raw_error in TransportStallError.
11
+ * Truncates error messages to prevent excessive memory usage.
12
+ */
13
+ const MAX_RAW_ERROR_LENGTH = 500;
14
+ /**
15
+ * Patterns that indicate a transport stall.
16
+ */
17
+ const STALL_PATTERNS = [
18
+ 'Connection stalled',
19
+ 'streamFromAgentBackend',
20
+ 'ECONNRESET',
21
+ 'ETIMEDOUT',
22
+ 'socket hang up',
23
+ ];
24
+ /**
25
+ * Detects transport stall patterns in error output.
26
+ *
27
+ * Checks for known patterns that indicate connection issues:
28
+ * - "Connection stalled" - Cursor/CLI connection issue
29
+ * - "streamFromAgentBackend" - Backend stream failure
30
+ * - "ECONNRESET" - Connection reset by peer
31
+ * - "ETIMEDOUT" - Connection timeout
32
+ * - "socket hang up" - Socket disconnection
33
+ *
34
+ * Also extracts Request ID if present for debugging.
35
+ *
36
+ * @param error - Error message or stderr output to analyze
37
+ * @returns Detection result with stalled flag and optional request_id
38
+ *
39
+ * @example
40
+ * ```typescript
41
+ * const result = isTransportStall('Connection stalled. Request ID: abc123');
42
+ * // result.stalled === true
43
+ * // result.request_id === 'abc123'
44
+ * ```
45
+ */
46
+ export function isTransportStall(error) {
47
+ if (!error) {
48
+ return { stalled: false, request_id: null, matched_pattern: null };
49
+ }
50
+ // Check for stall patterns
51
+ let matchedPattern = null;
52
+ for (const pattern of STALL_PATTERNS) {
53
+ if (error.includes(pattern)) {
54
+ matchedPattern = pattern;
55
+ break;
56
+ }
57
+ }
58
+ // Extract Request ID if present
59
+ // Common formats: "Request ID: xxx", "request_id: xxx", "requestId: xxx"
60
+ let requestId = null;
61
+ const requestIdMatch = error.match(/[Rr]equest[_\s]?[Ii][Dd][:\s]+([a-zA-Z0-9_-]+)/);
62
+ if (requestIdMatch) {
63
+ requestId = requestIdMatch[1];
64
+ }
65
+ return {
66
+ stalled: matchedPattern !== null,
67
+ request_id: requestId,
68
+ matched_pattern: matchedPattern,
69
+ };
70
+ }
71
+ /**
72
+ * Creates a TransportStallError from error information.
73
+ *
74
+ * @param stage - The stage where the stall occurred (ORCHESTRATE or BUILD)
75
+ * @param rawError - The raw error message
76
+ * @param requestId - Optional request ID extracted from error
77
+ * @returns Structured TransportStallError
78
+ */
79
+ export function createTransportStallError(stage, rawError, requestId = null) {
80
+ // Truncate raw_error to prevent excessive length
81
+ const truncatedError = rawError.length > MAX_RAW_ERROR_LENGTH
82
+ ? rawError.substring(0, MAX_RAW_ERROR_LENGTH) + '...'
83
+ : rawError;
84
+ return {
85
+ kind: 'transport_stalled',
86
+ stage,
87
+ request_id: requestId,
88
+ raw_error: truncatedError,
89
+ };
90
+ }
91
+ /**
92
+ * Invokes Claude Code CLI with stall detection.
93
+ *
94
+ * Wraps the standard invokeClaudeCode function and:
95
+ * 1. Catches timeout errors and converts to TransportStallError
96
+ * 2. Detects stall patterns in error output
97
+ * 3. Returns structured error for transport failures
98
+ *
99
+ * @param config - Claude Code CLI configuration
100
+ * @param invocation - Invocation parameters
101
+ * @param stage - The stage (ORCHESTRATE or BUILD) for error context
102
+ * @returns InvokeResult with either response or stall error
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const result = await invokeWithStallDetection(config, invocation, 'BUILD');
107
+ * if (result.ok) {
108
+ * console.log('Success:', result.response.result);
109
+ * } else {
110
+ * console.log('Stall:', result.error.raw_error);
111
+ * }
112
+ * ```
113
+ */
114
+ export async function invokeWithStallDetection(config, invocation, stage) {
115
+ try {
116
+ const response = await invokeClaudeCode(config, invocation);
117
+ return { ok: true, response };
118
+ }
119
+ catch (error) {
120
+ // Handle ClaudeError (timeout, process errors, etc.)
121
+ if (error instanceof ClaudeError) {
122
+ const errorMessage = error.message + (error.stderr ? `\n${error.stderr}` : '');
123
+ // Check if this is a timeout (exit code 124 is standard timeout)
124
+ const isTimeout = error.exitCode === 124 || error.message.includes('timed out');
125
+ // Check for stall patterns
126
+ const stallCheck = isTransportStall(errorMessage);
127
+ // If timeout or stall pattern detected, return TransportStallError
128
+ if (isTimeout || stallCheck.stalled) {
129
+ return {
130
+ ok: false,
131
+ error: createTransportStallError(stage, errorMessage, stallCheck.request_id),
132
+ };
133
+ }
134
+ // For other ClaudeErrors, re-throw (not a transport stall)
135
+ throw error;
136
+ }
137
+ // For unexpected errors, check if they contain stall patterns
138
+ const errorMessage = error instanceof Error ? error.message : String(error);
139
+ const stallCheck = isTransportStall(errorMessage);
140
+ if (stallCheck.stalled) {
141
+ return {
142
+ ok: false,
143
+ error: createTransportStallError(stage, errorMessage, stallCheck.request_id),
144
+ };
145
+ }
146
+ // Re-throw non-transport errors
147
+ throw error;
148
+ }
149
+ }
150
+ /**
151
+ * Normalizes any error type into a consistent format for stall detection.
152
+ *
153
+ * Handles:
154
+ * - ClaudeError: extracts message + stderr, checks for timeout
155
+ * - Error: extracts message
156
+ * - string: wraps in Error
157
+ * - unknown: converts to string and wraps in Error
158
+ *
159
+ * @param error - Any error type (ClaudeError, Error, string, unknown)
160
+ * @param stage - The stage where the error occurred (ORCHESTRATE or BUILD)
161
+ * @returns Normalized error with stall detection result
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * try {
166
+ * await invokeClaudeCode(config, invocation);
167
+ * } catch (error) {
168
+ * const normalized = normalizeTransportError(error, 'BUILD');
169
+ * if (normalized.isStall) {
170
+ * handleStall(normalized.stallError);
171
+ * } else {
172
+ * throw normalized.originalError;
173
+ * }
174
+ * }
175
+ * ```
176
+ */
177
+ /**
178
+ * Type guard to check if an error is a TransportStallError.
179
+ *
180
+ * @param error - Any value to check
181
+ * @returns True if the error is a TransportStallError
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const result = await invokeWithStallDetection(config, invocation, 'BUILD');
186
+ * if (!result.ok && isTransportStallError(result.error)) {
187
+ * console.log('Stage:', result.error.stage);
188
+ * console.log('Request ID:', result.error.request_id);
189
+ * }
190
+ * ```
191
+ */
192
+ export function isTransportStallError(error) {
193
+ if (typeof error !== 'object' || error === null) {
194
+ return false;
195
+ }
196
+ const obj = error;
197
+ return (obj.kind === 'transport_stalled' &&
198
+ (obj.stage === 'ORCHESTRATE' || obj.stage === 'BUILD') &&
199
+ (typeof obj.request_id === 'string' || obj.request_id === null) &&
200
+ typeof obj.raw_error === 'string');
201
+ }
202
+ export function normalizeTransportError(error, stage) {
203
+ let message;
204
+ let originalError;
205
+ let isTimeout = false;
206
+ // Handle different error types
207
+ if (error instanceof ClaudeError) {
208
+ message = error.message + (error.stderr ? `\n${error.stderr}` : '');
209
+ originalError = error;
210
+ isTimeout = error.exitCode === 124 || error.message.includes('timed out');
211
+ }
212
+ else if (error instanceof Error) {
213
+ message = error.message;
214
+ originalError = error;
215
+ }
216
+ else if (typeof error === 'string') {
217
+ message = error;
218
+ originalError = new Error(error);
219
+ }
220
+ else {
221
+ message = String(error);
222
+ originalError = new Error(message);
223
+ }
224
+ // Check for stall patterns
225
+ const stallCheck = isTransportStall(message);
226
+ // Determine if this is a stall
227
+ const isStall = isTimeout || stallCheck.stalled;
228
+ return {
229
+ isStall,
230
+ stallError: isStall
231
+ ? createTransportStallError(stage, message, stallCheck.request_id)
232
+ : null,
233
+ originalError,
234
+ message,
235
+ };
236
+ }
237
+ //# sourceMappingURL=transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../../src/lib/transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Verdict } from '../types/report.js';
2
+ export type DisplayState = 'CLEARED' | 'STANDBY' | 'BLOCKED' | 'OUT_OF_BOUNDS' | 'LIMIT_HIT' | 'ROLLED_BACK';
3
+ export declare function toDisplayState(verdict: Verdict, code: string): DisplayState;
4
+ export declare function formatDisplayState(verdict: Verdict, code: string): string;
5
+ //# sourceMappingURL=verdict_labels.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict_labels.d.ts","sourceRoot":"","sources":["../../src/lib/verdict_labels.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,MAAM,YAAY,GACpB,SAAS,GACT,SAAS,GACT,SAAS,GACT,eAAe,GACf,WAAW,GACX,aAAa,CAAC;AAclB,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,YAAY,CAO3E;AAED,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzE"}
@@ -0,0 +1,25 @@
1
+ function isOutOfBounds(code) {
2
+ return (code.startsWith('STOP_SCOPE_VIOLATION') ||
3
+ code === 'STOP_RUNNER_OWNED_MUTATION' ||
4
+ code === 'STOP_LOCKFILE_CHANGE_FORBIDDEN');
5
+ }
6
+ function isLimitHit(code) {
7
+ return code === 'STOP_DIFF_TOO_LARGE' || code.startsWith('BLOCKED_BUDGET_');
8
+ }
9
+ export function toDisplayState(verdict, code) {
10
+ if (code === 'SUCCESS' || verdict === 'success')
11
+ return 'CLEARED';
12
+ if (isOutOfBounds(code))
13
+ return 'OUT_OF_BOUNDS';
14
+ if (isLimitHit(code))
15
+ return 'LIMIT_HIT';
16
+ if (code === 'STOP_INTERRUPTED' || verdict === 'stop')
17
+ return 'STANDBY';
18
+ if (code.startsWith('BLOCKED_') || verdict === 'blocked')
19
+ return 'BLOCKED';
20
+ return 'STANDBY';
21
+ }
22
+ export function formatDisplayState(verdict, code) {
23
+ return `${toDisplayState(verdict, code)} (${code})`;
24
+ }
25
+ //# sourceMappingURL=verdict_labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verdict_labels.js","sourceRoot":"","sources":["../../src/lib/verdict_labels.ts"],"names":[],"mappings":"AAUA,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,CACL,IAAI,CAAC,UAAU,CAAC,sBAAsB,CAAC;QACvC,IAAI,KAAK,4BAA4B;QACrC,IAAI,KAAK,gCAAgC,CAC1C,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,IAAI,KAAK,qBAAqB,IAAI,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,CAAC;AAC9E,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,OAAgB,EAAE,IAAY;IAC3D,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAClE,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,eAAe,CAAC;IAChD,IAAI,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC;IACzC,IAAI,IAAI,KAAK,kBAAkB,IAAI,OAAO,KAAK,MAAM;QAAE,OAAO,SAAS,CAAC;IACxE,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,OAAO,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IAC3E,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAgB,EAAE,IAAY;IAC/D,OAAO,GAAG,cAAc,CAAC,OAAO,EAAE,IAAI,CAAC,KAAK,IAAI,GAAG,CAAC;AACtD,CAAC"}
@@ -0,0 +1,63 @@
1
+ /**
2
+ * Verification parameter safety validation module.
3
+ *
4
+ * Provides functions to validate verification parameters against security constraints
5
+ * to prevent shell injection and other security issues.
6
+ */
7
+ import type { VerificationConfig } from '../types/config.js';
8
+ /**
9
+ * Result of parameter validation.
10
+ */
11
+ export interface ParamValidationResult {
12
+ /** True if the parameter(s) are valid */
13
+ ok: boolean;
14
+ /** Stop code to use if validation fails */
15
+ stopCode: 'STOP_VERIFY_TAINTED' | null;
16
+ /** Name of the invalid parameter (if any) */
17
+ invalidParam: string | null;
18
+ /** Reason for validation failure */
19
+ reason: string | null;
20
+ }
21
+ /**
22
+ * Validates a single verification parameter against security constraints.
23
+ *
24
+ * Checks for:
25
+ * - Length exceeding max_param_len
26
+ * - Whitespace (if reject_whitespace_in_params is true)
27
+ * - Path traversal '..' (if reject_dotdot is true)
28
+ * - Shell metacharacters (using reject_metachars_regex)
29
+ *
30
+ * @param param - The parameter value to validate
31
+ * @param config - Verification configuration with validation rules
32
+ * @returns ParamValidationResult with ok=true if valid, or failure details
33
+ *
34
+ * @example
35
+ * ```typescript
36
+ * const result = validateVerifyParam('my-value', config);
37
+ * if (!result.ok) {
38
+ * console.error(`Invalid param: ${result.reason}`);
39
+ * }
40
+ * ```
41
+ */
42
+ export declare function validateVerifyParam(param: string, config: VerificationConfig): ParamValidationResult;
43
+ /**
44
+ * Validates all parameters in a record, returning the first failure.
45
+ *
46
+ * Validates each parameter value in the params object against the security
47
+ * constraints defined in the verification config. Returns the first validation
48
+ * failure encountered, or success if all parameters are valid.
49
+ *
50
+ * @param params - Record mapping parameter names to string values
51
+ * @param config - Verification configuration with validation rules
52
+ * @returns ParamValidationResult with ok=true if all params valid, or first failure details
53
+ *
54
+ * @example
55
+ * ```typescript
56
+ * const result = validateAllParams({ pkg: 'my-package', env: 'prod' }, config);
57
+ * if (!result.ok) {
58
+ * console.error(`Invalid param '${result.invalidParam}': ${result.reason}`);
59
+ * }
60
+ * ```
61
+ */
62
+ export declare function validateAllParams(params: Record<string, string>, config: VerificationConfig): ParamValidationResult;
63
+ //# sourceMappingURL=verify-safety.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-safety.d.ts","sourceRoot":"","sources":["../../src/lib/verify-safety.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAE7D;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,yCAAyC;IACzC,EAAE,EAAE,OAAO,CAAC;IACZ,2CAA2C;IAC3C,QAAQ,EAAE,qBAAqB,GAAG,IAAI,CAAC;IACvC,6CAA6C;IAC7C,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,oCAAoC;IACpC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,kBAAkB,GACzB,qBAAqB,CA4DvB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,MAAM,EAAE,kBAAkB,GACzB,qBAAqB,CAkBvB"}
@@ -0,0 +1,123 @@
1
+ /**
2
+ * Verification parameter safety validation module.
3
+ *
4
+ * Provides functions to validate verification parameters against security constraints
5
+ * to prevent shell injection and other security issues.
6
+ */
7
+ /**
8
+ * Validates a single verification parameter against security constraints.
9
+ *
10
+ * Checks for:
11
+ * - Length exceeding max_param_len
12
+ * - Whitespace (if reject_whitespace_in_params is true)
13
+ * - Path traversal '..' (if reject_dotdot is true)
14
+ * - Shell metacharacters (using reject_metachars_regex)
15
+ *
16
+ * @param param - The parameter value to validate
17
+ * @param config - Verification configuration with validation rules
18
+ * @returns ParamValidationResult with ok=true if valid, or failure details
19
+ *
20
+ * @example
21
+ * ```typescript
22
+ * const result = validateVerifyParam('my-value', config);
23
+ * if (!result.ok) {
24
+ * console.error(`Invalid param: ${result.reason}`);
25
+ * }
26
+ * ```
27
+ */
28
+ export function validateVerifyParam(param, config) {
29
+ // Check length
30
+ if (param.length > config.max_param_len) {
31
+ return {
32
+ ok: false,
33
+ stopCode: 'STOP_VERIFY_TAINTED',
34
+ invalidParam: null,
35
+ reason: `Parameter length ${param.length} exceeds maximum ${config.max_param_len}`,
36
+ };
37
+ }
38
+ // Check for whitespace if enabled
39
+ if (config.reject_whitespace_in_params && /\s/.test(param)) {
40
+ return {
41
+ ok: false,
42
+ stopCode: 'STOP_VERIFY_TAINTED',
43
+ invalidParam: null,
44
+ reason: 'Parameter contains whitespace',
45
+ };
46
+ }
47
+ // Check for path traversal '..' if enabled
48
+ if (config.reject_dotdot && param.includes('..')) {
49
+ return {
50
+ ok: false,
51
+ stopCode: 'STOP_VERIFY_TAINTED',
52
+ invalidParam: null,
53
+ reason: "Parameter contains '..' path traversal",
54
+ };
55
+ }
56
+ // Check for shell metacharacters
57
+ try {
58
+ const metacharRegex = new RegExp(config.reject_metachars_regex);
59
+ if (metacharRegex.test(param)) {
60
+ return {
61
+ ok: false,
62
+ stopCode: 'STOP_VERIFY_TAINTED',
63
+ invalidParam: null,
64
+ reason: `Parameter matches metacharacter regex: ${config.reject_metachars_regex}`,
65
+ };
66
+ }
67
+ }
68
+ catch (error) {
69
+ // If regex is invalid, treat as validation failure
70
+ // This shouldn't happen with valid config, but be defensive
71
+ return {
72
+ ok: false,
73
+ stopCode: 'STOP_VERIFY_TAINTED',
74
+ invalidParam: null,
75
+ reason: `Invalid metacharacter regex in config: ${error instanceof Error ? error.message : String(error)}`,
76
+ };
77
+ }
78
+ // All checks passed
79
+ return {
80
+ ok: true,
81
+ stopCode: null,
82
+ invalidParam: null,
83
+ reason: null,
84
+ };
85
+ }
86
+ /**
87
+ * Validates all parameters in a record, returning the first failure.
88
+ *
89
+ * Validates each parameter value in the params object against the security
90
+ * constraints defined in the verification config. Returns the first validation
91
+ * failure encountered, or success if all parameters are valid.
92
+ *
93
+ * @param params - Record mapping parameter names to string values
94
+ * @param config - Verification configuration with validation rules
95
+ * @returns ParamValidationResult with ok=true if all params valid, or first failure details
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const result = validateAllParams({ pkg: 'my-package', env: 'prod' }, config);
100
+ * if (!result.ok) {
101
+ * console.error(`Invalid param '${result.invalidParam}': ${result.reason}`);
102
+ * }
103
+ * ```
104
+ */
105
+ export function validateAllParams(params, config) {
106
+ for (const [paramName, paramValue] of Object.entries(params)) {
107
+ const result = validateVerifyParam(paramValue, config);
108
+ if (!result.ok) {
109
+ return {
110
+ ...result,
111
+ invalidParam: paramName,
112
+ };
113
+ }
114
+ }
115
+ // All parameters are valid
116
+ return {
117
+ ok: true,
118
+ stopCode: null,
119
+ invalidParam: null,
120
+ reason: null,
121
+ };
122
+ }
123
+ //# sourceMappingURL=verify-safety.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-safety.js","sourceRoot":"","sources":["../../src/lib/verify-safety.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,UAAU,mBAAmB,CACjC,KAAa,EACb,MAA0B;IAE1B,eAAe;IACf,IAAI,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,aAAa,EAAE,CAAC;QACxC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,qBAAqB;YAC/B,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,oBAAoB,KAAK,CAAC,MAAM,oBAAoB,MAAM,CAAC,aAAa,EAAE;SACnF,CAAC;IACJ,CAAC;IAED,kCAAkC;IAClC,IAAI,MAAM,CAAC,2BAA2B,IAAI,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,qBAAqB;YAC/B,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,+BAA+B;SACxC,CAAC;IACJ,CAAC;IAED,2CAA2C;IAC3C,IAAI,MAAM,CAAC,aAAa,IAAI,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,qBAAqB;YAC/B,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,wCAAwC;SACjD,CAAC;IACJ,CAAC;IAED,iCAAiC;IACjC,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,IAAI,MAAM,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC;QAChE,IAAI,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YAC9B,OAAO;gBACL,EAAE,EAAE,KAAK;gBACT,QAAQ,EAAE,qBAAqB;gBAC/B,YAAY,EAAE,IAAI;gBAClB,MAAM,EAAE,0CAA0C,MAAM,CAAC,sBAAsB,EAAE;aAClF,CAAC;QACJ,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,mDAAmD;QACnD,4DAA4D;QAC5D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,QAAQ,EAAE,qBAAqB;YAC/B,YAAY,EAAE,IAAI;YAClB,MAAM,EAAE,0CAA0C,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SAC3G,CAAC;IACJ,CAAC;IAED,oBAAoB;IACpB,OAAO;QACL,EAAE,EAAE,IAAI;QACR,QAAQ,EAAE,IAAI;QACd,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,IAAI;KACb,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA8B,EAC9B,MAA0B;IAE1B,KAAK,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC7D,MAAM,MAAM,GAAG,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC;YACf,OAAO;gBACL,GAAG,MAAM;gBACT,YAAY,EAAE,SAAS;aACxB,CAAC;QACJ,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,OAAO;QACL,EAAE,EAAE,IAAI;QACR,QAAQ,EAAE,IAAI;QACd,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,IAAI;KACb,CAAC;AACJ,CAAC"}
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Verification command execution module.
3
+ *
4
+ * Provides functions to execute verification commands safely using argv arrays
5
+ * (no shell) with parameter interpolation and timeout handling.
6
+ */
7
+ import type { VerificationTemplate, VerificationConfig } from '../types/config.js';
8
+ import type { Task } from '../types/task.js';
9
+ /**
10
+ * Result of a single verification command execution.
11
+ */
12
+ export interface VerificationRun {
13
+ /** ID of the verification template */
14
+ template_id: string;
15
+ /** Process exit code */
16
+ exit_code: number;
17
+ /** Captured stdout */
18
+ stdout: string;
19
+ /** Captured stderr */
20
+ stderr: string;
21
+ /** Execution time in milliseconds */
22
+ duration_ms: number;
23
+ /** Whether the command succeeded (exit_code === 0) */
24
+ success: boolean;
25
+ }
26
+ /**
27
+ * Validation error for a single parameter.
28
+ */
29
+ export interface ParamValidationError {
30
+ /** Name of the parameter */
31
+ param_name: string;
32
+ /** The invalid value */
33
+ value: string;
34
+ /** Reason for failure: too_long, whitespace, dotdot, or metachar */
35
+ reason: 'too_long' | 'whitespace' | 'dotdot' | 'metachar';
36
+ }
37
+ /**
38
+ * Result of parameter validation.
39
+ */
40
+ export interface ParamValidationResult {
41
+ /** True if all parameters are valid */
42
+ ok: boolean;
43
+ /** List of validation failures */
44
+ errors: ParamValidationError[];
45
+ }
46
+ /**
47
+ * Validates a single parameter value against security constraints.
48
+ *
49
+ * Checks for:
50
+ * - Length exceeding max_param_len
51
+ * - Whitespace (if reject_whitespace_in_params is true)
52
+ * - Path traversal '..' (if reject_dotdot is true)
53
+ * - Shell metacharacters (using reject_metachars_regex)
54
+ *
55
+ * @param paramName - Name of the parameter being validated
56
+ * @param value - The parameter value to validate (converted to string)
57
+ * @param config - Verification configuration with validation rules
58
+ * @returns ParamValidationError if validation fails, null if valid
59
+ */
60
+ export declare function validateParam(paramName: string, value: string | number | boolean | null, config: VerificationConfig): ParamValidationError | null;
61
+ /**
62
+ * Validates all verification parameters for a task.
63
+ *
64
+ * Validates all parameters in task.verification.params against the security
65
+ * constraints defined in the verification config.
66
+ *
67
+ * @param task - Task containing verification configuration and parameters
68
+ * @param config - Verification configuration with validation rules
69
+ * @returns ParamValidationResult with ok=true if all params valid, errors otherwise
70
+ *
71
+ * @example
72
+ * ```typescript
73
+ * const result = validateVerificationParams(task, config.verification);
74
+ * if (!result.ok) {
75
+ * // Handle validation errors
76
+ * console.error('Invalid parameters:', result.errors);
77
+ * }
78
+ * ```
79
+ */
80
+ export declare function validateVerificationParams(task: Task, config: VerificationConfig): ParamValidationResult;
81
+ /**
82
+ * Interpolates parameter placeholders in command arguments.
83
+ *
84
+ * Replaces {{param_name}} placeholders with values from the params object.
85
+ *
86
+ * @param args - Array of command arguments that may contain {{param}} placeholders
87
+ * @param params - Object mapping parameter names to values
88
+ * @returns Array of arguments with placeholders replaced
89
+ *
90
+ * @example
91
+ * ```typescript
92
+ * interpolateArgs(['--filter', '{{pkg}}'], { pkg: 'my-package' })
93
+ * // Returns: ['--filter', 'my-package']
94
+ * ```
95
+ */
96
+ export declare function interpolateArgs(args: string[], params: Record<string, string | number | boolean | null>): string[];
97
+ /**
98
+ * Executes a single verification command.
99
+ *
100
+ * Runs the command using spawn with shell:false for security. Captures stdout
101
+ * and stderr, enforces timeout, and returns execution results.
102
+ *
103
+ * @param template - Verification template containing cmd and args
104
+ * @param params - Parameters for template argument interpolation
105
+ * @param timeoutMs - Timeout in milliseconds (0 means no timeout)
106
+ * @returns Promise resolving to VerificationRun result
107
+ *
108
+ * @example
109
+ * ```typescript
110
+ * const result = await executeVerification(
111
+ * { id: 'lint', cmd: 'pnpm', args: ['-w', 'lint'] },
112
+ * {},
113
+ * 90000
114
+ * );
115
+ * ```
116
+ */
117
+ export declare function executeVerification(template: VerificationTemplate, params: Record<string, string | number | boolean | null>, timeoutMs: number): Promise<VerificationRun>;
118
+ /**
119
+ * Runs verification commands for a task.
120
+ *
121
+ * Executes fast verifications first, then slow verifications. Each verification
122
+ * uses the appropriate timeout from config. Parameters are taken from the task's
123
+ * verification.params object, keyed by template ID.
124
+ *
125
+ * @param templates - Map of template ID to VerificationTemplate
126
+ * @param task - Task containing verification configuration
127
+ * @param config - Verification configuration with timeouts
128
+ * @returns Promise resolving to array of VerificationRun results
129
+ *
130
+ * @example
131
+ * ```typescript
132
+ * const templates = new Map([
133
+ * ['lint', { id: 'lint', cmd: 'pnpm', args: ['-w', 'lint'] }]
134
+ * ]);
135
+ * const runs = await runVerifications(templates, task, config.verification);
136
+ * ```
137
+ */
138
+ export declare function runVerifications(templates: Map<string, VerificationTemplate>, task: Task, config: VerificationConfig): Promise<VerificationRun[]>;
139
+ //# sourceMappingURL=verify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify.d.ts","sourceRoot":"","sources":["../../src/lib/verify.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EACV,oBAAoB,EACpB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,IAAI,EAAoB,MAAM,kBAAkB,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,sCAAsC;IACtC,WAAW,EAAE,MAAM,CAAC;IACpB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,4BAA4B;IAC5B,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,oEAAoE;IACpE,MAAM,EAAE,UAAU,GAAG,YAAY,GAAG,QAAQ,GAAG,UAAU,CAAC;CAC3D;AAED;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,uCAAuC;IACvC,EAAE,EAAE,OAAO,CAAC;IACZ,kCAAkC;IAClC,MAAM,EAAE,oBAAoB,EAAE,CAAC;CAChC;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,EACvC,MAAM,EAAE,kBAAkB,GACzB,oBAAoB,GAAG,IAAI,CAuD7B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,kBAAkB,GACzB,qBAAqB,CAuBvB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EAAE,EACd,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,GACvD,MAAM,EAAE,CAcV;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,oBAAoB,EAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,IAAI,CAAC,EACxD,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,eAAe,CAAC,CAgH1B;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,gBAAgB,CACpC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,oBAAoB,CAAC,EAC5C,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,eAAe,EAAE,CAAC,CAsC5B"}