@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
@@ -0,0 +1,161 @@
1
+ #!/bin/bash
2
+ # dry-run-allowlist.sh - Preview which files would be restored for a given allowlist
3
+ # Usage: ./scripts/dry-run-allowlist.sh [--changed-files <file>] [--allowlist <pattern>]
4
+ # Example: ./scripts/dry-run-allowlist.sh --changed-files /results/kaseki-1/changed-files.txt
5
+
6
+ set -e
7
+
8
+ CHANGED_FILES=""
9
+ ALLOWLIST="${KASEKI_CHANGED_FILES_ALLOWLIST:-src/lib/parser.ts tests/parser.validation.ts}"
10
+ RESULT_DIR=""
11
+
12
+ # Parse arguments
13
+ while [[ $# -gt 0 ]]; do
14
+ case "$1" in
15
+ --changed-files)
16
+ CHANGED_FILES="$2"
17
+ shift 2
18
+ ;;
19
+ --allowlist)
20
+ ALLOWLIST="$2"
21
+ shift 2
22
+ ;;
23
+ --result-dir|--results)
24
+ RESULT_DIR="$2"
25
+ shift 2
26
+ ;;
27
+ --help)
28
+ cat << 'EOF'
29
+ dry-run-allowlist.sh - Preview which files would be restored for a given allowlist
30
+
31
+ Usage: ./scripts/dry-run-allowlist.sh [OPTIONS]
32
+
33
+ Options:
34
+ --changed-files <file> Path to changed-files.txt (default: /results/changed-files.txt)
35
+ --allowlist <pattern> Allowlist pattern (default: from KASEKI_CHANGED_FILES_ALLOWLIST)
36
+ --result-dir <dir> Result directory (for convenience, auto-finds changed-files.txt)
37
+ --help Show this help message
38
+
39
+ Examples:
40
+ # Preview current results
41
+ ./scripts/dry-run-allowlist.sh --result-dir /results/kaseki-1
42
+
43
+ # Test a custom allowlist
44
+ ./scripts/dry-run-allowlist.sh --allowlist "src/lib/** tests/**" --changed-files /results/kaseki-1/changed-files.txt
45
+
46
+ # Using template
47
+ ./scripts/dry-run-allowlist.sh --allowlist "$(cat templates/allowlist-ui-component.txt | tr '\n' ' ')"
48
+
49
+ EOF
50
+ exit 0
51
+ ;;
52
+ *)
53
+ echo "Unknown option: $1" >&2
54
+ exit 1
55
+ ;;
56
+ esac
57
+ done
58
+
59
+ # Determine changed-files location
60
+ if [ -z "$CHANGED_FILES" ]; then
61
+ if [ -n "$RESULT_DIR" ]; then
62
+ CHANGED_FILES="$RESULT_DIR/changed-files.txt"
63
+ else
64
+ CHANGED_FILES="${KASEKI_RESULTS:-/results}/changed-files.txt"
65
+ fi
66
+ fi
67
+
68
+ if [ ! -f "$CHANGED_FILES" ]; then
69
+ echo "❌ changed-files.txt not found: $CHANGED_FILES" >&2
70
+ exit 1
71
+ fi
72
+
73
+ # Source the allowlist helper
74
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
75
+ ALLOWLIST_HELPER="$SCRIPT_DIR/allowlist-helper.sh"
76
+ if [ ! -r "$ALLOWLIST_HELPER" ]; then
77
+ echo "❌ allowlist-helper.sh not found: $ALLOWLIST_HELPER" >&2
78
+ exit 1
79
+ fi
80
+
81
+ # shellcheck disable=SC1090
82
+ source "$ALLOWLIST_HELPER"
83
+
84
+ # Build regex from allowlist
85
+ allowlist_regex="$(build_allowlist_regex "$ALLOWLIST")"
86
+
87
+ if [ -z "$allowlist_regex" ]; then
88
+ echo "⚠️ Empty allowlist — all files would be restored"
89
+ cat "$CHANGED_FILES"
90
+ exit 0
91
+ fi
92
+
93
+ # Analyze files
94
+ declare -a would_restore
95
+ declare -a would_keep
96
+ total=0
97
+
98
+ while IFS= read -r file || [ -n "$file" ]; do
99
+ [ -z "$file" ] && continue
100
+ total=$((total + 1))
101
+
102
+ if printf '%s\n' "$file" | grep -Eq "^(${allowlist_regex})$"; then
103
+ would_keep+=("$file")
104
+ else
105
+ would_restore+=("$file")
106
+ fi
107
+ done < "$CHANGED_FILES"
108
+
109
+ # Print results
110
+ {
111
+ printf "# Dry-Run Allowlist Preview\n\n"
112
+ printf "Allowlist: \`%s\`\n" "$ALLOWLIST"
113
+ printf "Changed files: %s\n\n" "$CHANGED_FILES"
114
+
115
+ printf '## Summary\n\n'
116
+ printf '- **Total Files:** %d\n' "$total"
117
+ printf '- **Would Keep (matched):** %d\n' "${#would_keep[@]}"
118
+ printf '- **Would Restore (outside):** %d\n' "${#would_restore[@]}"
119
+
120
+ if [ "$total" -gt 0 ]; then
121
+ coverage=$((${#would_keep[@]} * 100 / total))
122
+ printf '- **Coverage:** %d%%\n\n' "$coverage"
123
+ else
124
+ printf '\n'
125
+ fi
126
+
127
+ if [ "${#would_restore[@]}" -gt 0 ]; then
128
+ printf '## Would Be Restored\n\n'
129
+ printf 'These files would NOT pass through to validation:\n\n'
130
+ for file in "${would_restore[@]}"; do
131
+ printf "- \`%s\`\n" "$file"
132
+ done
133
+ printf '\n'
134
+ fi
135
+
136
+ if [ "${#would_keep[@]}" -gt 0 ]; then
137
+ printf '## Would Be Kept\n\n'
138
+ printf 'These files would pass through to validation:\n\n'
139
+ for file in "${would_keep[@]}"; do
140
+ printf "- \`%s\`\n" "$file"
141
+ done
142
+ printf '\n'
143
+ fi
144
+
145
+ printf '## Recommendations\n\n'
146
+ if [ "${#would_restore[@]}" -gt 0 ] && [ "${#would_keep[@]}" -eq 0 ]; then
147
+ printf '⚠️ **ALL files would be restored** — allowlist is too narrow or wrong.\n'
148
+ elif [ "${#would_restore[@]}" -gt 0 ] && [ "$coverage" -lt 30 ]; then
149
+ printf '⚠️ **Low coverage (%d%%)** — consider:\n' "$coverage"
150
+ printf '1. Expanding the allowlist patterns\n'
151
+ printf "2. Using a broader template (e.g., \`allowlist-utility\`)\n"
152
+ printf '3. Reviewing the TASK_PROMPT for clarity\n'
153
+ elif [ "${#would_restore[@]}" -eq 0 ]; then
154
+ printf '✅ **Perfect coverage** — all files match the allowlist.\n'
155
+ else
156
+ printf '✅ **Good coverage** — allowlist looks reasonable.\n'
157
+ fi
158
+ } | tee /tmp/dry-run-allowlist-preview.md
159
+
160
+ echo ""
161
+ echo "Preview saved to: /tmp/dry-run-allowlist-preview.md"
@@ -0,0 +1,396 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ KASEKI_REPO_URL="${KASEKI_REPO_URL:-https://github.com/CyanAutomation/kaseki-agent.git}"
5
+ KASEKI_REF="${KASEKI_REF:-main}"
6
+ KASEKI_ROOT="${KASEKI_ROOT:-/agents}"
7
+ KASEKI_CHECKOUT_DIR="${KASEKI_CHECKOUT_DIR:-$KASEKI_ROOT/kaseki-agent}"
8
+ KASEKI_TEMPLATE_DIR="${KASEKI_TEMPLATE_DIR:-$KASEKI_ROOT/kaseki-template}"
9
+ KASEKI_LOG_DIR="${KASEKI_LOG_DIR:-/var/log/kaseki}"
10
+ KASEKI_STRICT_HOST_LOGGING="${KASEKI_STRICT_HOST_LOGGING:-0}"
11
+ KASEKI_OUTPUT_FORMAT="${KASEKI_OUTPUT_FORMAT:-text}"
12
+ KASEKI_CONTROLLER_MODE="${KASEKI_CONTROLLER_MODE:-0}"
13
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="${KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING:-1}"
14
+ KASEKI_IMAGE_PULL_POLICY="${KASEKI_IMAGE_PULL_POLICY:-always}"
15
+ KASEKI_REPLACE_STALE="${KASEKI_REPLACE_STALE:-0}"
16
+ KASEKI_DOCTOR_REQUIRE_OPENROUTER_KEY="${KASEKI_DOCTOR_REQUIRE_OPENROUTER_KEY:-1}"
17
+ KASEKI_JSON_LOG_COMPONENT="kaseki-activate"
18
+ COMMAND=""
19
+ COMMAND_ARGS=()
20
+
21
+ json_escape() {
22
+ local value="${1-}"
23
+ value="${value//\\/\\\\}"
24
+ value="${value//\"/\\\"}"
25
+ value="${value//$'\n'/\\n}"
26
+ value="${value//$'\r'/\\r}"
27
+ value="${value//$'\t'/\\t}"
28
+ printf '%s' "$value"
29
+ }
30
+
31
+ emit_json_log() {
32
+ local stage="$1"
33
+ local status="$2"
34
+ local detail="${3-}"
35
+ local line
36
+ line="$(printf '{"timestamp":"%s","component":"%s","stage":"%s","status":"%s","detail":"%s"}' \
37
+ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
38
+ "$KASEKI_JSON_LOG_COMPONENT" \
39
+ "$(json_escape "$stage")" \
40
+ "$(json_escape "$status")" \
41
+ "$(json_escape "$detail")")"
42
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
43
+ printf '%s\n' "$line" >&2
44
+ else
45
+ printf '%s\n' "$line"
46
+ fi
47
+ }
48
+
49
+ json_string() {
50
+ printf '"%s"' "$(json_escape "${1-}")"
51
+ }
52
+
53
+ json_bool() {
54
+ case "${1-}" in
55
+ 1|true|TRUE|yes|YES) printf 'true' ;;
56
+ *) printf 'false' ;;
57
+ esac
58
+ }
59
+
60
+ parse_args() {
61
+ for arg in "$@"; do
62
+ case "$arg" in
63
+ --json)
64
+ KASEKI_OUTPUT_FORMAT="json"
65
+ ;;
66
+ --jsonl)
67
+ KASEKI_OUTPUT_FORMAT="jsonl"
68
+ ;;
69
+ --format=json)
70
+ KASEKI_OUTPUT_FORMAT="json"
71
+ ;;
72
+ --format=jsonl)
73
+ KASEKI_OUTPUT_FORMAT="jsonl"
74
+ ;;
75
+ --format=text)
76
+ KASEKI_OUTPUT_FORMAT="text"
77
+ ;;
78
+ --controller)
79
+ KASEKI_CONTROLLER_MODE="1"
80
+ KASEKI_OUTPUT_FORMAT="json"
81
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="0"
82
+ KASEKI_IMAGE_PULL_POLICY="always"
83
+ ;;
84
+ --no-build)
85
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="0"
86
+ ;;
87
+ --replace-stale)
88
+ KASEKI_REPLACE_STALE="1"
89
+ ;;
90
+ *)
91
+ if [ -z "$COMMAND" ]; then
92
+ COMMAND="$arg"
93
+ else
94
+ COMMAND_ARGS+=("$arg")
95
+ fi
96
+ ;;
97
+ esac
98
+ done
99
+ COMMAND="${COMMAND:-bootstrap}"
100
+ }
101
+
102
+ print_command_json() {
103
+ local command="$1"
104
+ local exit_code="$2"
105
+ local message="${3-}"
106
+ local result_dir="${4-}"
107
+ local instance="${5-}"
108
+ local checkout_ref=""
109
+ local template_ready="false"
110
+ if [ -d "$KASEKI_CHECKOUT_DIR/.git" ]; then
111
+ checkout_ref="$(git -C "$KASEKI_CHECKOUT_DIR" rev-parse --short HEAD 2>/dev/null || true)"
112
+ fi
113
+ [ -x "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" ] && template_ready="true"
114
+ cat <<JSON
115
+ {"command":$(json_string "$command"),"exit_code":$exit_code,"ok":$(json_bool "$([ "$exit_code" -eq 0 ] && printf 1 || printf 0)"),"message":$(json_string "$message"),"instance":$(json_string "$instance"),"result_dir":$(json_string "$result_dir"),"checkout":$(json_string "$KASEKI_CHECKOUT_DIR"),"checkout_ref":$(json_string "$checkout_ref"),"template":$(json_string "$KASEKI_TEMPLATE_DIR"),"template_ready":$template_ready}
116
+ JSON
117
+ }
118
+
119
+ setup_host_logging() {
120
+ local stamp host_log_file
121
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
122
+ return 0
123
+ fi
124
+ if mkdir -p "$KASEKI_LOG_DIR" 2>/dev/null && [ -w "$KASEKI_LOG_DIR" ]; then
125
+ stamp="$(date -u +%Y%m%dT%H%M%SZ)"
126
+ host_log_file="$KASEKI_LOG_DIR/kaseki-activate-${stamp}.log"
127
+ exec > >(tee -a "$host_log_file") 2> >(tee -a "$host_log_file" >&2)
128
+ emit_json_log "logging" "ok" "$host_log_file"
129
+ return 0
130
+ fi
131
+ if [ "$KASEKI_STRICT_HOST_LOGGING" = "1" ]; then
132
+ emit_json_log "logging" "error" "KASEKI_LOG_DIR is not writable: $KASEKI_LOG_DIR"
133
+ exit 1
134
+ fi
135
+ emit_json_log "logging" "warning" "host log mirroring disabled: $KASEKI_LOG_DIR"
136
+ }
137
+
138
+ show_help() {
139
+ cat <<HELP
140
+ Usage: scripts/kaseki-activate.sh [--json|--jsonl] [bootstrap|install|deploy|doctor|run|status|clean] [run args...]
141
+
142
+ Host-side activation entrypoint for local or SSH-launched agents.
143
+
144
+ Commands:
145
+ bootstrap Install/update checkout, deploy template, then run doctor.
146
+ install Clone or fast-forward KASEKI_CHECKOUT_DIR to KASEKI_REF.
147
+ deploy Deploy KASEKI_TEMPLATE_DIR from the configured image or local build.
148
+ doctor Run /agents/kaseki-template/run-kaseki.sh --doctor.
149
+ run Run /agents/kaseki-template/run-kaseki.sh with remaining args.
150
+ status Print template presence and recent Kaseki instances.
151
+ clean Remove template, runs, results, cache, and checkout.
152
+
153
+ Output:
154
+ --json Print a final machine-readable JSON object for status, doctor, and run.
155
+ --jsonl Keep newline-delimited JSON progress logs on stdout.
156
+
157
+ Controller options:
158
+ --controller JSON output, pull registry image, and fail instead of building locally.
159
+ --no-build Fail deployment if the registry image cannot be used.
160
+ --replace-stale
161
+ Reset and clean an existing dirty checkout before updating it.
162
+
163
+ Useful environment:
164
+ KASEKI_REPO_URL=$KASEKI_REPO_URL
165
+ KASEKI_REF=$KASEKI_REF
166
+ KASEKI_ROOT=$KASEKI_ROOT
167
+ KASEKI_CHECKOUT_DIR=$KASEKI_CHECKOUT_DIR
168
+ KASEKI_TEMPLATE_DIR=$KASEKI_TEMPLATE_DIR
169
+ KASEKI_CONTROLLER_MODE=$KASEKI_CONTROLLER_MODE
170
+ KASEKI_IMAGE_PULL_POLICY=$KASEKI_IMAGE_PULL_POLICY
171
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING=$KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING
172
+ KASEKI_REPLACE_STALE=$KASEKI_REPLACE_STALE
173
+ HELP
174
+ }
175
+
176
+ require_bin() {
177
+ local bin="$1"
178
+ if ! command -v "$bin" >/dev/null 2>&1; then
179
+ emit_json_log "preflight" "error" "missing required binary: $bin"
180
+ exit 1
181
+ fi
182
+ }
183
+
184
+ install_checkout() {
185
+ require_bin git
186
+ mkdir -p "$(dirname "$KASEKI_CHECKOUT_DIR")"
187
+ if [ -d "$KASEKI_CHECKOUT_DIR/.git" ]; then
188
+ if [ -n "$(git -C "$KASEKI_CHECKOUT_DIR" status --porcelain)" ]; then
189
+ if [ "$KASEKI_REPLACE_STALE" = "1" ]; then
190
+ emit_json_log "install" "warning" "dirty checkout detected; resetting because KASEKI_REPLACE_STALE=1"
191
+ git -C "$KASEKI_CHECKOUT_DIR" reset --hard HEAD >&2
192
+ git -C "$KASEKI_CHECKOUT_DIR" clean -fdx >&2
193
+ else
194
+ emit_json_log "install" "error" "dirty checkout at $KASEKI_CHECKOUT_DIR; rerun with --replace-stale or KASEKI_REPLACE_STALE=1 to reset it"
195
+ [ "$KASEKI_OUTPUT_FORMAT" = "json" ] && print_command_json "install" 3 "dirty checkout; use --replace-stale to reset stale local files" "" ""
196
+ exit 3
197
+ fi
198
+ fi
199
+ emit_json_log "install" "started" "updating $KASEKI_CHECKOUT_DIR"
200
+ git -C "$KASEKI_CHECKOUT_DIR" fetch --prune origin >&2
201
+ else
202
+ rm -rf "$KASEKI_CHECKOUT_DIR"
203
+ emit_json_log "install" "started" "cloning $KASEKI_REPO_URL to $KASEKI_CHECKOUT_DIR"
204
+ git clone "$KASEKI_REPO_URL" "$KASEKI_CHECKOUT_DIR" >&2
205
+ fi
206
+ git -C "$KASEKI_CHECKOUT_DIR" checkout "$KASEKI_REF" >&2
207
+ git -C "$KASEKI_CHECKOUT_DIR" pull --ff-only origin "$KASEKI_REF" >&2 || true
208
+ emit_json_log "install" "finished" "$(git -C "$KASEKI_CHECKOUT_DIR" rev-parse --short HEAD)"
209
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ] && [ "$COMMAND" = "install" ]; then
210
+ print_command_json "install" 0 "checkout installed" "" ""
211
+ fi
212
+ }
213
+
214
+ deploy_template() {
215
+ local code output_file
216
+ require_bin docker
217
+ emit_json_log "deploy" "started" "$KASEKI_TEMPLATE_DIR"
218
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
219
+ output_file="$(mktemp)"
220
+ set +e
221
+ KASEKI_TEMPLATE_DIR="$KASEKI_TEMPLATE_DIR" \
222
+ KASEKI_IMAGE_PULL_POLICY="$KASEKI_IMAGE_PULL_POLICY" \
223
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="$KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING" \
224
+ "$KASEKI_CHECKOUT_DIR/scripts/deploy-pi-template.sh" >"$output_file" 2>&1
225
+ code=$?
226
+ set -e
227
+ cat "$output_file" >&2
228
+ if [ "$COMMAND" = "deploy" ]; then
229
+ print_command_json "deploy" "$code" "$(tail -n 20 "$output_file")" "" ""
230
+ fi
231
+ rm -f "$output_file"
232
+ [ "$code" -eq 0 ] || exit "$code"
233
+ else
234
+ KASEKI_TEMPLATE_DIR="$KASEKI_TEMPLATE_DIR" \
235
+ KASEKI_IMAGE_PULL_POLICY="$KASEKI_IMAGE_PULL_POLICY" \
236
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="$KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING" \
237
+ "$KASEKI_CHECKOUT_DIR/scripts/deploy-pi-template.sh"
238
+ fi
239
+ emit_json_log "deploy" "finished" "$KASEKI_TEMPLATE_DIR"
240
+ }
241
+
242
+ run_doctor() {
243
+ local code output_file
244
+ if [ ! -x "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" ]; then
245
+ emit_json_log "doctor" "error" "template is not deployed: $KASEKI_TEMPLATE_DIR"
246
+ [ "$KASEKI_OUTPUT_FORMAT" = "json" ] && print_command_json "doctor" 2 "template is not deployed" "" ""
247
+ exit 2
248
+ fi
249
+ emit_json_log "doctor" "started" "$KASEKI_TEMPLATE_DIR"
250
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
251
+ output_file="$(mktemp)"
252
+ set +e
253
+ KASEKI_DOCTOR_REQUIRE_OPENROUTER_KEY="$KASEKI_DOCTOR_REQUIRE_OPENROUTER_KEY" \
254
+ "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" --doctor >"$output_file" 2>&1
255
+ code=$?
256
+ set -e
257
+ print_command_json "doctor" "$code" "$(tail -n 20 "$output_file")" "" ""
258
+ rm -f "$output_file"
259
+ [ "$code" -eq 0 ] || exit "$code"
260
+ else
261
+ KASEKI_DOCTOR_REQUIRE_OPENROUTER_KEY="$KASEKI_DOCTOR_REQUIRE_OPENROUTER_KEY" \
262
+ "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" --doctor
263
+ fi
264
+ emit_json_log "doctor" "finished" "$KASEKI_TEMPLATE_DIR"
265
+ }
266
+
267
+ run_kaseki() {
268
+ local code output_file instance result_dir
269
+ if [ ! -x "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" ]; then
270
+ emit_json_log "run" "error" "template is not deployed: $KASEKI_TEMPLATE_DIR"
271
+ [ "$KASEKI_OUTPUT_FORMAT" = "json" ] && print_command_json "run" 2 "template is not deployed" "" ""
272
+ exit 2
273
+ fi
274
+ emit_json_log "run" "started" "run-kaseki.sh with $(($# > 0 ? $# : 0)) arguments"
275
+ set +e
276
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
277
+ output_file="$(mktemp)"
278
+ "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" "$@" >"$output_file" 2>&1
279
+ else
280
+ "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" "$@"
281
+ fi
282
+ code=$?
283
+ set -e
284
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
285
+ instance="$(awk '/^kaseki-[0-9]+$/ { value=$0 } END { print value }' "$output_file")"
286
+ result_dir="$(awk -F= '/^result_dir=/ { value=$2 } END { print value }' "$output_file")"
287
+ print_command_json "run" "$code" "$(tail -n 40 "$output_file")" "$result_dir" "$instance"
288
+ rm -f "$output_file"
289
+ fi
290
+ if [ "$code" -eq 0 ]; then
291
+ emit_json_log "run" "finished" "$*"
292
+ else
293
+ emit_json_log "run" "error" "run-kaseki.sh exited with code $code"
294
+ fi
295
+ return "$code"
296
+ }
297
+
298
+ show_status() {
299
+ emit_json_log "status" "started" "$KASEKI_ROOT"
300
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
301
+ local checkout_ref="" template_ready="false" instances_json="[]"
302
+ if [ -d "$KASEKI_CHECKOUT_DIR/.git" ]; then
303
+ checkout_ref="$(git -C "$KASEKI_CHECKOUT_DIR" rev-parse --short HEAD 2>/dev/null || true)"
304
+ fi
305
+ [ -x "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" ] && template_ready="true"
306
+ if [ -d "$KASEKI_ROOT/kaseki-results" ]; then
307
+ instances_json="$(
308
+ find "$KASEKI_ROOT/kaseki-results" -mindepth 1 -maxdepth 1 -type d -name 'kaseki-*' -print 2>/dev/null |
309
+ sort -Vr |
310
+ awk -v root="$KASEKI_ROOT/kaseki-results" '
311
+ BEGIN { printf "[" }
312
+ {
313
+ name=$0
314
+ sub("^" root "/", "", name)
315
+ if (count++ > 0) printf ","
316
+ printf "{\"instance\":\"%s\",\"result_dir\":\"%s\"}", name, $0
317
+ }
318
+ END { printf "]" }
319
+ '
320
+ )"
321
+ fi
322
+ cat <<JSON
323
+ {"command":"status","exit_code":0,"ok":true,"checkout":$(json_string "$KASEKI_CHECKOUT_DIR"),"checkout_ref":$(json_string "$checkout_ref"),"template":$(json_string "$KASEKI_TEMPLATE_DIR"),"template_ready":$template_ready,"results_dir":$(json_string "$KASEKI_ROOT/kaseki-results"),"instances":$instances_json}
324
+ JSON
325
+ emit_json_log "status" "finished" "$KASEKI_ROOT"
326
+ return 0
327
+ fi
328
+ printf 'checkout=%s\n' "$KASEKI_CHECKOUT_DIR"
329
+ if [ -d "$KASEKI_CHECKOUT_DIR/.git" ]; then
330
+ printf 'checkout_ref=%s\n' "$(git -C "$KASEKI_CHECKOUT_DIR" rev-parse --short HEAD)"
331
+ fi
332
+ printf 'template=%s\n' "$KASEKI_TEMPLATE_DIR"
333
+ [ -x "$KASEKI_TEMPLATE_DIR/run-kaseki.sh" ] && printf 'template_ready=true\n' || printf 'template_ready=false\n'
334
+ if [ -x "$KASEKI_TEMPLATE_DIR/kaseki" ]; then
335
+ "$KASEKI_TEMPLATE_DIR/kaseki" list || true
336
+ fi
337
+ emit_json_log "status" "finished" "$KASEKI_ROOT"
338
+ }
339
+
340
+ clean_all() {
341
+ emit_json_log "clean" "started" "$KASEKI_ROOT"
342
+ rm -rf "$KASEKI_TEMPLATE_DIR" \
343
+ "$KASEKI_ROOT/kaseki-runs" \
344
+ "$KASEKI_ROOT/kaseki-results" \
345
+ "$KASEKI_ROOT/kaseki-cache" \
346
+ "$KASEKI_CHECKOUT_DIR"
347
+ emit_json_log "clean" "finished" "$KASEKI_ROOT"
348
+ if [ "$KASEKI_OUTPUT_FORMAT" = "json" ]; then
349
+ print_command_json "clean" 0 "removed Kaseki checkout, template, runs, results, and cache" "" ""
350
+ fi
351
+ }
352
+
353
+ parse_args "$@"
354
+ if [ "$KASEKI_CONTROLLER_MODE" = "1" ]; then
355
+ KASEKI_OUTPUT_FORMAT="json"
356
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="0"
357
+ KASEKI_IMAGE_PULL_POLICY="always"
358
+ if [ -z "${OPENROUTER_API_KEY:-}" ] && [ -z "${OPENROUTER_API_KEY_FILE:-}" ]; then
359
+ KASEKI_DOCTOR_REQUIRE_OPENROUTER_KEY="0"
360
+ fi
361
+ fi
362
+ setup_host_logging
363
+
364
+ case "$COMMAND" in
365
+ bootstrap)
366
+ install_checkout
367
+ deploy_template
368
+ run_doctor
369
+ ;;
370
+ install)
371
+ install_checkout
372
+ ;;
373
+ deploy)
374
+ deploy_template
375
+ ;;
376
+ doctor)
377
+ run_doctor
378
+ ;;
379
+ run)
380
+ run_kaseki "${COMMAND_ARGS[@]}"
381
+ ;;
382
+ status)
383
+ show_status
384
+ ;;
385
+ clean)
386
+ clean_all
387
+ ;;
388
+ --help|-h|help)
389
+ show_help
390
+ ;;
391
+ *)
392
+ emit_json_log "usage" "error" "unknown command: $COMMAND"
393
+ show_help >&2
394
+ exit 2
395
+ ;;
396
+ esac
@@ -0,0 +1,62 @@
1
+ [Unit]
2
+ Description=Kaseki Agent API Service
3
+ Documentation=https://github.com/CyanAutomation/kaseki-agent
4
+ After=network.target docker.service
5
+
6
+ [Service]
7
+ Type=simple
8
+ User=nobody
9
+ Group=nogroup
10
+ EnvironmentFile=-/etc/kaseki-api/kaseki-api.env
11
+
12
+ # Security hardening (match Docker settings)
13
+ NoNewPrivileges=true
14
+ PrivateTmp=true
15
+ ProtectSystem=strict
16
+ ProtectHome=true
17
+ ReadWritePaths=/agents/kaseki-results /var/log/kaseki-api /tmp
18
+ UMask=0077
19
+
20
+ # Restart behavior
21
+ Restart=on-failure
22
+ RestartSec=10
23
+ StandardOutput=journal
24
+ StandardError=journal
25
+ SyslogIdentifier=kaseki-api
26
+
27
+ # Timeout and graceful shutdown
28
+ TimeoutStopSec=30
29
+ KillSignal=SIGTERM
30
+
31
+ # Authoritative runtime mode: Docker container.
32
+ # This unit intentionally runs the baked image artifact at /app/dist/kaseki-api-service.js.
33
+ # Do not switch this unit to a host Node.js ExecStart; use a separate unit for host-mode if needed.
34
+ #
35
+ # Required deployment sequence for image lifecycle:
36
+ # 1) Build image from this repo: docker build -t <tag> .
37
+ # 2) If using a registry image, push it: docker push <registry>/<image>:<tag>
38
+ # 3) On host, set KASEKI_API_IMAGE in /etc/kaseki-api/kaseki-api.env and pull it:
39
+ # docker pull "${KASEKI_API_IMAGE}"
40
+ # 4) Restart service: systemctl restart kaseki-api
41
+ ExecStartPre=/usr/bin/bash -lc 'printf "KASEKI_API_IMAGE=%s\n" "${KASEKI_API_IMAGE:-kaseki-agent:node24-local}"; docker image inspect "${KASEKI_API_IMAGE:-kaseki-agent:node24-local}" --format "ImageId={{.Id}} RepoDigests={{join .RepoDigests \",\"}}"'
42
+ ExecStartPre=/usr/bin/docker run --rm --entrypoint /bin/bash "${KASEKI_API_IMAGE:-kaseki-agent:node24-local}" -lc 'test -f /app/dist/kaseki-api-service.js && ls -l /app/dist/kaseki-api-service.js'
43
+ ExecStart=/usr/bin/docker run --rm \
44
+ --name kaseki-api-container \
45
+ -p 8080:8080 \
46
+ -v /agents:/agents:rw \
47
+ -v /agents/kaseki-results:/agents/kaseki-results:rw \
48
+ -v /var/log/kaseki-api:/var/log/kaseki-api:rw \
49
+ -v /var/run/docker.sock:/var/run/docker.sock \
50
+ --env-file /etc/kaseki-api/kaseki-api.env \
51
+ --user 0:0 \
52
+ --cap-drop ALL \
53
+ --security-opt no-new-privileges:true \
54
+ --read-only \
55
+ --entrypoint /bin/bash \
56
+ "${KASEKI_API_IMAGE:-kaseki-agent:node24-local}" \
57
+ -lc 'set -euo pipefail; test -f /app/dist/kaseki-api-service.js; ls -l /app/dist/kaseki-api-service.js; test ! -e /agents/kaseki-template/dist/kaseki-api-service.js || echo "INFO: host /agents/kaseki-template/dist exists but is ignored in Docker mode"; exec node /app/dist/kaseki-api-service.js'
58
+
59
+ ExecStop=/usr/bin/docker stop -t 30 kaseki-api-container
60
+
61
+ [Install]
62
+ WantedBy=multi-user.target