@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
package/dist/ui/csp.js ADDED
@@ -0,0 +1,66 @@
1
+ // Hash-based Content-Security-Policy support (ADR-0011 D5, risk #1). The Next static export emits
2
+ // inline RSC-bootstrap `<script>` blocks (`self.__next_f.push(...)`). The BFF serves
3
+ // `script-src 'self'` with NO `'unsafe-inline'`, so each distinct inline script must be allowed by
4
+ // its SHA-256 hash. `extractInlineScriptHashes` computes those hashes from exported HTML at build
5
+ // time; `buildCspHeader` folds them into the policy the BFF sets on every response.
6
+ import { createHash } from "node:crypto";
7
+ // `/\bsrc\s*=/i` matches an attribute key only — no `<`/`>` involved, so it does not trigger
8
+ // CodeQL js/bad-tag-filter (which fires on regexes that structurally match HTML tags).
9
+ const SRC_ATTRIBUTE_PATTERN = /\bsrc\s*=/i;
10
+ function sha256Base64(body) {
11
+ return createHash("sha256").update(body, "utf8").digest("base64");
12
+ }
13
+ // Finds the next inline-script body starting at cursor `i`, using a case-insensitive indexOf scan
14
+ // rather than a tag-matching regex (eliminates the CodeQL js/bad-tag-filter class entirely). Body
15
+ // is sliced from original-case `html` so the SHA-256 matches what the browser executes.
16
+ function nextInlineScript(html, lower, i) {
17
+ const open = lower.indexOf("<script", i);
18
+ if (open === -1)
19
+ return null;
20
+ const openEnd = lower.indexOf(">", open);
21
+ if (openEnd === -1)
22
+ return null;
23
+ const close = lower.indexOf("</script", openEnd + 1);
24
+ if (close === -1)
25
+ return null;
26
+ const closeEnd = lower.indexOf(">", close);
27
+ const next = closeEnd === -1 ? close + 8 : closeEnd + 1;
28
+ return { openTag: html.slice(open, openEnd + 1), body: html.slice(openEnd + 1, close), next };
29
+ }
30
+ // Returns the distinct `'sha256-...'` CSP source tokens for every inline script across the given
31
+ // HTML documents, in stable sorted order so the generated policy is deterministic.
32
+ export function extractInlineScriptHashes(htmlDocuments) {
33
+ const tokens = new Set();
34
+ for (const html of htmlDocuments) {
35
+ const lower = html.toLowerCase();
36
+ let i = 0;
37
+ for (;;) {
38
+ const found = nextInlineScript(html, lower, i);
39
+ if (found === null)
40
+ break;
41
+ const { openTag, body, next } = found;
42
+ if (!SRC_ATTRIBUTE_PATTERN.test(openTag) && body.length > 0) {
43
+ tokens.add(`'sha256-${sha256Base64(body)}'`);
44
+ }
45
+ i = next;
46
+ }
47
+ }
48
+ return [...tokens].sort();
49
+ }
50
+ // Builds the full CSP header value. `scriptHashes` are folded into `script-src` alongside `'self'`.
51
+ // `style-src` keeps `'unsafe-inline'` for Tailwind's injected styles (the only permitted inline
52
+ // source); `script-src` never receives `'unsafe-inline'` or `'unsafe-eval'`.
53
+ export function buildCspHeader(scriptHashes) {
54
+ const scriptSrc = ["'self'", ...scriptHashes].join(" ");
55
+ return [
56
+ "default-src 'none'",
57
+ `script-src ${scriptSrc}`,
58
+ "style-src 'self' 'unsafe-inline'",
59
+ "img-src 'self' data:",
60
+ "connect-src 'self'",
61
+ "font-src 'self'",
62
+ "base-uri 'none'",
63
+ "form-action 'none'",
64
+ "frame-ancestors 'none'",
65
+ ].join("; ");
66
+ }
@@ -0,0 +1,34 @@
1
+ import { type EnvSource, type GatewayConfig } from "../gateway/index.js";
2
+ import type { ModelPort } from "../harness/index.js";
3
+ import type { EvidenceStore } from "../audit/index.js";
4
+ import type { RunRegistry } from "./runs.js";
5
+ import { type UiStore } from "./store/index.js";
6
+ import { type TerminalExecutionManager } from "./terminal.js";
7
+ import { type BrowserSessionManager } from "../tools/browser/index.js";
8
+ export type Redactor = (value: unknown) => unknown;
9
+ export type ModelPortFactory = (modelId: string) => ModelPort | undefined;
10
+ export interface UiHandlerDeps {
11
+ readonly config: GatewayConfig | undefined;
12
+ readonly configPresent: boolean;
13
+ readonly evidenceStore: EvidenceStore;
14
+ readonly env: EnvSource;
15
+ readonly redactor: Redactor;
16
+ readonly registry: RunRegistry;
17
+ readonly modelPortFactory: ModelPortFactory;
18
+ readonly redactionSecrets?: readonly string[] | undefined;
19
+ readonly store: UiStore;
20
+ readonly uiDbPath?: string | undefined;
21
+ readonly terminal?: TerminalExecutionManager | undefined;
22
+ readonly browser?: BrowserSessionManager | undefined;
23
+ }
24
+ export interface BuildHandlerDepsOptions {
25
+ readonly configPath: string | undefined;
26
+ readonly evidenceDir: string | undefined;
27
+ readonly env: EnvSource;
28
+ readonly registry?: RunRegistry | undefined;
29
+ readonly modelPortFactory?: ModelPortFactory | undefined;
30
+ readonly uiDbPath?: string | undefined;
31
+ readonly store?: UiStore | undefined;
32
+ }
33
+ export declare function buildRedactor(env: EnvSource, config?: GatewayConfig): Redactor;
34
+ export declare function buildUiHandlerDeps(options: BuildHandlerDepsOptions): UiHandlerDeps;
@@ -0,0 +1,137 @@
1
+ // Wave 2 BFF handler dependencies (ADR-0011 D5/D8/D9). The Wave 1 skeleton's `UiServerDeps` carried
2
+ // only the static-serving + CSP + port fields; the JSON/SSE handlers additionally need the resolved
3
+ // gateway config (for the config inspector and for building a ModelPort), an evidence store, a live
4
+ // redactor, the process env, and the in-memory run registry. Every field here is OPTIONAL so the
5
+ // 3-arg `createUiServer({ staticRoot, csp, port })` form still compiles and the Wave 1 server tests
6
+ // pass unchanged; the handlers degrade gracefully (no config → 400 NO_MODEL on a run, null config on
7
+ // the inspector; no store → an empty evidence list).
8
+ import { listCapabilities, loadConfigFromFile, parseGatewayConfig, } from "../gateway/index.js";
9
+ import { GatewayError, Gateway } from "../gateway/index.js";
10
+ import { GatewayModelPort } from "../harness/index.js";
11
+ import { createAuditRedactor } from "../audit/index.js";
12
+ import { deepRedactStrings } from "../audit/redaction.js";
13
+ import { createNodeEvidenceStore, resolveEvidenceDir } from "../audit/store.js";
14
+ import { createRunRegistry } from "./runs.js";
15
+ import { createNodeUiStore, resolveUiDbPath, } from "./store/index.js";
16
+ import { createTerminalExecutionManager, } from "./terminal.js";
17
+ import { createBrowserSessionManager, } from "../tools/browser/index.js";
18
+ function envModelToken(modelId) {
19
+ return modelId.replace(/[^A-Za-z0-9]/g, "_").toUpperCase();
20
+ }
21
+ function hasEnvProvider(modelId, env) {
22
+ const token = envModelToken(modelId);
23
+ const baseUrl = env[`KEIKO_MODEL_${token}_BASE_URL`];
24
+ const apiKey = env[`KEIKO_MODEL_${token}_API_KEY`];
25
+ return baseUrl !== undefined && baseUrl.length > 0 && apiKey !== undefined && apiKey.length > 0;
26
+ }
27
+ function resolveEnvOnlyConfig(env) {
28
+ const providers = listCapabilities()
29
+ .filter((capability) => capability.kind === "chat" && hasEnvProvider(capability.id, env))
30
+ .map((capability) => ({ modelId: capability.id, baseUrl: "", apiKey: "" }));
31
+ if (providers.length === 0) {
32
+ return undefined;
33
+ }
34
+ try {
35
+ return parseGatewayConfig({ providers }, env);
36
+ }
37
+ catch (error) {
38
+ if (error instanceof GatewayError) {
39
+ return undefined;
40
+ }
41
+ throw error;
42
+ }
43
+ }
44
+ // Loads the config without leaking the path or any secret on failure: a missing/invalid config file
45
+ // falls back to KEIKO_MODEL_* env wiring when present, otherwise it is a normal "no config" state.
46
+ function resolveConfig(configPath, env) {
47
+ if (configPath === undefined) {
48
+ const config = resolveEnvOnlyConfig(env);
49
+ return { config, configPresent: config !== undefined };
50
+ }
51
+ try {
52
+ return { config: loadConfigFromFile(configPath, env), configPresent: true };
53
+ }
54
+ catch (error) {
55
+ if (error instanceof GatewayError) {
56
+ const config = resolveEnvOnlyConfig(env);
57
+ return { config, configPresent: config !== undefined };
58
+ }
59
+ throw error;
60
+ }
61
+ }
62
+ function isKeikoApiKeyEnvName(name) {
63
+ return (name === "KEIKO_DEFAULT_API_KEY" ||
64
+ (name.startsWith("KEIKO_MODEL_") && name.endsWith("_API_KEY")));
65
+ }
66
+ function envSecretValues(env) {
67
+ const values = [];
68
+ for (const [key, value] of Object.entries(env)) {
69
+ if (value !== undefined && isKeikoApiKeyEnvName(key)) {
70
+ values.push(value);
71
+ }
72
+ }
73
+ return values;
74
+ }
75
+ function configSecretValues(config) {
76
+ return config?.providers.map((provider) => provider.apiKey) ?? [];
77
+ }
78
+ function redactionSecrets(env, config) {
79
+ return [...envSecretValues(env), ...configSecretValues(config)];
80
+ }
81
+ // Builds the live-payload redactor from the configured redaction settings + env. No new regex: this
82
+ // reuses `createAuditRedactor` (escaped literals + audited gateway patterns) wrapped by
83
+ // `deepRedactStrings` so every string leaf of a serialized payload is scrubbed.
84
+ export function buildRedactor(env, config) {
85
+ const redactString = createAuditRedactor({ additionalSecrets: redactionSecrets(env, config) }, env);
86
+ return (value) => deepRedactStrings(value, redactString);
87
+ }
88
+ // The production ModelPort factory: a GatewayModelPort over a Gateway built from the resolved
89
+ // config (mirrors the CLI's `new GatewayModelPort(new Gateway(config))`). Returns undefined when no
90
+ // config was resolved so the run route answers 400 NO_MODEL rather than constructing a broken port.
91
+ function defaultModelPortFactory(config) {
92
+ return () => {
93
+ if (config === undefined) {
94
+ return undefined;
95
+ }
96
+ return new GatewayModelPort(new Gateway(config));
97
+ };
98
+ }
99
+ // Assembles the handler deps for the real `keiko ui` process, mirroring the CLI config/evidence
100
+ // wiring (loadConfigFromFile / resolveEvidenceDir / createNodeEvidenceStore). The UI store is
101
+ // created at the resolved UI-DB path (explicit → KEIKO_UI_DATA_DIR → ~/.keiko/keiko-ui.db) unless
102
+ // an injected store is supplied (tests).
103
+ export function buildUiHandlerDeps(options) {
104
+ const { config, configPresent } = resolveConfig(options.configPath, options.env);
105
+ const evidenceStore = createNodeEvidenceStore(resolveEvidenceDir(options.evidenceDir, options.env));
106
+ const secrets = redactionSecrets(options.env, config);
107
+ const redactString = createAuditRedactor({ additionalSecrets: secrets }, options.env);
108
+ const liveRedactor = buildRedactor(options.env, config);
109
+ const resolvedUiDbPath = resolveUiDbPath(options.uiDbPath, options.env);
110
+ const uiStore = options.store ?? createNodeUiStore(resolvedUiDbPath, { redactString });
111
+ return {
112
+ config,
113
+ configPresent,
114
+ evidenceStore,
115
+ env: options.env,
116
+ redactor: liveRedactor,
117
+ registry: options.registry ?? createRunRegistry(),
118
+ modelPortFactory: options.modelPortFactory ?? defaultModelPortFactory(config),
119
+ redactionSecrets: secrets,
120
+ store: uiStore,
121
+ uiDbPath: resolvedUiDbPath,
122
+ terminal: createTerminalExecutionManager({
123
+ store: uiStore,
124
+ evidenceStore,
125
+ processEnv: options.env,
126
+ redactor: (value) => {
127
+ const redacted = liveRedactor(value);
128
+ return typeof redacted === "string" ? redacted : value;
129
+ },
130
+ }),
131
+ browser: createBrowserSessionManager({
132
+ evidenceDir: resolveEvidenceDir(options.evidenceDir, options.env),
133
+ evidenceStore,
134
+ redactor: liveRedactor,
135
+ }),
136
+ };
137
+ }
@@ -0,0 +1,27 @@
1
+ import { type EvidenceReport } from "../audit/index.js";
2
+ import { type RunResult } from "../harness/index.js";
3
+ import type { EnvSource } from "../gateway/index.js";
4
+ import type { EvidenceStore } from "../audit/index.js";
5
+ import type { StreamEvent } from "./sink.js";
6
+ import type { RunKind } from "./run-request.js";
7
+ import type { RunStatus } from "./runs.js";
8
+ type TerminalStatus = Exclude<RunStatus, "running">;
9
+ export interface EvidencePersistContext {
10
+ readonly store: EvidenceStore;
11
+ readonly env: EnvSource;
12
+ readonly additionalSecrets?: readonly string[] | undefined;
13
+ }
14
+ export interface RunIdentity {
15
+ readonly runId: string;
16
+ readonly fingerprint: string;
17
+ readonly modelId: string;
18
+ readonly kind: RunKind;
19
+ readonly status: TerminalStatus;
20
+ readonly startedAt: number;
21
+ readonly finishedAt: number;
22
+ readonly workspaceRoot?: string | undefined;
23
+ }
24
+ export declare function persistWorkflowEvidence(identity: RunIdentity, report: unknown, events: readonly StreamEvent[], ctx: EvidencePersistContext): EvidenceReport;
25
+ export declare function persistExplainEvidence(identity: RunIdentity, result: RunResult, ctx: EvidencePersistContext): EvidenceReport;
26
+ export declare function persistVerifyEvidence(identity: RunIdentity, ctx: EvidencePersistContext): EvidenceReport;
27
+ export {};
@@ -0,0 +1,142 @@
1
+ // Evidence persistence for UI-initiated runs (ADR-0011 AC5; #10 audit public API only). The Wave 2
2
+ // BFF never persisted evidence, so UI runs (including cancellations) never reached the evidence
3
+ // browser. This module folds a terminated run into a redacted EvidenceManifest and writes it through
4
+ // the #10 EvidenceStore, composing the audit layer's PUBLIC API UNCHANGED (no frozen-core edit).
5
+ //
6
+ // The WORKFLOW manifest mapping now lives in the shared audit module `workflow-evidence.ts` (ADR-0012
7
+ // C2), so the evaluation harness and this BFF build it from one implementation. This module keeps the
8
+ // EXPLAIN-PLAN harness path (whose `usage` shape differs) local, and adapts the UI RunKind/RunStatus
9
+ // to the shared module's narrow workflow types. Persistence errors surface to the run engine so the
10
+ // final registry payload cannot silently omit required evidence.
11
+ import { buildEvidenceReport, createAuditRedactor, EVIDENCE_SCHEMA_VERSION, resolveCostClass, persistWorkflowEvidence as persistWorkflowEvidenceCore, } from "../audit/index.js";
12
+ import { deepRedactStrings } from "../audit/redaction.js";
13
+ import { HARNESS_VERSION } from "../harness/index.js";
14
+ // Only the two model-driven workflow kinds map to the shared audit core; explain-plan and verify
15
+ // follow their own manifest paths (different usage shape / no usage at all).
16
+ function toWorkflowKind(kind) {
17
+ return kind === "bug-investigation" ? "bug-investigation" : "unit-tests";
18
+ }
19
+ // Persists a terminated WORKFLOW run (unit-tests / bug-investigation) via the shared audit core. The
20
+ // report is the workflow's own typed report; only counts/summaries are folded in (never the raw diff).
21
+ export function persistWorkflowEvidence(identity, report, events, ctx) {
22
+ return persistWorkflowEvidenceCore({
23
+ runId: identity.runId,
24
+ fingerprint: identity.fingerprint,
25
+ modelId: identity.modelId,
26
+ kind: toWorkflowKind(identity.kind),
27
+ status: identity.status,
28
+ startedAt: identity.startedAt,
29
+ finishedAt: identity.finishedAt,
30
+ ...(identity.workspaceRoot === undefined ? {} : { workspaceRoot: identity.workspaceRoot }),
31
+ }, report, events, ctx);
32
+ }
33
+ // Persists a terminated EXPLAIN-PLAN harness run. The RunResult carries the raw harness events whose
34
+ // `usage` shape the audit fold understands; the usage is folded directly so the explain path keeps a
35
+ // single manifest-build path independent of the shared workflow core (which folds top-level fields).
36
+ export function persistExplainEvidence(identity, result, ctx) {
37
+ const manifest = buildExplainManifest(identity, result);
38
+ const redactor = createAuditRedactor({ additionalSecrets: ctx.additionalSecrets ?? [] }, ctx.env);
39
+ const redacted = deepRedactStrings(manifest, redactor);
40
+ const location = ctx.store.put(redacted.run.runId, JSON.stringify(redacted));
41
+ return buildEvidenceReport(redacted, location);
42
+ }
43
+ const KIND_TO_TASK_TYPE = {
44
+ "unit-tests": "generate-unit-tests",
45
+ "bug-investigation": "investigate-bug",
46
+ "explain-plan": "explain-plan",
47
+ verify: "verify",
48
+ };
49
+ // Persists a terminated VERIFY run. Verify never calls a model, so usageTotals are all zero and
50
+ // stateTransitions/toolCalls/commandExecutions stay empty (the verification orchestrator's own
51
+ // audit summarisation lives in `src/verification/summary.ts` and is out of scope for this leaf).
52
+ export function persistVerifyEvidence(identity, ctx) {
53
+ const manifest = buildVerifyManifest(identity);
54
+ const redactor = createAuditRedactor({ additionalSecrets: ctx.additionalSecrets ?? [] }, ctx.env);
55
+ const redacted = deepRedactStrings(manifest, redactor);
56
+ const location = ctx.store.put(redacted.run.runId, JSON.stringify(redacted));
57
+ return buildEvidenceReport(redacted, location);
58
+ }
59
+ function buildVerifyManifest(identity) {
60
+ const context = identity.workspaceRoot === undefined
61
+ ? undefined
62
+ : {
63
+ workspaceRoot: identity.workspaceRoot,
64
+ totalCandidates: 0,
65
+ usedBytes: 0,
66
+ budgetBytes: 0,
67
+ droppedForBudget: 0,
68
+ entries: [],
69
+ };
70
+ return {
71
+ evidenceSchemaVersion: EVIDENCE_SCHEMA_VERSION,
72
+ run: {
73
+ runId: identity.runId,
74
+ fingerprint: identity.fingerprint,
75
+ harnessVersion: HARNESS_VERSION,
76
+ taskType: KIND_TO_TASK_TYPE[identity.kind],
77
+ outcome: identity.status,
78
+ startedAt: identity.startedAt,
79
+ finishedAt: identity.finishedAt,
80
+ durationMs: Math.max(0, identity.finishedAt - identity.startedAt),
81
+ },
82
+ model: { modelId: identity.modelId, costClass: resolveCostClass(identity.modelId) },
83
+ usageTotals: { promptTokens: 0, completionTokens: 0, requestCount: 0, totalLatencyMs: 0 },
84
+ ...(context === undefined ? {} : { context }),
85
+ stateTransitions: [],
86
+ toolCalls: [],
87
+ commandExecutions: [],
88
+ verification: undefined,
89
+ patch: undefined,
90
+ failure: undefined,
91
+ };
92
+ }
93
+ function buildExplainManifest(identity, result) {
94
+ const context = identity.workspaceRoot === undefined
95
+ ? undefined
96
+ : {
97
+ workspaceRoot: identity.workspaceRoot,
98
+ totalCandidates: 0,
99
+ usedBytes: 0,
100
+ budgetBytes: 0,
101
+ droppedForBudget: 0,
102
+ entries: [],
103
+ };
104
+ return {
105
+ evidenceSchemaVersion: EVIDENCE_SCHEMA_VERSION,
106
+ run: {
107
+ runId: identity.runId,
108
+ fingerprint: identity.fingerprint,
109
+ harnessVersion: HARNESS_VERSION,
110
+ taskType: KIND_TO_TASK_TYPE[identity.kind],
111
+ outcome: identity.status,
112
+ startedAt: identity.startedAt,
113
+ finishedAt: identity.finishedAt,
114
+ durationMs: Math.max(0, identity.finishedAt - identity.startedAt),
115
+ },
116
+ model: { modelId: identity.modelId, costClass: resolveCostClass(identity.modelId) },
117
+ usageTotals: foldHarnessUsage(result.events),
118
+ ...(context === undefined ? {} : { context }),
119
+ stateTransitions: [],
120
+ toolCalls: [],
121
+ commandExecutions: [],
122
+ verification: undefined,
123
+ patch: undefined,
124
+ failure: undefined,
125
+ };
126
+ }
127
+ function foldHarnessUsage(events) {
128
+ let promptTokens = 0;
129
+ let completionTokens = 0;
130
+ let requestCount = 0;
131
+ let totalLatencyMs = 0;
132
+ for (const event of events) {
133
+ if (event.type !== "model:call:completed") {
134
+ continue;
135
+ }
136
+ promptTokens += event.usage.promptTokens;
137
+ completionTokens += event.usage.completionTokens;
138
+ totalLatencyMs += event.usage.latencyMs;
139
+ requestCount += 1;
140
+ }
141
+ return { promptTokens, completionTokens, requestCount, totalLatencyMs };
142
+ }
@@ -0,0 +1,2 @@
1
+ export declare const DENIED_MESSAGE = "The requested path is excluded from the read surface.";
2
+ export declare function pathIsDenied(relativePath: string): boolean;
@@ -0,0 +1,12 @@
1
+ // Deny-list wiring for the Files BFF (`/api/files/*`). Reuses
2
+ // `src/workspace/ignore.ts` unchanged: `isDenied` is the always-on security
3
+ // gate that filters secret/dep/build/vcs/log entries from both tree listings
4
+ // and previews. See ADR-0016.
5
+ import { isDenied } from "../workspace/ignore.js";
6
+ // Generic, non-leaking deny message. NEVER include the requested path or the
7
+ // matched pattern: the deny list is treated as a server-side safety invariant
8
+ // the client must not be able to probe.
9
+ export const DENIED_MESSAGE = "The requested path is excluded from the read surface.";
10
+ export function pathIsDenied(relativePath) {
11
+ return isDenied(relativePath);
12
+ }
@@ -0,0 +1,65 @@
1
+ import { type RouteContext, type RouteResult } from "./routes.js";
2
+ import type { UiHandlerDeps } from "./deps.js";
3
+ import type { UiStore } from "./store/index.js";
4
+ export interface FilesDirectoryRoot {
5
+ readonly label: string;
6
+ readonly path: string;
7
+ }
8
+ export interface FilesDirectoryEntry {
9
+ readonly name: string;
10
+ readonly path: string;
11
+ }
12
+ export interface FilesDirectoryListing {
13
+ readonly path: string;
14
+ readonly parent: string | null;
15
+ readonly entries: readonly FilesDirectoryEntry[];
16
+ readonly roots: readonly FilesDirectoryRoot[];
17
+ }
18
+ export type FilesEntryKind = "directory" | "file" | "symlink";
19
+ export interface FilesTreeEntry {
20
+ readonly name: string;
21
+ readonly path: string;
22
+ readonly kind: FilesEntryKind;
23
+ readonly sizeBytes: number;
24
+ readonly modifiedAt: number;
25
+ readonly extension: string | null;
26
+ readonly symlink: boolean;
27
+ readonly readable: boolean;
28
+ }
29
+ export interface FilesTreeResponse {
30
+ readonly root: string;
31
+ readonly path: string;
32
+ readonly entries: readonly FilesTreeEntry[];
33
+ readonly truncated: boolean;
34
+ }
35
+ interface FilesPreviewBase {
36
+ readonly root: string;
37
+ readonly path: string;
38
+ readonly name: string;
39
+ readonly sizeBytes: number;
40
+ readonly modifiedAt: number;
41
+ readonly extension: string | null;
42
+ readonly mime: string;
43
+ readonly symlink: boolean;
44
+ }
45
+ export type FilesPreviewResponse = (FilesPreviewBase & {
46
+ readonly kind: "text";
47
+ readonly content: string;
48
+ readonly truncated: boolean;
49
+ readonly maxBytes: number;
50
+ }) | (FilesPreviewBase & {
51
+ readonly kind: "image";
52
+ readonly dataUrl: string;
53
+ readonly maxBytes: number;
54
+ }) | (FilesPreviewBase & {
55
+ readonly kind: "binary";
56
+ readonly reason: "unsupported" | "too_large";
57
+ readonly maxBytes?: number | undefined;
58
+ });
59
+ export declare function listFilesDirectories(store: UiStore, rootInput: string | null, pathInput?: string): Promise<FilesDirectoryListing>;
60
+ export declare function readFilesTree(store: UiStore, rootInput: string | null, pathInput: string | null): Promise<FilesTreeResponse>;
61
+ export declare function readFilesPreview(store: UiStore, rootInput: string | null, pathInput: string | null, redactor: UiHandlerDeps["redactor"]): Promise<FilesPreviewResponse>;
62
+ export declare function handleFilesDirectories(ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
63
+ export declare function handleFilesTree(ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
64
+ export declare function handleFilesPreview(ctx: RouteContext, deps: UiHandlerDeps): Promise<RouteResult>;
65
+ export {};