@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/README.md ADDED
@@ -0,0 +1,1527 @@
1
+ # Kaseki Agent
2
+
3
+ Kaseki is a proof-of-concept ephemeral coding-agent runner. Each run is a numbered, disposable container instance such as `kaseki-1` or `kaseki-2`. This package provides a complete CLI and REST API for orchestrating the Pi coding-agent with OpenRouter.
4
+
5
+ ## Quick Start
6
+
7
+ ### **Installation (Recommended)**
8
+
9
+ ```bash
10
+ # Global install (recommended)
11
+ npm install -g @cyanautomation/kaseki-agent
12
+
13
+ # First-time setup
14
+ kaseki-agent setup
15
+
16
+ # Run agent on a repository
17
+ kaseki-agent run https://github.com/CyanAutomation/crudmapper main
18
+
19
+ # View results
20
+ kaseki-agent list
21
+ kaseki-agent report kaseki-1
22
+ ```
23
+
24
+ ### **Without Global Install**
25
+
26
+ ```bash
27
+ npm install @cyanautomation/kaseki-agent
28
+ npx kaseki-agent setup
29
+ npx kaseki-agent run https://github.com/CyanAutomation/crudmapper main
30
+ ```
31
+
32
+ ### **Using Docker** ⭐ (Alternative)
33
+
34
+ If you prefer to avoid installing Node.js globally:
35
+
36
+ ```bash
37
+ # Setup API key
38
+ docker run -it \
39
+ -v ~/.kaseki/secrets:/secrets \
40
+ docker.io/cyanautomation/kaseki-agent:latest \
41
+ setup
42
+
43
+ # Run agent
44
+ docker run -it \
45
+ -v ~/.kaseki/secrets:/secrets \
46
+ -v /var/run/docker.sock:/var/run/docker.sock \
47
+ docker.io/cyanautomation/kaseki-agent:latest \
48
+ run https://github.com/CyanAutomation/crudmapper main
49
+ ```
50
+
51
+ ## Overview
52
+
53
+ **Kaseki** orchestrates three deployment patterns:
54
+
55
+ 1. **CLI** — `kaseki-agent` command for direct execution (this package)
56
+ 2. **Docker** — Containerized execution without host dependencies
57
+ 3. **REST API** — `kaseki-agent serve` for distributed orchestration
58
+
59
+ Each produces a numbered instance (kaseki-1, kaseki-2, …) with isolated workspace and results.
60
+
61
+ ---
62
+
63
+ ## Getting Started
64
+
65
+ ### **1. Installation & Setup**
66
+
67
+ **Option A: Global NPM**
68
+
69
+ ```bash
70
+ npm install -g @cyanautomation/kaseki-agent
71
+ kaseki-agent setup
72
+ ```
73
+
74
+ **Option B: Local NPM**
75
+
76
+ ```bash
77
+ npm install @cyanautomation/kaseki-agent
78
+ npx kaseki-agent setup
79
+ ```
80
+
81
+ **Option C: Docker**
82
+
83
+ ```bash
84
+ docker run -it \
85
+ -v ~/.kaseki/secrets:/secrets \
86
+ docker.io/cyanautomation/kaseki-agent:latest \
87
+ setup
88
+ ```
89
+
90
+ ### **2. Verify Installation**
91
+
92
+ ```bash
93
+ kaseki-agent doctor
94
+ ```
95
+
96
+ ### **3. Run Your First Task**
97
+
98
+ ```bash
99
+ # Simple example
100
+ kaseki-agent run https://github.com/CyanAutomation/crudmapper main
101
+
102
+ # With custom task prompt
103
+ kaseki-agent run https://github.com/CyanAutomation/crudmapper main \
104
+ "Fix the TypeScript errors in src/"
105
+ ```
106
+
107
+ ### **4. View Results**
108
+
109
+ ```bash
110
+ # List all instances
111
+ kaseki-agent list
112
+
113
+ # View specific instance
114
+ kaseki-agent report kaseki-1
115
+ ```
116
+
117
+ ---
118
+
119
+ ## CLI Commands
120
+
121
+ ### `setup` — Interactive Configuration Wizard
122
+
123
+ First-time setup to validate environment and store API credentials securely.
124
+
125
+ ```bash
126
+ kaseki-agent setup
127
+ ```
128
+
129
+ **What it does:**
130
+ - Validates Docker installation and daemon
131
+ - Checks Node.js v24+ availability
132
+ - Validates git installation
133
+ - Prompts for OpenRouter API key (securely stored in keyring)
134
+ - Saves configuration (project-local or user-global)
135
+ - Runs doctor checks to verify everything works
136
+
137
+ ### `run` — Execute Agent on Repository
138
+
139
+ ```bash
140
+ kaseki-agent run <REPO_URL> [GIT_REF] [TASK_PROMPT]
141
+ ```
142
+
143
+ **Examples:**
144
+ ```bash
145
+ # Simple execution (uses main branch)
146
+ kaseki-agent run https://github.com/CyanAutomation/crudmapper
147
+
148
+ # Specify branch
149
+ kaseki-agent run https://github.com/CyanAutomation/crudmapper develop
150
+
151
+ # With custom task prompt
152
+ kaseki-agent run https://github.com/CyanAutomation/crudmapper main \
153
+ "Fix all TypeScript errors in src/"
154
+ ```
155
+
156
+ **Execution Flow:**
157
+ 1. Pre-flight checks (docker, node, npm, git, API key)
158
+ 2. Auto-pull Docker image (if needed)
159
+ 3. Create instance directories (workspace + results)
160
+ 4. Spawn container with security hardening
161
+ 5. Stream agent output in real-time
162
+ 6. Collect results and generate report
163
+
164
+ ### `doctor` — Health Check & Validation
165
+
166
+ ```bash
167
+ kaseki-agent doctor [--json] [--fix]
168
+ ```
169
+
170
+ **Checks:**
171
+ - Docker daemon availability
172
+ - Node.js v24+ validation
173
+ - npm availability
174
+ - git installation
175
+ - OpenRouter API key configuration
176
+ - Docker image status
177
+ - Disk space availability
178
+
179
+ **Options:**
180
+ - `--json` — JSON output (useful for scripts)
181
+ - `--fix` — Attempt auto-remediation (pull image, show install hints)
182
+
183
+ ### `list` — Show All Instances
184
+
185
+ ```bash
186
+ kaseki-agent list [--status STATE]
187
+ ```
188
+
189
+ **Filter by status:**
190
+ ```bash
191
+ kaseki-agent list --status completed
192
+ kaseki-agent list --status failed
193
+ kaseki-agent list --status running
194
+ ```
195
+
196
+ **Output:**
197
+ - Instance ID
198
+ - Status (running/completed/failed)
199
+ - Creation date
200
+ - Execution duration
201
+
202
+ ### `report` — View Instance Results
203
+
204
+ ```bash
205
+ kaseki-agent report <INSTANCE_ID>
206
+ ```
207
+
208
+ **Shows:**
209
+ - Instance metadata (repo, branch, model, status)
210
+ - Execution stages with timing
211
+ - Final status and exit code
212
+ - Detailed summary (if available)
213
+
214
+ ### `config` — Manage Configuration
215
+
216
+ ```bash
217
+ kaseki-agent config <SUBCOMMAND> [OPTIONS]
218
+ ```
219
+
220
+ **Subcommands:**
221
+ ```bash
222
+ # Get a value
223
+ kaseki-agent config get agent.timeout_seconds
224
+
225
+ # Set a value (project-local)
226
+ kaseki-agent config set agent.timeout_seconds 1800
227
+
228
+ # Set globally
229
+ kaseki-agent config set agent.timeout_seconds 1800 --global
230
+
231
+ # Show active configuration
232
+ kaseki-agent config show
233
+
234
+ # Show available locations
235
+ kaseki-agent config locations
236
+ ```
237
+
238
+ ### `secrets` — Manage Credentials
239
+
240
+ ```bash
241
+ kaseki-agent secrets <SUBCOMMAND>
242
+ ```
243
+
244
+ **Subcommands:**
245
+ ```bash
246
+ # Initialize keyring
247
+ kaseki-agent secrets init
248
+
249
+ # Store a secret
250
+ kaseki-agent secrets set openrouter-api-key sk-or-...
251
+
252
+ # Retrieve (hidden by default)
253
+ kaseki-agent secrets get openrouter-api-key
254
+
255
+ # Show secret value
256
+ kaseki-agent secrets get openrouter-api-key --show
257
+
258
+ # Delete
259
+ kaseki-agent secrets delete openrouter-api-key
260
+
261
+ # List all keys
262
+ kaseki-agent secrets list
263
+ ```
264
+
265
+ **Storage:**
266
+ - Linux: Uses `pass` (password-store) keyring
267
+ - Headless: Falls back to `~/.kaseki/secrets/` (0600 permissions)
268
+
269
+ ### `serve` — Start REST API Service
270
+
271
+ ```bash
272
+ kaseki-agent serve [--port PORT]
273
+ ```
274
+
275
+ **Default port:** 8080
276
+
277
+ ```bash
278
+ # Start on default port
279
+ kaseki-agent serve
280
+
281
+ # Custom port
282
+ kaseki-agent serve --port 9000
283
+ ```
284
+
285
+ **API Endpoints:**
286
+ - `GET /health` — Service health check
287
+ - `GET /api/runs` — List instances
288
+ - `POST /api/runs` — Start new run
289
+ - `GET /api/runs/:id` — Get instance status
290
+ - `GET /api/runs/:id/logs` — Stream logs
291
+ - `GET /api/runs/:id/results` — Get results
292
+
293
+ ---
294
+
295
+ ## Configuration
296
+
297
+ Configuration is loaded from (in order of precedence):
298
+
299
+ 1. **CLI flags** (highest precedence)
300
+ 2. **`kaseki-agent.json`** (project-local)
301
+ 3. **`~/.kaseki/config.json`** (user-global)
302
+ 4. **Environment variables** (`KASEKI_*`, `OPENROUTER_*`, `GITHUB_*`)
303
+ 5. **Built-in defaults**
304
+
305
+ **Example `kaseki-agent.json`:**
306
+
307
+ ```json
308
+ {
309
+ "agent": {
310
+ "model": "openrouter/free",
311
+ "timeout_seconds": 1200
312
+ },
313
+ "validation": {
314
+ "allowlist": ["src/lib/", "tests/"],
315
+ "max_diff_bytes": 200000
316
+ },
317
+ "docker": {
318
+ "auto_pull": true
319
+ }
320
+ }
321
+ ```
322
+
323
+ **Common Environment Variables:**
324
+
325
+ ```bash
326
+ # Required
327
+ OPENROUTER_API_KEY_FILE=~/.kaseki/secrets/openrouter_api_key
328
+
329
+ # Optional
330
+ KASEKI_ROOT=/agents # Base directory
331
+ KASEKI_MODEL=openrouter/free # AI model
332
+ KASEKI_AGENT_TIMEOUT_SECONDS=1200 # Timeout
333
+ KASEKI_VALIDATION_COMMANDS="npm run check;npm run test;npm run build"
334
+ ```
335
+
336
+ ---
337
+
338
+ ## Architecture
339
+
340
+ ### Deployment Patterns
341
+
342
+ **1. CLI (Direct Execution)**
343
+ ```bash
344
+ kaseki-agent run <repo> <ref>
345
+ ```
346
+ - Single-step orchestration
347
+ - Immediate results
348
+ - Best for: CI/CD, direct usage
349
+
350
+ **2. REST API (Distributed)**
351
+ ```bash
352
+ kaseki-agent serve --port 8080
353
+ # Then: POST /api/runs with repo/ref
354
+ ```
355
+ - Long-running service
356
+ - Async execution
357
+ - Best for: Controllers, distributed systems
358
+
359
+ **3. Docker (Self-Contained)**
360
+ ```bash
361
+ docker run docker.io/cyanautomation/kaseki-agent:latest run <repo> <ref>
362
+ ```
363
+ - No host dependencies
364
+ - Full isolation
365
+ - Best for: Clean environments, CI/CD containers
366
+
367
+ **Host layer** — Management and orchestration:
368
+
369
+ - `run-kaseki.sh` — Direct runner (creates workspace, launches container, cleans up)
370
+ - `kaseki-activate.sh` — Remote activation entrypoint (install, deploy, run, status, clean)
371
+ - `kaseki-healthcheck.sh` — Host heartbeat and container status check
372
+
373
+ **Container layer** — Agent execution:
374
+
375
+ - `kaseki-agent.sh` — Inside the container (clones repo, installs deps, invokes Pi, validates, stores results)
376
+ - `entrypoint.sh` — Container startup orchestrator
377
+
378
+ > **Important:** `kaseki-agent.sh` runs from the Docker image (`/usr/local/bin/kaseki-agent`) and is **not** host-mounted during runs.
379
+ > For Direct CLI mode, the host needs `run-kaseki.sh` (plus `scripts/kaseki-preflight.sh`) and Docker access; the agent script itself stays inside the image.
380
+
381
+ **Supporting utilities (Node.js):**
382
+
383
+ - `pi-event-filter.js` — Filters raw Pi JSONL, strips thinking blocks, emits `pi-events.jsonl` + `pi-summary.json`
384
+ - `kaseki-report.js` — Reads a results directory and prints diagnostic report
385
+ - `kaseki-cli.js` + `kaseki-cli-lib.js` — Live monitoring CLI for external agents
386
+ - `kaseki-api-service.js` — REST API service for remote runs
387
+ - `kaseki-api-client.ts` — TypeScript client for integration
388
+
389
+ **Directory layout at runtime:**
390
+
391
+ ```
392
+ /agents/kaseki-template/ # Dockerfile, scripts (this repo)
393
+ /agents/kaseki-agent/ # Checkout (source of truth for controllers)
394
+ /agents/kaseki-runs/kaseki-N/ # Per-run workspace (cloned repo, node_modules)
395
+ /agents/kaseki-results/kaseki-N/ # Artifacts (logs, diff, metadata, summary)
396
+ /agents/kaseki-cache/ # Optional host-level dependency cache (lockfile-first npm keys)
397
+ /cache/git/ # Optional host-mounted bare Git mirrors for target repos
398
+ ```
399
+
400
+ ---
401
+
402
+ ## Deployment Modes
403
+
404
+ ### 1. Direct CLI (run-kaseki.sh)
405
+
406
+ Simplest single-run invocation on a host:
407
+
408
+ ```bash
409
+ # Set API key via environment or file
410
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
411
+ ./run-kaseki.sh https://github.com/org/repo main
412
+ ```
413
+
414
+ **When to use:** Local development, one-off tasks, testing on a Pi.
415
+
416
+ **Host file requirements (Direct CLI):**
417
+
418
+ - Required on host: `run-kaseki.sh`, `scripts/kaseki-preflight.sh`
419
+ - Required in image/container: `kaseki-agent.sh` (invoked by container entrypoint as `/usr/local/bin/kaseki-agent`)
420
+ - Runtime mounts are workspace/results/cache/secrets; host script files are not mounted into `/app` at run time
421
+
422
+ ---
423
+
424
+ ### 2. Remote Activation (kaseki-activate.sh)
425
+
426
+ For SSH/controller-driven setup and execution. Used by OpenClaw and similar orchestrators.
427
+
428
+ #### Bootstrap a Remote Host
429
+
430
+ ```bash
431
+ # Single SSH command to bootstrap a Pi (install, deploy, doctor)
432
+ ssh pi@192.168.1.100 'curl -fsSL https://raw.githubusercontent.com//main/scripts/kaseki-install.sh | \
433
+ KASEKI_CONTROLLER_MODE=1 \
434
+ sh'
435
+ ```
436
+
437
+ Controller bootstrap can install, deploy, and run host diagnostics without an
438
+ OpenRouter key. Actual `run` commands still require `OPENROUTER_API_KEY` or
439
+ `OPENROUTER_API_KEY_FILE`, unless the API container provides the key for
440
+ HTTP-triggered runs.
441
+
442
+ #### Local Activation (No SSH)
443
+
444
+ ```bash
445
+ cd /agents/kaseki-agent
446
+
447
+ # Bootstrap: install, deploy, doctor
448
+ ./scripts/kaseki-activate.sh --controller bootstrap
449
+
450
+ # Install checkout only
451
+ KASEKI_REPO_URL=https://github.com/org/repo \
452
+ ./scripts/kaseki-activate.sh install
453
+
454
+ # Deploy template
455
+ ./scripts/kaseki-activate.sh deploy
456
+
457
+ # Health check
458
+ ./scripts/kaseki-activate.sh doctor
459
+
460
+ # Run a task
461
+ TASK_PROMPT='Fix the bug in parser.ts' \
462
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
463
+ ./scripts/kaseki-activate.sh run https://github.com/org/repo main
464
+ ```
465
+
466
+ #### Machine-Readable Output
467
+
468
+ For controller integration, use `--json` or `--jsonl`:
469
+
470
+ ```bash
471
+ ./scripts/kaseki-activate.sh --json doctor
472
+
473
+ ./scripts/kaseki-activate.sh --json run https://github.com/org/repo main
474
+ ```
475
+
476
+ Returns newline-delimited JSON for each major step.
477
+
478
+ **When to use:** Controller-driven setup, multi-host management, integration with orchestrators.
479
+
480
+ **Key Features:**
481
+
482
+ - Idempotent installation and deployment
483
+ - Machine-readable JSON output for parsing
484
+ - Automatic image pull/build with caching
485
+ - Dirty-checkout detection with `--replace-stale` option
486
+ - Comprehensive logging to `$KASEKI_LOG_DIR`
487
+
488
+ ---
489
+
490
+ ### 3. REST API Service (kaseki-api)
491
+
492
+ Long-running async orchestration service. Ideal for:
493
+
494
+ - **OpenClaw** and similar AI orchestrators
495
+ - **Distributed agents** that need to queue and poll runs
496
+ - **Multi-user environments** with authentication
497
+ - **Webhook integration** and external monitoring
498
+
499
+ #### Quick Start
500
+
501
+ ```bash
502
+ # Option A: Docker Compose (Recommended)
503
+ cd /agents/kaseki-template
504
+ export KASEKI_API_KEYS=sk-your-secret-key
505
+ docker build -t kaseki-agent:latest .
506
+ docker-compose up -d
507
+
508
+ # Option B: Node.js Process
509
+ npm install
510
+ KASEKI_API_KEYS=sk-your-secret-key npm run kaseki-api
511
+
512
+ # Option C: Docker directly
513
+ docker run -d --name kaseki-api \
514
+ -p 8080:8080 \
515
+ -e KASEKI_API_KEYS=sk-your-secret-key \
516
+ -v /agents:/agents:rw \
517
+ -v /var/run/docker.sock:/var/run/docker.sock \
518
+ docker.io/:latest api
519
+
520
+ # Option D: systemd Service
521
+ sudo cp scripts/kaseki-api.service /etc/systemd/system/
522
+ sudo systemctl start kaseki-api
523
+ ```
524
+
525
+ #### Trigger a Run
526
+
527
+ ```bash
528
+ curl -X POST http://localhost:8080/api/runs \
529
+ -H "Authorization: Bearer sk-your-secret-key" \
530
+ -H "Content-Type: application/json" \
531
+ -d '{
532
+ "repoUrl": "https://github.com/org/repo",
533
+ "taskPrompt": "Fix the parser bug",
534
+ "changedFilesAllowlist": ["src/lib/parser.ts"],
535
+ "allowlist": { "include": ["src/lib/parser.ts"] },
536
+ "validationCommands": ["npm run test", "npm run build"],
537
+ "validation": { "commands": ["npm run test", "npm run build"] },
538
+ "publishMode": "draft_pr"
539
+ }'
540
+
541
+ # Returns: {"id":"kaseki-42","status":"queued","createdAt":"2026-05-02T..."}
542
+ ```
543
+
544
+ #### Poll Status
545
+
546
+ ```bash
547
+ curl -H "Authorization: Bearer sk-your-secret-key" \
548
+ http://localhost:8080/api/runs/kaseki-42/status
549
+
550
+ # Returns: {"id":"kaseki-42","status":"running","elapsedSeconds":45,"timeoutRiskPercent":4,...}
551
+ ```
552
+
553
+ #### Download Results
554
+
555
+ ```bash
556
+ curl -H "Authorization: Bearer sk-your-secret-key" \
557
+ http://localhost:8080/api/results/kaseki-42/git.diff -o patch.diff
558
+
559
+ curl -H "Authorization: Bearer sk-your-secret-key" \
560
+ http://localhost:8080/api/runs/kaseki-42/analysis | jq '.'
561
+ ```
562
+
563
+ #### Key Endpoints
564
+
565
+ | Method | Endpoint | Purpose |
566
+ |--------|----------|---------|
567
+ | `GET` | `/health` | No-auth health check |
568
+ | `POST` | `/api/runs` | Submit a new task |
569
+ | `GET` | `/api/runs` | List recent runs |
570
+ | `GET` | `/api/runs/:id/status` | Poll run status |
571
+ | `GET` | `/api/runs/:id/progress` | Fetch progress events |
572
+ | `POST` | `/api/runs/:id/cancel` | Cancel queued/running job |
573
+ | `GET` | `/api/runs/:id/analysis` | Comprehensive summary |
574
+ | `GET` | `/api/results/:id/:file` | Download artifact (diff, metadata) |
575
+
576
+ **Full API documentation:** See [docs/API.md](docs/API.md)
577
+ **Deployment guide:** See [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)
578
+
579
+ **When to use:** Distributed orchestration, external controller integration, multi-user scenarios.
580
+
581
+ ---
582
+
583
+ ## Common Commands
584
+
585
+ ### Direct CLI
586
+
587
+ ```bash
588
+ # Basic run (auto-generates kaseki-N)
589
+ OPENROUTER_API_KEY=sk-or-... ./run-kaseki.sh
590
+
591
+ # Explicit instance and repo
592
+ OPENROUTER_API_KEY=sk-or-... ./run-kaseki.sh https://github.com/org/repo feature/branch kaseki-7
593
+
594
+ # API key via secret file
595
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key ./run-kaseki.sh
596
+
597
+ # Health/sanity check after deploying the host template
598
+ /agents/kaseki-template/run-kaseki.sh --doctor
599
+
600
+ # Build image locally
601
+ docker build -t kaseki-template:latest .
602
+
603
+ # Generate diagnostic report
604
+ docker run --rm --entrypoint kaseki-report \
605
+ -v /agents/kaseki-results/kaseki-4:/results:ro \
606
+ kaseki-template:latest /results
607
+ ```
608
+
609
+ ### Remote Activation
610
+
611
+ ```bash
612
+ cd /agents/kaseki-agent
613
+
614
+ # Bootstrap remote host via SSH
615
+ ssh pi@host 'curl -fsSL https://raw.githubusercontent.com//main/scripts/kaseki-install.sh | KASEKI_CONTROLLER_MODE=1 sh'
616
+
617
+ # Or locally after cloning
618
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
619
+ ./scripts/kaseki-activate.sh --controller bootstrap
620
+
621
+ # Status check
622
+ ./scripts/kaseki-activate.sh status
623
+
624
+ # Run with task
625
+ TASK_PROMPT='Make the requested change' \
626
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
627
+ ./scripts/kaseki-activate.sh run https://github.com/org/repo main
628
+
629
+ # Inspect mode (no diff required)
630
+ KASEKI_TASK_MODE=inspect \
631
+ TASK_PROMPT='Analyze the repo' \
632
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
633
+ ./scripts/kaseki-activate.sh --json run https://github.com/org/repo main
634
+ ```
635
+
636
+ ### REST API Service
637
+
638
+ ```bash
639
+ # Start service
640
+ KASEKI_API_KEYS=sk-dev npm run kaseki-api
641
+
642
+ # In another terminal:
643
+ curl http://localhost:8080/health
644
+
645
+ curl -H "Authorization: Bearer sk-dev" \
646
+ http://localhost:8080/api/preflight
647
+
648
+ curl -X POST http://localhost:8080/api/runs \
649
+ -H "Authorization: Bearer sk-dev" \
650
+ -H "Content-Type: application/json" \
651
+ -d '{"repoUrl":"https://github.com/org/repo","taskPrompt":"Fix bug"}'
652
+ ```
653
+
654
+ ---
655
+
656
+ ## Deploying the Kaseki API Service
657
+
658
+ ### ✅ Recommended: Docker Compose
659
+
660
+ ```bash
661
+ cd /agents/kaseki-template
662
+
663
+ # Build image
664
+ docker build -t kaseki-agent:latest .
665
+
666
+ # Set API key and start
667
+ export KASEKI_API_KEYS=sk-your-secret-key
668
+ docker-compose up -d
669
+
670
+ # Monitor logs
671
+ docker-compose logs -f kaseki-api
672
+
673
+ # Stop services
674
+ docker-compose down
675
+ ```
676
+
677
+ **Features:**
678
+
679
+ - Health checks included
680
+ - Authenticated `/api/preflight` controller readiness diagnostics
681
+ - Log aggregation
682
+ - Volume management for results
683
+ - Automatic restart on host reboot
684
+
685
+ ### Alternative: systemd Service
686
+
687
+ ```bash
688
+ # 1. Install service file
689
+ sudo cp scripts/kaseki-api.service /etc/systemd/system/
690
+
691
+ # 2. Create environment file
692
+ sudo mkdir -p /etc/kaseki-api
693
+ sudo tee /etc/kaseki-api/kaseki-api.env << EOF
694
+ KASEKI_API_KEYS=sk-your-secret-key
695
+ KASEKI_API_PORT=8080
696
+ KASEKI_RESULTS_DIR=/agents/kaseki-results
697
+ EOF
698
+ sudo chmod 600 /etc/kaseki-api/kaseki-api.env
699
+
700
+ # 3. Start service
701
+ sudo systemctl enable kaseki-api
702
+ sudo systemctl start kaseki-api
703
+
704
+ # 4. Monitor
705
+ sudo journalctl -u kaseki-api -f
706
+ ```
707
+
708
+ ### Fallback: Node.js Process
709
+
710
+ ```bash
711
+ npm install
712
+ KASEKI_API_KEYS=sk-your-secret-key npm run kaseki-api
713
+ ```
714
+
715
+ **Full deployment options:** See [docs/DEPLOYMENT.md](docs/DEPLOYMENT.md)
716
+
717
+ ---
718
+
719
+ ## TypeScript Debt Status
720
+
721
+ Full-project TypeScript checks (`npm run type-check` / `npm run type-check:full`) may surface known unrelated errors while debt burn-down is in progress.
722
+
723
+ For pull requests, `npm run type-check:changed` is the blocking gate.
724
+
725
+ Track and prioritize debt items in [docs/BACKLOG.md](docs/BACKLOG.md).
726
+
727
+ ---
728
+
729
+ ## Required Host Dependencies
730
+
731
+ `run-kaseki.sh` and `kaseki-activate.sh` validate host binaries via preflight check.
732
+
733
+ **Required:**
734
+
735
+ - `docker`
736
+
737
+ **Optional (validated and reported in `--doctor`):**
738
+
739
+ - `wget`
740
+ - `sshpass`
741
+ - `git`
742
+ - `node`
743
+ - `npm`
744
+
745
+ ### Installation
746
+
747
+ **Debian/Ubuntu/Raspberry Pi OS:**
748
+
749
+ ```bash
750
+ sudo apt update
751
+ sudo apt install -y wget sshpass docker.io git nodejs npm
752
+ sudo usermod -aG docker $USER && newgrp docker
753
+ ```
754
+
755
+ **Fedora/RHEL/CentOS Stream:**
756
+
757
+ ```bash
758
+ sudo dnf install -y wget sshpass docker git nodejs npm
759
+ sudo usermod -aG docker $USER && newgrp docker
760
+ ```
761
+
762
+ **Arch Linux:**
763
+
764
+ ```bash
765
+ sudo pacman -S --needed wget sshpass docker git nodejs npm
766
+ sudo usermod -aG docker $USER && newgrp docker
767
+ ```
768
+
769
+ ---
770
+
771
+ ## Host Logging and Log Rotation
772
+
773
+ Kaseki scripts support mirrored host logs via `KASEKI_LOG_DIR` (default: `/var/log/kaseki`):
774
+
775
+ - `run-kaseki.sh` writes `run-kaseki-<instance>-<timestamp>.log`
776
+ - `kaseki-activate.sh` writes `kaseki-activate-<timestamp>.log`
777
+ - `deploy-pi-template.sh` writes `deploy-pi-template-<timestamp>.log`
778
+ - `cleanup-kaseki.sh` writes `cleanup-kaseki-<timestamp>.log`
779
+ - `kaseki-healthcheck.sh` writes a JSON heartbeat file (`/var/log/kaseki/heartbeat.json`)
780
+ - `kaseki-agent.sh` keeps `/results/stdout.log` and `/results/stderr.log` in container artifacts
781
+
782
+ ### Recommended Host Setup
783
+
784
+ ```bash
785
+ sudo mkdir -p /var/log/kaseki
786
+ sudo chown root:adm /var/log/kaseki
787
+ sudo chmod 0750 /var/log/kaseki
788
+ ```
789
+
790
+ ### Strict Mode
791
+
792
+ Set `KASEKI_STRICT_HOST_LOGGING=1` to fail fast when `KASEKI_LOG_DIR` cannot be created or written. Leave unset (or `0`) for graceful degradation.
793
+
794
+ ### Log Rotation
795
+
796
+ ```bash
797
+ sudo install -m 0644 /agents/kaseki-template/ops/logrotate/kaseki /etc/logrotate.d/kaseki
798
+ sudo logrotate -d /etc/logrotate.d/kaseki
799
+ ```
800
+
801
+ ---
802
+
803
+ ## Heartbeat Healthcheck
804
+
805
+ Use `kaseki-healthcheck.sh` to write a single JSON heartbeat object per run:
806
+
807
+ ```bash
808
+ # Write to default target
809
+ /agents/kaseki-template/kaseki-healthcheck.sh
810
+
811
+ # Custom file
812
+ KASEKI_HEARTBEAT_FILE=/tmp/kaseki-heartbeat.json /agents/kaseki-template/kaseki-healthcheck.sh
813
+
814
+ # Disable container status check
815
+ KASEKI_HEALTHCHECK_CONTAINERS=0 /agents/kaseki-template/kaseki-healthcheck.sh
816
+ ```
817
+
818
+ ### Cron Setup
819
+
820
+ ```cron
821
+ */5 * * * * /agents/kaseki-template/kaseki-healthcheck.sh >/dev/null 2>&1
822
+ ```
823
+
824
+ ### systemd Timer
825
+
826
+ ```ini
827
+ # /etc/systemd/system/kaseki-healthcheck.service
828
+ [Unit]
829
+ Description=Kaseki heartbeat healthcheck
830
+
831
+ [Service]
832
+ Type=oneshot
833
+ ExecStart=/agents/kaseki-template/kaseki-healthcheck.sh
834
+ ```
835
+
836
+ ```ini
837
+ # /etc/systemd/system/kaseki-healthcheck.timer
838
+ [Unit]
839
+ Description=Run Kaseki heartbeat healthcheck every 5 minutes
840
+
841
+ [Timer]
842
+ OnBootSec=2min
843
+ OnUnitActiveSec=5min
844
+ Unit=kaseki-healthcheck.service
845
+
846
+ [Install]
847
+ WantedBy=timers.target
848
+ ```
849
+
850
+ ```bash
851
+ sudo systemctl daemon-reload
852
+ sudo systemctl enable --now kaseki-healthcheck.timer
853
+ ```
854
+
855
+ ---
856
+
857
+ ## Image Registries
858
+
859
+ **Docker Hub** (recommended):
860
+
861
+ ```bash
862
+ docker pull docker.io/:latest
863
+ ```
864
+
865
+ **GitHub Container Registry**:
866
+
867
+ ```bash
868
+ docker pull ghcr.io/:latest
869
+ ```
870
+
871
+ Both are equivalent and receive identical multi-architecture builds for `linux/amd64` and `linux/arm64`.
872
+
873
+ ### Releasing a New Version
874
+
875
+ Releases are fully automated using **semantic-release** and **conventional commits**. Versions are determined automatically based on commit messages.
876
+
877
+ **Prerequisites:**
878
+
879
+ - All recent commits on `main` follow [conventional commit](CONTRIBUTING.md#6-release-process-and-conventional-commits) format (`feat:`, `fix:`, `chore:`, etc.)
880
+ - CI/CD checks are passing on `main`
881
+
882
+ **Release via GitHub Actions (Recommended):**
883
+
884
+ 1. Go to the [Actions](https://github.com/CyanAutomation/kaseki-agent/actions) tab → **Release** workflow
885
+ 2. Click **Run workflow**
886
+ 3. Optionally check "Dry-run" to preview without creating tags
887
+ 4. Click **Run workflow**
888
+ 5. The workflow automatically:
889
+ - Analyzes commits since last release
890
+ - Determines version bump (major/minor/patch)
891
+ - Updates `package.json` and `CHANGELOG.md`
892
+ - Creates GitHub Release with release notes
893
+ - Triggers Docker multi-arch builds and publishes to registries
894
+ 6. Monitor in Actions tab; verify in [Releases](https://github.com/CyanAutomation/kaseki-agent/releases)
895
+
896
+ **Release via Local Command (Alternative):**
897
+
898
+ ```bash
899
+ npm run release:dry # Preview (optional)
900
+ npm run release # Create release
901
+ ```
902
+
903
+ See [CONTRIBUTING.md § Release Process](CONTRIBUTING.md#6-release-process-and-conventional-commits) for detailed commit format guidelines and options.
904
+
905
+ ### Tag Publishing Schedule
906
+
907
+ - **Stable version tags** (e.g., `0.1.0`): Published once via version tag push; never overwritten
908
+ - **`latest` tag**: Updated on every merge to `main`, every version push, and weekly Sunday 00:00 UTC
909
+ - **Commit tags** (e.g., `main-3278b67abcd1`): Published on every merge to `main`
910
+
911
+ **Production guidance:** Pin a stable tag once verified, or use a `main-<sha>` tag for reproducibility.
912
+
913
+ ### Local Fallback Build
914
+
915
+ ```bash
916
+ cd /agents/kaseki-template
917
+ docker build -t kaseki-template:latest .
918
+ KASEKI_IMAGE=kaseki-template:latest OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key ./run-kaseki.sh --doctor
919
+ ```
920
+
921
+ For readable logs over SSH on a Pi:
922
+
923
+ ```bash
924
+ docker build --progress=plain -t kaseki-template:latest .
925
+ ```
926
+
927
+ ---
928
+
929
+ ## Deployment and Installation
930
+
931
+ ### Deploy to Host Template Directory
932
+
933
+ Use `scripts/deploy-pi-template.sh` to idempotently install the runnable Kaseki template on a host:
934
+
935
+ ```bash
936
+ cd /path/to/kaseki-agent
937
+ sudo ./scripts/deploy-pi-template.sh
938
+
939
+ # Optional: override destination (must match guardrails: under /agents/ or $HOME/)
940
+ sudo KASEKI_TEMPLATE_DIR=~/kaseki-template ./scripts/deploy-pi-template.sh
941
+ ```
942
+
943
+ **Guardrails:**
944
+
945
+ - Destination must end with `kaseki-template` and be under `/agents/` or `$HOME/`
946
+ - Existing `run`, `result`, `cache`, and `secrets` directories are preserved
947
+ - Destination root is deleted and recreated before install
948
+
949
+ **Workflow:**
950
+
951
+ 1. Pulls `KASEKI_IMAGE` by default
952
+ 2. Verifies image contains `/app` template
953
+ 3. Falls back to building from current checkout if registry image is stale or unavailable
954
+ 4. Records selected image and digest in `.kaseki-image` and `.kaseki-image-digest`
955
+ `.kaseki-image` preserves the configured ref such as `docker.io/cyanautomation/kaseki-agent:latest`,
956
+ while `.kaseki-image-digest` records the resolved local digest when Docker provides one.
957
+
958
+ **Offline deployment:**
959
+
960
+ ```bash
961
+ # For Raspberry Pi (avoid builds)
962
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING=0 sudo ./scripts/deploy-pi-template.sh
963
+
964
+ # Reuse existing local image
965
+ KASEKI_IMAGE_PULL_POLICY=missing sudo ./scripts/deploy-pi-template.sh
966
+
967
+ # Offline only
968
+ KASEKI_IMAGE_PULL_POLICY=never sudo ./scripts/deploy-pi-template.sh
969
+
970
+ # Dockhand / Portainer style
971
+ KASEKI_IMAGE=docker.io/cyanautomation/kaseki-agent:latest \
972
+ KASEKI_IMAGE_PULL_POLICY=always sudo ./scripts/deploy-pi-template.sh
973
+ ```
974
+
975
+ ---
976
+
977
+ ## Monitoring Kaseki Runs
978
+
979
+ ### Live CLI (No Host Node.js Required)
980
+
981
+ ```bash
982
+ # List all runs
983
+ /agents/kaseki-template/kaseki list
984
+
985
+ # Get status of specific run
986
+ /agents/kaseki-template/kaseki status kaseki-1
987
+
988
+ # Get comprehensive analysis
989
+ /agents/kaseki-template/kaseki analysis kaseki-1
990
+
991
+ # Follow progress logs
992
+ /agents/kaseki-template/kaseki follow kaseki-4 --tail=50
993
+
994
+ # Show sanitized progress
995
+ /agents/kaseki-template/kaseki progress kaseki-4 --tail=25
996
+ ```
997
+
998
+ The `kaseki` wrapper runs the Node-based CLI inside the configured Kaseki Docker image and mounts `/agents/kaseki-results` read-only.
999
+
1000
+ ### Diagnostic Report
1001
+
1002
+ ```bash
1003
+ docker run --rm --entrypoint kaseki-report \
1004
+ -v /agents/kaseki-results/kaseki-4:/results:ro \
1005
+ kaseki-template:latest \
1006
+ /results
1007
+ ```
1008
+
1009
+ Includes:
1010
+
1011
+ - Status and exit code
1012
+ - Failed command and detail
1013
+ - Model and duration
1014
+ - Stage timings and validation timings
1015
+ - Dependency cache status
1016
+ - Changed files and secret-scan status
1017
+ - Recommended next diagnostic artifact to inspect
1018
+
1019
+ ---
1020
+
1021
+ ## Metrics Export
1022
+
1023
+ `run-kaseki.sh` writes a stable metrics artifact at the end of each run:
1024
+
1025
+ - `$RESULT_DIR/metrics.json` (schema `kaseki.metrics.v1`)
1026
+ - Optional centralized stream: `/var/log/kaseki/metrics.jsonl`
1027
+
1028
+ ### Generate Metrics Manually
1029
+
1030
+ ```bash
1031
+ ./kaseki-metrics.sh /agents/kaseki-results/kaseki-4/stage-timings.tsv \
1032
+ /agents/kaseki-results/kaseki-4/metadata.json \
1033
+ /agents/kaseki-results/kaseki-4/metrics.json
1034
+ ```
1035
+
1036
+ ### Aggregation Examples
1037
+
1038
+ ```bash
1039
+ # Inspect one run
1040
+ jq . /agents/kaseki-results/kaseki-4/metrics.json
1041
+
1042
+ # Aggregate JSONL by repo
1043
+ jq -s 'group_by(.repo_url) | map({repo_url: .[0].repo_url, runs: length, total_runtime_seconds: (map(.total_runtime_seconds // 0) | add)})' /var/log/kaseki/metrics.jsonl
1044
+
1045
+ # Prometheus textfile bridge
1046
+ jq -r '"kaseki_total_runtime_seconds{instance=\"" + (.instance // "unknown") + "\"} " + ((.total_runtime_seconds // 0)|tostring)' /agents/kaseki-results/kaseki-4/metrics.json > /var/lib/node_exporter/textfile_collector/kaseki.prom
1047
+ ```
1048
+
1049
+ ---
1050
+
1051
+ ## Host Readiness Check
1052
+
1053
+ Run the doctor command before first use or after host changes:
1054
+
1055
+ ```bash
1056
+ /agents/kaseki-template/run-kaseki.sh --doctor
1057
+ ```
1058
+
1059
+ Run doctor from the deployed template directory, not directly from a source-only
1060
+ checkout. The deployed template includes generated `lib/*.js` helper payloads
1061
+ extracted from the Docker image.
1062
+
1063
+ Checks:
1064
+
1065
+ - Docker availability and daemon accessibility
1066
+ - Writable run/result directories
1067
+ - Image presence and readiness
1068
+ - OpenRouter key availability
1069
+ - Host script/image parity
1070
+
1071
+ ### Verify API Key (Non-Exposing)
1072
+
1073
+ ```bash
1074
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
1075
+ KASEKI_VERIFY_OPENROUTER_AUTH=1 \
1076
+ /agents/kaseki-template/run-kaseki.sh --doctor
1077
+ ```
1078
+
1079
+ ---
1080
+
1081
+ ## GitHub App Integration (Optional)
1082
+
1083
+ Kaseki can automatically push changes and create draft pull requests using a GitHub App.
1084
+ Use file-mounted secrets for the private key. It is acceptable to provide the App ID
1085
+ and Client ID as environment variables, but production deployments should keep all
1086
+ three values in files or Docker secrets and pass only `*_FILE` paths through the
1087
+ container environment.
1088
+
1089
+ ### Prerequisites
1090
+
1091
+ 1. Create a GitHub App with:
1092
+ - `contents: read & write`
1093
+ - `pull_requests: read & write`
1094
+ - `workflows: read` (optional)
1095
+
1096
+ 2. Generate a private key and save locally
1097
+
1098
+ 3. Install the app on the target repository
1099
+
1100
+ ### Setup
1101
+
1102
+ ```bash
1103
+ mkdir -p ~/secrets
1104
+ chmod 0700 ~/secrets
1105
+
1106
+ echo "YOUR_APP_ID" > ~/secrets/github_app_id
1107
+ echo "YOUR_CLIENT_ID" > ~/secrets/github_client_id
1108
+ cp ~/path/to/private-key.pem ~/secrets/github_app_private_key
1109
+ chmod 0600 ~/secrets/github_app_*
1110
+ ```
1111
+
1112
+ ### Usage
1113
+
1114
+ ```bash
1115
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
1116
+ GITHUB_APP_ID_FILE=~/secrets/github_app_id \
1117
+ GITHUB_APP_CLIENT_ID_FILE=~/secrets/github_client_id \
1118
+ GITHUB_APP_PRIVATE_KEY_FILE=~/secrets/github_app_private_key \
1119
+ /agents/kaseki-template/run-kaseki.sh https://github.com/org/repo
1120
+ ```
1121
+
1122
+ For Docker Compose or Dockhand deployments, mount the secret files under `/agents`
1123
+ and pass paths rather than embedding the PEM in `.env`:
1124
+
1125
+ ```yaml
1126
+ environment:
1127
+ GITHUB_APP_ID_FILE: /agents/secrets/github_app_id
1128
+ GITHUB_APP_CLIENT_ID_FILE: /agents/secrets/github_client_id
1129
+ GITHUB_APP_PRIVATE_KEY_FILE: /agents/secrets/github_app_private_key
1130
+ volumes:
1131
+ - /agents:/agents:rw
1132
+ ```
1133
+
1134
+ `GITHUB_APP_PRIVATE_KEY` is still accepted as a fallback for local experiments,
1135
+ including escaped `\n` or single-line PEM values, but avoid it for shared hosts:
1136
+ environment variables are easier to leak through process inspection, logs, and
1137
+ orchestration UIs.
1138
+
1139
+ ### Behavior
1140
+
1141
+ When credentials are configured and publishing is enabled:
1142
+
1143
+ 1. After validation passes and diff is non-empty, Kaseki generates a GitHub App installation token
1144
+ 2. Creates a feature branch `kaseki/<instance-name>`
1145
+ 3. Commits and pushes changes to remote
1146
+ 4. Creates a draft PR against the target branch when `KASEKI_PUBLISH_MODE=draft_pr` or API `publishMode` is `draft_pr`, with:
1147
+ - Title: `Kaseki: <instance-name>`
1148
+ - Body: Model, duration, validation result, quality checks
1149
+ - Draft: `true` for safety; review before merging
1150
+
1151
+ Publishing modes are `none`, `branch`, and `draft_pr`. Controller requests that
1152
+ ask for `branch` or `draft_pr` fail before queueing unless GitHub App credentials
1153
+ are readable, so orchestrators can surface a clear setup error instead of waiting
1154
+ for a run that cannot publish.
1155
+
1156
+ ### Result Artifacts
1157
+
1158
+ - `git-push.log`: Detailed log of push and PR creation
1159
+ - `metadata.json` includes:
1160
+ - `github_pr_url`: URL of created PR (if successful)
1161
+ - `github_push_exit_code`: Push operation status
1162
+ - `github_pr_exit_code`: PR creation status
1163
+
1164
+ ---
1165
+
1166
+ ## Environment Variables Reference
1167
+
1168
+ ### Core Configuration
1169
+
1170
+ | Variable | Default | Notes |
1171
+ |---|---|---|
1172
+ | `OPENROUTER_API_KEY` | — | Required (or use file) |
1173
+ | `OPENROUTER_API_KEY_FILE` | `/run/secrets/openrouter_api_key` | Preferred; mounted read-only |
1174
+ | `REPO_URL` | CyanAutomation/crudmapper | Target repository |
1175
+ | `GIT_REF` | main | Branch/tag/commit |
1176
+
1177
+ ### Model and Execution
1178
+
1179
+ | Variable | Default | Notes |
1180
+ |---|---|---|
1181
+ | `KASEKI_MODEL` | openrouter/free | Pi model string |
1182
+ | `KASEKI_AGENT_TIMEOUT_SECONDS` | 1200 | Agent timeout (20 min) |
1183
+ | `TASK_PROMPT` | *(code fix task)* | Agent instructions |
1184
+ | `KASEKI_TASK_MODE` | patch | `patch` (require diff) or `inspect` (no diff) |
1185
+ | `KASEKI_PUBLISH_MODE` | auto | `none`, `branch`, or `draft_pr`; API requests use `publishMode` |
1186
+
1187
+ ### Validation and Quality Gates
1188
+
1189
+ | Variable | Default | Notes |
1190
+ |---|---|---|
1191
+ | `KASEKI_VALIDATION_COMMANDS` | `npm run check;npm run test;npm run build` | Semicolon-separated; set to `none` to skip. Missing npm scripts are skipped with a warning (non-fatal). |
1192
+ | `KASEKI_CHANGED_FILES_ALLOWLIST` | `src/lib/parser.ts tests/parser.validation.ts` | Space-separated patterns |
1193
+ | `KASEKI_MAX_DIFF_BYTES` | 200000 | Max diff size (200 KB) |
1194
+ | `KASEKI_ALLOW_EMPTY_DIFF` | 0 | Set to `1` to allow empty diff with `KASEKI_TASK_MODE=patch` |
1195
+ | `KASEKI_AGENT_GUARDRAILS` | 1 | Prepend safety instructions that reserve commit/push/PR actions for Kaseki |
1196
+ | `KASEKI_RESTORE_DISALLOWED_CHANGES` | 1 | Restore changes outside `KASEKI_CHANGED_FILES_ALLOWLIST` before validation and GitHub publishing |
1197
+ | `KASEKI_NPM_OMIT_DEV` | 0 | Set to `1` to omit dev dependencies during `npm ci`; default keeps test/build tools available |
1198
+
1199
+ `KASEKI_CHANGED_FILES_ALLOWLIST` patterns are repo-relative globs. Exact paths match only that path; `*` and `?` match within a single path segment; `**` can span directory separators. A `**/` segment may match zero or more directories, so `src/**/*.ts` matches both `src/index.ts` and nested files such as `src/lib/file-storage.ts`.
1200
+
1201
+ API controllers may send either the direct fields (`changedFilesAllowlist`, `validationCommands`) or the structured aliases (`allowlist.include`, `validation.commands`). The scheduler normalizes both forms before launching the worker.
1202
+
1203
+ ### Paths and Caching
1204
+
1205
+ | Variable | Default | Notes |
1206
+ |---|---|---|
1207
+ | `KASEKI_ROOT` | `/agents` | Base directory for runs, results, cache |
1208
+ | `KASEKI_DEPENDENCY_CACHE_DIR` | `/workspace/.kaseki-cache` | Workspace dependency cache, keyed as `npm/<lock_hash>/node-<major>/flags-<flags_hash>` |
1209
+ | `KASEKI_IMAGE_DEPENDENCY_CACHE_DIR` | `/opt/kaseki/workspace-cache` | Image-provided seed cache using the same lockfile-first key layout |
1210
+ | `KASEKI_GIT_CACHE_MODE` | `mirror` | Git object cache mode: `mirror` uses host-mounted bare mirrors under `/cache/git`; `off` keeps the direct shallow clone path |
1211
+ | `KASEKI_REPO_MEMORY_MODE` | `off` | Opt-in repository prompt memory: `off` disables it; `summary` appends a compact prior-context summary when fresh |
1212
+ | `KASEKI_REPO_MEMORY_TTL_DAYS` | `30` | Maximum age for a repository memory summary before it is ignored |
1213
+ | `KASEKI_REPO_MEMORY_MAX_BYTES` | `8000` | Maximum bytes to read/write for the repository memory prompt section |
1214
+
1215
+ ### Docker and Images
1216
+
1217
+ | Variable | Default | Notes |
1218
+ |---|---|---|
1219
+ | `KASEKI_IMAGE` | `docker.io/cyanautomation/kaseki-agent:latest` | Docker image to use |
1220
+ | `KASEKI_CONTAINER_USER` | `$(id -u):$(id -g)` | UID:GID for container process |
1221
+ | `KASEKI_PROVIDER` | `openrouter` | LLM provider |
1222
+
1223
+ ### Debugging and Logging
1224
+
1225
+ | Variable | Default | Notes |
1226
+ |---|---|---|
1227
+ | `KASEKI_DEBUG_RAW_EVENTS` | 0 | Keep raw Pi JSONL as `pi-events.raw.jsonl` |
1228
+ | `KASEKI_STREAM_PROGRESS` | 1 | Stream sanitized progress lines |
1229
+ | `KASEKI_LOG_DIR` | `/var/log/kaseki` | Host log mirror directory |
1230
+ | `KASEKI_STRICT_HOST_LOGGING` | 0 | Fail fast if logs can't be written |
1231
+ | `KASEKI_KEEP_WORKSPACE` | 0 | Keep workspace after run (set `1` for debugging) |
1232
+ | `KASEKI_VALIDATE_AFTER_AGENT_FAILURE` | 0 | Run validation even if agent fails |
1233
+
1234
+ ### API Service
1235
+
1236
+ | Variable | Default | Notes |
1237
+ |---|---|---|
1238
+ | `KASEKI_API_KEYS` | — | Comma-separated API keys (required for service) |
1239
+ | `KASEKI_API_PORT` | 8080 | HTTP listen port |
1240
+ | `KASEKI_API_LOG_LEVEL` | info | Log verbosity: debug/info/warn/error |
1241
+ | `KASEKI_API_MAX_CONCURRENT_RUNS` | 3 | Max concurrent jobs |
1242
+ | `KASEKI_RESULTS_DIR` | `/agents/kaseki-results` | Results artifact directory |
1243
+ | `GITHUB_APP_ID_FILE` | — | Path to file containing GitHub App ID for PR creation |
1244
+ | `GITHUB_APP_CLIENT_ID_FILE` | — | Path to file containing GitHub App Client ID |
1245
+ | `GITHUB_APP_PRIVATE_KEY_FILE` | — | Path to GitHub App private key file; preferred over inline private key env |
1246
+
1247
+ ### Metrics
1248
+
1249
+ | Variable | Default | Notes |
1250
+ |---|---|---|
1251
+ | `KASEKI_APPEND_METRICS_JSONL` | 1 | Append metrics to centralized JSONL stream |
1252
+ | `KASEKI_METRICS_JSONL_PATH` | `/var/log/kaseki/metrics.jsonl` | Centralized metrics stream |
1253
+
1254
+ ---
1255
+
1256
+ ## Exit Codes
1257
+
1258
+ Kaseki uses specific non-zero exit codes for diagnostic purposes:
1259
+
1260
+ | Code | Reason |
1261
+ |---|---|
1262
+ | 0 | Success |
1263
+ | 2 | Missing required configuration (e.g., `OPENROUTER_API_KEY`) or invalid instance format |
1264
+ | 3 | Empty git diff (no changes made by agent). Set `KASEKI_TASK_MODE=inspect` or `KASEKI_ALLOW_EMPTY_DIFF=1` when expected |
1265
+ | 4 | Diff exceeds `KASEKI_MAX_DIFF_BYTES` |
1266
+ | 5 | Changed file outside `KASEKI_CHANGED_FILES_ALLOWLIST` |
1267
+ | 6 | Secret scan detected credential-like content |
1268
+ | 7 | GitHub push/PR setup failed (missing credentials, invalid key, etc.) |
1269
+ | 8 | Failed to push branch to GitHub |
1270
+ | 9 | Push succeeded but PR creation failed (non-blocking; push result retained) |
1271
+ | 124 | Agent timeout (SIGTERM after `KASEKI_AGENT_TIMEOUT_SECONDS`) |
1272
+
1273
+ Other non-zero codes may propagate from failed steps (clone, install, agent run, validation). Check `/results/metadata.json` for `failed_command` and details.
1274
+
1275
+ ---
1276
+
1277
+ ## Container Healthcheck
1278
+
1279
+ The image defines a `HEALTHCHECK`:
1280
+
1281
+ ```dockerfile
1282
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
1283
+ CMD test -f /results/stdout.log && test -f /results/stderr.log
1284
+ ```
1285
+
1286
+ - `/results` is created in the image and again at runtime by `kaseki-agent.sh`
1287
+ - Container is **healthy** after runner initializes result logs
1288
+ - Run completion is tracked by `/results/exit_code`
1289
+
1290
+ ---
1291
+
1292
+ ## Cleanup
1293
+
1294
+ ### Workspace Cleanup
1295
+
1296
+ Remove old per-run workspaces while keeping results:
1297
+
1298
+ ```bash
1299
+ KASEKI_CLEANUP_DAYS=1 /agents/kaseki-template/cleanup-kaseki.sh
1300
+ ```
1301
+
1302
+ ### Docker Cleanup
1303
+
1304
+ Explicit and guarded. Use `--dry-run` first:
1305
+
1306
+ ```bash
1307
+ /agents/kaseki-template/cleanup-kaseki.sh --docker --dry-run
1308
+ /agents/kaseki-template/cleanup-kaseki.sh --docker --force
1309
+ ```
1310
+
1311
+ Prunes old Docker build cache and dangling images.
1312
+
1313
+ ---
1314
+
1315
+ ## Help and Usage
1316
+
1317
+ View the full usage guide:
1318
+
1319
+ ```bash
1320
+ /agents/kaseki-template/run-kaseki.sh --help
1321
+ ```
1322
+
1323
+ Displays all invocation patterns, argument descriptions, environment variables, and examples.
1324
+
1325
+ ---
1326
+
1327
+ ## Git Object Cache Behavior
1328
+
1329
+ `kaseki-agent.sh` can reuse host-mounted Git object caches before dependency installation:
1330
+
1331
+ 1. Build a safe cache key from `REPO_URL` and store the bare mirror at `/cache/git/<repo-key>.git`.
1332
+ 2. Serialize mirror population and updates with `flock` on a per-repository lock file.
1333
+ 3. On cache hit, refresh the mirror with `git -C <mirror> fetch --prune --tags origin` under a timeout.
1334
+ 4. Clone `/workspace/repo` with `git clone --reference-if-able <mirror> --depth 1 --branch "$GIT_REF" "$REPO_URL" /workspace/repo`.
1335
+ 5. If the reference clone cannot be used, try cloning from the mirror and then reset the workspace origin back to `REPO_URL`.
1336
+ 6. If the mirror is disabled, unavailable, corrupt, or cannot be refreshed/populated, fall back to the existing direct shallow clone.
1337
+
1338
+ Set `KASEKI_GIT_CACHE_MODE=off` to disable Git mirror caching. Clone duration plus cache mode/status/hit/key/strategy data are emitted to `stage-timings.tsv`, `progress.jsonl`, and `metadata.json`.
1339
+
1340
+ ### Repository Memory Cache
1341
+
1342
+ Repository memory is disabled by default. Set `KASEKI_REPO_MEMORY_MODE=summary` to opt in to a compact prompt-context cache for the target repository and ref. Kaseki stores this summary at `/cache/repo-memory/<repo-key>/summary.md`, where `<repo-key>` is derived from the repository URL and default ref. Before invoking the agent, Kaseki appends a clearly labeled “Prior repository context” section only when the summary exists, is within `KASEKI_REPO_MEMORY_TTL_DAYS`, and is no larger than `KASEKI_REPO_MEMORY_MAX_BYTES`.
1343
+
1344
+ After a successful run, or an inspect-mode run where the agent completed and the secret scan passed, Kaseki rewrites the summary from bounded, sanitized artifacts: `result-summary.md`, `analysis.md`, `changed-files.txt`, and validation timing/status outcomes. The summary records the repo URL, default ref, commit SHA, and timestamp so stale context is visible to the next agent. Kaseki does not blindly persist raw logs or user prompts, and lines resembling secrets, credentials, API keys, tokens, or prompt text are filtered out before writing memory.
1345
+
1346
+ This memory is an efficiency feature, not an authoritative source of truth. Agents should use it only as hints and must inspect the current repository state before relying on prior context.
1347
+
1348
+ ---
1349
+
1350
+ ## Dependency Install Behavior
1351
+
1352
+ `kaseki-agent.sh` prepares dependencies in this order:
1353
+
1354
+ 1. Skip if no `package.json`
1355
+ 2. Skip if `node_modules` exists and the external dependency stamp matches the lock hash
1356
+ 3. Try workspace cache hit at `$KASEKI_DEPENDENCY_CACHE_DIR/npm/<lock_hash>/node-<major>/flags-<flags_hash>/node_modules`
1357
+ 4. Try image seed cache hit at `$KASEKI_IMAGE_DEPENDENCY_CACHE_DIR/npm/<lock_hash>/node-<major>/flags-<flags_hash>/node_modules`
1358
+ 5. Refresh with `npm ci --prefer-offline` plus the active install-mode flags
1359
+ 6. Atomically publish `node_modules` back to the workspace cache for reuse
1360
+
1361
+ The primary cache boundary is lockfile-first: `npm/<lock_hash>/node-<major>/flags-<flags_hash>`. The `flags_hash` covers install-mode switches such as `KASEKI_NPM_OMIT_DEV` and `KASEKI_INSTALL_IGNORE_SCRIPTS`, so incompatible installs do not share `node_modules`. Repo/ref information is recorded as metadata in cache logs and `repo-ref-metadata.tsv`, but it is not part of the reuse key; two refs with the same lockfile, Node major version, and install flags can reuse the same dependency cache path.
1362
+
1363
+ The dependency stamp is stored outside the repo, so git status/diff remain focused on target changes.
1364
+
1365
+ ---
1366
+
1367
+ ## Running Against a Custom Repo
1368
+
1369
+ ### Method 1: CLI Arguments (Recommended)
1370
+
1371
+ ```bash
1372
+ # Custom repo, auto git-ref
1373
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
1374
+ ./run-kaseki.sh https://github.com/org/repo
1375
+
1376
+ # Custom repo and branch
1377
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
1378
+ ./run-kaseki.sh https://github.com/org/repo feature/my-branch
1379
+
1380
+ # Custom repo, ref, and explicit instance
1381
+ OPENROUTER_API_KEY_FILE=~/secrets/openrouter_api_key \
1382
+ ./run-kaseki.sh https://github.com/org/repo develop kaseki-42
1383
+ ```
1384
+
1385
+ Arguments are parsed intelligently:
1386
+
1387
+ - Strings with `/` or `.git` → repo URLs
1388
+ - Short strings (`main`, `v1.0.0`) → Git refs
1389
+ - Strings matching `kaseki-N` → explicit instance names
1390
+ - Unspecified → auto-generated
1391
+
1392
+ ### Method 2: Environment Variables (Legacy)
1393
+
1394
+ ```bash
1395
+ OPENROUTER_API_KEY=... REPO_URL=https://github.com/org/repo GIT_REF=feature/branch ./run-kaseki.sh
1396
+ ```
1397
+
1398
+ **Note:** CLI arguments take precedence over environment variables.
1399
+
1400
+ ---
1401
+
1402
+ ## Useful Links
1403
+
1404
+ - **[API Reference](docs/API.md)** — Complete REST endpoint specifications
1405
+ - **[Deployment Guide](docs/DEPLOYMENT.md)** — systemd, Docker, docker-compose setup
1406
+ - **[Integration Example](docs/INTEGRATION_EXAMPLE.md)** — Real-world usage with TypeScript client
1407
+ - **[CLI Reference](docs/CLI.md)** — Live monitoring CLI (`kaseki` wrapper)
1408
+ - **[Backlog](docs/BACKLOG.md)** — Known TypeScript debt and planned improvements
1409
+
1410
+ ---
1411
+
1412
+ ## Getting Help
1413
+
1414
+ ### Run a Health Check
1415
+
1416
+ ```bash
1417
+ ./run-kaseki.sh --doctor
1418
+ ```
1419
+
1420
+ ### Inspect a Completed Run
1421
+
1422
+ ```bash
1423
+ docker run --rm --entrypoint kaseki-report \
1424
+ -v /agents/kaseki-results/kaseki-4:/results:ro \
1425
+ kaseki-template:latest \
1426
+ /results
1427
+ ```
1428
+
1429
+ ### Check Script Permissions
1430
+
1431
+ If scripts aren't executable:
1432
+
1433
+ ```bash
1434
+ chmod +x run-kaseki.sh kaseki kaseki-agent.sh scripts/*.sh
1435
+ ```
1436
+
1437
+ ### Verify Pi in Image
1438
+
1439
+ ```bash
1440
+ # Docker Hub
1441
+ docker run --rm --entrypoint pi docker.io/cyanautomation/kaseki-agent:latest --version
1442
+
1443
+ # GitHub Container Registry
1444
+ docker run --rm --entrypoint pi ghcr.io/cyanautomation/kaseki-agent:latest --version
1445
+ ```
1446
+
1447
+ ---
1448
+
1449
+ ## Troubleshooting: Too Many Files Restored?
1450
+
1451
+ When you run kaseki with a targeted task, you might see many files being "restored" (reverted) because they fall outside the allowlist. This is expected behavior—but here's how to fix it:
1452
+
1453
+ ### Symptoms
1454
+
1455
+ - Run completes but `restoration-report.md` shows 20+ files were restored
1456
+ - Only a few files were kept in the allowlist
1457
+ - `kaseki-report` shows "Allowlist coverage: 5/25 files (20%)"
1458
+
1459
+ ### Quick Fix: Use a Better Template
1460
+
1461
+ 1. **Check what type of task you're running:**
1462
+ - Fixing a UI component? Use `templates/allowlist-ui-component.txt`
1463
+ - Fixing an API endpoint? Use `templates/allowlist-api-route.txt`
1464
+ - Fixing a utility function? Use `templates/allowlist-utility.txt`
1465
+
1466
+ 2. **Run with the template:**
1467
+
1468
+ ```bash
1469
+ KASEKI_CHANGED_FILES_ALLOWLIST="$(cat templates/allowlist-ui-component.txt | tr '\n' ' ')" ./run-kaseki.sh
1470
+ ```
1471
+
1472
+ ### Deep Dive: Understanding Restoration
1473
+
1474
+ 1. **Look at the restoration report:**
1475
+
1476
+ ```bash
1477
+ cat /agents/kaseki-results/kaseki-N/restoration-report.md
1478
+ ```
1479
+
1480
+ This shows exactly which files were kept vs. restored.
1481
+
1482
+ 2. **Auto-generate a better allowlist:**
1483
+
1484
+ ```bash
1485
+ ./scripts/suggest-allowlist.sh /agents/kaseki-results/kaseki-N
1486
+ ```
1487
+
1488
+ This analyzes what files were actually changed and suggests patterns.
1489
+
1490
+ 3. **Preview before running:**
1491
+
1492
+ ```bash
1493
+ ./scripts/dry-run-allowlist.sh --changed-files /agents/kaseki-results/kaseki-N/changed-files.txt \
1494
+ --allowlist "src/lib/** tests/**"
1495
+ ```
1496
+
1497
+ This shows what WOULD be restored with a given allowlist.
1498
+
1499
+ ### Root Causes
1500
+
1501
+ **Allowlist too narrow:**
1502
+
1503
+ - ❌ `KASEKI_CHANGED_FILES_ALLOWLIST="src/lib/parser.ts"` (single file only)
1504
+ - ✅ `KASEKI_CHANGED_FILES_ALLOWLIST="src/lib/parser.ts tests/**"` (file + tests)
1505
+
1506
+ **TASK_PROMPT too vague:**
1507
+
1508
+ - ❌ "Fix the bug"
1509
+ - ✅ "Fix the null-reference bug in src/lib/parser.ts. Do not modify other files."
1510
+
1511
+ **Task affects multiple files:**
1512
+
1513
+ - Build a better allowlist by running suggest-allowlist.sh
1514
+ - Or use a broader template (allowlist-comprehensive.txt)
1515
+
1516
+ ### More Information
1517
+
1518
+ - Full guide: [docs/QUALITY_GATES.md](docs/QUALITY_GATES.md)
1519
+ - Prompt best practices: [docs/TASK_PROMPT_TEMPLATES.md](docs/TASK_PROMPT_TEMPLATES.md)
1520
+ - Auto-generate patterns: `./scripts/suggest-allowlist.sh <results-dir>`
1521
+ - Preview patterns: `./scripts/dry-run-allowlist.sh --help`
1522
+
1523
+ ---
1524
+
1525
+ ## License and Contributing
1526
+
1527
+ See the repository for contribution guidelines and license information.