@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,208 @@
1
+ // `keiko gen-tests` — generates a reviewable unit-test patch for a target file/dir/changed-set
2
+ // (ADR-0008 D9). Dry-run by default; --apply writes the tests and runs verification. The text path
3
+ // prints the reviewable proposed diff AND the #6 validation summary so a terminal reviewer sees the
4
+ // actual generated test code (AC #4/#6); --json emits the full UnitTestWorkflowReport. The gateway
5
+ // ModelPort is built from config (loadConfigFromFile); tests inject deps.model directly so no live
6
+ // gateway is needed. Exit 0 on completed/dry-run, 1 on rejected/cancelled/failed/runtime, 2 on
7
+ // usage. Mirrors runVerifyCli's flag-parse / typed-error-catch structure.
8
+ import { Gateway } from "../gateway/gateway.js";
9
+ import { loadConfigFromFile } from "../gateway/config.js";
10
+ import { ConfigInvalidError, GatewayError } from "../gateway/errors.js";
11
+ import { assertConfiguredModel, selectConfiguredModel } from "../gateway/model-selection.js";
12
+ import { redact } from "../gateway/redaction.js";
13
+ import { GatewayModelPort } from "../harness/adapters.js";
14
+ import { WorkspaceError } from "../workspace/index.js";
15
+ import { generateUnitTests, renderMarkdownReport } from "../workflows/index.js";
16
+ const USAGE = `Usage:
17
+ keiko gen-tests (--file PATH | --dir PATH) [--function NAME] [--changed FILE[,FILE]]
18
+ [--apply] [--model MODEL_ID] [--config PATH] [--json] [--dir-root PATH]
19
+
20
+ Generates a reviewable unit-test patch for a target TypeScript file, function, or
21
+ module. Dry-run by default (prints the proposed diff, writes nothing); pass --apply
22
+ to write the tests and run verification through the safe tool + verification layers.
23
+ `;
24
+ // Returns the value of a `--flag value` pair, undefined if absent, or null if present without a
25
+ // value (a usage error) — identical contract to runVerifyCli's flagValue.
26
+ function flagValue(args, name) {
27
+ const i = args.indexOf(name);
28
+ if (i === -1) {
29
+ return undefined;
30
+ }
31
+ const value = args[i + 1];
32
+ return value === undefined || value.startsWith("--") ? null : value;
33
+ }
34
+ const VALUE_FLAGS = [
35
+ "--file",
36
+ "--dir",
37
+ "--function",
38
+ "--changed",
39
+ "--model",
40
+ "--config",
41
+ "--dir-root",
42
+ ];
43
+ // Reads every value flag once; returns null if any is present without a value (a usage error).
44
+ function readValueFlags(args) {
45
+ const values = {};
46
+ for (const flag of VALUE_FLAGS) {
47
+ const value = flagValue(args, flag);
48
+ if (value === null) {
49
+ return null;
50
+ }
51
+ values[flag] = value;
52
+ }
53
+ return values;
54
+ }
55
+ function parseArgs(args) {
56
+ const values = readValueFlags(args);
57
+ if (values === null) {
58
+ return null;
59
+ }
60
+ const file = values["--file"];
61
+ const dir = values["--dir"];
62
+ // Exactly one of --file / --dir is required.
63
+ if ((file === undefined) === (dir === undefined)) {
64
+ return null;
65
+ }
66
+ const changedRaw = values["--changed"];
67
+ const changedPaths = changedRaw === undefined
68
+ ? undefined
69
+ : changedRaw
70
+ .split(",")
71
+ .map((p) => p.trim())
72
+ .filter((p) => p.length > 0);
73
+ return {
74
+ file,
75
+ dir,
76
+ fn: values["--function"],
77
+ changed: changedPaths === undefined || changedPaths.length === 0 ? undefined : changedPaths,
78
+ apply: args.includes("--apply"),
79
+ model: values["--model"],
80
+ config: values["--config"],
81
+ json: args.includes("--json"),
82
+ dirRoot: values["--dir-root"] ?? ".",
83
+ };
84
+ }
85
+ // --changed composes with both --file and --dir: when present it is the authoritative target set.
86
+ function resolveTarget(parsed) {
87
+ if (parsed.changed !== undefined) {
88
+ return { kind: "changedFiles", filePaths: parsed.changed };
89
+ }
90
+ if (parsed.dir !== undefined) {
91
+ return { kind: "module", moduleDir: parsed.dir };
92
+ }
93
+ return {
94
+ kind: "file",
95
+ filePath: parsed.file ?? "",
96
+ ...(parsed.fn === undefined ? {} : { targetFunction: parsed.fn }),
97
+ };
98
+ }
99
+ // Builds a ModelPort from the gateway config, or returns a usage/runtime error code via io. The
100
+ // workflow sends plain chat messages, so the default only requires a configured chat model.
101
+ function buildModel(parsed, io, env) {
102
+ try {
103
+ const path = parsed.config ?? env.KEIKO_CONFIG_FILE;
104
+ if (path === undefined) {
105
+ throw new ConfigInvalidError("no config source; pass --config PATH or set KEIKO_CONFIG_FILE");
106
+ }
107
+ const config = loadConfigFromFile(path, env);
108
+ if (parsed.model !== undefined) {
109
+ assertConfiguredModel(config, parsed.model);
110
+ }
111
+ const modelId = parsed.model ??
112
+ selectConfiguredModel(config, {
113
+ kind: "chat",
114
+ });
115
+ if (modelId === undefined) {
116
+ io.err("Error: no configured chat model is available.\n");
117
+ return 1;
118
+ }
119
+ return { port: new GatewayModelPort(new Gateway(config)), modelId };
120
+ }
121
+ catch (error) {
122
+ if (error instanceof GatewayError) {
123
+ io.err(`Error: model gateway configuration problem — ${redact(error.message)}\n` +
124
+ `Provide a gateway config with --config PATH or KEIKO_CONFIG_FILE.\n`);
125
+ return 1;
126
+ }
127
+ throw error;
128
+ }
129
+ }
130
+ function resolveConfiguredModelId(parsed, env) {
131
+ const path = parsed.config ?? env.KEIKO_CONFIG_FILE;
132
+ if (path === undefined) {
133
+ return parsed.model ?? "default";
134
+ }
135
+ const config = loadConfigFromFile(path, env);
136
+ if (parsed.model !== undefined) {
137
+ assertConfiguredModel(config, parsed.model);
138
+ return parsed.model;
139
+ }
140
+ return selectConfiguredModel(config, {
141
+ kind: "chat",
142
+ });
143
+ }
144
+ function resolveModel(parsed, io, env, deps) {
145
+ if (deps.model !== undefined) {
146
+ try {
147
+ const modelId = resolveConfiguredModelId(parsed, env);
148
+ if (modelId === undefined) {
149
+ io.err("Error: no configured chat model is available.\n");
150
+ return 1;
151
+ }
152
+ return { port: deps.model, modelId };
153
+ }
154
+ catch (error) {
155
+ if (error instanceof GatewayError) {
156
+ io.err(`Error: model gateway configuration problem — ${redact(error.message)}\n`);
157
+ return 1;
158
+ }
159
+ throw error;
160
+ }
161
+ }
162
+ return buildModel(parsed, io, env);
163
+ }
164
+ function printText(report, io) {
165
+ io.out(`${renderMarkdownReport(report)}\n`);
166
+ if (report.dryRunPreview !== undefined) {
167
+ io.out(`\n${report.dryRunPreview}\n`);
168
+ }
169
+ if (report.proposedDiff !== undefined) {
170
+ io.out(`\n--- proposed test patch ---\n${report.proposedDiff}\n`);
171
+ }
172
+ }
173
+ function exitCodeFor(status) {
174
+ return status === "completed" || status === "dry-run" ? 0 : 1;
175
+ }
176
+ export async function runGenTestsCli(args, io, env = {}, deps = {}) {
177
+ const parsed = parseArgs(args);
178
+ if (parsed === null) {
179
+ io.err(USAGE);
180
+ return 2;
181
+ }
182
+ const model = resolveModel(parsed, io, env, deps);
183
+ if (typeof model === "number") {
184
+ return model;
185
+ }
186
+ try {
187
+ const report = await generateUnitTests({
188
+ workspaceRoot: parsed.dirRoot,
189
+ target: resolveTarget(parsed),
190
+ apply: parsed.apply,
191
+ modelId: model.modelId,
192
+ }, { model: model.port });
193
+ if (parsed.json) {
194
+ io.out(`${JSON.stringify(report, null, 2)}\n`);
195
+ }
196
+ else {
197
+ printText(report, io);
198
+ }
199
+ return exitCodeFor(report.status);
200
+ }
201
+ catch (error) {
202
+ if (error instanceof WorkspaceError) {
203
+ io.err(`Error [${error.code}]: ${error.message}\n`);
204
+ return 1;
205
+ }
206
+ throw error;
207
+ }
208
+ }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env node
2
+ import { runCli } from "./runner.js";
3
+ // runCli returns a number for synchronous commands and a Promise<number> for the async
4
+ // `run` command. Promise.resolve normalises both before exiting with the resulting code.
5
+ void Promise.resolve(runCli(process.argv.slice(2), {
6
+ out: (text) => {
7
+ process.stdout.write(text);
8
+ },
9
+ err: (text) => {
10
+ process.stderr.write(text);
11
+ },
12
+ }, process.env)).then((code) => {
13
+ process.exit(code);
14
+ });
@@ -0,0 +1,8 @@
1
+ import { type EnvSource } from "../gateway/config.js";
2
+ import type { ModelPort } from "../harness/ports.js";
3
+ import type { CliIo } from "./runner.js";
4
+ export interface InvestigateDeps {
5
+ readonly model?: ModelPort | undefined;
6
+ readonly readFile?: ((path: string) => string) | undefined;
7
+ }
8
+ export declare function runInvestigateCli(args: readonly string[], io: CliIo, env?: EnvSource, deps?: InvestigateDeps): Promise<number>;
@@ -0,0 +1,242 @@
1
+ // `keiko investigate` — investigates a bounded bug report and proposes a minimal fix + a
2
+ // regression test (ADR-0009 D14). Dry-run by default; --apply writes the fix and runs verification.
3
+ // The text path prints the proposed diff (when present) plus clearly-labelled verified facts and
4
+ // the UNVERIFIED model hypothesis; --json emits the full BugInvestigationReport. Failing output and
5
+ // stack traces may be read from files (--output-file / --stack-file) to avoid huge argv. Evidence
6
+ // files are read through the workspace boundary, never raw node:fs. The gateway ModelPort is built
7
+ // from config (loadConfigFromFile); tests inject deps.model directly so no live gateway is needed.
8
+ // Exit 0 on fix-applied/fix-proposed/investigation-only, 1 on
9
+ // rejected/cancelled/failed/runtime, 2 on usage. Mirrors runGenTestsCli's structure.
10
+ import { Gateway } from "../gateway/gateway.js";
11
+ import { loadConfigFromFile } from "../gateway/config.js";
12
+ import { ConfigInvalidError, GatewayError } from "../gateway/errors.js";
13
+ import { assertConfiguredModel, selectConfiguredModel } from "../gateway/model-selection.js";
14
+ import { redact } from "../gateway/redaction.js";
15
+ import { GatewayModelPort } from "../harness/adapters.js";
16
+ import { detectWorkspace, readWorkspaceFile, WorkspaceError, } from "../workspace/index.js";
17
+ import { investigateBug, renderBugMarkdownReport } from "../workflows/index.js";
18
+ const USAGE = `Usage:
19
+ keiko investigate [--description TEXT] [--output TEXT | --output-file PATH]
20
+ [--stack TEXT | --stack-file PATH] [--file PATH[,PATH]]
21
+ [--apply] [--model MODEL_ID] [--config PATH] [--json] [--dir-root PATH]
22
+
23
+ Investigates a bounded bug report and proposes a root-cause hypothesis with a
24
+ minimal fix and a regression test, separating verified facts from model
25
+ hypotheses. At least one evidence source is required (--description, --output[-file],
26
+ --stack[-file], or --file). Dry-run by default (writes nothing); pass --apply to
27
+ write the fix and run verification through the safe tool + verification layers.
28
+ `;
29
+ // Returns the value of a `--flag value` pair, undefined if absent, or null if present without a
30
+ // value (a usage error) — identical contract to runGenTestsCli's flagValue.
31
+ function flagValue(args, name) {
32
+ const i = args.indexOf(name);
33
+ if (i === -1) {
34
+ return undefined;
35
+ }
36
+ const value = args[i + 1];
37
+ return value === undefined || value.startsWith("--") ? null : value;
38
+ }
39
+ const VALUE_FLAGS = [
40
+ "--description",
41
+ "--output",
42
+ "--output-file",
43
+ "--stack",
44
+ "--stack-file",
45
+ "--file",
46
+ "--model",
47
+ "--config",
48
+ "--dir-root",
49
+ ];
50
+ function readValueFlags(args) {
51
+ const values = {};
52
+ for (const flag of VALUE_FLAGS) {
53
+ const value = flagValue(args, flag);
54
+ if (value === null) {
55
+ return null;
56
+ }
57
+ values[flag] = value;
58
+ }
59
+ return values;
60
+ }
61
+ function parseFiles(raw) {
62
+ if (raw === undefined) {
63
+ return undefined;
64
+ }
65
+ const parts = raw
66
+ .split(",")
67
+ .map((p) => p.trim())
68
+ .filter((p) => p.length > 0);
69
+ return parts.length === 0 ? undefined : parts;
70
+ }
71
+ function parseArgs(args) {
72
+ const values = readValueFlags(args);
73
+ if (values === null) {
74
+ return null;
75
+ }
76
+ return {
77
+ description: values["--description"],
78
+ output: values["--output"],
79
+ outputFile: values["--output-file"],
80
+ stack: values["--stack"],
81
+ stackFile: values["--stack-file"],
82
+ files: parseFiles(values["--file"]),
83
+ apply: args.includes("--apply"),
84
+ model: values["--model"],
85
+ config: values["--config"],
86
+ json: args.includes("--json"),
87
+ dirRoot: values["--dir-root"] ?? ".",
88
+ };
89
+ }
90
+ // At least one evidence source must be present, else there is nothing to investigate.
91
+ function hasEvidenceFlag(parsed) {
92
+ return (parsed.description !== undefined ||
93
+ parsed.output !== undefined ||
94
+ parsed.outputFile !== undefined ||
95
+ parsed.stack !== undefined ||
96
+ parsed.stackFile !== undefined ||
97
+ parsed.files !== undefined);
98
+ }
99
+ // Resolves the failing output and stack trace, reading from files when the *-file flags are set.
100
+ // The inline flag is used only when its file counterpart is absent. Throws on a read failure (the
101
+ // CLI catch maps it to a runtime error).
102
+ function resolveReport(parsed, readFile) {
103
+ const failingOutput = parsed.outputFile !== undefined ? readFile(parsed.outputFile) : parsed.output;
104
+ const stackTrace = parsed.stackFile !== undefined ? readFile(parsed.stackFile) : parsed.stack;
105
+ return {
106
+ ...(parsed.description === undefined ? {} : { description: parsed.description }),
107
+ ...(failingOutput === undefined ? {} : { failingOutput }),
108
+ ...(stackTrace === undefined ? {} : { stackTrace }),
109
+ ...(parsed.files === undefined ? {} : { targetFiles: parsed.files }),
110
+ };
111
+ }
112
+ function workspaceEvidenceReader(workspace) {
113
+ return (path) => readWorkspaceFile(workspace, path).text;
114
+ }
115
+ function buildModel(parsed, io, env) {
116
+ try {
117
+ const path = parsed.config ?? env.KEIKO_CONFIG_FILE;
118
+ if (path === undefined) {
119
+ throw new ConfigInvalidError("no config source; pass --config PATH or set KEIKO_CONFIG_FILE");
120
+ }
121
+ const config = loadConfigFromFile(path, env);
122
+ if (parsed.model !== undefined) {
123
+ assertConfiguredModel(config, parsed.model);
124
+ }
125
+ const modelId = parsed.model ??
126
+ selectConfiguredModel(config, {
127
+ kind: "chat",
128
+ });
129
+ if (modelId === undefined) {
130
+ io.err("Error: no configured chat model is available.\n");
131
+ return 1;
132
+ }
133
+ return { port: new GatewayModelPort(new Gateway(config)), modelId };
134
+ }
135
+ catch (error) {
136
+ if (error instanceof GatewayError) {
137
+ io.err(`Error: model gateway configuration problem — ${redact(error.message)}\n` +
138
+ `Provide a gateway config with --config PATH or KEIKO_CONFIG_FILE.\n`);
139
+ return 1;
140
+ }
141
+ throw error;
142
+ }
143
+ }
144
+ function resolveConfiguredModelId(parsed, env) {
145
+ const path = parsed.config ?? env.KEIKO_CONFIG_FILE;
146
+ if (path === undefined) {
147
+ return parsed.model ?? "default";
148
+ }
149
+ const config = loadConfigFromFile(path, env);
150
+ if (parsed.model !== undefined) {
151
+ assertConfiguredModel(config, parsed.model);
152
+ return parsed.model;
153
+ }
154
+ return selectConfiguredModel(config, {
155
+ kind: "chat",
156
+ });
157
+ }
158
+ function resolveModel(parsed, io, env, deps) {
159
+ if (deps.model !== undefined) {
160
+ try {
161
+ const modelId = resolveConfiguredModelId(parsed, env);
162
+ if (modelId === undefined) {
163
+ io.err("Error: no configured chat model is available.\n");
164
+ return 1;
165
+ }
166
+ return { port: deps.model, modelId };
167
+ }
168
+ catch (error) {
169
+ if (error instanceof GatewayError) {
170
+ io.err(`Error: model gateway configuration problem — ${redact(error.message)}\n`);
171
+ return 1;
172
+ }
173
+ throw error;
174
+ }
175
+ }
176
+ return buildModel(parsed, io, env);
177
+ }
178
+ function printText(report, io) {
179
+ io.out(`${renderBugMarkdownReport(report)}\n`);
180
+ if (report.dryRunPreview !== undefined) {
181
+ io.out(`\n${report.dryRunPreview}\n`);
182
+ }
183
+ if (report.proposedDiff !== undefined) {
184
+ io.out(`\n--- proposed fix ---\n${report.proposedDiff}\n`);
185
+ }
186
+ }
187
+ function exitCodeFor(status) {
188
+ return status === "fix-applied" || status === "fix-proposed" || status === "investigation-only"
189
+ ? 0
190
+ : 1;
191
+ }
192
+ function emitReport(report, io, json) {
193
+ if (json) {
194
+ io.out(`${JSON.stringify(report, null, 2)}\n`);
195
+ }
196
+ else {
197
+ printText(report, io);
198
+ }
199
+ return exitCodeFor(report.status);
200
+ }
201
+ // Maps a boundary error to an exit code, or rethrows when it is not a recognised IO failure.
202
+ function handleCliError(error, io) {
203
+ if (error instanceof WorkspaceError) {
204
+ io.err(`Error [${error.code}]: ${error.message}\n`);
205
+ return 1;
206
+ }
207
+ if (error instanceof Error && isFileReadError(error)) {
208
+ io.err(`Error: could not read an evidence file — ${redact(error.message)}\n`);
209
+ return 1;
210
+ }
211
+ throw error;
212
+ }
213
+ export async function runInvestigateCli(args, io, env = {}, deps = {}) {
214
+ const parsed = parseArgs(args);
215
+ if (parsed === null || !hasEvidenceFlag(parsed)) {
216
+ io.err(USAGE);
217
+ return 2;
218
+ }
219
+ const model = resolveModel(parsed, io, env, deps);
220
+ if (typeof model === "number") {
221
+ return model;
222
+ }
223
+ try {
224
+ const workspace = detectWorkspace(parsed.dirRoot);
225
+ const readFile = deps.readFile ?? workspaceEvidenceReader(workspace);
226
+ const report = await investigateBug({
227
+ workspaceRoot: workspace.root,
228
+ report: resolveReport(parsed, readFile),
229
+ apply: parsed.apply,
230
+ modelId: model.modelId,
231
+ }, { model: model.port });
232
+ return emitReport(report, io, parsed.json);
233
+ }
234
+ catch (error) {
235
+ return handleCliError(error, io);
236
+ }
237
+ }
238
+ // A Node fs read error carries a string `code` (e.g. ENOENT); narrow without `any`.
239
+ function isFileReadError(error) {
240
+ const code = error.code;
241
+ return typeof code === "string" && code.length > 0;
242
+ }
@@ -0,0 +1,3 @@
1
+ import { type EnvSource } from "../gateway/config.js";
2
+ import type { CliIo } from "./runner.js";
3
+ export declare function runModelsCli(args: readonly string[], io: CliIo, env: EnvSource): number;
@@ -0,0 +1,64 @@
1
+ // `keiko models` CLI handler. Synchronous by design: `list` reads the static
2
+ // capability registry; `validate` reads a config file with readFileSync and runs
3
+ // the hand-rolled validator. Neither path needs a live async Gateway, so the
4
+ // existing `process.exit(runCli(...))` shim stays synchronous. No credential value
5
+ // is ever written to stdout or stderr.
6
+ import { listCapabilities } from "../gateway/capabilities.js";
7
+ import { loadConfigFromFile } from "../gateway/config.js";
8
+ import { GatewayError } from "../gateway/errors.js";
9
+ import { resolveConfigPathFromArgs } from "./gateway-config.js";
10
+ const USAGE = `Usage:
11
+ keiko models list List registered model capabilities.
12
+ keiko models validate [--config PATH] Validate gateway configuration.
13
+ `;
14
+ function formatUseCases(useCases) {
15
+ return useCases.map((useCase) => useCase.toLowerCase().replace(/\s+/g, "-")).join(",");
16
+ }
17
+ function listModels(io) {
18
+ io.out("ID\tKIND\tCOST\tLATENCY\tTOOLS\tSTRUCT\tUSE-CASES\n");
19
+ for (const cap of listCapabilities()) {
20
+ const tools = cap.toolCalling ? "yes" : "no";
21
+ const struct = cap.structuredOutput ? "yes" : "no";
22
+ io.out(`${cap.id}\t${cap.kind}\t${cap.costClass}\t${cap.latencyClass}\t${tools}\t${struct}\t${formatUseCases(cap.preferredUseCases)}\n`);
23
+ }
24
+ return 0;
25
+ }
26
+ function validateConfig(args, io, env) {
27
+ const resolution = resolveConfigPathFromArgs(args, env);
28
+ if (resolution.kind === "missing-value") {
29
+ io.err("Error: --config requires a path argument.\n");
30
+ return 2;
31
+ }
32
+ if (resolution.kind === "not-configured") {
33
+ io.err("Error [GATEWAY_CONFIG_INVALID]: no config source; pass --config PATH or set KEIKO_CONFIG_FILE.\n");
34
+ return 1;
35
+ }
36
+ try {
37
+ const config = loadConfigFromFile(resolution.path, env);
38
+ io.out(`Gateway config valid. ${String(config.providers.length)} model providers configured.\n`);
39
+ return 0;
40
+ }
41
+ catch (error) {
42
+ if (error instanceof GatewayError) {
43
+ io.err(`Error [${error.code}]: ${error.message}\n`);
44
+ return 1;
45
+ }
46
+ throw error;
47
+ }
48
+ }
49
+ export function runModelsCli(args, io, env) {
50
+ const sub = args[0];
51
+ if (sub === "list") {
52
+ return listModels(io);
53
+ }
54
+ if (sub === "validate") {
55
+ return validateConfig(args.slice(1), io, env);
56
+ }
57
+ if (sub === undefined) {
58
+ io.err(USAGE);
59
+ return 2;
60
+ }
61
+ io.err(`keiko models: unknown sub-command: ${sub}\n`);
62
+ io.err(USAGE);
63
+ return 2;
64
+ }
@@ -0,0 +1,7 @@
1
+ import { type EvidenceStore } from "../audit/store.js";
2
+ import type { EnvSource } from "../gateway/config.js";
3
+ import type { CliIo } from "./runner.js";
4
+ export interface RunDeps {
5
+ readonly store?: EvidenceStore | undefined;
6
+ }
7
+ export declare function runAgentCli(args: readonly string[], io: CliIo, env?: EnvSource, deps?: RunDeps): Promise<number>;