@cyanautomation/kaseki-agent 1.4.1

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 (459) hide show
  1. package/.dockerignore +54 -0
  2. package/.eslintignore +11 -0
  3. package/.eslintrc.json +95 -0
  4. package/.github/ISSUE_TEMPLATE/bug_report.md +53 -0
  5. package/.github/ISSUE_TEMPLATE/feature_request.md +53 -0
  6. package/.github/ISSUE_TEMPLATE/security.md +51 -0
  7. package/.github/PULL_REQUEST_TEMPLATE/default.md +71 -0
  8. package/.github/dependabot.yml +38 -0
  9. package/.github/skills/dependency-cache-optimization/SKILL.md +526 -0
  10. package/.github/skills/docker-image-management/SKILL.md +532 -0
  11. package/.github/skills/frontend-design/SKILL.md +782 -0
  12. package/.github/skills/prompt-engineering/SKILL.md +360 -0
  13. package/.github/skills/quality-gate-config/SKILL.md +591 -0
  14. package/.github/skills/result-report-analysis/SKILL.md +576 -0
  15. package/.github/skills/test-automation/SKILL.md +593 -0
  16. package/.github/skills/workflow-diagnosis/SKILL.md +468 -0
  17. package/.github/workflows/build-docker-image.yml +453 -0
  18. package/.github/workflows/release.yml +68 -0
  19. package/.releaserc.json +135 -0
  20. package/CHANGELOG.md +117 -0
  21. package/CLAUDE.md +336 -0
  22. package/CONTRIBUTING.md +339 -0
  23. package/Dockerfile +217 -0
  24. package/README.md +1527 -0
  25. package/STYLE.md +521 -0
  26. package/add-js-extensions.d.ts +9 -0
  27. package/add-js-extensions.d.ts.map +1 -0
  28. package/add-js-extensions.js.map +1 -0
  29. package/dist/add-js-extensions.d.ts +9 -0
  30. package/dist/add-js-extensions.d.ts.map +1 -0
  31. package/dist/add-js-extensions.js +52 -0
  32. package/dist/add-js-extensions.js.map +1 -0
  33. package/dist/ansi-colors.d.ts +26 -0
  34. package/dist/ansi-colors.d.ts.map +1 -0
  35. package/dist/ansi-colors.js +51 -0
  36. package/dist/ansi-colors.js.map +1 -0
  37. package/dist/cli/BaseCommand.d.ts +18 -0
  38. package/dist/cli/BaseCommand.d.ts.map +1 -0
  39. package/dist/cli/BaseCommand.js +31 -0
  40. package/dist/cli/BaseCommand.js.map +1 -0
  41. package/dist/cli/KasekiCLI.d.ts +30 -0
  42. package/dist/cli/KasekiCLI.d.ts.map +1 -0
  43. package/dist/cli/KasekiCLI.js +134 -0
  44. package/dist/cli/KasekiCLI.js.map +1 -0
  45. package/dist/cli/commands/ConfigCommand.d.ts +13 -0
  46. package/dist/cli/commands/ConfigCommand.d.ts.map +1 -0
  47. package/dist/cli/commands/ConfigCommand.js +131 -0
  48. package/dist/cli/commands/ConfigCommand.js.map +1 -0
  49. package/dist/cli/commands/DoctorCommand.d.ts +45 -0
  50. package/dist/cli/commands/DoctorCommand.d.ts.map +1 -0
  51. package/dist/cli/commands/DoctorCommand.js +309 -0
  52. package/dist/cli/commands/DoctorCommand.js.map +1 -0
  53. package/dist/cli/commands/ListCommand.d.ts +9 -0
  54. package/dist/cli/commands/ListCommand.d.ts.map +1 -0
  55. package/dist/cli/commands/ListCommand.js +81 -0
  56. package/dist/cli/commands/ListCommand.js.map +1 -0
  57. package/dist/cli/commands/ReportCommand.d.ts +9 -0
  58. package/dist/cli/commands/ReportCommand.d.ts.map +1 -0
  59. package/dist/cli/commands/ReportCommand.js +98 -0
  60. package/dist/cli/commands/ReportCommand.js.map +1 -0
  61. package/dist/cli/commands/RunCommand.d.ts +13 -0
  62. package/dist/cli/commands/RunCommand.d.ts.map +1 -0
  63. package/dist/cli/commands/RunCommand.js +191 -0
  64. package/dist/cli/commands/RunCommand.js.map +1 -0
  65. package/dist/cli/commands/SecretsCommand.d.ts +9 -0
  66. package/dist/cli/commands/SecretsCommand.d.ts.map +1 -0
  67. package/dist/cli/commands/SecretsCommand.js +109 -0
  68. package/dist/cli/commands/SecretsCommand.js.map +1 -0
  69. package/dist/cli/commands/ServeCommand.d.ts +9 -0
  70. package/dist/cli/commands/ServeCommand.d.ts.map +1 -0
  71. package/dist/cli/commands/ServeCommand.js +50 -0
  72. package/dist/cli/commands/ServeCommand.js.map +1 -0
  73. package/dist/cli/commands/SetupCommand.d.ts +42 -0
  74. package/dist/cli/commands/SetupCommand.d.ts.map +1 -0
  75. package/dist/cli/commands/SetupCommand.js +249 -0
  76. package/dist/cli/commands/SetupCommand.js.map +1 -0
  77. package/dist/cli.d.ts +9 -0
  78. package/dist/cli.d.ts.map +1 -0
  79. package/dist/cli.js +130 -0
  80. package/dist/cli.js.map +1 -0
  81. package/dist/config/ConfigManager.d.ts +395 -0
  82. package/dist/config/ConfigManager.d.ts.map +1 -0
  83. package/dist/config/ConfigManager.js +446 -0
  84. package/dist/config/ConfigManager.js.map +1 -0
  85. package/dist/docker/DockerManager.d.ts +69 -0
  86. package/dist/docker/DockerManager.d.ts.map +1 -0
  87. package/dist/docker/DockerManager.js +266 -0
  88. package/dist/docker/DockerManager.js.map +1 -0
  89. package/dist/event-aggregator.d.ts +71 -0
  90. package/dist/event-aggregator.d.ts.map +1 -0
  91. package/dist/event-aggregator.js +95 -0
  92. package/dist/event-aggregator.js.map +1 -0
  93. package/dist/github-app-token.d.ts +16 -0
  94. package/dist/github-app-token.d.ts.map +1 -0
  95. package/dist/github-app-token.js +148 -0
  96. package/dist/github-app-token.js.map +1 -0
  97. package/dist/idempotency-store.d.ts +61 -0
  98. package/dist/idempotency-store.d.ts.map +1 -0
  99. package/dist/idempotency-store.js +321 -0
  100. package/dist/idempotency-store.js.map +1 -0
  101. package/dist/index.d.ts +25 -0
  102. package/dist/index.d.ts.map +1 -0
  103. package/dist/index.js +31 -0
  104. package/dist/index.js.map +1 -0
  105. package/dist/instance/InstanceManager.d.ts +81 -0
  106. package/dist/instance/InstanceManager.d.ts.map +1 -0
  107. package/dist/instance/InstanceManager.js +220 -0
  108. package/dist/instance/InstanceManager.js.map +1 -0
  109. package/dist/instance-metadata-reader.d.ts +48 -0
  110. package/dist/instance-metadata-reader.d.ts.map +1 -0
  111. package/dist/instance-metadata-reader.js +94 -0
  112. package/dist/instance-metadata-reader.js.map +1 -0
  113. package/dist/instance-state-derivation.d.ts +42 -0
  114. package/dist/instance-state-derivation.d.ts.map +1 -0
  115. package/dist/instance-state-derivation.js +133 -0
  116. package/dist/instance-state-derivation.js.map +1 -0
  117. package/dist/job-scheduler.d.ts +124 -0
  118. package/dist/job-scheduler.d.ts.map +1 -0
  119. package/dist/job-scheduler.js +992 -0
  120. package/dist/job-scheduler.js.map +1 -0
  121. package/dist/kaseki-api-client.d.ts +89 -0
  122. package/dist/kaseki-api-client.d.ts.map +1 -0
  123. package/dist/kaseki-api-client.js +405 -0
  124. package/dist/kaseki-api-client.js.map +1 -0
  125. package/dist/kaseki-api-config.d.ts +34 -0
  126. package/dist/kaseki-api-config.d.ts.map +1 -0
  127. package/dist/kaseki-api-config.js +113 -0
  128. package/dist/kaseki-api-config.js.map +1 -0
  129. package/dist/kaseki-api-routes.d.ts +13 -0
  130. package/dist/kaseki-api-routes.d.ts.map +1 -0
  131. package/dist/kaseki-api-routes.js +559 -0
  132. package/dist/kaseki-api-routes.js.map +1 -0
  133. package/dist/kaseki-api-service-wrapper.d.ts +43 -0
  134. package/dist/kaseki-api-service-wrapper.d.ts.map +1 -0
  135. package/dist/kaseki-api-service-wrapper.js +150 -0
  136. package/dist/kaseki-api-service-wrapper.js.map +1 -0
  137. package/dist/kaseki-api-service.d.ts +16 -0
  138. package/dist/kaseki-api-service.d.ts.map +1 -0
  139. package/dist/kaseki-api-service.js +143 -0
  140. package/dist/kaseki-api-service.js.map +1 -0
  141. package/dist/kaseki-api-types.d.ts +440 -0
  142. package/dist/kaseki-api-types.d.ts.map +1 -0
  143. package/dist/kaseki-api-types.js +64 -0
  144. package/dist/kaseki-api-types.js.map +1 -0
  145. package/dist/kaseki-cli-lib.d.ts +219 -0
  146. package/dist/kaseki-cli-lib.d.ts.map +1 -0
  147. package/dist/kaseki-cli-lib.js +523 -0
  148. package/dist/kaseki-cli-lib.js.map +1 -0
  149. package/dist/kaseki-cli.d.ts +38 -0
  150. package/dist/kaseki-cli.d.ts.map +1 -0
  151. package/dist/kaseki-cli.js +559 -0
  152. package/dist/kaseki-cli.js.map +1 -0
  153. package/dist/kaseki-report.d.ts +3 -0
  154. package/dist/kaseki-report.d.ts.map +1 -0
  155. package/dist/kaseki-report.js +140 -0
  156. package/dist/kaseki-report.js.map +1 -0
  157. package/dist/lib/subprocess-helpers.d.ts +98 -0
  158. package/dist/lib/subprocess-helpers.d.ts.map +1 -0
  159. package/dist/lib/subprocess-helpers.js +136 -0
  160. package/dist/lib/subprocess-helpers.js.map +1 -0
  161. package/dist/logger.d.ts +39 -0
  162. package/dist/logger.d.ts.map +1 -0
  163. package/dist/logger.js +79 -0
  164. package/dist/logger.js.map +1 -0
  165. package/dist/metrics.d.ts +19 -0
  166. package/dist/metrics.d.ts.map +1 -0
  167. package/dist/metrics.js +59 -0
  168. package/dist/metrics.js.map +1 -0
  169. package/dist/middleware/job-lookup.d.ts +27 -0
  170. package/dist/middleware/job-lookup.d.ts.map +1 -0
  171. package/dist/middleware/job-lookup.js +28 -0
  172. package/dist/middleware/job-lookup.js.map +1 -0
  173. package/dist/pi-event-filter.d.ts +3 -0
  174. package/dist/pi-event-filter.d.ts.map +1 -0
  175. package/dist/pi-event-filter.js +126 -0
  176. package/dist/pi-event-filter.js.map +1 -0
  177. package/dist/pi-progress-stream.d.ts +3 -0
  178. package/dist/pi-progress-stream.d.ts.map +1 -0
  179. package/dist/pi-progress-stream.js +205 -0
  180. package/dist/pi-progress-stream.js.map +1 -0
  181. package/dist/pi-progress-summarizer.d.ts +61 -0
  182. package/dist/pi-progress-summarizer.d.ts.map +1 -0
  183. package/dist/pi-progress-summarizer.js +246 -0
  184. package/dist/pi-progress-summarizer.js.map +1 -0
  185. package/dist/pre-flight-validator.d.ts +72 -0
  186. package/dist/pre-flight-validator.d.ts.map +1 -0
  187. package/dist/pre-flight-validator.js +513 -0
  188. package/dist/pre-flight-validator.js.map +1 -0
  189. package/dist/progress-stream-utils.d.ts +3 -0
  190. package/dist/progress-stream-utils.d.ts.map +1 -0
  191. package/dist/progress-stream-utils.js +15 -0
  192. package/dist/progress-stream-utils.js.map +1 -0
  193. package/dist/result-cache.d.ts +52 -0
  194. package/dist/result-cache.d.ts.map +1 -0
  195. package/dist/result-cache.js +134 -0
  196. package/dist/result-cache.js.map +1 -0
  197. package/dist/routes/artifact-routes.d.ts +10 -0
  198. package/dist/routes/artifact-routes.d.ts.map +1 -0
  199. package/dist/routes/artifact-routes.js +126 -0
  200. package/dist/routes/artifact-routes.js.map +1 -0
  201. package/dist/routes/log-routes.d.ts +8 -0
  202. package/dist/routes/log-routes.d.ts.map +1 -0
  203. package/dist/routes/log-routes.js +345 -0
  204. package/dist/routes/log-routes.js.map +1 -0
  205. package/dist/routes/status-routes.d.ts +8 -0
  206. package/dist/routes/status-routes.d.ts.map +1 -0
  207. package/dist/routes/status-routes.js +82 -0
  208. package/dist/routes/status-routes.js.map +1 -0
  209. package/dist/routes/webhook-routes.d.ts +6 -0
  210. package/dist/routes/webhook-routes.d.ts.map +1 -0
  211. package/dist/routes/webhook-routes.js +86 -0
  212. package/dist/routes/webhook-routes.js.map +1 -0
  213. package/dist/run-artifact-metadata-cache.d.ts +42 -0
  214. package/dist/run-artifact-metadata-cache.d.ts.map +1 -0
  215. package/dist/run-artifact-metadata-cache.js +139 -0
  216. package/dist/run-artifact-metadata-cache.js.map +1 -0
  217. package/dist/secret-value-cache.d.ts +13 -0
  218. package/dist/secret-value-cache.d.ts.map +1 -0
  219. package/dist/secret-value-cache.js +44 -0
  220. package/dist/secret-value-cache.js.map +1 -0
  221. package/dist/secrets/SecretsManager.d.ts +80 -0
  222. package/dist/secrets/SecretsManager.d.ts.map +1 -0
  223. package/dist/secrets/SecretsManager.js +306 -0
  224. package/dist/secrets/SecretsManager.js.map +1 -0
  225. package/dist/test-utils.d.ts +55 -0
  226. package/dist/test-utils.d.ts.map +1 -0
  227. package/dist/test-utils.js +48 -0
  228. package/dist/test-utils.js.map +1 -0
  229. package/dist/timestamp-tracker.d.ts +75 -0
  230. package/dist/timestamp-tracker.d.ts.map +1 -0
  231. package/dist/timestamp-tracker.js +121 -0
  232. package/dist/timestamp-tracker.js.map +1 -0
  233. package/dist/utils/failure-artifact-writer.d.ts +29 -0
  234. package/dist/utils/failure-artifact-writer.d.ts.map +1 -0
  235. package/dist/utils/failure-artifact-writer.js +157 -0
  236. package/dist/utils/failure-artifact-writer.js.map +1 -0
  237. package/dist/utils/file-helpers.d.ts +41 -0
  238. package/dist/utils/file-helpers.d.ts.map +1 -0
  239. package/dist/utils/file-helpers.js +143 -0
  240. package/dist/utils/file-helpers.js.map +1 -0
  241. package/dist/utils/http-client-factory.d.ts +46 -0
  242. package/dist/utils/http-client-factory.d.ts.map +1 -0
  243. package/dist/utils/http-client-factory.js +114 -0
  244. package/dist/utils/http-client-factory.js.map +1 -0
  245. package/dist/utils/progress-normalizer.d.ts +13 -0
  246. package/dist/utils/progress-normalizer.d.ts.map +1 -0
  247. package/dist/utils/progress-normalizer.js +57 -0
  248. package/dist/utils/progress-normalizer.js.map +1 -0
  249. package/dist/utils/response-helpers.d.ts +34 -0
  250. package/dist/utils/response-helpers.d.ts.map +1 -0
  251. package/dist/utils/response-helpers.js +78 -0
  252. package/dist/utils/response-helpers.js.map +1 -0
  253. package/dist/utils/route-helpers.d.ts +17 -0
  254. package/dist/utils/route-helpers.d.ts.map +1 -0
  255. package/dist/utils/route-helpers.js +22 -0
  256. package/dist/utils/route-helpers.js.map +1 -0
  257. package/dist/utils/status-response-builder.d.ts +23 -0
  258. package/dist/utils/status-response-builder.d.ts.map +1 -0
  259. package/dist/utils/status-response-builder.js +144 -0
  260. package/dist/utils/status-response-builder.js.map +1 -0
  261. package/dist/utils/type-guards.d.ts +37 -0
  262. package/dist/utils/type-guards.d.ts.map +1 -0
  263. package/dist/utils/type-guards.js +45 -0
  264. package/dist/utils/type-guards.js.map +1 -0
  265. package/dist/utils/utf8-helpers.d.ts +32 -0
  266. package/dist/utils/utf8-helpers.d.ts.map +1 -0
  267. package/dist/utils/utf8-helpers.js +97 -0
  268. package/dist/utils/utf8-helpers.js.map +1 -0
  269. package/dist/utils/webhook-event-builder.d.ts +26 -0
  270. package/dist/utils/webhook-event-builder.d.ts.map +1 -0
  271. package/dist/utils/webhook-event-builder.js +77 -0
  272. package/dist/utils/webhook-event-builder.js.map +1 -0
  273. package/dist/webhook-manager.d.ts +56 -0
  274. package/dist/webhook-manager.d.ts.map +1 -0
  275. package/dist/webhook-manager.js +359 -0
  276. package/dist/webhook-manager.js.map +1 -0
  277. package/docker/workspace-cache/package-lock.json +13 -0
  278. package/docker/workspace-cache/package.json +7 -0
  279. package/docker-compose.yml +53 -0
  280. package/docs/API.md +708 -0
  281. package/docs/BACKLOG.md +19 -0
  282. package/docs/BUILD_STRATEGY.md +404 -0
  283. package/docs/CLI.md +569 -0
  284. package/docs/DEPLOYMENT.md +521 -0
  285. package/docs/DEVELOPMENT.md +459 -0
  286. package/docs/DOCKER_SETUP.md +522 -0
  287. package/docs/ENHANCED_PROGRESS_LOGS.md +264 -0
  288. package/docs/IMPLEMENTATION_SUMMARY.md +549 -0
  289. package/docs/INTEGRATION_EXAMPLE.md +217 -0
  290. package/docs/NPM_SETUP.md +468 -0
  291. package/docs/PHASE1-4_IMPLEMENTATION.md +302 -0
  292. package/docs/PHASE1_COMPLETION.md +192 -0
  293. package/docs/PHASE2_COMPLETION.md +134 -0
  294. package/docs/PHASE6_MIGRATION.md +392 -0
  295. package/docs/PRINTF_SAFETY_FIX.md +282 -0
  296. package/docs/QUALITY_GATES.md +369 -0
  297. package/docs/SETUP_GUIDE.md +482 -0
  298. package/docs/TASK_PROMPT_TEMPLATES.md +533 -0
  299. package/docs/VALIDATION_FIX.md +139 -0
  300. package/docs/VERIFICATION_CHECKLIST.md +335 -0
  301. package/docs/repo-maturity.md +760 -0
  302. package/fix-tests.d.ts +9 -0
  303. package/fix-tests.d.ts.map +1 -0
  304. package/fix-tests.js.map +1 -0
  305. package/fix-tests.ts +53 -0
  306. package/jest.config.ts +31 -0
  307. package/kaseki +183 -0
  308. package/kaseki-agent.sh +1961 -0
  309. package/ops/logrotate/kaseki +10 -0
  310. package/package.json +83 -0
  311. package/perf/README.md +54 -0
  312. package/perf/pi-event-filter.benchmark.test.ts +98 -0
  313. package/run-kaseki-json.test.sh +106 -0
  314. package/run-kaseki.sh +990 -0
  315. package/scripts/allowlist-helper.sh +56 -0
  316. package/scripts/cleanup-kaseki.sh +168 -0
  317. package/scripts/deploy-pi-template.sh +293 -0
  318. package/scripts/docker-entrypoint.sh +71 -0
  319. package/scripts/dry-run-allowlist.sh +161 -0
  320. package/scripts/kaseki-activate.sh +396 -0
  321. package/scripts/kaseki-api.service +62 -0
  322. package/scripts/kaseki-container-entrypoint-wrapper.sh +119 -0
  323. package/scripts/kaseki-container-setup-remote.sh +172 -0
  324. package/scripts/kaseki-container-setup.sh +193 -0
  325. package/scripts/kaseki-healthcheck.sh +95 -0
  326. package/scripts/kaseki-install.sh +50 -0
  327. package/scripts/kaseki-maturity-score.sh +291 -0
  328. package/scripts/kaseki-performance-metrics.sh +122 -0
  329. package/scripts/kaseki-preflight.sh +270 -0
  330. package/scripts/kaseki-setup.sh +265 -0
  331. package/scripts/pi-setup-remote.sh +213 -0
  332. package/scripts/setup-github-labels.sh +42 -0
  333. package/scripts/suggest-allowlist.sh +68 -0
  334. package/scripts/templates/MULTI_HOST_DISTRIBUTED.md +337 -0
  335. package/scripts/templates/REST_API_SERVICE.md +490 -0
  336. package/scripts/templates/SINGLE_HOST_CLI.md +194 -0
  337. package/scripts/test-github-app.sh +248 -0
  338. package/src/add-js-extensions.ts +61 -0
  339. package/src/ansi-colors.test.ts +62 -0
  340. package/src/ansi-colors.ts +67 -0
  341. package/src/cli/BaseCommand.ts +40 -0
  342. package/src/cli/KasekiCLI.ts +154 -0
  343. package/src/cli/commands/ConfigCommand.ts +145 -0
  344. package/src/cli/commands/DoctorCommand.ts +329 -0
  345. package/src/cli/commands/ListCommand.ts +105 -0
  346. package/src/cli/commands/ReportCommand.ts +110 -0
  347. package/src/cli/commands/RunCommand.ts +218 -0
  348. package/src/cli/commands/SecretsCommand.ts +120 -0
  349. package/src/cli/commands/ServeCommand.ts +62 -0
  350. package/src/cli/commands/SetupCommand.ts +301 -0
  351. package/src/cli.ts +138 -0
  352. package/src/config/ConfigManager.ts +476 -0
  353. package/src/docker/DockerManager.ts +319 -0
  354. package/src/docker-entrypoint-packaging.test.ts +33 -0
  355. package/src/event-aggregator.test.ts +117 -0
  356. package/src/event-aggregator.ts +126 -0
  357. package/src/github-app-token.ts +215 -0
  358. package/src/idempotency-store.test.ts +117 -0
  359. package/src/idempotency-store.ts +385 -0
  360. package/src/index.ts +89 -0
  361. package/src/instance/InstanceManager.ts +285 -0
  362. package/src/instance-metadata-reader.test.ts +190 -0
  363. package/src/instance-metadata-reader.ts +129 -0
  364. package/src/instance-state-derivation.test.ts +263 -0
  365. package/src/instance-state-derivation.ts +148 -0
  366. package/src/job-scheduler.test.ts +1236 -0
  367. package/src/job-scheduler.ts +1117 -0
  368. package/src/kaseki-api-client.ts +488 -0
  369. package/src/kaseki-api-config.test.ts +315 -0
  370. package/src/kaseki-api-config.ts +175 -0
  371. package/src/kaseki-api-routes.test.ts +1615 -0
  372. package/src/kaseki-api-routes.ts +643 -0
  373. package/src/kaseki-api-service-wrapper.ts +188 -0
  374. package/src/kaseki-api-service.test.ts +418 -0
  375. package/src/kaseki-api-service.ts +192 -0
  376. package/src/kaseki-api-types.ts +320 -0
  377. package/src/kaseki-cli-lib.test.ts +552 -0
  378. package/src/kaseki-cli-lib.ts +760 -0
  379. package/src/kaseki-cli.ts +682 -0
  380. package/src/kaseki-report.test.ts +118 -0
  381. package/src/kaseki-report.ts +192 -0
  382. package/src/lib/subprocess-helpers.ts +177 -0
  383. package/src/logger.ts +114 -0
  384. package/src/metrics.ts +66 -0
  385. package/src/middleware/job-lookup.test.ts +113 -0
  386. package/src/middleware/job-lookup.ts +45 -0
  387. package/src/pi-event-filter.test.ts +183 -0
  388. package/src/pi-event-filter.ts +183 -0
  389. package/src/pi-progress-stream.ts +287 -0
  390. package/src/pi-progress-summarizer.test.ts +302 -0
  391. package/src/pi-progress-summarizer.ts +287 -0
  392. package/src/pre-flight-validator.test.ts +512 -0
  393. package/src/pre-flight-validator.ts +618 -0
  394. package/src/progress-stream-utils.test.ts +35 -0
  395. package/src/progress-stream-utils.ts +14 -0
  396. package/src/result-cache.test.ts +195 -0
  397. package/src/result-cache.ts +181 -0
  398. package/src/routes/artifact-routes.ts +169 -0
  399. package/src/routes/log-routes.ts +391 -0
  400. package/src/routes/status-routes.ts +92 -0
  401. package/src/routes/webhook-routes.ts +97 -0
  402. package/src/run-artifact-metadata-cache.test.ts +80 -0
  403. package/src/run-artifact-metadata-cache.ts +184 -0
  404. package/src/secret-value-cache.test.ts +66 -0
  405. package/src/secret-value-cache.ts +55 -0
  406. package/src/secrets/SecretsManager.ts +343 -0
  407. package/src/test-utils.ts +81 -0
  408. package/src/timestamp-tracker.test.ts +134 -0
  409. package/src/timestamp-tracker.ts +132 -0
  410. package/src/utils/failure-artifact-writer.ts +187 -0
  411. package/src/utils/file-helpers.test.ts +235 -0
  412. package/src/utils/file-helpers.ts +150 -0
  413. package/src/utils/http-client-factory.test.ts +245 -0
  414. package/src/utils/http-client-factory.ts +157 -0
  415. package/src/utils/progress-normalizer.test.ts +442 -0
  416. package/src/utils/progress-normalizer.ts +68 -0
  417. package/src/utils/response-helpers.test.ts +122 -0
  418. package/src/utils/response-helpers.ts +101 -0
  419. package/src/utils/route-helpers.ts +30 -0
  420. package/src/utils/status-response-builder.ts +159 -0
  421. package/src/utils/type-guards.ts +52 -0
  422. package/src/utils/utf8-helpers.ts +102 -0
  423. package/src/utils/webhook-event-builder.test.ts +143 -0
  424. package/src/utils/webhook-event-builder.ts +87 -0
  425. package/src/webhook-manager.test.ts +152 -0
  426. package/src/webhook-manager.ts +445 -0
  427. package/templates/allowlist-api-route.txt +7 -0
  428. package/templates/allowlist-comprehensive.txt +8 -0
  429. package/templates/allowlist-parser-fix.txt +6 -0
  430. package/templates/allowlist-ui-component.txt +9 -0
  431. package/templates/allowlist-utility.txt +9 -0
  432. package/test/actual-model-metadata.test.sh +102 -0
  433. package/test/dry-run.test.sh +131 -0
  434. package/test/fixtures/kaseki-report-exit-codes/metadata-exit-0.json +1 -0
  435. package/test/fixtures/kaseki-report-exit-codes/metadata-exit-1.json +1 -0
  436. package/test/fixtures/kaseki-report-exit-codes/metadata-exit-invalid.json +1 -0
  437. package/test/fixtures/kaseki-report-exit-codes/metadata-exit-str-0.json +1 -0
  438. package/test/fixtures/kaseki-report-exit-codes/metadata-exit-str-1.json +1 -0
  439. package/test/kaseki-api.integration.test.sh +165 -0
  440. package/test/pi-event-filter-failure.test.sh +83 -0
  441. package/test/printf-safety-focused.test.sh +99 -0
  442. package/test/printf-safety-results/results/restoration.jsonl +10 -0
  443. package/test/printf-safety-results/results/test.jsonl +0 -0
  444. package/test/printf-safety.test.sh +297 -0
  445. package/test/validation-fix.test.sh +79 -0
  446. package/test/validation-integration.test.sh +109 -0
  447. package/tests/allowlist-glob.test.sh +61 -0
  448. package/tests/dependency-cache-key.test.sh +48 -0
  449. package/tests/dependency-restore-mode.test.sh +48 -0
  450. package/tests/doctor-template-parity.test.sh +95 -0
  451. package/tests/github-operations.test.sh +142 -0
  452. package/tests/npm-install-flags.test.sh +58 -0
  453. package/tests/quality-gates.test.sh +178 -0
  454. package/tests/repo-memory.test.sh +103 -0
  455. package/tests/restore-disallowed-changes.test.sh +80 -0
  456. package/tests/validation-missing-npm-scripts.test.sh +93 -0
  457. package/tests/validation-strict-mode.test.sh +118 -0
  458. package/tsconfig.changed.json +7 -0
  459. package/tsconfig.json +39 -0
