@oscharko-dev/keiko 0.1.0-beta.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 (450) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +7 -0
  3. package/README.md +621 -0
  4. package/TRADEMARKS.md +41 -0
  5. package/dist/audit/aggregate.d.ts +5 -0
  6. package/dist/audit/aggregate.js +25 -0
  7. package/dist/audit/build.d.ts +2 -0
  8. package/dist/audit/build.js +224 -0
  9. package/dist/audit/errors.d.ts +25 -0
  10. package/dist/audit/errors.js +39 -0
  11. package/dist/audit/index-api.d.ts +14 -0
  12. package/dist/audit/index-api.js +131 -0
  13. package/dist/audit/index.d.ts +12 -0
  14. package/dist/audit/index.js +17 -0
  15. package/dist/audit/persist.d.ts +8 -0
  16. package/dist/audit/persist.js +40 -0
  17. package/dist/audit/redaction.d.ts +3 -0
  18. package/dist/audit/redaction.js +61 -0
  19. package/dist/audit/report.d.ts +18 -0
  20. package/dist/audit/report.js +50 -0
  21. package/dist/audit/retention.d.ts +3 -0
  22. package/dist/audit/retention.js +95 -0
  23. package/dist/audit/runid.d.ts +1 -0
  24. package/dist/audit/runid.js +29 -0
  25. package/dist/audit/side-file.d.ts +12 -0
  26. package/dist/audit/side-file.js +82 -0
  27. package/dist/audit/store.d.ts +12 -0
  28. package/dist/audit/store.js +198 -0
  29. package/dist/audit/types.d.ts +188 -0
  30. package/dist/audit/types.js +8 -0
  31. package/dist/audit/workflow-evidence.d.ts +27 -0
  32. package/dist/audit/workflow-evidence.js +145 -0
  33. package/dist/cli/context.d.ts +2 -0
  34. package/dist/cli/context.js +102 -0
  35. package/dist/cli/evaluate.d.ts +7 -0
  36. package/dist/cli/evaluate.js +207 -0
  37. package/dist/cli/evidence.d.ts +8 -0
  38. package/dist/cli/evidence.js +88 -0
  39. package/dist/cli/gateway-config.d.ts +10 -0
  40. package/dist/cli/gateway-config.js +12 -0
  41. package/dist/cli/gen-tests.d.ts +7 -0
  42. package/dist/cli/gen-tests.js +208 -0
  43. package/dist/cli/index.d.ts +2 -0
  44. package/dist/cli/index.js +14 -0
  45. package/dist/cli/investigate.d.ts +8 -0
  46. package/dist/cli/investigate.js +242 -0
  47. package/dist/cli/models.d.ts +3 -0
  48. package/dist/cli/models.js +64 -0
  49. package/dist/cli/run.d.ts +7 -0
  50. package/dist/cli/run.js +187 -0
  51. package/dist/cli/runner.d.ts +6 -0
  52. package/dist/cli/runner.js +83 -0
  53. package/dist/cli/ui.d.ts +31 -0
  54. package/dist/cli/ui.js +240 -0
  55. package/dist/cli/verify.d.ts +2 -0
  56. package/dist/cli/verify.js +103 -0
  57. package/dist/evaluations/fixtures/bug-investigation/happy-path.d.ts +2 -0
  58. package/dist/evaluations/fixtures/bug-investigation/happy-path.js +66 -0
  59. package/dist/evaluations/fixtures/bug-investigation/investigation-only.d.ts +2 -0
  60. package/dist/evaluations/fixtures/bug-investigation/investigation-only.js +39 -0
  61. package/dist/evaluations/fixtures/bug-investigation/unsafe-action.d.ts +2 -0
  62. package/dist/evaluations/fixtures/bug-investigation/unsafe-action.js +37 -0
  63. package/dist/evaluations/fixtures/index.d.ts +7 -0
  64. package/dist/evaluations/fixtures/index.js +35 -0
  65. package/dist/evaluations/fixtures/support.d.ts +5 -0
  66. package/dist/evaluations/fixtures/support.js +42 -0
  67. package/dist/evaluations/fixtures/unit-tests/happy-path.d.ts +2 -0
  68. package/dist/evaluations/fixtures/unit-tests/happy-path.js +40 -0
  69. package/dist/evaluations/fixtures/unit-tests/retry-then-accept.d.ts +2 -0
  70. package/dist/evaluations/fixtures/unit-tests/retry-then-accept.js +39 -0
  71. package/dist/evaluations/fixtures/unit-tests/unsafe-action.d.ts +2 -0
  72. package/dist/evaluations/fixtures/unit-tests/unsafe-action.js +32 -0
  73. package/dist/evaluations/index.d.ts +12 -0
  74. package/dist/evaluations/index.js +12 -0
  75. package/dist/evaluations/manifest-check.d.ts +1 -0
  76. package/dist/evaluations/manifest-check.js +48 -0
  77. package/dist/evaluations/model-provider.d.ts +12 -0
  78. package/dist/evaluations/model-provider.js +26 -0
  79. package/dist/evaluations/render.d.ts +2 -0
  80. package/dist/evaluations/render.js +59 -0
  81. package/dist/evaluations/runner-support.d.ts +27 -0
  82. package/dist/evaluations/runner-support.js +163 -0
  83. package/dist/evaluations/runner.d.ts +20 -0
  84. package/dist/evaluations/runner.js +174 -0
  85. package/dist/evaluations/scorer.d.ts +14 -0
  86. package/dist/evaluations/scorer.js +131 -0
  87. package/dist/evaluations/scripted-model.d.ts +6 -0
  88. package/dist/evaluations/scripted-model.js +26 -0
  89. package/dist/evaluations/surface-parity.d.ts +2 -0
  90. package/dist/evaluations/surface-parity.js +184 -0
  91. package/dist/evaluations/types.d.ts +74 -0
  92. package/dist/evaluations/types.js +16 -0
  93. package/dist/gateway/capabilities.d.ts +11 -0
  94. package/dist/gateway/capabilities.data.d.ts +2 -0
  95. package/dist/gateway/capabilities.data.js +203 -0
  96. package/dist/gateway/capabilities.js +41 -0
  97. package/dist/gateway/config.d.ts +15 -0
  98. package/dist/gateway/config.js +154 -0
  99. package/dist/gateway/errors.d.ts +72 -0
  100. package/dist/gateway/errors.js +82 -0
  101. package/dist/gateway/gateway.d.ts +19 -0
  102. package/dist/gateway/gateway.js +94 -0
  103. package/dist/gateway/index.d.ts +10 -0
  104. package/dist/gateway/index.js +11 -0
  105. package/dist/gateway/model-selection.d.ts +9 -0
  106. package/dist/gateway/model-selection.js +36 -0
  107. package/dist/gateway/normalize.d.ts +7 -0
  108. package/dist/gateway/normalize.js +93 -0
  109. package/dist/gateway/openai-adapter.d.ts +20 -0
  110. package/dist/gateway/openai-adapter.js +263 -0
  111. package/dist/gateway/redaction.d.ts +1 -0
  112. package/dist/gateway/redaction.js +51 -0
  113. package/dist/gateway/resilience.d.ts +24 -0
  114. package/dist/gateway/resilience.js +166 -0
  115. package/dist/gateway/types.d.ts +108 -0
  116. package/dist/gateway/types.js +2 -0
  117. package/dist/harness/adapters.d.ts +23 -0
  118. package/dist/harness/adapters.js +38 -0
  119. package/dist/harness/context.d.ts +33 -0
  120. package/dist/harness/context.js +21 -0
  121. package/dist/harness/emitter.d.ts +15 -0
  122. package/dist/harness/emitter.js +72 -0
  123. package/dist/harness/errors.d.ts +21 -0
  124. package/dist/harness/errors.js +39 -0
  125. package/dist/harness/executor.d.ts +3 -0
  126. package/dist/harness/executor.js +211 -0
  127. package/dist/harness/fingerprint.d.ts +6 -0
  128. package/dist/harness/fingerprint.js +43 -0
  129. package/dist/harness/index.d.ts +9 -0
  130. package/dist/harness/index.js +13 -0
  131. package/dist/harness/loop.d.ts +3 -0
  132. package/dist/harness/loop.js +159 -0
  133. package/dist/harness/patcher.d.ts +4 -0
  134. package/dist/harness/patcher.js +49 -0
  135. package/dist/harness/planner.d.ts +3 -0
  136. package/dist/harness/planner.js +21 -0
  137. package/dist/harness/ports.d.ts +61 -0
  138. package/dist/harness/ports.js +4 -0
  139. package/dist/harness/session.d.ts +25 -0
  140. package/dist/harness/session.js +116 -0
  141. package/dist/harness/sinks.d.ts +30 -0
  142. package/dist/harness/sinks.js +72 -0
  143. package/dist/harness/tasks/explain-plan.d.ts +3 -0
  144. package/dist/harness/tasks/explain-plan.js +29 -0
  145. package/dist/harness/tasks/generate-unit-tests.d.ts +3 -0
  146. package/dist/harness/tasks/generate-unit-tests.js +28 -0
  147. package/dist/harness/tasks/investigate-bug.d.ts +3 -0
  148. package/dist/harness/tasks/investigate-bug.js +31 -0
  149. package/dist/harness/tasks/policy.d.ts +11 -0
  150. package/dist/harness/tasks/policy.js +22 -0
  151. package/dist/harness/tasks/verify.d.ts +3 -0
  152. package/dist/harness/tasks/verify.js +16 -0
  153. package/dist/harness/types.d.ts +270 -0
  154. package/dist/harness/types.js +33 -0
  155. package/dist/index.d.ts +11 -0
  156. package/dist/index.js +36 -0
  157. package/dist/sdk/index.d.ts +9 -0
  158. package/dist/sdk/index.js +37 -0
  159. package/dist/sdk/run-agent.d.ts +16 -0
  160. package/dist/sdk/run-agent.js +56 -0
  161. package/dist/tools/browser/cdp-client.d.ts +35 -0
  162. package/dist/tools/browser/cdp-client.js +218 -0
  163. package/dist/tools/browser/errors.d.ts +25 -0
  164. package/dist/tools/browser/errors.js +55 -0
  165. package/dist/tools/browser/index.d.ts +5 -0
  166. package/dist/tools/browser/index.js +6 -0
  167. package/dist/tools/browser/session.d.ts +44 -0
  168. package/dist/tools/browser/session.js +748 -0
  169. package/dist/tools/browser/types.d.ts +48 -0
  170. package/dist/tools/browser/types.js +2 -0
  171. package/dist/tools/browser/validators.d.ts +5 -0
  172. package/dist/tools/browser/validators.js +97 -0
  173. package/dist/tools/errors.d.ts +59 -0
  174. package/dist/tools/errors.js +94 -0
  175. package/dist/tools/exec.d.ts +42 -0
  176. package/dist/tools/exec.js +327 -0
  177. package/dist/tools/index.d.ts +11 -0
  178. package/dist/tools/index.js +14 -0
  179. package/dist/tools/patch-content.d.ts +10 -0
  180. package/dist/tools/patch-content.js +126 -0
  181. package/dist/tools/patch-normalize.d.ts +1 -0
  182. package/dist/tools/patch-normalize.js +80 -0
  183. package/dist/tools/patch-parse.d.ts +8 -0
  184. package/dist/tools/patch-parse.js +201 -0
  185. package/dist/tools/patch.d.ts +18 -0
  186. package/dist/tools/patch.js +403 -0
  187. package/dist/tools/registry.d.ts +36 -0
  188. package/dist/tools/registry.js +231 -0
  189. package/dist/tools/sandbox.d.ts +8 -0
  190. package/dist/tools/sandbox.js +121 -0
  191. package/dist/tools/schemas.d.ts +2 -0
  192. package/dist/tools/schemas.js +51 -0
  193. package/dist/tools/terminal-policy.d.ts +9 -0
  194. package/dist/tools/terminal-policy.js +313 -0
  195. package/dist/tools/types.d.ts +99 -0
  196. package/dist/tools/types.js +103 -0
  197. package/dist/tools/writer.d.ts +7 -0
  198. package/dist/tools/writer.js +20 -0
  199. package/dist/ui/browser.d.ts +10 -0
  200. package/dist/ui/browser.js +231 -0
  201. package/dist/ui/chat-handlers.d.ts +4 -0
  202. package/dist/ui/chat-handlers.js +281 -0
  203. package/dist/ui/csp-hashes.json +17 -0
  204. package/dist/ui/csp.d.ts +2 -0
  205. package/dist/ui/csp.js +66 -0
  206. package/dist/ui/deps.d.ts +34 -0
  207. package/dist/ui/deps.js +137 -0
  208. package/dist/ui/evidence.d.ts +27 -0
  209. package/dist/ui/evidence.js +142 -0
  210. package/dist/ui/files-deny.d.ts +2 -0
  211. package/dist/ui/files-deny.js +12 -0
  212. package/dist/ui/files.d.ts +65 -0
  213. package/dist/ui/files.js +492 -0
  214. package/dist/ui/headers.d.ts +2 -0
  215. package/dist/ui/headers.js +21 -0
  216. package/dist/ui/host-check.d.ts +2 -0
  217. package/dist/ui/host-check.js +58 -0
  218. package/dist/ui/index.d.ts +20 -0
  219. package/dist/ui/index.js +23 -0
  220. package/dist/ui/load-csp.d.ts +1 -0
  221. package/dist/ui/load-csp.js +28 -0
  222. package/dist/ui/read-handlers.d.ts +8 -0
  223. package/dist/ui/read-handlers.js +247 -0
  224. package/dist/ui/routes.d.ts +36 -0
  225. package/dist/ui/routes.js +129 -0
  226. package/dist/ui/run-engine.d.ts +20 -0
  227. package/dist/ui/run-engine.js +345 -0
  228. package/dist/ui/run-handlers.d.ts +8 -0
  229. package/dist/ui/run-handlers.js +431 -0
  230. package/dist/ui/run-request.d.ts +13 -0
  231. package/dist/ui/run-request.js +219 -0
  232. package/dist/ui/runs.d.ts +43 -0
  233. package/dist/ui/runs.js +92 -0
  234. package/dist/ui/server.d.ts +11 -0
  235. package/dist/ui/server.js +143 -0
  236. package/dist/ui/sink.d.ts +27 -0
  237. package/dist/ui/sink.js +80 -0
  238. package/dist/ui/sse.d.ts +7 -0
  239. package/dist/ui/sse.js +27 -0
  240. package/dist/ui/static/404.html +1 -0
  241. package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_buildManifest.js +1 -0
  242. package/dist/ui/static/_next/static/ca-A01hy9W98aRvMZKdAw/_ssgManifest.js +1 -0
  243. package/dist/ui/static/_next/static/chunks/255-d47fd57964443afe.js +1 -0
  244. package/dist/ui/static/_next/static/chunks/4-be1fef693af8e088.js +1 -0
  245. package/dist/ui/static/_next/static/chunks/4bd1b696-c023c6e3521b1417.js +1 -0
  246. package/dist/ui/static/_next/static/chunks/app/_not-found/page-75825b09bcecad97.js +1 -0
  247. package/dist/ui/static/_next/static/chunks/app/launch/page-9c86a13c29884245.js +1 -0
  248. package/dist/ui/static/_next/static/chunks/app/layout-bdea63fe87947d50.js +1 -0
  249. package/dist/ui/static/_next/static/chunks/app/page-4168c12c68b7a853.js +1 -0
  250. package/dist/ui/static/_next/static/chunks/framework-a6e0b7e30f98059a.js +1 -0
  251. package/dist/ui/static/_next/static/chunks/main-778a50aebff02192.js +1 -0
  252. package/dist/ui/static/_next/static/chunks/main-app-30679af7240d63e9.js +1 -0
  253. package/dist/ui/static/_next/static/chunks/pages/_app-7d307437aca18ad4.js +1 -0
  254. package/dist/ui/static/_next/static/chunks/pages/_error-cb2a52f75f2162e2.js +1 -0
  255. package/dist/ui/static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  256. package/dist/ui/static/_next/static/chunks/webpack-4a462cecab786e93.js +1 -0
  257. package/dist/ui/static/_next/static/css/be7cb54d5c5673b6.css +1 -0
  258. package/dist/ui/static/assets/editors/goland.svg +35 -0
  259. package/dist/ui/static/assets/editors/intellij.svg +39 -0
  260. package/dist/ui/static/assets/editors/pycharm.svg +58 -0
  261. package/dist/ui/static/assets/editors/rustrover.svg +19 -0
  262. package/dist/ui/static/assets/editors/vscode.svg +1 -0
  263. package/dist/ui/static/assets/editors/webstorm.svg +21 -0
  264. package/dist/ui/static/assets/icons/anthropic.svg +1 -0
  265. package/dist/ui/static/assets/icons/brave.svg +1 -0
  266. package/dist/ui/static/assets/icons/css3.svg +1 -0
  267. package/dist/ui/static/assets/icons/docker.svg +1 -0
  268. package/dist/ui/static/assets/icons/git.svg +1 -0
  269. package/dist/ui/static/assets/icons/github.svg +1 -0
  270. package/dist/ui/static/assets/icons/go.svg +1 -0
  271. package/dist/ui/static/assets/icons/gradle.svg +1 -0
  272. package/dist/ui/static/assets/icons/grafana.svg +1 -0
  273. package/dist/ui/static/assets/icons/graphql.svg +1 -0
  274. package/dist/ui/static/assets/icons/html5.svg +1 -0
  275. package/dist/ui/static/assets/icons/image.svg +1 -0
  276. package/dist/ui/static/assets/icons/java.svg +1 -0
  277. package/dist/ui/static/assets/icons/javascript.svg +1 -0
  278. package/dist/ui/static/assets/icons/json.svg +1 -0
  279. package/dist/ui/static/assets/icons/kafka.svg +1 -0
  280. package/dist/ui/static/assets/icons/kubernetes.svg +1 -0
  281. package/dist/ui/static/assets/icons/linear.svg +1 -0
  282. package/dist/ui/static/assets/icons/markdown.svg +1 -0
  283. package/dist/ui/static/assets/icons/nginx.svg +1 -0
  284. package/dist/ui/static/assets/icons/nodejs.svg +1 -0
  285. package/dist/ui/static/assets/icons/notion.svg +1 -0
  286. package/dist/ui/static/assets/icons/openai.svg +1 -0
  287. package/dist/ui/static/assets/icons/playwright.svg +1 -0
  288. package/dist/ui/static/assets/icons/postgresql.svg +1 -0
  289. package/dist/ui/static/assets/icons/prometheus.svg +1 -0
  290. package/dist/ui/static/assets/icons/properties.svg +1 -0
  291. package/dist/ui/static/assets/icons/puppeteer.svg +1 -0
  292. package/dist/ui/static/assets/icons/python.svg +1 -0
  293. package/dist/ui/static/assets/icons/react.svg +1 -0
  294. package/dist/ui/static/assets/icons/redis.svg +1 -0
  295. package/dist/ui/static/assets/icons/rust.svg +1 -0
  296. package/dist/ui/static/assets/icons/sentry.svg +1 -0
  297. package/dist/ui/static/assets/icons/slack.svg +1 -0
  298. package/dist/ui/static/assets/icons/spring.svg +1 -0
  299. package/dist/ui/static/assets/icons/typescript.svg +1 -0
  300. package/dist/ui/static/assets/icons/upstash.svg +1 -0
  301. package/dist/ui/static/assets/icons/yaml.svg +1 -0
  302. package/dist/ui/static/assets/keiko-logo.svg +10 -0
  303. package/dist/ui/static/index.html +1 -0
  304. package/dist/ui/static/index.txt +19 -0
  305. package/dist/ui/static/keiko-logo.svg +10 -0
  306. package/dist/ui/static/launch.html +1 -0
  307. package/dist/ui/static/launch.txt +19 -0
  308. package/dist/ui/static.d.ts +3 -0
  309. package/dist/ui/static.js +72 -0
  310. package/dist/ui/store/chats.d.ts +14 -0
  311. package/dist/ui/store/chats.js +110 -0
  312. package/dist/ui/store/db.d.ts +6 -0
  313. package/dist/ui/store/db.js +182 -0
  314. package/dist/ui/store/errors.d.ts +12 -0
  315. package/dist/ui/store/errors.js +30 -0
  316. package/dist/ui/store/index.d.ts +6 -0
  317. package/dist/ui/store/index.js +6 -0
  318. package/dist/ui/store/messages.d.ts +5 -0
  319. package/dist/ui/store/messages.js +137 -0
  320. package/dist/ui/store/paths.d.ts +4 -0
  321. package/dist/ui/store/paths.js +69 -0
  322. package/dist/ui/store/projects.d.ts +7 -0
  323. package/dist/ui/store/projects.js +61 -0
  324. package/dist/ui/store/schema.d.ts +3 -0
  325. package/dist/ui/store/schema.js +77 -0
  326. package/dist/ui/store/types.d.ts +80 -0
  327. package/dist/ui/store/types.js +3 -0
  328. package/dist/ui/store/validation.d.ts +4 -0
  329. package/dist/ui/store/validation.js +72 -0
  330. package/dist/ui/store-handlers.d.ts +16 -0
  331. package/dist/ui/store-handlers.js +465 -0
  332. package/dist/ui/terminal-errors.d.ts +21 -0
  333. package/dist/ui/terminal-errors.js +45 -0
  334. package/dist/ui/terminal-evidence.d.ts +20 -0
  335. package/dist/ui/terminal-evidence.js +65 -0
  336. package/dist/ui/terminal-routes.d.ts +9 -0
  337. package/dist/ui/terminal-routes.js +219 -0
  338. package/dist/ui/terminal.d.ts +67 -0
  339. package/dist/ui/terminal.js +835 -0
  340. package/dist/verification/classify.d.ts +10 -0
  341. package/dist/verification/classify.js +53 -0
  342. package/dist/verification/detect.d.ts +4 -0
  343. package/dist/verification/detect.js +81 -0
  344. package/dist/verification/errors.d.ts +11 -0
  345. package/dist/verification/errors.js +21 -0
  346. package/dist/verification/index.d.ts +17 -0
  347. package/dist/verification/index.js +13 -0
  348. package/dist/verification/limits.d.ts +3 -0
  349. package/dist/verification/limits.js +40 -0
  350. package/dist/verification/monitor.d.ts +4 -0
  351. package/dist/verification/monitor.js +58 -0
  352. package/dist/verification/orchestrator.d.ts +16 -0
  353. package/dist/verification/orchestrator.js +363 -0
  354. package/dist/verification/plan.d.ts +9 -0
  355. package/dist/verification/plan.js +125 -0
  356. package/dist/verification/summary.d.ts +40 -0
  357. package/dist/verification/summary.js +67 -0
  358. package/dist/verification/types.d.ts +63 -0
  359. package/dist/verification/types.js +13 -0
  360. package/dist/workflows/bug-investigation/context.d.ts +7 -0
  361. package/dist/workflows/bug-investigation/context.js +119 -0
  362. package/dist/workflows/bug-investigation/descriptor.d.ts +3 -0
  363. package/dist/workflows/bug-investigation/descriptor.js +46 -0
  364. package/dist/workflows/bug-investigation/emit.d.ts +12 -0
  365. package/dist/workflows/bug-investigation/emit.js +35 -0
  366. package/dist/workflows/bug-investigation/events.d.ts +81 -0
  367. package/dist/workflows/bug-investigation/events.js +9 -0
  368. package/dist/workflows/bug-investigation/failure-parse.d.ts +3 -0
  369. package/dist/workflows/bug-investigation/failure-parse.js +154 -0
  370. package/dist/workflows/bug-investigation/guard.d.ts +2 -0
  371. package/dist/workflows/bug-investigation/guard.js +69 -0
  372. package/dist/workflows/bug-investigation/index.d.ts +7 -0
  373. package/dist/workflows/bug-investigation/index.js +13 -0
  374. package/dist/workflows/bug-investigation/internal.d.ts +37 -0
  375. package/dist/workflows/bug-investigation/internal.js +64 -0
  376. package/dist/workflows/bug-investigation/model-loop.d.ts +4 -0
  377. package/dist/workflows/bug-investigation/model-loop.js +223 -0
  378. package/dist/workflows/bug-investigation/parse.d.ts +3 -0
  379. package/dist/workflows/bug-investigation/parse.js +123 -0
  380. package/dist/workflows/bug-investigation/prompt.d.ts +4 -0
  381. package/dist/workflows/bug-investigation/prompt.js +107 -0
  382. package/dist/workflows/bug-investigation/report.d.ts +23 -0
  383. package/dist/workflows/bug-investigation/report.js +151 -0
  384. package/dist/workflows/bug-investigation/stages.d.ts +13 -0
  385. package/dist/workflows/bug-investigation/stages.js +242 -0
  386. package/dist/workflows/bug-investigation/types.d.ts +91 -0
  387. package/dist/workflows/bug-investigation/types.js +14 -0
  388. package/dist/workflows/bug-investigation/verify-stage.d.ts +10 -0
  389. package/dist/workflows/bug-investigation/verify-stage.js +91 -0
  390. package/dist/workflows/bug-investigation/workflow.d.ts +2 -0
  391. package/dist/workflows/bug-investigation/workflow.js +74 -0
  392. package/dist/workflows/descriptor.d.ts +20 -0
  393. package/dist/workflows/descriptor.js +8 -0
  394. package/dist/workflows/index.d.ts +3 -0
  395. package/dist/workflows/index.js +2 -0
  396. package/dist/workflows/unit-tests/context.d.ts +7 -0
  397. package/dist/workflows/unit-tests/context.js +129 -0
  398. package/dist/workflows/unit-tests/conventions.d.ts +4 -0
  399. package/dist/workflows/unit-tests/conventions.js +87 -0
  400. package/dist/workflows/unit-tests/descriptor.d.ts +4 -0
  401. package/dist/workflows/unit-tests/descriptor.js +43 -0
  402. package/dist/workflows/unit-tests/emit.d.ts +12 -0
  403. package/dist/workflows/unit-tests/emit.js +35 -0
  404. package/dist/workflows/unit-tests/events.d.ts +78 -0
  405. package/dist/workflows/unit-tests/events.js +7 -0
  406. package/dist/workflows/unit-tests/index.d.ts +6 -0
  407. package/dist/workflows/unit-tests/index.js +10 -0
  408. package/dist/workflows/unit-tests/internal.d.ts +35 -0
  409. package/dist/workflows/unit-tests/internal.js +43 -0
  410. package/dist/workflows/unit-tests/model-loop.d.ts +4 -0
  411. package/dist/workflows/unit-tests/model-loop.js +95 -0
  412. package/dist/workflows/unit-tests/parse.d.ts +6 -0
  413. package/dist/workflows/unit-tests/parse.js +68 -0
  414. package/dist/workflows/unit-tests/prompt.d.ts +4 -0
  415. package/dist/workflows/unit-tests/prompt.js +71 -0
  416. package/dist/workflows/unit-tests/report.d.ts +21 -0
  417. package/dist/workflows/unit-tests/report.js +90 -0
  418. package/dist/workflows/unit-tests/stages.d.ts +9 -0
  419. package/dist/workflows/unit-tests/stages.js +155 -0
  420. package/dist/workflows/unit-tests/types.d.ts +70 -0
  421. package/dist/workflows/unit-tests/types.js +11 -0
  422. package/dist/workflows/unit-tests/verify-stage.d.ts +9 -0
  423. package/dist/workflows/unit-tests/verify-stage.js +56 -0
  424. package/dist/workflows/unit-tests/workflow.d.ts +2 -0
  425. package/dist/workflows/unit-tests/workflow.js +58 -0
  426. package/dist/workspace/contextPack.d.ts +9 -0
  427. package/dist/workspace/contextPack.js +94 -0
  428. package/dist/workspace/detect.d.ts +3 -0
  429. package/dist/workspace/detect.js +135 -0
  430. package/dist/workspace/discovery.d.ts +9 -0
  431. package/dist/workspace/discovery.js +167 -0
  432. package/dist/workspace/errors.d.ts +39 -0
  433. package/dist/workspace/errors.js +66 -0
  434. package/dist/workspace/fs.d.ts +21 -0
  435. package/dist/workspace/fs.js +36 -0
  436. package/dist/workspace/ignore.d.ts +14 -0
  437. package/dist/workspace/ignore.js +176 -0
  438. package/dist/workspace/index.d.ts +11 -0
  439. package/dist/workspace/index.js +13 -0
  440. package/dist/workspace/paths.d.ts +2 -0
  441. package/dist/workspace/paths.js +38 -0
  442. package/dist/workspace/realpath.d.ts +7 -0
  443. package/dist/workspace/realpath.js +72 -0
  444. package/dist/workspace/retrieval.d.ts +9 -0
  445. package/dist/workspace/retrieval.js +74 -0
  446. package/dist/workspace/summary.d.ts +3 -0
  447. package/dist/workspace/summary.js +54 -0
  448. package/dist/workspace/types.d.ts +103 -0
  449. package/dist/workspace/types.js +27 -0
  450. package/package.json +58 -0
