@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,49 @@
1
+ // Handlers for the patch-proposal, verification, and reporting states. The harness NEVER
2
+ // applies a patch: the diff is emitted as a patch:proposed event and carried on the run
3
+ // result. Nothing here touches the file system (ADR-0004 D8, dry-run by default).
4
+ import { HARNESS_CODES, toFailure } from "./errors.js";
5
+ const encoder = new TextEncoder();
6
+ function patchByteLength(diff) {
7
+ return encoder.encode(diff).length;
8
+ }
9
+ export function handlePatchProposal(ctx) {
10
+ const diff = ctx.lastResponse?.content ?? "";
11
+ const bytes = patchByteLength(diff);
12
+ if (bytes > ctx.limits.maxPatchBytes) {
13
+ ctx.failure = toFailure(HARNESS_CODES.LIMIT_PATCH_SIZE, `patch ${String(bytes)} bytes exceeds limit ${String(ctx.limits.maxPatchBytes)}`);
14
+ return { to: "limit-exceeded", reason: "maxPatchBytes exceeded" };
15
+ }
16
+ ctx.patchDiff = diff;
17
+ ctx.emitter.emit({
18
+ type: "patch:proposed",
19
+ targetFile: ctx.plan.targetFile,
20
+ patchBytes: bytes,
21
+ diff,
22
+ });
23
+ return { to: "verification", reason: "patch assembled and proposed (not applied)" };
24
+ }
25
+ // Wave-1 verification is a structural check: a proposed patch must be non-empty. Real test/
26
+ // command verification arrives with the tool execution layer (issue #6).
27
+ export function handleVerification(ctx) {
28
+ const passed = (ctx.patchDiff ?? "").trim().length > 0;
29
+ ctx.emitter.emit({
30
+ type: "verification:result",
31
+ passed,
32
+ detail: passed ? "non-empty patch produced" : "empty patch",
33
+ });
34
+ if (passed) {
35
+ return { to: "reporting", reason: "verification passed" };
36
+ }
37
+ ctx.counters.failureAttempts += 1;
38
+ if (ctx.counters.failureAttempts >= ctx.limits.maxFailureAttempts) {
39
+ ctx.failure = toFailure(HARNESS_CODES.LIMIT_FAILURE_ATTEMPTS, "verification kept failing");
40
+ return { to: "limit-exceeded", reason: "maxFailureAttempts exceeded after verification" };
41
+ }
42
+ return { to: "planning", reason: "verification failed; re-planning" };
43
+ }
44
+ // Records the final report on the context. The run:completed event is emitted by the loop
45
+ // once the terminal `completed` state is reached, so it is the last event in the stream.
46
+ export function handleReporting(ctx) {
47
+ ctx.report = ctx.lastResponse?.content ?? "no model output";
48
+ return { to: "completed", reason: "report generated" };
49
+ }
@@ -0,0 +1,3 @@
1
+ import { type RunContext, type StateStep } from "./context.js";
2
+ export declare function handlePlanning(ctx: RunContext): StateStep;
3
+ export declare function handleContextSelection(ctx: RunContext): StateStep;
@@ -0,0 +1,21 @@
1
+ // Handlers for the planning and context-selection states. Planning emits the task
2
+ // rationale as a reasoning:trace. Context-selection finalises the message array and
3
+ // enforces maxContextBytes before any model call (ADR-0004 D3 enforcement point).
4
+ import { HARNESS_CODES, toFailure } from "./errors.js";
5
+ import { contextBytes } from "./context.js";
6
+ export function handlePlanning(ctx) {
7
+ ctx.emitter.emit({
8
+ type: "reasoning:trace",
9
+ phase: "planning",
10
+ rationale: ctx.plan.rationale,
11
+ });
12
+ return { to: "context-selection", reason: "plan constructed" };
13
+ }
14
+ export function handleContextSelection(ctx) {
15
+ const bytes = contextBytes(ctx.messages);
16
+ if (bytes > ctx.limits.maxContextBytes) {
17
+ ctx.failure = toFailure(HARNESS_CODES.LIMIT_CONTEXT_SIZE, `context ${String(bytes)} bytes exceeds limit ${String(ctx.limits.maxContextBytes)}`);
18
+ return { to: "limit-exceeded", reason: "maxContextBytes exceeded" };
19
+ }
20
+ return { to: "model-call", reason: "context assembled within byte budget" };
21
+ }
@@ -0,0 +1,61 @@
1
+ import type { GatewayRequest, NormalizedResponse, ToolDefinition } from "../gateway/types.js";
2
+ import type { HarnessEvent, HarnessLimits, TaskInput, TaskType } from "./types.js";
3
+ export interface ModelPort {
4
+ readonly call: (request: GatewayRequest, signal: AbortSignal) => Promise<NormalizedResponse>;
5
+ }
6
+ export interface ToolCallRequest {
7
+ readonly toolCallId: string;
8
+ readonly toolName: string;
9
+ readonly arguments: Record<string, unknown>;
10
+ readonly signal: AbortSignal;
11
+ }
12
+ export type ToolCallMetadata = {
13
+ readonly kind: "command";
14
+ readonly executable: string;
15
+ readonly argCount: number;
16
+ readonly exitCode: number | null;
17
+ readonly timedOut: boolean;
18
+ readonly sandbox: {
19
+ readonly envAllowlist: readonly string[];
20
+ readonly network: "inherit" | "none";
21
+ readonly maxOutputBytes: number;
22
+ readonly timeoutMs: number;
23
+ readonly terminationGraceMs: number;
24
+ readonly cwdRequested: boolean;
25
+ };
26
+ } | {
27
+ readonly kind: "patch-apply";
28
+ readonly changedFiles: number;
29
+ readonly created: number;
30
+ readonly deleted: number;
31
+ };
32
+ export interface ToolCallResult {
33
+ readonly toolCallId: string;
34
+ readonly output: string;
35
+ readonly durationMs: number;
36
+ readonly commandExecuted?: boolean | undefined;
37
+ readonly metadata?: ToolCallMetadata | undefined;
38
+ }
39
+ export interface ToolPort {
40
+ readonly execute: (request: ToolCallRequest) => Promise<ToolCallResult>;
41
+ readonly listTools: () => readonly ToolDefinition[];
42
+ }
43
+ export interface EventSink {
44
+ readonly emit: (event: HarnessEvent) => void;
45
+ readonly retainsRawContent?: boolean | undefined;
46
+ }
47
+ export interface IdSource {
48
+ readonly newRunId: () => string;
49
+ }
50
+ export interface FingerprintInput {
51
+ readonly taskType: TaskType;
52
+ readonly taskInput: TaskInput;
53
+ readonly limits: HarnessLimits;
54
+ readonly modelId: string;
55
+ readonly workingDirectory: string;
56
+ readonly dryRun: boolean;
57
+ readonly harnessVersion: string;
58
+ }
59
+ export interface Fingerprinter {
60
+ readonly compute: (input: FingerprintInput) => string;
61
+ }
@@ -0,0 +1,4 @@
1
+ // Hexagonal port interfaces. The harness (high-level policy) depends only on these
2
+ // abstractions, never on the concrete Gateway, file system, or terminal. Issues #6,
3
+ // #10, and #13 each plug in their own implementations without touching the harness.
4
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { Clock } from "../gateway/types.js";
2
+ import type { EventSink, Fingerprinter, IdSource, ModelPort, ToolPort } from "./ports.js";
3
+ import { type HarnessLimits, type RunResult, type TaskInput } from "./types.js";
4
+ export declare const HARNESS_VERSION = "0.1.0-beta.0";
5
+ export interface AgentConfig {
6
+ readonly model: string;
7
+ readonly workingDirectory: string;
8
+ readonly limits?: Partial<HarnessLimits> | undefined;
9
+ readonly dryRun?: boolean | undefined;
10
+ }
11
+ export interface HarnessDeps {
12
+ readonly model: ModelPort;
13
+ readonly tools: ToolPort;
14
+ readonly sink: EventSink;
15
+ readonly clock?: Clock | undefined;
16
+ readonly idSource?: IdSource | undefined;
17
+ readonly fingerprinter?: Fingerprinter | undefined;
18
+ }
19
+ export interface AgentSession {
20
+ readonly runId: string;
21
+ readonly fingerprint: string;
22
+ readonly result: Promise<RunResult>;
23
+ readonly cancel: (reason?: string) => void;
24
+ }
25
+ export declare function createSession(task: TaskInput, config: AgentConfig, deps: HarnessDeps): AgentSession;
@@ -0,0 +1,116 @@
1
+ // The public session/run API. createSession() builds the run context, kicks off the loop
2
+ // asynchronously, and exposes the run id, config fingerprint, a result Promise, and a
3
+ // cancel() that aborts the single per-run AbortController (ADR-0004 D4, D9).
4
+ import { systemClock } from "../gateway/resilience.js";
5
+ import { newCounters } from "./context.js";
6
+ import { Emitter } from "./emitter.js";
7
+ import { HARNESS_CODES, toFailure } from "./errors.js";
8
+ import { defaultFingerprinter, defaultIdSource } from "./fingerprint.js";
9
+ import { runLoop } from "./loop.js";
10
+ import { MemoryEventSink } from "./sinks.js";
11
+ import { resolveTaskPlan } from "./tasks/policy.js";
12
+ import { DEFAULT_LIMITS, } from "./types.js";
13
+ export const HARNESS_VERSION = "0.1.0-beta.0";
14
+ function resolveLimits(config) {
15
+ return { ...DEFAULT_LIMITS, ...config.limits };
16
+ }
17
+ function resolveDryRun(config) {
18
+ return config.dryRun ?? true;
19
+ }
20
+ function buildResult(ctx, outcome, sink, identity) {
21
+ return {
22
+ runId: identity.runId,
23
+ fingerprint: identity.fingerprint,
24
+ outcome,
25
+ taskType: ctx.taskType,
26
+ ...(ctx.report === undefined ? {} : { report: ctx.report }),
27
+ ...(ctx.patchDiff === undefined ? {} : { patchDiff: ctx.patchDiff }),
28
+ ...(ctx.failure === undefined ? {} : { failure: ctx.failure }),
29
+ startedAt: ctx.startedAt,
30
+ finishedAt: ctx.clock.now(),
31
+ events: sink.events(),
32
+ };
33
+ }
34
+ function buildContext(task, config, deps, signal, runId, fingerprint) {
35
+ const clock = deps.clock ?? systemClock;
36
+ const memory = new MemoryEventSink();
37
+ const plan = resolveTaskPlan(task);
38
+ const ctx = {
39
+ model: deps.model,
40
+ tools: deps.tools,
41
+ emitter: new Emitter([memory, deps.sink], clock, runId, fingerprint),
42
+ clock,
43
+ signal,
44
+ limits: resolveLimits(config),
45
+ modelId: config.model,
46
+ taskType: task.taskType,
47
+ plan,
48
+ startedAt: clock.now(),
49
+ counters: newCounters(),
50
+ messages: [...plan.messages],
51
+ lastResponse: undefined,
52
+ patchDiff: undefined,
53
+ report: undefined,
54
+ failure: undefined,
55
+ cancelReason: undefined,
56
+ cancelledAtState: undefined,
57
+ };
58
+ return { ctx, memory };
59
+ }
60
+ function armWallTimeDeadline(ctx, controller, clock) {
61
+ let cleared = false;
62
+ const deadlineController = new AbortController();
63
+ void clock
64
+ .sleep(ctx.limits.maxWallTimeMs, deadlineController.signal)
65
+ .then(() => {
66
+ if (cleared || controller.signal.aborted) {
67
+ return;
68
+ }
69
+ ctx.failure = toFailure(HARNESS_CODES.LIMIT_WALL_TIME, "wall-time budget exhausted");
70
+ ctx.cancelReason = "maxWallTimeMs exceeded";
71
+ controller.abort("maxWallTimeMs exceeded");
72
+ })
73
+ .catch(() => undefined);
74
+ return () => {
75
+ cleared = true;
76
+ deadlineController.abort("run finished");
77
+ };
78
+ }
79
+ export function createSession(task, config, deps) {
80
+ const limits = resolveLimits(config);
81
+ const dryRun = resolveDryRun(config);
82
+ const runId = (deps.idSource ?? defaultIdSource).newRunId();
83
+ const fingerprint = (deps.fingerprinter ?? defaultFingerprinter).compute({
84
+ taskType: task.taskType,
85
+ taskInput: task,
86
+ limits,
87
+ modelId: config.model,
88
+ workingDirectory: config.workingDirectory,
89
+ dryRun,
90
+ harnessVersion: HARNESS_VERSION,
91
+ });
92
+ const controller = new AbortController();
93
+ const { ctx, memory } = buildContext(task, config, deps, controller.signal, runId, fingerprint);
94
+ const clearDeadline = armWallTimeDeadline(ctx, controller, ctx.clock);
95
+ ctx.emitter.emit({
96
+ type: "run:started",
97
+ taskType: task.taskType,
98
+ modelId: config.model,
99
+ limits,
100
+ });
101
+ // Defer the loop to a microtask so a cancel() issued synchronously after createSession is
102
+ // observed at the loop's first abort check, before any model or tool call is made.
103
+ const result = Promise.resolve()
104
+ .then(() => runLoop(ctx))
105
+ .finally(clearDeadline)
106
+ .then((outcome) => buildResult(ctx, outcome, memory, { runId, fingerprint }));
107
+ return {
108
+ runId,
109
+ fingerprint,
110
+ result,
111
+ cancel: (reason) => {
112
+ ctx.cancelReason = reason;
113
+ controller.abort(reason);
114
+ },
115
+ };
116
+ }
@@ -0,0 +1,30 @@
1
+ import type { EventSink } from "./ports.js";
2
+ import type { HarnessEvent, RunManifest } from "./types.js";
3
+ export interface EventWriter {
4
+ readonly out: (text: string) => void;
5
+ readonly err: (text: string) => void;
6
+ }
7
+ export interface ManifestSeed {
8
+ readonly runId: string;
9
+ readonly fingerprint: string;
10
+ readonly harnessVersion: string;
11
+ readonly taskType: RunManifest["taskType"];
12
+ readonly taskInput: RunManifest["taskInput"];
13
+ readonly limits: RunManifest["limits"];
14
+ readonly modelId: string;
15
+ readonly workingDirectory: string;
16
+ readonly dryRun: boolean;
17
+ readonly startedAt: string;
18
+ }
19
+ export declare class MemoryEventSink implements EventSink {
20
+ readonly retainsRawContent = true;
21
+ private readonly collected;
22
+ emit(event: HarnessEvent): void;
23
+ events(): readonly HarnessEvent[];
24
+ collectManifest(seed: ManifestSeed): RunManifest;
25
+ }
26
+ export declare class CliEventSink implements EventSink {
27
+ private readonly io;
28
+ constructor(io: EventWriter);
29
+ emit(event: HarnessEvent): void;
30
+ }
@@ -0,0 +1,72 @@
1
+ // Event sinks. MemoryEventSink collects events in order for tests and for assembling
2
+ // the replay manifest (issue #10 persists it). CliEventSink renders a one-line summary
3
+ // per event for the CLI; it NEVER prints SENSITIVE fields verbatim (rationale,
4
+ // modelResponse, diff) — only safe metadata and byte counts (ADR-0004 D6).
5
+ export class MemoryEventSink {
6
+ // The in-memory collector retains SENSITIVE fields verbatim so the manifest is a faithful
7
+ // replay record. The audit ledger (issue #10) applies its own redaction before persistence.
8
+ retainsRawContent = true;
9
+ collected = [];
10
+ emit(event) {
11
+ this.collected.push(event);
12
+ }
13
+ events() {
14
+ return this.collected;
15
+ }
16
+ collectManifest(seed) {
17
+ return { ...seed, events: this.collected };
18
+ }
19
+ }
20
+ // Per-variant one-line summary. SENSITIVE fields (rationale, modelResponse, diff) are
21
+ // never included — only safe metadata and byte counts. The handler map keeps cyclomatic
22
+ // complexity bounded (one entry per event type, no growing switch).
23
+ const SUMMARISERS = {
24
+ "run:started": (e) => `task=${e.taskType} model=${e.modelId}`,
25
+ "state:transition": (e) => `${e.from} -> ${e.to} (${e.reason})`,
26
+ "model:call:started": (e) => `model=${e.modelId} messages=${String(e.messageCount)} bytes=${String(e.contextBytes)}`,
27
+ "model:call:completed": (e) => `model=${e.modelId} finish=${e.finishReason} tools=${String(e.toolCallCount)}`,
28
+ "model:call:failed": (e) => `model=${e.modelId} code=${e.errorCode}`,
29
+ "tool:call:started": (e) => `tool=${e.toolName} id=${e.toolCallId}`,
30
+ "tool:call:completed": (e) => `tool=${e.toolName} id=${e.toolCallId}`,
31
+ "tool:call:failed": (e) => `tool=${e.toolName} code=${e.errorCode}`,
32
+ "sandbox:configured": (e) => `env=${e.envAllowlist.join(",")} network=${e.network} timeoutMs=${String(e.timeoutMs)} maxOutputBytes=${String(e.maxOutputBytes)} cwdRequested=${String(e.cwdRequested)}`,
33
+ "command:executed": (e) => `exec=${e.executable} args=${String(e.argCount)} exit=${String(e.exitCode)} timedOut=${String(e.timedOut)}`,
34
+ "patch:applied": (e) => `changed=${String(e.changedFiles)} created=${String(e.created)} deleted=${String(e.deleted)}`,
35
+ "reasoning:trace": (e) => `phase=${e.phase} (rationale redacted)`,
36
+ "patch:proposed": (e) => `file=${e.targetFile} bytes=${String(e.patchBytes)} (diff redacted)`,
37
+ "verification:result": (e) => `passed=${String(e.passed)}`,
38
+ "run:completed": () => "completed",
39
+ "run:cancelled": (e) => `cancelled at ${e.atState}${e.reason === undefined ? "" : ` (${e.reason})`}`,
40
+ "run:failed": (e) => `${e.failure.category}: ${e.failure.message}`,
41
+ // ADR-0017 — browser-tool events. originOnly is the scheme+authority only; never a path/query.
42
+ "browser:session-opened": (e) => `session=${e.sessionId} port=${String(e.cdpPort)} target=${e.targetId}`,
43
+ "browser:navigated": (e) => `session=${e.sessionId} origin=${e.originOnly} status=${String(e.httpStatus)}`,
44
+ "browser:screenshot-captured": (e) => `session=${e.sessionId} seq=${String(e.captureSeq)} persisted=${String(e.persisted)}`,
45
+ "browser:page-content-captured": (e) => `session=${e.sessionId} seq=${String(e.captureSeq)} bytes=${String(e.byteLength)}`,
46
+ "browser:session-closed": (e) => `session=${e.sessionId} reason=${e.reason}`,
47
+ "browser:trust-warning": (e) => `session=${e.sessionId} warning=${e.warning}`,
48
+ "browser:error": (e) => `session=${e.sessionId} code=${e.code}`,
49
+ };
50
+ function summarise(event) {
51
+ const handler = SUMMARISERS[event.type];
52
+ return handler(event);
53
+ }
54
+ function isFailureEvent(event) {
55
+ return (event.type === "run:failed" ||
56
+ event.type === "model:call:failed" ||
57
+ event.type === "tool:call:failed");
58
+ }
59
+ export class CliEventSink {
60
+ io;
61
+ constructor(io) {
62
+ this.io = io;
63
+ }
64
+ emit(event) {
65
+ const line = `[${String(event.seq)}] ${event.type} ${summarise(event)}\n`;
66
+ if (isFailureEvent(event)) {
67
+ this.io.err(line);
68
+ return;
69
+ }
70
+ this.io.out(line);
71
+ }
72
+ }
@@ -0,0 +1,3 @@
1
+ import type { ExplainPlanInput } from "../types.js";
2
+ import type { TaskPlan } from "./policy.js";
3
+ export declare function buildExplainPlan(input: ExplainPlanInput): TaskPlan;
@@ -0,0 +1,29 @@
1
+ // explain-plan: a read-only task. The harness must never enter tool-call, patch-proposal,
2
+ // or verification for this task type — enforced here by setting all `allows*` flags false.
3
+ // State path: intake -> planning -> context-selection -> model-call -> reporting -> completed.
4
+ const SYSTEM_PROMPT = "You are a senior engineer. Explain only the provided file excerpt and the user's question. " +
5
+ "Do not infer APIs, constants, or behavior that are not present in the excerpt. If the excerpt " +
6
+ "is missing or insufficient, say that explicitly. Do not propose code edits; this is a " +
7
+ "read-only explanation task.";
8
+ function contextBlock(input) {
9
+ return input.context === undefined
10
+ ? "\n\nFile excerpt: not available. State that limitation before answering."
11
+ : `\n\nFile excerpt:\n${input.context}`;
12
+ }
13
+ export function buildExplainPlan(input) {
14
+ const question = input.question === undefined
15
+ ? `Explain how the file at ${input.filePath} works.`
16
+ : `Regarding ${input.filePath}: ${input.question}`;
17
+ const messages = [
18
+ { role: "system", content: SYSTEM_PROMPT },
19
+ { role: "user", content: `${question}${contextBlock(input)}` },
20
+ ];
21
+ return {
22
+ allowsTools: false,
23
+ allowsPatch: false,
24
+ allowsVerification: false,
25
+ targetFile: input.filePath,
26
+ messages,
27
+ rationale: `explain-plan over ${input.filePath} (read-only)`,
28
+ };
29
+ }
@@ -0,0 +1,3 @@
1
+ import type { GenerateUnitTestsInput } from "../types.js";
2
+ import type { TaskPlan } from "./policy.js";
3
+ export declare function buildGenerateUnitTests(input: GenerateUnitTestsInput): TaskPlan;
@@ -0,0 +1,28 @@
1
+ // generate-unit-tests: proposes a test patch for a target file. The harness may reach
2
+ // patch-proposal and verification, but NEVER applies the patch (dry-run by default).
3
+ // Tool use is not part of this task path. State path:
4
+ // intake -> planning -> context-selection -> model-call -> patch-proposal -> verification
5
+ // -> reporting -> completed (verification may loop back to model-call).
6
+ const SYSTEM_PROMPT = "You are a senior engineer writing rigorous unit tests. Produce a unified diff that " +
7
+ "adds tests for the target. Cover edge cases (null, empty, boundary, error paths). " +
8
+ "Output only the diff.";
9
+ function userMessage(input) {
10
+ const target = input.targetFunction === undefined
11
+ ? `Write unit tests for the public API in ${input.filePath}.`
12
+ : `Write unit tests for the function ${input.targetFunction} in ${input.filePath}.`;
13
+ return input.context === undefined ? target : `${target}\n\nContext: ${input.context}`;
14
+ }
15
+ export function buildGenerateUnitTests(input) {
16
+ const messages = [
17
+ { role: "system", content: SYSTEM_PROMPT },
18
+ { role: "user", content: userMessage(input) },
19
+ ];
20
+ return {
21
+ allowsTools: false,
22
+ allowsPatch: true,
23
+ allowsVerification: true,
24
+ targetFile: input.filePath,
25
+ messages,
26
+ rationale: `generate-unit-tests for ${input.filePath}`,
27
+ };
28
+ }
@@ -0,0 +1,3 @@
1
+ import type { InvestigateBugInput } from "../types.js";
2
+ import type { TaskPlan } from "./policy.js";
3
+ export declare function buildInvestigateBug(input: InvestigateBugInput): TaskPlan;
@@ -0,0 +1,31 @@
1
+ // investigate-bug: the model may request tool calls to inspect the repo before proposing
2
+ // a fix patch. The harness may reach tool-call, patch-proposal, and verification, but NEVER
3
+ // applies the patch. State path:
4
+ // intake -> planning -> context-selection -> model-call [-> tool-call]* -> patch-proposal
5
+ // -> verification -> reporting -> completed.
6
+ const SYSTEM_PROMPT = "You are a senior engineer investigating a defect. Use the available read-only tools to " +
7
+ "gather evidence, then propose a minimal fix as a unified diff. Output only the diff once " +
8
+ "you have enough evidence.";
9
+ const UNSPECIFIED_TARGET = "<unspecified>";
10
+ function userMessage(input) {
11
+ const files = input.filePaths === undefined || input.filePaths.length === 0
12
+ ? ""
13
+ : `\n\nSuspected files: ${input.filePaths.join(", ")}`;
14
+ const context = input.context === undefined ? "" : `\n\nContext: ${input.context}`;
15
+ return `Investigate this bug: ${input.description}${files}${context}`;
16
+ }
17
+ export function buildInvestigateBug(input) {
18
+ const target = input.filePaths?.[0] ?? UNSPECIFIED_TARGET;
19
+ const messages = [
20
+ { role: "system", content: SYSTEM_PROMPT },
21
+ { role: "user", content: userMessage(input) },
22
+ ];
23
+ return {
24
+ allowsTools: true,
25
+ allowsPatch: true,
26
+ allowsVerification: true,
27
+ targetFile: target,
28
+ messages,
29
+ rationale: `investigate-bug: ${input.description.slice(0, 40)}`,
30
+ };
31
+ }
@@ -0,0 +1,11 @@
1
+ import type { ChatMessage } from "../../gateway/types.js";
2
+ import type { TaskInput } from "../types.js";
3
+ export interface TaskPlan {
4
+ readonly allowsTools: boolean;
5
+ readonly allowsPatch: boolean;
6
+ readonly allowsVerification: boolean;
7
+ readonly targetFile: string;
8
+ readonly messages: readonly ChatMessage[];
9
+ readonly rationale: string;
10
+ }
11
+ export declare function resolveTaskPlan(task: TaskInput): TaskPlan;
@@ -0,0 +1,22 @@
1
+ // Shared task abstraction. Each Wave-1 task type provides a TaskPlan describing the
2
+ // initial model messages, the patch target, and the state-path capabilities the loop is
3
+ // allowed to enter. The loop reads `allows*` flags to route — read-only enforcement for
4
+ // explain-plan is a property of the task, not of configuration (ADR-0004 D8).
5
+ import { buildExplainPlan } from "./explain-plan.js";
6
+ import { buildGenerateUnitTests } from "./generate-unit-tests.js";
7
+ import { buildInvestigateBug } from "./investigate-bug.js";
8
+ import { buildVerify } from "./verify.js";
9
+ // Routes a validated TaskInput to its task-specific plan. The discriminated union makes
10
+ // this total: adding a TaskType without a branch is a compile error.
11
+ export function resolveTaskPlan(task) {
12
+ switch (task.taskType) {
13
+ case "generate-unit-tests":
14
+ return buildGenerateUnitTests(task.input);
15
+ case "investigate-bug":
16
+ return buildInvestigateBug(task.input);
17
+ case "explain-plan":
18
+ return buildExplainPlan(task.input);
19
+ case "verify":
20
+ return buildVerify(task.input);
21
+ }
22
+ }
@@ -0,0 +1,3 @@
1
+ import type { VerifyInput } from "../types.js";
2
+ import type { TaskPlan } from "./policy.js";
3
+ export declare function buildVerify(input: VerifyInput): TaskPlan;
@@ -0,0 +1,16 @@
1
+ // verify: a deterministic repository-gate task. The harness loop is NOT entered for this task —
2
+ // the BFF run engine invokes the verification orchestrator directly (it spawns lint/test/build
3
+ // rather than calling a model). This plan exists so the task-policy switch remains total and so
4
+ // the discriminated union can carry a verify variant alongside the model-driven tasks. All
5
+ // `allows*` flags are false: there is no model call, no tool call, no patch proposal.
6
+ export function buildVerify(input) {
7
+ const messages = [];
8
+ return {
9
+ allowsTools: false,
10
+ allowsPatch: false,
11
+ allowsVerification: false,
12
+ targetFile: input.workspaceRoot,
13
+ messages,
14
+ rationale: `verify gates over ${input.workspaceRoot} (deterministic, no model call)`,
15
+ };
16
+ }