package/docs/API.md ADDED
@@ -0,0 +1,708 @@
1
+ # Kaseki Agent REST API Reference
2
+
3
+ ## Overview
4
+
5
+ The Kaseki API Service provides HTTP endpoints for remotely triggering, monitoring, and retrieving results from kaseki-agent runs. This allows external tools like OpenClaw to control kaseki without SSH/sshpass.
6
+
7
+ ## Quick Start
8
+
9
+ ### Start the API Service
10
+
11
+ ```bash
12
+ # Set API keys and start
13
+ KASEKI_API_KEYS=sk-test-abc123 npm run kaseki-api
14
+
15
+ # Or with configuration file
16
+ KASEKI_API_KEYS_FILE=~/.kaseki-api-keys npm run kaseki-api
17
+
18
+ # Specify custom port
19
+ KASEKI_API_PORT=9000 KASEKI_API_KEYS=sk-test-abc123 npm run kaseki-api
20
+ ```
21
+
22
+ ### Environment Variables
23
+
24
+ | Variable | Default | Description |
25
+ |----------|---------|-------------|
26
+ | `KASEKI_API_PORT` | 8080 | HTTP port for API server |
27
+ | `KASEKI_API_KEYS` | *(required)* | Comma-separated API keys for auth |
28
+ | `KASEKI_API_KEYS_FILE` | — | Path to file with newline-separated keys |
29
+ | `KASEKI_API_LOG_DIR` | /var/log/kaseki-api/ | Log file output directory |
30
+ | `KASEKI_API_MAX_CONCURRENT_RUNS` | 3 | Max concurrent kaseki jobs |
31
+ | `KASEKI_RESULTS_DIR` | /agents/kaseki-results | Directory for run artifacts |
32
+ | `KASEKI_AGENT_TIMEOUT_SECONDS` | 5700 | Timeout for agent (95 min) |
33
+ | `KASEKI_MAX_DIFF_BYTES` | 200000 | Max diff size (200 KB) |
34
+ | `KASEKI_TASK_MODE` | patch | Default task mode: patch or inspect |
35
+ | `KASEKI_PUBLISH_MODE` | auto | Publish behavior: auto, none, branch, or draft_pr |
36
+ | `KASEKI_REPO_MEMORY_MODE` | off | Opt-in repository prompt memory: `off` or `summary` |
37
+ | `KASEKI_REPO_MEMORY_TTL_DAYS` | 30 | Maximum age of repository memory summaries |
38
+ | `KASEKI_REPO_MEMORY_MAX_BYTES` | 8000 | Maximum bytes read/written for repository memory summaries |
39
+ | `KASEKI_API_LOG_LEVEL` | info | Log verbosity: debug/info/warn/error |
40
+ | `GITHUB_APP_ID_FILE` | — | Path to file containing GitHub App ID for PR creation |
41
+ | `GITHUB_APP_CLIENT_ID_FILE` | — | Path to file containing GitHub App Client ID |
42
+ | `GITHUB_APP_PRIVATE_KEY_FILE` | — | Path to GitHub App private key file; preferred over inline private key env |
43
+
44
+ ## Authentication
45
+
46
+ All endpoints (except `/health`, `/api/health`, `/ready`, and `/api/ready`) require Bearer token authentication:
47
+
48
+ ```bash
49
+ curl -H "Authorization: Bearer sk-your-api-key" http://localhost:8080/api/runs
50
+ ```
51
+
52
+ If the token is missing or invalid, the API returns `401 Unauthorized`.
53
+
54
+ ## API Endpoints
55
+
56
+ ### Health Check
57
+
58
+ **GET `/health`** or **GET `/api/health`**
59
+
60
+ No authentication required. Check service health and queue status.
61
+
62
+ **Response (200 OK):**
63
+
64
+ ```json
65
+ {
66
+ "status": "healthy",
67
+ "timestamp": "2026-05-02T14:30:00Z",
68
+ "queue": {
69
+ "pending": 2,
70
+ "running": 1,
71
+ "maxConcurrent": 3
72
+ }
73
+ }
74
+ ```
75
+
76
+ `image` and `templateImage` reflect the configured image reference that the runner looks up locally, such as `docker.io/cyanautomation/kaseki-agent:latest`. `imageDigest` and `templateImageDigest` report the resolved local digest when available.
77
+
78
+ ### Controller Preflight
79
+
80
+ **GET `/api/preflight`**
81
+
82
+ Requires authentication. Run this before submitting jobs from OpenClaw or another remote controller. It validates the runtime dependencies that the API needs in order to launch ephemeral Kaseki containers.
83
+
84
+ ```bash
85
+ curl -H "Authorization: Bearer sk-your-api-key" \
86
+ http://localhost:8080/api/preflight
87
+ ```
88
+
89
+ **Response (200 OK or 503 Service Unavailable):**
90
+
91
+ ```json
92
+ {
93
+ "status": "ok",
94
+ "timestamp": "2026-05-03T21:30:00.000Z",
95
+ "image": "docker.io/:latest",
96
+ "imageDigest": "docker.io/@sha256:...",
97
+ "templateImage": "docker.io/cyanautomation/kaseki-agent:latest",
98
+ "templateImageDigest": "docker.io/cyanautomation/kaseki-agent:latest",
99
+ "templateDir": "/agents/kaseki-template",
100
+ "templateRef": "abc1234",
101
+ "resultsDir": "/agents/kaseki-results",
102
+ "runtime": {
103
+ "nodeVersion": "v24.15.0",
104
+ "uid": 1000,
105
+ "gid": 1000,
106
+ "groups": [1000, 985]
107
+ },
108
+ "docker": {
109
+ "version": "20.10.24 -> 29.4.1",
110
+ "clientVersion": "20.10.24",
111
+ "serverVersion": "29.4.1"
112
+ },
113
+ "checks": [
114
+ {
115
+ "name": "docker-daemon",
116
+ "ok": true,
117
+ "detail": "20.10.24 -> 29.4.1"
118
+ }
119
+ ]
120
+ }
121
+ ```
122
+
123
+ If Docker socket access is denied, the response includes remediation such as adding `group_add: ["${DOCKER_GID:-985}"]` to the API container.
124
+
125
+ When GitHub App settings are present, preflight also validates that the App ID,
126
+ Client ID, and private key are readable and structurally valid. A partial GitHub
127
+ configuration returns `503` so controllers can fail early before starting a run
128
+ that cannot publish its patch.
129
+
130
+ ### Readiness Check
131
+
132
+ **GET `/ready`** or **GET `/api/ready`**
133
+
134
+ No authentication required. Returns readiness for queue/scheduler dependencies used to accept and execute runs.
135
+
136
+ - `200` when:
137
+ - results directory is readable+writable,
138
+ - scheduler queue status is available,
139
+ - webhook manager loop is healthy.
140
+ - `503` when one or more dependencies are not ready.
141
+
142
+ **Response (200 OK):**
143
+
144
+ ```json
145
+ {
146
+ "status": "ready",
147
+ "timestamp": "2026-05-05T12:00:00.000Z"
148
+ }
149
+ ```
150
+
151
+ **Response (503 Service Unavailable):**
152
+
153
+ ```json
154
+ {
155
+ "status": "not_ready",
156
+ "timestamp": "2026-05-05T12:00:00.000Z",
157
+ "reasons": [
158
+ "results_dir_unwritable:EACCES: permission denied, access '/agents/kaseki-results'"
159
+ ]
160
+ }
161
+ ```
162
+
163
+ ### Prometheus Metrics
164
+
165
+ **GET `/api/metrics`**
166
+
167
+ Requires authentication. Returns Prometheus text exposition (`text/plain; version=0.0.4`) including:
168
+
169
+ - `kaseki_queue_pending` (gauge)
170
+ - `kaseki_running_jobs` (gauge)
171
+ - `kaseki_runs_total{result="success|failure"}` (counter)
172
+ - `kaseki_run_duration_seconds` (histogram)
173
+ - `kaseki_timeouts_total` (counter)
174
+ - `kaseki_timeout_rate` (gauge)
175
+
176
+ ### Trigger a Run
177
+
178
+ **POST `/api/runs`**
179
+
180
+ Submit a new kaseki job to the queue. Returns immediately (async).
181
+
182
+ **Request:**
183
+
184
+ ```bash
185
+ curl -X POST http://localhost:8080/api/runs \
186
+ -H "Authorization: Bearer sk-your-api-key" \
187
+ -H "Content-Type: application/json" \
188
+ -d '{
189
+ "repoUrl": "https://github.com/org/repo",
190
+ "ref": "main",
191
+ "taskPrompt": "Fix the parser bug in src/lib/parser.ts",
192
+ "changedFilesAllowlist": ["src/lib/parser.ts", "tests/parser.test.ts"],
193
+ "allowlist": { "include": ["src/lib/parser.ts", "tests/parser.test.ts"] },
194
+ "maxDiffBytes": 150000,
195
+ "validationCommands": ["npm run lint", "npm run test"],
196
+ "validation": { "commands": ["npm run lint", "npm run test"] },
197
+ "taskMode": "patch",
198
+ "publishMode": "draft_pr"
199
+ }'
200
+ ```
201
+
202
+ **Request Schema:**
203
+
204
+ ```typescript
205
+ {
206
+ repoUrl: string; // ✓ Required, must be valid URL
207
+ ref?: string; // Git branch/tag/commit (default: "main")
208
+ taskPrompt?: string; // Instructions for Pi agent
209
+ changedFilesAllowlist?: string[]; // File patterns Pi must not modify outside
210
+ allowlist?: { include?: string[] }; // Alias accepted for controllers
211
+ maxDiffBytes?: number; // Max diff size in bytes
212
+ validationCommands?: string[]; // Commands to run after agent completes
213
+ validation?: { commands?: string[] }; // Alias accepted for controllers
214
+ taskMode?: "patch" | "inspect"; // "patch" (default) = require changes
215
+ publishMode?: "none" | "branch" | "draft_pr"; // Optional publish behavior
216
+ startupCheck?: boolean; // Start worker, verify boot/runtime, then exit
217
+ timeoutSeconds?: number; // Optional per-run timeout (60-10800 seconds)
218
+ }
219
+ ```
220
+
221
+ Set `publishMode` when a controller needs deterministic publish behavior:
222
+ `none` skips GitHub publishing, `branch` pushes a Kaseki branch after validation,
223
+ and `draft_pr` pushes a branch and opens a draft pull request. Requests with
224
+ `branch` or `draft_pr` fail before queueing unless GitHub App credentials are
225
+ readable; call `GET /api/preflight` first to verify that readiness.
226
+
227
+ For controller activation checks, submit `startupCheck: true` or call `POST /api/runs?dryRun=true`. This starts the same worker path as a normal run, verifies the cloned repo, OpenRouter secret mount, writable workspace/results/cache paths, Node, Git, and Pi CLI, then exits before spending a full agent run.
228
+
229
+ Dependency installation in worker runs is lockfile-enforced (`npm ci --omit=dev`, optionally with `--ignore-scripts`), and run artifacts expose cache/install observability. Controllers can read `progress.jsonl`, `stage-timings.tsv`, and `dependency-cache.log` for install elapsed time plus cache hit/miss and reuse source details.
230
+
231
+ **Response (202 Accepted):**
232
+
233
+ ```json
234
+ {
235
+ "id": "kaseki-42",
236
+ "status": "queued",
237
+ "createdAt": "2026-05-02T14:30:00Z"
238
+ }
239
+ ```
240
+
241
+ Idempotency replays return `200 OK` with `cached: true` and the current job status when the original job is still known to the scheduler. This prevents controllers from seeing stale `running` or `queued` responses after a retry of a completed, failed, or cancelled run.
242
+
243
+ ### List All Runs
244
+
245
+ **GET `/api/runs`**
246
+
247
+ List recent kaseki runs, newest first.
248
+
249
+ **Response (200 OK):**
250
+
251
+ ```json
252
+ {
253
+ "runs": [
254
+ {
255
+ "id": "kaseki-42",
256
+ "status": "running",
257
+ "createdAt": "2026-05-02T14:30:00Z"
258
+ },
259
+ {
260
+ "id": "kaseki-41",
261
+ "status": "completed",
262
+ "createdAt": "2026-05-02T14:20:00Z",
263
+ "completedAt": "2026-05-02T14:28:00Z"
264
+ }
265
+ ],
266
+ "total": 2
267
+ }
268
+ ```
269
+
270
+ ### Get Run Status
271
+
272
+ **GET `/api/runs/:id/status`**
273
+
274
+ Poll the status of a specific run. Returns progress and timeout risk.
275
+
276
+ **Progress Object** (only present for running jobs):
277
+ The `progress` field contains a structured object describing the current execution stage with the following fields:
278
+
279
+ - `stage` (string, required) — Current execution stage name (e.g., "pi coding agent", "validation")
280
+ - `percentComplete` (number, optional) — Progress percentage (0-100)
281
+ - `message` (string, optional) — Detailed status message or stage name fallback
282
+ - `updatedAt` (ISO-8601 string, optional) — Timestamp when progress was last updated
283
+
284
+ For non-running jobs, `progress` is omitted.
285
+
286
+ **Response (200 OK):**
287
+
288
+ ```json
289
+ {
290
+ "id": "kaseki-42",
291
+ "status": "running",
292
+ "progress": {
293
+ "stage": "pi coding agent",
294
+ "percentComplete": 85,
295
+ "message": "Refactoring implementation",
296
+ "updatedAt": "2026-05-05T12:34:00.000Z"
297
+ },
298
+ "elapsedSeconds": 315,
299
+ "timeoutRiskPercent": 26,
300
+ "resultDir": "/agents/kaseki-results/kaseki-42"
301
+ }
302
+ ```
303
+
304
+ **Response (Terminal Status - 200 OK):**
305
+
306
+ ```json
307
+ {
308
+ "id": "kaseki-42",
309
+ "status": "failed",
310
+ "elapsedSeconds": 500,
311
+ "timeoutRiskPercent": 41,
312
+ "exitCode": 1,
313
+ "failureClass": "validation",
314
+ "resultDir": "/agents/kaseki-results/kaseki-42",
315
+ "artifacts": {
316
+ "metadataJson": true,
317
+ "analysisMd": true,
318
+ "resultSummaryMd": true,
319
+ "failureJson": true,
320
+ "stderrLog": true,
321
+ "availableFiles": [
322
+ "metadata.json",
323
+ "analysis.md",
324
+ "result-summary.md",
325
+ "failure.json",
326
+ "stderr.log"
327
+ ]
328
+ },
329
+ "diagnosticEntryPoint": "failure.json"
330
+ }
331
+ ```
332
+
333
+ **Status Values:**
334
+
335
+ - `queued` — Waiting in queue
336
+ - `running` — Currently executing
337
+ - `completed` — Finished successfully (check exitCode)
338
+ - `failed` — Failed validation, timeout, or quality gate
339
+
340
+ For terminal states (`completed` and `failed`), the response includes an `artifacts` object so clients can branch without probing `/api/results/:id/:file` and handling avoidable `404` responses. `availableFiles` is deterministic and ordered as:
341
+
342
+ 1) `metadata.json`
343
+ 2) `analysis.md`
344
+ 3) `result-summary.md`
345
+ 4) `failure.json`
346
+ 5) `stderr.log`
347
+
348
+ For failed runs, `diagnosticEntryPoint` is included:
349
+
350
+ - `failure.json` when present and non-empty
351
+ - otherwise `analysis.md` when present and non-empty
352
+ - otherwise `result-summary.md` when present and non-empty
353
+
354
+ Zero-byte key artifacts are reported as unavailable, so controller clients can trust artifact hints instead of downloading empty placeholders.
355
+
356
+ **Timeout Risk:** Percentage of agent timeout elapsed. Monitor for >85% and consider canceling if needed.
357
+
358
+ ### Get Progress Events
359
+
360
+ **GET `/api/runs/:id/progress`**
361
+
362
+ Returns sanitized progress events from `progress.jsonl`. Assistant text, environment values, and secrets are not included.
363
+ For running jobs whose result directory has not been promoted yet, the API falls back to sanitized `[progress]` lines from the live Docker container logs.
364
+
365
+ ```bash
366
+ curl -H "Authorization: Bearer sk-your-api-key" \
367
+ "http://localhost:8080/api/runs/kaseki-42/progress?tail=25"
368
+ ```
369
+
370
+ **Response (200 OK):**
371
+
372
+ ```json
373
+ {
374
+ "id": "kaseki-42",
375
+ "status": "running",
376
+ "events": [
377
+ {
378
+ "timestamp": "2026-05-02T14:31:00Z",
379
+ "stage": "pi coding agent",
380
+ "message": "working; events=65, tool starts=4, tool ends=3"
381
+ }
382
+ ],
383
+ "total": 120
384
+ }
385
+ ```
386
+
387
+ ### Get Controller Events
388
+
389
+ **GET `/api/runs/:id/events`**
390
+
391
+ Returns a controller-friendly event snapshot. It reads promoted `progress.jsonl` events when available and appends sanitized live Docker progress events while the worker container is still running.
392
+
393
+ ```bash
394
+ curl -H "Authorization: Bearer sk-your-api-key" \
395
+ "http://localhost:8080/api/runs/kaseki-42/events?tail=50"
396
+ ```
397
+
398
+ **Response (200 OK):**
399
+
400
+ ```json
401
+ {
402
+ "id": "kaseki-42",
403
+ "status": "running",
404
+ "events": [
405
+ {
406
+ "source": "docker-logs",
407
+ "stage": "startup check",
408
+ "message": "container booted"
409
+ }
410
+ ],
411
+ "total": 1,
412
+ "sources": ["docker-logs"]
413
+ }
414
+ ```
415
+
416
+ ### Cancel a Run
417
+
418
+ **POST `/api/runs/:id/cancel`**
419
+
420
+ Cancels a queued or running job. Completed jobs are returned unchanged.
421
+ Cancelled jobs get API-written fallback diagnostics when the worker exits before writing its own final artifacts. Guaranteed non-empty files on failure are: `analysis.md`, `metadata.json`, `stderr.log`, `failure.json`, and `result-summary.md` (kept for backward compatibility during migration).
422
+
423
+ ```bash
424
+ curl -X POST -H "Authorization: Bearer sk-your-api-key" \
425
+ http://localhost:8080/api/runs/kaseki-42/cancel
426
+ ```
427
+
428
+ **Response (200 OK):**
429
+
430
+ ```json
431
+ {
432
+ "id": "kaseki-42",
433
+ "status": "failed",
434
+ "exitCode": 143,
435
+ "failureClass": "cancelled",
436
+ "error": "Job cancelled by API request"
437
+ }
438
+ ```
439
+
440
+ ### Get Logs
441
+
442
+ **GET `/api/runs/:id/logs/:logtype`**
443
+
444
+ Retrieve specific log files from a run.
445
+
446
+ **Log Types:**
447
+
448
+ - `stdout` — Standard output
449
+ - `stderr` — Standard error
450
+ - `validation` — Validation command output
451
+ - `progress` — Pi agent progress events
452
+ - `quality` — Quality gate results
453
+ - `secret-scan` — Secret detection results
454
+
455
+ **Example:**
456
+
457
+ ```bash
458
+ curl -H "Authorization: Bearer sk-your-api-key" \
459
+ http://localhost:8080/api/runs/kaseki-42/logs/stdout
460
+ ```
461
+
462
+ **Response (200 OK):**
463
+
464
+ ```json
465
+ {
466
+ "logType": "stdout",
467
+ "content": "[kaseki-42] Cloning repo...\n[kaseki-42] Installing dependencies...\n...",
468
+ "size": 45678
469
+ }
470
+ ```
471
+
472
+ Note: Large logs (>100 KB) are truncated with a marker showing how much is hidden.
473
+
474
+ ### Get Run Analysis
475
+
476
+ **GET `/api/runs/:id/analysis`**
477
+
478
+ Comprehensive post-run analysis including metadata, changes, and validation results.
479
+
480
+ **Response (200 OK):**
481
+
482
+ ```json
483
+ {
484
+ "id": "kaseki-42",
485
+ "status": "completed",
486
+ "createdAt": "2026-05-02T14:30:00Z",
487
+ "completedAt": "2026-05-02T14:40:00Z",
488
+ "elapsedSeconds": 600,
489
+ "exitCode": 0,
490
+ "metadata": {
491
+ "model": "openrouter/free",
492
+ "instance": "kaseki-42",
493
+ "repo": "https://github.com/org/repo",
494
+ "ref": "main"
495
+ },
496
+ "changes": {
497
+ "changedFiles": ["src/lib/parser.ts"],
498
+ "diffSize": 2048
499
+ },
500
+ "validation": {
501
+ "passed": true,
502
+ "commandResults": [
503
+ {
504
+ "command": "npm run lint",
505
+ "exitCode": 0,
506
+ "elapsed": 15000
507
+ },
508
+ {
509
+ "command": "npm run test",
510
+ "exitCode": 0,
511
+ "elapsed": 45000
512
+ }
513
+ ]
514
+ }
515
+ }
516
+ ```
517
+
518
+ ### List Run Artifacts (Discovery Endpoint)
519
+
520
+ **GET `/api/runs/:id/artifacts`**
521
+
522
+ List only allowlisted artifact files, whether they currently exist, and whether each file is currently available to download.
523
+ This endpoint is designed to remove guesswork before calling `GET /api/results/:id/:file`.
524
+
525
+ Resolution logic:
526
+
527
+ - Uses `job.resultDir` when present.
528
+ - Falls back to `${KASEKI_RESULTS_DIR}/${runId}` when `job.resultDir` is not set.
529
+
530
+ **Example (failed run):**
531
+
532
+ ```bash
533
+ curl -s -H "Authorization: Bearer sk-your-api-key" \
534
+ http://localhost:8080/api/runs/kaseki-42/artifacts | jq '.'
535
+ ```
536
+
537
+ **Response (200 OK):**
538
+
539
+ ```json
540
+ {
541
+ "id": "kaseki-42",
542
+ "runStatus": "failed",
543
+ "exitCode": 1,
544
+ "artifacts": [
545
+ { "name": "result-summary.md", "size": 1382, "contentType": "text/markdown", "available": true },
546
+ { "name": "failure.json", "size": 224, "contentType": "application/json", "available": true },
547
+ { "name": "stderr.log", "size": 9821, "contentType": "text/plain", "available": true },
548
+ { "name": "validation.log", "size": 0, "contentType": "text/plain", "available": false }
549
+ ],
550
+ "recommended": ["failure.json", "stderr.log", "stdout.log", "validation.log", "quality.log"]
551
+ }
552
+ ```
553
+
554
+ `recommended` is status-aware:
555
+
556
+ - `failed`: triage artifacts (`failure.json`, logs, quality/validation output)
557
+ - non-failed (`queued`, `running`, `completed`): summary artifacts (`result-summary.md`, `metadata.json`, `pi-summary.json`, `git.diff`)
558
+
559
+ ### Download Artifact
560
+
561
+ **GET `/api/results/:id/:file`**
562
+
563
+ Download specific result artifacts.
564
+
565
+ **Allowed Files (always-safe summary artifacts):**
566
+
567
+ - `git.diff` — Unified diff of changes
568
+ - `metadata.json` — Full run metadata
569
+ - `analysis.md` — Canonical failure-minimum analysis summary (when run fails)
570
+ - `result-summary.md` — Human-readable summary
571
+ - `pi-events.jsonl` — Pi agent events (newline-delimited JSON)
572
+ - `pi-summary.json` — Pi agent statistics
573
+ - `progress.log` — Execution progress log
574
+
575
+ **Allowed Files (failure-only diagnostics):**
576
+
577
+ - `failure.json` — Failure classification and details
578
+ - `stderr.log` — Captured standard error output
579
+ - `stdout.log` — Captured standard output
580
+ - `validation.log` — Validation command output (if validation configured)
581
+ - `quality.log` — Quality-gate output (if quality checks configured)
582
+
583
+ Failure-only diagnostics are returned only when the run status is `failed`.
584
+
585
+ **Example:**
586
+
587
+ ```bash
588
+ curl -H "Authorization: Bearer sk-your-api-key" \
589
+ http://localhost:8080/api/results/kaseki-42/git.diff -o patch.diff
590
+ ```
591
+
592
+ ## Error Handling
593
+
594
+ Errors follow [RFC 7807 Problem Details](https://tools.ietf.org/html/rfc7807):
595
+
596
+ ```json
597
+ {
598
+ "type": "https://api.kaseki.local/errors#bad-request",
599
+ "title": "Bad Request",
600
+ "status": 400,
601
+ "detail": "Invalid repository URL format"
602
+ }
603
+ ```
604
+
605
+ Common error codes:
606
+
607
+ | Status | Reason |
608
+ |--------|--------|
609
+ | 400 | Invalid request (validation failed) |
610
+ | 401 | Missing/invalid API key |
611
+ | 404 | Run not found |
612
+ | 500 | Server error (check logs) |
613
+
614
+ ## Workflow Example
615
+
616
+ ### 1. Trigger a run
617
+
618
+ ```bash
619
+ RESPONSE=$(curl -s -X POST http://localhost:8080/api/runs \
620
+ -H "Authorization: Bearer sk-test-key" \
621
+ -H "Content-Type: application/json" \
622
+ -d '{
623
+ "repoUrl": "https://github.com/org/repo",
624
+ "taskPrompt": "Fix bug in parser.ts"
625
+ }')
626
+
627
+ RUN_ID=$(echo $RESPONSE | jq -r '.id')
628
+ echo "Run started: $RUN_ID"
629
+ ```
630
+
631
+ ### 2. Poll status
632
+
633
+ ```bash
634
+ while true; do
635
+ STATUS=$(curl -s -H "Authorization: Bearer sk-test-key" \
636
+ http://localhost:8080/api/runs/$RUN_ID/status)
637
+
638
+ STATE=$(echo $STATUS | jq -r '.status')
639
+ PROGRESS=$(echo $STATUS | jq -r '.progress // "waiting"')
640
+ ELAPSED=$(echo $STATUS | jq -r '.elapsedSeconds // 0')
641
+
642
+ echo "[$ELAPSED s] $STATE: $PROGRESS"
643
+
644
+ [ "$STATE" != "running" ] && break
645
+ sleep 5
646
+ done
647
+ ```
648
+
649
+ ### 3. Check results
650
+
651
+ ```bash
652
+ # Get comprehensive analysis
653
+ curl -s -H "Authorization: Bearer sk-test-key" \
654
+ http://localhost:8080/api/runs/$RUN_ID/analysis | jq '.'
655
+
656
+ # Download the diff
657
+ curl -H "Authorization: Bearer sk-test-key" \
658
+ http://localhost:8080/api/results/$RUN_ID/git.diff -o changes.diff
659
+ ```
660
+
661
+ ## Best Practices
662
+
663
+ 1. **Set appropriate timeouts** — Agent timeout defaults to 95 minutes. Adjust globally via `KASEKI_AGENT_TIMEOUT_SECONDS` or per-run via `timeoutSeconds`.
664
+
665
+ 2. **Monitor timeout risk** — Check `timeoutRiskPercent` in status. If >85%, consider graceful shutdown.
666
+
667
+ 3. **Use allowlists** — Always set `changedFilesAllowlist` to prevent Pi from modifying unintended files.
668
+
669
+ 4. **Limit concurrent runs** — Set `KASEKI_API_MAX_CONCURRENT_RUNS` to prevent host overload.
670
+
671
+ 5. **Rotate API keys** — Keep keys in secure storage (`KASEKI_API_KEYS_FILE`), not in scripts.
672
+
673
+ 6. **Parse errors** — Check `failureClass` in status to determine failure root cause:
674
+ - `validation` — Validation command failed
675
+ - `timeout` — Agent timeout
676
+ - `quality` — Diff/allowlist/secret scan violation
677
+ - `empty-diff` — No changes (when mode=patch)
678
+
679
+ ## API Versioning
680
+
681
+ Current version: **v1** (embedded in base path `/api/`)
682
+
683
+ Future versions will use `/api/v2/`, `/api/v3/`, etc., allowing peaceful transitions.
684
+
685
+ ---
686
+
687
+ ## TypeScript Client (Coming Soon)
688
+
689
+ OpenClaw and other tools can use the auto-generated TypeScript client:
690
+
691
+ ```typescript
692
+ import { KasekiApiClient } from '@kaseki-agent/api-client';
693
+
694
+ const client = new KasekiApiClient('http://localhost:8080', 'sk-api-key');
695
+
696
+ const run = await client.submit({
697
+ repoUrl: 'https://github.com/org/repo',
698
+ taskPrompt: 'Fix the bug'
699
+ });
700
+
701
+ console.log(`Run started: ${run.id}`);
702
+
703
+ // Monitor
704
+ const status = await client.getStatus(run.id);
705
+ console.log(`Status: ${status.status}, elapsed: ${status.elapsedSeconds}s`);
706
+ ```
707
+
708
+ (Client implementation coming in Phase 8)