@@ -0,0 +1,11 @@
1
+ export type { CommandResult, CommandRule, CommandRunInput, NetworkPolicy, PatchApplyResult, PatchChangeKind, PatchConflict, PatchFileChange, PatchHunk, PatchLimits, PatchRejection, PatchRejectionCode, PatchValidation, SandboxPolicy, ToolHostConfig, ToolHostConfigInput, } from "./types.js";
2
+ export { DEFAULT_COMMAND_RULES, DEFAULT_ENV_ALLOWLIST, DEFAULT_PATCH_LIMITS, DEFAULT_SANDBOX_POLICY, DEFAULT_TOOL_HOST_CONFIG, resolveToolHostConfig, } from "./types.js";
3
+ export { CommandCancelledError, CommandDeniedError, CommandTimeoutError, OutputLimitError, PatchApplyDisabledError, PatchApplyError, PatchValidationError, TOOL_CODES, ToolArgumentError, ToolError, UnknownToolError, type ToolCode, } from "./errors.js";
4
+ export { buildSandboxEnv, collectSensitiveEnvValues, isCommandAllowed, type CommandDecision, } from "./sandbox.js";
5
+ export { nodeWorkspaceWriter, type WorkspaceWriter } from "./writer.js";
6
+ export { nodeSpawnFn, runCommand, type RunCommandDeps, type RunCommandInput, type ExecutableResolver, type ExecutableResolverDeps, type SpawnFn, type SpawnOptions, } from "./exec.js";
7
+ export { applyPatch, renderDryRun, validatePatch, type ApplyDeps, type ValidateDeps, } from "./patch.js";
8
+ export { normalizeUnifiedDiffHunks } from "./patch-normalize.js";
9
+ export { parseUnifiedDiff, type ParsedPatch } from "./patch-parse.js";
10
+ export { TOOL_DEFINITIONS } from "./schemas.js";
11
+ export { WorkspaceToolHost } from "./registry.js";
@@ -0,0 +1,14 @@
1
+ // Public barrel for the safe tool-execution layer (ADR-0006). The tool host is the trust
2
+ // boundary between model output and developer repositories: deny-by-default command allowlist,
3
+ // env-isolated no-shell spawn, and a fail-closed, atomic patch workflow. Explicit named
4
+ // re-exports, `type` keyword for type-only, double quotes, `.js`.
5
+ export { DEFAULT_COMMAND_RULES, DEFAULT_ENV_ALLOWLIST, DEFAULT_PATCH_LIMITS, DEFAULT_SANDBOX_POLICY, DEFAULT_TOOL_HOST_CONFIG, resolveToolHostConfig, } from "./types.js";
6
+ export { CommandCancelledError, CommandDeniedError, CommandTimeoutError, OutputLimitError, PatchApplyDisabledError, PatchApplyError, PatchValidationError, TOOL_CODES, ToolArgumentError, ToolError, UnknownToolError, } from "./errors.js";
7
+ export { buildSandboxEnv, collectSensitiveEnvValues, isCommandAllowed, } from "./sandbox.js";
8
+ export { nodeWorkspaceWriter } from "./writer.js";
9
+ export { nodeSpawnFn, runCommand, } from "./exec.js";
10
+ export { applyPatch, renderDryRun, validatePatch, } from "./patch.js";
11
+ export { normalizeUnifiedDiffHunks } from "./patch-normalize.js";
12
+ export { parseUnifiedDiff } from "./patch-parse.js";
13
+ export { TOOL_DEFINITIONS } from "./schemas.js";
14
+ export { WorkspaceToolHost } from "./registry.js";
@@ -0,0 +1,10 @@
1
+ import type { PatchFileChange } from "./types.js";
2
+ export interface HunkConflict {
3
+ readonly hunkIndex: number;
4
+ readonly reason: string;
5
+ }
6
+ export interface ApplyOutcome {
7
+ readonly content: string | null;
8
+ readonly conflicts: readonly HunkConflict[];
9
+ }
10
+ export declare function computeFileContent(change: PatchFileChange, current: string | undefined): ApplyOutcome;
@@ -0,0 +1,126 @@
1
+ // PURE hunk application against in-memory file content. Given the current file lines and a
2
+ // file's hunks, it verifies the pre-image (context and removed lines must match the current
3
+ // content at the hunk location) and produces the post-image. A mismatch yields a conflict
4
+ // rather than a silent corruption — the apply phase refuses to write when any conflict exists.
5
+ // Splits file content into lines WITHOUT a trailing empty element for a final newline, so line
6
+ // indexing matches unified-diff 1-based line numbers. An empty file is zero lines.
7
+ function toLines(content) {
8
+ if (content === "") {
9
+ return [];
10
+ }
11
+ const lines = content.split("\n");
12
+ if (lines.at(-1) === "") {
13
+ lines.pop();
14
+ }
15
+ return lines;
16
+ }
17
+ function joinLines(lines) {
18
+ return lines.length === 0 ? "" : `${lines.join("\n")}\n`;
19
+ }
20
+ // Applies a single hunk starting at `cursor` (0-based index into the original lines). Returns the
21
+ // produced output lines, the count of original lines consumed, and a conflict reason on mismatch.
22
+ function applyHunk(original, hunk, cursor) {
23
+ const out = [];
24
+ let pos = cursor;
25
+ for (const raw of hunk.lines) {
26
+ const marker = raw.charAt(0);
27
+ const text = raw.slice(1);
28
+ if (marker === "+") {
29
+ out.push(text);
30
+ continue;
31
+ }
32
+ // context (" ") and removal ("-") must both match the current line at pos.
33
+ if (original[pos] !== text) {
34
+ return {
35
+ outLines: [],
36
+ consumed: 0,
37
+ conflict: `context mismatch at original line ${String(pos + 1)}`,
38
+ };
39
+ }
40
+ if (marker === " ") {
41
+ out.push(text);
42
+ }
43
+ pos += 1;
44
+ }
45
+ return { outLines: out, consumed: pos - cursor, conflict: undefined };
46
+ }
47
+ // Applies all hunks of a modify in order. Hunks are anchored by their stated oldStart (1-based);
48
+ // lines between hunks are copied verbatim. Returns the new content or the collected conflicts.
49
+ function applyModify(original, hunks) {
50
+ const out = [];
51
+ const conflicts = [];
52
+ let cursor = 0;
53
+ hunks.forEach((hunk, index) => {
54
+ const anchor = Math.max(hunk.oldStart - 1, 0);
55
+ if (anchor < cursor) {
56
+ conflicts.push({ hunkIndex: index, reason: "overlapping or out-of-order hunk" });
57
+ return;
58
+ }
59
+ // Copy verbatim the unchanged lines between the previous cursor and this hunk's anchor.
60
+ out.push(...original.slice(cursor, Math.min(anchor, original.length)));
61
+ cursor = anchor;
62
+ const result = applyHunk(original, hunk, cursor);
63
+ if (result.conflict !== undefined) {
64
+ conflicts.push({ hunkIndex: index, reason: result.conflict });
65
+ return;
66
+ }
67
+ out.push(...result.outLines);
68
+ cursor += result.consumed;
69
+ });
70
+ // Copy any remaining original lines after the last applied hunk.
71
+ out.push(...original.slice(cursor));
72
+ return conflicts.length > 0
73
+ ? { content: null, conflicts }
74
+ : { content: joinLines(out), conflicts: [] };
75
+ }
76
+ // Verifies a delete's pre-image against the current content (C2). A delete hunk lists the lines to
77
+ // remove (`-`) and surrounding context (` `); their concatenation must equal the current file, or
78
+ // the diff is stale/fabricated and we MUST NOT delete a mismatched file. A hunk-free delete (no
79
+ // pre-image to check) is accepted as-is. `+` lines are not expected in a delete and are ignored.
80
+ function verifyDeletePreImage(change, current) {
81
+ const preImage = [];
82
+ for (const hunk of change.hunks) {
83
+ for (const raw of hunk.lines) {
84
+ const marker = raw.charAt(0);
85
+ if (marker === " " || marker === "-") {
86
+ preImage.push(raw.slice(1));
87
+ }
88
+ }
89
+ }
90
+ if (preImage.length === 0) {
91
+ return { content: null, conflicts: [] };
92
+ }
93
+ const matches = joinLines(preImage) === current || preImage.join("\n") === current;
94
+ return matches
95
+ ? { content: null, conflicts: [] }
96
+ : {
97
+ content: null,
98
+ conflicts: [{ hunkIndex: 0, reason: "delete pre-image does not match current content" }],
99
+ };
100
+ }
101
+ // Computes the post-image for one file change against its current content (undefined = absent).
102
+ export function computeFileContent(change, current) {
103
+ if (change.kind === "create") {
104
+ if (current !== undefined) {
105
+ return {
106
+ content: null,
107
+ conflicts: [{ hunkIndex: 0, reason: "create target already exists" }],
108
+ };
109
+ }
110
+ const added = change.hunks.flatMap((h) => h.lines.filter((l) => l.startsWith("+")).map((l) => l.slice(1)));
111
+ return { content: joinLines(added), conflicts: [] };
112
+ }
113
+ if (change.kind === "delete") {
114
+ if (current === undefined) {
115
+ return {
116
+ content: null,
117
+ conflicts: [{ hunkIndex: 0, reason: "delete target does not exist" }],
118
+ };
119
+ }
120
+ return verifyDeletePreImage(change, current);
121
+ }
122
+ if (current === undefined) {
123
+ return { content: null, conflicts: [{ hunkIndex: 0, reason: "modify target does not exist" }] };
124
+ }
125
+ return applyModify(toLines(current), change.hunks);
126
+ }
@@ -0,0 +1 @@
1
+ export declare function normalizeUnifiedDiffHunks(diff: string): string;
@@ -0,0 +1,80 @@
1
+ // Best-effort normalization for common LLM unified-diff shorthand. This module rewrites hunk headers
2
+ // from the hunk body markers (" ", "+", "-") and repairs blank context lines that models often emit
3
+ // as an empty line instead of a single-space diff line. It does not invent paths; the normal
4
+ // validate/apply path still performs path containment, deny-list checks, and conflict checks.
5
+ const HUNK_HEADER = /^@@ -(\d+)(?:,\d+)? \+(\d+)(?:,\d+)? @@(.*)$/;
6
+ function isBodyLine(line) {
7
+ const marker = line.charAt(0);
8
+ return marker === " " || marker === "+" || marker === "-";
9
+ }
10
+ function isFileHeaderPair(lines, index) {
11
+ return (lines[index]?.startsWith("--- ") === true &&
12
+ lines[index + 1]?.startsWith("+++ ") === true);
13
+ }
14
+ function hunkEnd(lines, start) {
15
+ let index = start;
16
+ while (index < lines.length) {
17
+ const line = lines[index] ?? "";
18
+ if (line.startsWith("@@") || isFileHeaderPair(lines, index)) {
19
+ break;
20
+ }
21
+ index += 1;
22
+ }
23
+ return index;
24
+ }
25
+ function countOldLines(lines) {
26
+ return lines.filter((line) => line.startsWith(" ") || line.startsWith("-")).length;
27
+ }
28
+ function countNewLines(lines) {
29
+ return lines.filter((line) => line.startsWith(" ") || line.startsWith("+")).length;
30
+ }
31
+ function parseStarts(line) {
32
+ const match = HUNK_HEADER.exec(line);
33
+ if (match === null) {
34
+ return line.trim() === "@@" ? { oldStart: 0, newStart: 1, suffix: "" } : undefined;
35
+ }
36
+ return {
37
+ oldStart: Number(match[1]),
38
+ newStart: Number(match[2]),
39
+ suffix: match[3] ?? "",
40
+ };
41
+ }
42
+ function formatRange(start, count) {
43
+ return `${String(start)},${String(count)}`;
44
+ }
45
+ function normalizeHunkHeader(header, body) {
46
+ const starts = parseStarts(header);
47
+ if (starts === undefined) {
48
+ return header;
49
+ }
50
+ const { oldStart, newStart, suffix } = starts;
51
+ return `@@ -${formatRange(oldStart, countOldLines(body))} +${formatRange(newStart, countNewLines(body))} @@${suffix}`;
52
+ }
53
+ function hasBodyLineBefore(lines, index) {
54
+ return lines.slice(0, index).some(isBodyLine);
55
+ }
56
+ function hasBodyLineAfter(lines, index) {
57
+ return lines.slice(index + 1).some(isBodyLine);
58
+ }
59
+ function normalizeBlankContextLines(lines) {
60
+ return lines.map((line, index) => line === "" && hasBodyLineBefore(lines, index) && hasBodyLineAfter(lines, index) ? " " : line);
61
+ }
62
+ export function normalizeUnifiedDiffHunks(diff) {
63
+ const lines = diff.split("\n");
64
+ const out = [];
65
+ let index = 0;
66
+ while (index < lines.length) {
67
+ const line = lines[index] ?? "";
68
+ if (!line.startsWith("@@")) {
69
+ out.push(line);
70
+ index += 1;
71
+ continue;
72
+ }
73
+ const end = hunkEnd(lines, index + 1);
74
+ const normalizedLines = normalizeBlankContextLines(lines.slice(index + 1, end));
75
+ const body = normalizedLines.filter(isBodyLine);
76
+ out.push(normalizeHunkHeader(line, body), ...normalizedLines);
77
+ index = end;
78
+ }
79
+ return out.join("\n");
80
+ }
@@ -0,0 +1,8 @@
1
+ import type { PatchFileChange } from "./types.js";
2
+ export interface ParsedPatch {
3
+ readonly files: readonly PatchFileChange[];
4
+ }
5
+ export declare class PatchParseError extends Error {
6
+ constructor(message: string);
7
+ }
8
+ export declare function parseUnifiedDiff(diff: string): ParsedPatch;
@@ -0,0 +1,201 @@
1
+ // PURE, ReDoS-free unified-diff parser. Supported subset (documented in ADR-0006):
2
+ // - file headers `--- a/<path>` / `+++ b/<path>`, with `/dev/null` for create/delete;
3
+ // - hunk headers `@@ -l,s +l,s @@` (the count `,s` defaults to 1 when omitted);
4
+ // - body lines beginning with " " (context), "+" (add), "-" (remove), and "\" (no-newline).
5
+ // This is NOT git-apply: no rename detection, no binary patches, no fuzzy matching. The parser
6
+ // is linear (a single pass with bounded per-line regexes) so it cannot backtrack catastrophically.
7
+ // Bounded, anchored hunk-header regex. Each numeric group is `\d+` (linear, no nesting).
8
+ const HUNK_HEADER = /^@@ -(\d+)(?:,(\d+))? \+(\d+)(?:,(\d+))? @@/;
9
+ export class PatchParseError extends Error {
10
+ constructor(message) {
11
+ super(message);
12
+ this.name = "PatchParseError";
13
+ }
14
+ }
15
+ function stripPrefix(raw) {
16
+ if (raw === "/dev/null") {
17
+ return raw;
18
+ }
19
+ // Drop a leading `a/` or `b/` git prefix; otherwise keep the path verbatim.
20
+ if (raw.startsWith("a/") || raw.startsWith("b/")) {
21
+ return raw.slice(2);
22
+ }
23
+ return raw;
24
+ }
25
+ // The header path may carry a trailing tab + timestamp (`path\t2024-…`); keep only the path.
26
+ function headerPath(line, marker) {
27
+ const rest = line.slice(marker.length);
28
+ const tab = rest.indexOf("\t");
29
+ const raw = tab === -1 ? rest : rest.slice(0, tab);
30
+ return stripPrefix(raw.trim());
31
+ }
32
+ function classify(oldPath, newPath) {
33
+ if (oldPath === "/dev/null") {
34
+ return { kind: "create", path: newPath };
35
+ }
36
+ if (newPath === "/dev/null") {
37
+ return { kind: "delete", path: oldPath };
38
+ }
39
+ return { kind: "modify", path: newPath };
40
+ }
41
+ function toHunk(acc) {
42
+ return {
43
+ oldStart: acc.oldStart,
44
+ oldLines: acc.oldLines,
45
+ newStart: acc.newStart,
46
+ newLines: acc.newLines,
47
+ lines: acc.lines,
48
+ };
49
+ }
50
+ function parseHunkHeader(line) {
51
+ const match = HUNK_HEADER.exec(line);
52
+ if (match === null) {
53
+ throw new PatchParseError("malformed hunk header");
54
+ }
55
+ const oldLines = match[2] === undefined ? 1 : Number(match[2]);
56
+ const newLines = match[4] === undefined ? 1 : Number(match[4]);
57
+ return {
58
+ oldStart: Number(match[1]),
59
+ oldLines,
60
+ newStart: Number(match[3]),
61
+ newLines,
62
+ lines: [],
63
+ oldRemaining: oldLines,
64
+ newRemaining: newLines,
65
+ };
66
+ }
67
+ function newFileAccumulator() {
68
+ return {
69
+ oldPath: undefined,
70
+ newPath: undefined,
71
+ hunks: [],
72
+ current: undefined,
73
+ added: 0,
74
+ removed: 0,
75
+ };
76
+ }
77
+ function finishHunk(file) {
78
+ if (file.current !== undefined) {
79
+ if (file.current.oldRemaining !== 0 || file.current.newRemaining !== 0) {
80
+ throw new PatchParseError("hunk body has fewer lines than declared");
81
+ }
82
+ file.hunks.push(toHunk(file.current));
83
+ file.current = undefined;
84
+ }
85
+ }
86
+ function finishFile(files, file) {
87
+ finishHunk(file);
88
+ if (file.oldPath === undefined || file.newPath === undefined) {
89
+ return;
90
+ }
91
+ const { kind, path } = classify(file.oldPath, file.newPath);
92
+ files.push({
93
+ path,
94
+ kind,
95
+ hunks: file.hunks,
96
+ addedLines: file.added,
97
+ removedLines: file.removed,
98
+ });
99
+ }
100
+ function countBody(file, line) {
101
+ if (line.startsWith("+")) {
102
+ file.added += 1;
103
+ }
104
+ else if (line.startsWith("-")) {
105
+ file.removed += 1;
106
+ }
107
+ }
108
+ function startNewFile(state, oldPath) {
109
+ if (state.current !== undefined) {
110
+ finishFile(state.files, state.current);
111
+ }
112
+ const file = newFileAccumulator();
113
+ file.oldPath = oldPath;
114
+ state.current = file;
115
+ return file;
116
+ }
117
+ function isHunkBodyLine(line) {
118
+ const marker = line.charAt(0);
119
+ return marker === " " || marker === "+" || marker === "-";
120
+ }
121
+ // A hunk is still consuming body lines while either the old or the new line budget is positive.
122
+ function hunkActive(file) {
123
+ const hunk = file.current;
124
+ return hunk !== undefined && (hunk.oldRemaining > 0 || hunk.newRemaining > 0);
125
+ }
126
+ // Draws down the hunk's old/new line budget for a body line (context draws both, `-` old, `+` new).
127
+ function assertBudgetAvailable(hunk, line) {
128
+ const marker = line.charAt(0);
129
+ const oldNeeded = marker === " " || marker === "-" ? 1 : 0;
130
+ const newNeeded = marker === " " || marker === "+" ? 1 : 0;
131
+ if (hunk.oldRemaining < oldNeeded || hunk.newRemaining < newNeeded) {
132
+ throw new PatchParseError("hunk body has more lines than declared");
133
+ }
134
+ }
135
+ function consumeBudget(hunk, line) {
136
+ const marker = line.charAt(0);
137
+ if (marker === " ") {
138
+ hunk.oldRemaining -= 1;
139
+ hunk.newRemaining -= 1;
140
+ }
141
+ else if (marker === "-") {
142
+ hunk.oldRemaining -= 1;
143
+ }
144
+ else if (marker === "+") {
145
+ hunk.newRemaining -= 1;
146
+ }
147
+ }
148
+ function handleBodyLine(file, line) {
149
+ if (file.current === undefined) {
150
+ return; // lines outside a hunk (e.g. `diff --git`, `index …`) are ignored
151
+ }
152
+ if (line.startsWith("\\")) {
153
+ return; // "" marker
154
+ }
155
+ // Only genuine body lines (context/add/remove) belong to the hunk. An empty trailing line
156
+ // (the split artifact of a final newline) or any other token ends the hunk so it is not
157
+ // mistaken for a zero-length context line that would never match the file content.
158
+ if (!isHunkBodyLine(line)) {
159
+ finishHunk(file);
160
+ return;
161
+ }
162
+ assertBudgetAvailable(file.current, line);
163
+ file.current.lines.push(line);
164
+ countBody(file, line);
165
+ consumeBudget(file.current, line);
166
+ }
167
+ function handleLine(state, line) {
168
+ // While a hunk still has budget, ` `/`+`/`-` lines are BODY even if they render as `--- `/`+++ `
169
+ // (C6). Only once the hunk is consumed (or absent) can a `--- ` line open a new file.
170
+ if (state.current !== undefined && hunkActive(state.current) && isHunkBodyLine(line)) {
171
+ handleBodyLine(state.current, line);
172
+ return;
173
+ }
174
+ if (line.startsWith("--- ")) {
175
+ startNewFile(state, headerPath(line, "--- "));
176
+ return;
177
+ }
178
+ if (state.current === undefined) {
179
+ return; // skip preamble before the first file header
180
+ }
181
+ if (line.startsWith("+++ ")) {
182
+ state.current.newPath = headerPath(line, "+++ ");
183
+ return;
184
+ }
185
+ if (line.startsWith("@@")) {
186
+ finishHunk(state.current);
187
+ state.current.current = parseHunkHeader(line);
188
+ return;
189
+ }
190
+ handleBodyLine(state.current, line);
191
+ }
192
+ export function parseUnifiedDiff(diff) {
193
+ const state = { files: [], current: undefined };
194
+ for (const line of diff.split("\n")) {
195
+ handleLine(state, line);
196
+ }
197
+ if (state.current !== undefined) {
198
+ finishFile(state.files, state.current);
199
+ }
200
+ return { files: state.files };
201
+ }
@@ -0,0 +1,18 @@
1
+ import { type WorkspaceFs } from "../workspace/fs.js";
2
+ import type { WorkspaceInfo } from "../workspace/types.js";
3
+ import { type WorkspaceWriter } from "./writer.js";
4
+ import { type PatchApplyResult, type PatchLimits, type PatchValidation } from "./types.js";
5
+ export interface ValidateDeps {
6
+ readonly fs?: WorkspaceFs | undefined;
7
+ readonly limits?: PatchLimits | undefined;
8
+ }
9
+ export declare function validatePatch(workspace: WorkspaceInfo, diff: string, deps?: ValidateDeps): PatchValidation;
10
+ export declare function renderDryRun(validation: PatchValidation): string;
11
+ export interface ApplyDeps {
12
+ readonly applyEnabled: boolean;
13
+ readonly signal: AbortSignal;
14
+ readonly fs?: WorkspaceFs | undefined;
15
+ readonly writer?: WorkspaceWriter | undefined;
16
+ readonly limits?: PatchLimits | undefined;
17
+ }
18
+ export declare function applyPatch(workspace: WorkspaceInfo, diff: string, deps: ApplyDeps): PatchApplyResult;