@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,56 @@
1
+ #!/usr/bin/env bash
2
+
3
+ # Convert a glob-style repo-relative allowlist pattern into an extended regex.
4
+ # Supported glob operators:
5
+ # - * matches within a single path segment
6
+ # - ** matches across path segments
7
+ # - **/ matches zero or more path segments
8
+ # - ? matches one character within a single path segment
9
+ # All other regex metacharacters are escaped so exact path patterns remain exact.
10
+ allowlist_pattern_to_regex() {
11
+ awk -v pattern="$1" '
12
+ BEGIN {
13
+ regex = ""
14
+ i = 1
15
+ while (i <= length(pattern)) {
16
+ c = substr(pattern, i, 1)
17
+ next_c = substr(pattern, i + 1, 1)
18
+ next_next_c = substr(pattern, i + 2, 1)
19
+
20
+ if (c == "*" && next_c == "*") {
21
+ if (next_next_c == "/") {
22
+ regex = regex "([^/]+/)*"
23
+ i += 3
24
+ } else {
25
+ regex = regex ".*"
26
+ i += 2
27
+ }
28
+ } else if (c == "*") {
29
+ regex = regex "[^/]*"
30
+ i++
31
+ } else if (c == "?") {
32
+ regex = regex "[^/]"
33
+ i++
34
+ } else {
35
+ if (index(".\\^$()+{}|[]", c) > 0) {
36
+ regex = regex "\\" c
37
+ } else {
38
+ regex = regex c
39
+ }
40
+ i++
41
+ }
42
+ }
43
+ print regex
44
+ }
45
+ '
46
+ }
47
+
48
+ build_allowlist_regex() {
49
+ local pattern regexes=()
50
+ while IFS= read -r pattern || [ -n "$pattern" ]; do
51
+ [ -z "$pattern" ] && continue
52
+ regexes+=("$(allowlist_pattern_to_regex "$pattern")")
53
+ done < <(printf '%s\n' "$KASEKI_CHANGED_FILES_ALLOWLIST" | tr ' ' '\n')
54
+
55
+ (IFS='|'; printf '%s' "${regexes[*]}")
56
+ }
@@ -0,0 +1,168 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT="${KASEKI_ROOT:-/agents}"
5
+ RUNS="$ROOT/kaseki-runs"
6
+ RESULTS="$ROOT/kaseki-results"
7
+ OLDER_THAN_DAYS="${KASEKI_CLEANUP_DAYS:-1}"
8
+ DRY_RUN=0
9
+ DOCKER_CLEANUP=0
10
+ FORCE=0
11
+ KASEKI_LOG_DIR="${KASEKI_LOG_DIR:-/var/log/kaseki}"
12
+ KASEKI_STRICT_HOST_LOGGING="${KASEKI_STRICT_HOST_LOGGING:-0}"
13
+ KASEKI_JSON_LOG_COMPONENT="cleanup-kaseki"
14
+
15
+ json_escape() {
16
+ local value="${1-}"
17
+ value="${value//\\/\\\\}"
18
+ value="${value//\"/\\\"}"
19
+ value="${value//$'\n'/\\n}"
20
+ value="${value//$'\r'/\\r}"
21
+ value="${value//$'\t'/\\t}"
22
+ printf '%s' "$value"
23
+ }
24
+
25
+ emit_json_log() {
26
+ local stage="$1"
27
+ local status="$2"
28
+ local detail="${3-}"
29
+ printf '{"timestamp":"%s","component":"%s","stage":"%s","status":"%s","instance":"%s","detail":"%s"}\n' \
30
+ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
31
+ "$KASEKI_JSON_LOG_COMPONENT" \
32
+ "$(json_escape "$stage")" \
33
+ "$(json_escape "$status")" \
34
+ "maintenance" \
35
+ "$(json_escape "$detail")"
36
+ }
37
+
38
+ on_cleanup_exit() {
39
+ local code=$?
40
+ if [ "$code" -eq 0 ]; then
41
+ emit_json_log "cleanup" "finished" "cleanup-kaseki.sh completed successfully"
42
+ else
43
+ emit_json_log "cleanup" "error" "cleanup-kaseki.sh exited with code $code"
44
+ fi
45
+ }
46
+
47
+ trap on_cleanup_exit EXIT
48
+ emit_json_log "cleanup" "started" "cleanup-kaseki.sh starting"
49
+
50
+ setup_host_logging() {
51
+ local base_name="$1"
52
+ local stamp host_log_file
53
+ if mkdir -p "$KASEKI_LOG_DIR" 2>/dev/null && [ -w "$KASEKI_LOG_DIR" ]; then
54
+ stamp="$(date -u +%Y%m%dT%H%M%SZ)"
55
+ host_log_file="$KASEKI_LOG_DIR/${base_name}-${stamp}.log"
56
+ exec > >(tee -a "$host_log_file") 2> >(tee -a "$host_log_file" >&2)
57
+ printf 'Host log mirror: %s\n' "$host_log_file"
58
+ return 0
59
+ fi
60
+ if [ "$KASEKI_STRICT_HOST_LOGGING" = "1" ]; then
61
+ printf 'Error: strict host logging enabled, but KASEKI_LOG_DIR is not writable: %s\n' "$KASEKI_LOG_DIR" >&2
62
+ exit 1
63
+ fi
64
+ printf 'Warning: host logging disabled; KASEKI_LOG_DIR is unavailable: %s\n' "$KASEKI_LOG_DIR" >&2
65
+ }
66
+
67
+ show_help() {
68
+ cat <<HELP
69
+ Usage: KASEKI_CLEANUP_DAYS=1 $0 [--docker] [--dry-run] [--force]
70
+
71
+ Deletes finalized kaseki-N workspaces older than the configured age.
72
+ Results under $RESULTS are preserved.
73
+ Transient staging directories (for example: .staging-run-kaseki-N-XXXXXX)
74
+ are created and cleaned automatically by run-kaseki.sh.
75
+
76
+ Options:
77
+ --docker Also remove stopped kaseki containers and prune Docker build cache.
78
+ --dry-run Print what would be removed.
79
+ --force Required with --docker to actually prune Docker build cache.
80
+ HELP
81
+ }
82
+
83
+ while [ "$#" -gt 0 ]; do
84
+ case "$1" in
85
+ --help|-h)
86
+ show_help
87
+ exit 0
88
+ ;;
89
+ --docker)
90
+ DOCKER_CLEANUP=1
91
+ ;;
92
+ --dry-run)
93
+ DRY_RUN=1
94
+ ;;
95
+ --force)
96
+ FORCE=1
97
+ ;;
98
+ *)
99
+ printf 'Unknown option: %s\n' "$1" >&2
100
+ show_help >&2
101
+ exit 2
102
+ ;;
103
+ esac
104
+ shift
105
+ done
106
+
107
+ setup_host_logging "cleanup-kaseki"
108
+
109
+ run_or_print() {
110
+ if [ "$DRY_RUN" -eq 1 ]; then
111
+ printf '+ %q' "$1"
112
+ shift
113
+ while [ "$#" -gt 0 ]; do
114
+ printf ' %q' "$1"
115
+ shift
116
+ done
117
+ printf '\n'
118
+ else
119
+ "$@"
120
+ fi
121
+ }
122
+
123
+ printf 'Kaseki cleanup\n'
124
+ printf 'Root: %s\n' "$ROOT"
125
+ printf 'Runs: %s\n' "$RUNS"
126
+ printf 'Results preserved: %s\n' "$RESULTS"
127
+
128
+ if [ -d "$RUNS" ]; then
129
+ emit_json_log "workspace-prune" "started" "removing stale run directories older than $OLDER_THAN_DAYS days"
130
+ find "$RUNS" -mindepth 1 -maxdepth 1 -type d -name 'kaseki-[0-9]*' -mtime +"$OLDER_THAN_DAYS" -print |
131
+ while IFS= read -r run_dir; do
132
+ run_or_print rm -rf "$run_dir"
133
+ done
134
+ emit_json_log "workspace-prune" "finished" "stale run directory cleanup complete"
135
+ else
136
+ printf 'No Kaseki runs directory found: %s\n' "$RUNS"
137
+ emit_json_log "workspace-prune" "finished" "runs directory missing; nothing to prune"
138
+ fi
139
+
140
+ if [ "$DOCKER_CLEANUP" -eq 1 ]; then
141
+ emit_json_log "docker-cleanup" "started" "docker cleanup requested"
142
+ if ! command -v docker >/dev/null 2>&1; then
143
+ printf 'Docker: missing; skipping Docker cleanup\n' >&2
144
+ emit_json_log "docker-cleanup" "error" "docker binary missing; skipping docker cleanup"
145
+ exit 0
146
+ fi
147
+
148
+ printf '\nDocker disk usage before cleanup:\n'
149
+ docker system df || true
150
+
151
+ docker ps -a --format '{{.ID}} {{.Names}}' |
152
+ awk '$2 ~ /^kaseki-[0-9]+$/ { print $1 }' |
153
+ while IFS= read -r container_id; do
154
+ [ -z "$container_id" ] && continue
155
+ run_or_print docker rm "$container_id"
156
+ done
157
+
158
+ if [ "$FORCE" -eq 1 ]; then
159
+ run_or_print docker builder prune -f --filter until=24h
160
+ run_or_print docker image prune -f
161
+ else
162
+ printf 'Docker build/image prune skipped; pass --force with --docker to prune cache and dangling images.\n'
163
+ fi
164
+
165
+ printf '\nDocker disk usage after cleanup:\n'
166
+ docker system df || true
167
+ emit_json_log "docker-cleanup" "finished" "docker cleanup stage complete"
168
+ fi
@@ -0,0 +1,293 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ DEFAULT_TARGET_DIR="/agents/kaseki-template"
6
+ TARGET_DIR="${KASEKI_TEMPLATE_DIR:-$DEFAULT_TARGET_DIR}"
7
+ REQUESTED_IMAGE="${KASEKI_IMAGE:-docker.io/cyanautomation/kaseki-agent:latest}"
8
+ IMAGE="$REQUESTED_IMAGE"
9
+ LOCAL_BUILD_IMAGE="${KASEKI_LOCAL_BUILD_IMAGE:-kaseki-agent:local}"
10
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="${KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING:-1}"
11
+ KASEKI_IMAGE_PULL_POLICY="${KASEKI_IMAGE_PULL_POLICY:-always}"
12
+ KASEKI_LOG_DIR="${KASEKI_LOG_DIR:-/var/log/kaseki}"
13
+ KASEKI_STRICT_HOST_LOGGING="${KASEKI_STRICT_HOST_LOGGING:-0}"
14
+ KASEKI_JSON_LOG_COMPONENT="deploy-pi-template"
15
+ CONTAINER=""
16
+
17
+ is_probably_digest_ref() {
18
+ local image_ref="$1"
19
+ case "$image_ref" in
20
+ *@sha256:*) return 0 ;;
21
+ *) return 1 ;;
22
+ esac
23
+ }
24
+
25
+ resolve_local_repo_digest() {
26
+ local image_ref="$1"
27
+ docker image inspect "$image_ref" --format '{{index .RepoDigests 0}}' 2>/dev/null || true
28
+ }
29
+
30
+ json_escape() {
31
+ local value="${1-}"
32
+ value="${value//\\/\\\\}"
33
+ value="${value//\"/\\\"}"
34
+ value="${value//$'\n'/\\n}"
35
+ value="${value//$'\r'/\\r}"
36
+ value="${value//$'\t'/\\t}"
37
+ printf '%s' "$value"
38
+ }
39
+
40
+ emit_json_log() {
41
+ local stage="$1"
42
+ local status="$2"
43
+ local detail="${3-}"
44
+ printf '{"timestamp":"%s","component":"%s","stage":"%s","status":"%s","instance":"%s","detail":"%s"}\n' \
45
+ "$(date -u +%Y-%m-%dT%H:%M:%SZ)" \
46
+ "$KASEKI_JSON_LOG_COMPONENT" \
47
+ "$(json_escape "$stage")" \
48
+ "$(json_escape "$status")" \
49
+ "template" \
50
+ "$(json_escape "$detail")"
51
+ }
52
+
53
+ on_deploy_exit() {
54
+ local code=$?
55
+ if [ -n "${CONTAINER:-}" ]; then
56
+ docker rm "$CONTAINER" >/dev/null 2>&1 || true
57
+ fi
58
+ if [ "$code" -eq 0 ]; then
59
+ emit_json_log "deploy" "finished" "deploy-pi-template.sh completed successfully"
60
+ else
61
+ emit_json_log "deploy" "error" "deploy-pi-template.sh exited with code $code"
62
+ fi
63
+ }
64
+
65
+ trap on_deploy_exit EXIT
66
+ emit_json_log "deploy" "started" "deploy-pi-template.sh starting"
67
+
68
+ setup_host_logging() {
69
+ local base_name="$1"
70
+ local stamp host_log_file
71
+ if mkdir -p "$KASEKI_LOG_DIR" 2>/dev/null && [ -w "$KASEKI_LOG_DIR" ]; then
72
+ stamp="$(date -u +%Y%m%dT%H%M%SZ)"
73
+ host_log_file="$KASEKI_LOG_DIR/${base_name}-${stamp}.log"
74
+ exec > >(tee -a "$host_log_file") 2> >(tee -a "$host_log_file" >&2)
75
+ printf 'Host log mirror: %s\n' "$host_log_file"
76
+ return 0
77
+ fi
78
+ if [ "$KASEKI_STRICT_HOST_LOGGING" = "1" ]; then
79
+ printf 'Error: strict host logging enabled, but KASEKI_LOG_DIR is not writable: %s\n' "$KASEKI_LOG_DIR" >&2
80
+ exit 1
81
+ fi
82
+ printf 'Warning: host logging disabled; KASEKI_LOG_DIR is unavailable: %s\n' "$KASEKI_LOG_DIR" >&2
83
+ }
84
+
85
+ setup_host_logging "deploy-pi-template"
86
+
87
+ if [ "${1:-}" = "--help" ]; then
88
+ cat <<HELP
89
+ Usage: KASEKI_TEMPLATE_DIR=$DEFAULT_TARGET_DIR $0
90
+
91
+ Deploys the current Kaseki runner files into KASEKI_TEMPLATE_DIR
92
+ (default: $DEFAULT_TARGET_DIR).
93
+
94
+ Idempotent behavior:
95
+ - Refuses to clean unexpected targets (guardrails require basename "kaseki-template"
96
+ and path prefix "/agents/" or "$HOME/").
97
+ - Cleans destination root before install.
98
+ - Preserves existing destination subdirectories named run, result, cache, and secrets.
99
+
100
+ Image behavior:
101
+ - Pulls KASEKI_IMAGE by default before using a local tag.
102
+ - Set KASEKI_IMAGE_PULL_POLICY=missing to pull only when absent.
103
+ - Set KASEKI_IMAGE_PULL_POLICY=never to use only local Docker images.
104
+ - If the image lacks a deployable /app template and
105
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING=1, builds this checkout as
106
+ $LOCAL_BUILD_IMAGE and deploys that image instead.
107
+ HELP
108
+ exit 0
109
+ fi
110
+
111
+ is_allowed_target_dir() {
112
+ local target="$1"
113
+ local base
114
+ base="$(basename "$target")"
115
+ [ "$base" = "kaseki-template" ] || return 1
116
+ case "$target" in
117
+ /agents/*) return 0 ;;
118
+ "$HOME"/*) return 0 ;;
119
+ esac
120
+ return 1
121
+ }
122
+
123
+ prepare_target_dir() {
124
+ local target="$1"
125
+ local abs_target
126
+ local backup_root=""
127
+ local persistent
128
+ local path
129
+
130
+ abs_target="$(cd "$(dirname "$target")" 2>/dev/null && pwd)/$(basename "$target")" || abs_target="$target"
131
+
132
+ if ! is_allowed_target_dir "$abs_target"; then
133
+ printf 'Error: target directory is not allowed: %s\n' "$abs_target" >&2
134
+ printf 'Allowed paths: /agents/kaseki-template, %s/kaseki-template\n' "$HOME" >&2
135
+ exit 2
136
+ fi
137
+
138
+ if [ -d "$target" ]; then
139
+ backup_root="$(mktemp -d)"
140
+ for persistent in run result cache secrets; do
141
+ path="$target/$persistent"
142
+ if [ -d "$path" ]; then
143
+ printf 'Preserving: %s\n' "$path"
144
+ mv "$path" "$backup_root/$persistent"
145
+ fi
146
+ done
147
+ fi
148
+
149
+ mkdir -p "$target"
150
+ rm -rf "${target:?}"/*
151
+ mkdir -p "$target"
152
+
153
+ if [ -n "$backup_root" ]; then
154
+ for persistent in run result cache secrets; do
155
+ if [ -d "$backup_root/$persistent" ]; then
156
+ mv "$backup_root/$persistent" "$target/$persistent"
157
+ printf 'Restored: %s\n' "$target/$persistent"
158
+ fi
159
+ done
160
+ rmdir "$backup_root" 2>/dev/null || true
161
+ fi
162
+ }
163
+
164
+ image_has_template() {
165
+ local image="$1"
166
+ local probe_container=""
167
+ probe_container="$(docker create "$image" 2>/dev/null)" || return 1
168
+ if docker cp "$probe_container:/app/run-kaseki.sh" - >/dev/null 2>&1; then
169
+ docker rm "$probe_container" >/dev/null 2>&1 || true
170
+ return 0
171
+ fi
172
+ docker rm "$probe_container" >/dev/null 2>&1 || true
173
+ return 1
174
+ }
175
+
176
+ ensure_deployable_image() {
177
+ local local_image_present=0
178
+ local resolved_digest=""
179
+
180
+ docker image inspect "$IMAGE" >/dev/null 2>&1 || local_image_present=1
181
+
182
+ case "$KASEKI_IMAGE_PULL_POLICY" in
183
+ always)
184
+ emit_json_log "deploy" "started" "Pulling Docker image: $IMAGE"
185
+ if ! docker pull "$IMAGE"; then
186
+ if [ "$local_image_present" -eq 0 ]; then
187
+ emit_json_log "deploy" "warning" "Pull failed; using existing local Docker image: $IMAGE"
188
+ else
189
+ return 1
190
+ fi
191
+ fi
192
+ ;;
193
+ missing|if-not-present)
194
+ if [ "$local_image_present" -eq 0 ]; then
195
+ emit_json_log "deploy" "started" "Using local Docker image: $IMAGE"
196
+ else
197
+ emit_json_log "deploy" "started" "Pulling Docker image: $IMAGE"
198
+ docker pull "$IMAGE"
199
+ fi
200
+ ;;
201
+ never)
202
+ if [ "$local_image_present" -eq 0 ]; then
203
+ emit_json_log "deploy" "started" "Using local Docker image: $IMAGE"
204
+ else
205
+ printf 'Error: image is not present locally and KASEKI_IMAGE_PULL_POLICY=never: %s\n' "$IMAGE" >&2
206
+ return 1
207
+ fi
208
+ ;;
209
+ *)
210
+ printf 'Error: invalid KASEKI_IMAGE_PULL_POLICY: %s (expected always, missing, if-not-present, or never)\n' "$KASEKI_IMAGE_PULL_POLICY" >&2
211
+ return 2
212
+ ;;
213
+ esac
214
+
215
+ resolved_digest="$(resolve_local_repo_digest "$IMAGE")"
216
+ if [ -n "$resolved_digest" ] && ! is_probably_digest_ref "$IMAGE"; then
217
+ emit_json_log "deploy" "started" "Resolved image tag to immutable digest: $resolved_digest"
218
+ elif [ -z "$resolved_digest" ] && ! is_probably_digest_ref "$IMAGE"; then
219
+ emit_json_log "deploy" "warning" "No repo digest found for image reference; continuing with tag: $IMAGE"
220
+ fi
221
+
222
+ if image_has_template "$IMAGE"; then
223
+ return 0
224
+ fi
225
+
226
+ if [ "$KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING" != "1" ]; then
227
+ printf 'Error: image does not contain deployable /app template: %s\n' "$IMAGE" >&2
228
+ return 1
229
+ fi
230
+
231
+ emit_json_log "deploy" "started" "Image lacks /app template; building $LOCAL_BUILD_IMAGE from checkout"
232
+ printf 'Image lacks /app template, building local fallback: %s\n' "$LOCAL_BUILD_IMAGE"
233
+ docker build --progress=plain -t "$LOCAL_BUILD_IMAGE" "$SOURCE_DIR"
234
+ IMAGE="$LOCAL_BUILD_IMAGE"
235
+
236
+ if ! image_has_template "$IMAGE"; then
237
+ printf 'Error: locally built image still does not contain /app template: %s\n' "$IMAGE" >&2
238
+ return 1
239
+ fi
240
+ }
241
+
242
+ verify_template() {
243
+ local target="$1"
244
+ local missing=0
245
+ local required
246
+ for required in run-kaseki.sh kaseki kaseki-agent.sh scripts/kaseki-preflight.sh lib/pi-event-filter.js lib/pi-progress-stream.js lib/kaseki-report.js lib/github-app-token.js; do
247
+ if [ ! -f "$target/$required" ]; then
248
+ printf 'Missing deployed template file: %s\n' "$required" >&2
249
+ missing=1
250
+ fi
251
+ done
252
+ return "$missing"
253
+ }
254
+
255
+ write_image_metadata() {
256
+ local target="$1"
257
+ local configured_image="$2"
258
+ local deployed_image="$3"
259
+ local repo_digest=""
260
+
261
+ printf '%s\n' "$configured_image" > "$target/.kaseki-image"
262
+ repo_digest="$(docker image inspect "$deployed_image" --format '{{range .RepoDigests}}{{println .}}{{end}}' 2>/dev/null | head -n 1 || true)"
263
+ if [ -n "$repo_digest" ]; then
264
+ printf '%s\n' "$repo_digest" > "$target/.kaseki-image-digest"
265
+ else
266
+ rm -f "$target/.kaseki-image-digest"
267
+ fi
268
+ }
269
+
270
+ printf 'Kaseki template deployment\n'
271
+ printf 'Source: %s\n' "$SOURCE_DIR"
272
+ printf 'Target: %s\n' "$TARGET_DIR"
273
+ printf 'Image: %s\n' "$REQUESTED_IMAGE"
274
+
275
+ prepare_target_dir "$TARGET_DIR"
276
+
277
+ ensure_deployable_image
278
+
279
+ emit_json_log "deploy" "started" "Creating container for extraction"
280
+ CONTAINER=$(docker create "$IMAGE")
281
+
282
+ emit_json_log "deploy" "started" "Extracting files from container"
283
+ docker cp "$CONTAINER:/app/." "$TARGET_DIR/"
284
+
285
+ emit_json_log "deploy" "started" "Cleaning up container"
286
+ docker rm "$CONTAINER"
287
+ CONTAINER=""
288
+
289
+ write_image_metadata "$TARGET_DIR" "$REQUESTED_IMAGE" "$IMAGE"
290
+ verify_template "$TARGET_DIR"
291
+
292
+ emit_json_log "deploy" "finished" "Deployment completed successfully"
293
+ printf '\n✓ Kaseki template deployed to: %s\n' "$TARGET_DIR"
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ case "${1:-agent}" in
5
+ setup)
6
+ # Interactive setup wizard inside container
7
+ # Usage: docker run -it -v ~/.kaseki/secrets:/secrets kaseki-agent setup
8
+ shift || true
9
+ exec /scripts/kaseki-container-setup.sh "$@"
10
+ ;;
11
+
12
+ doctor)
13
+ # Health check and diagnostics
14
+ # Usage: docker run kaseki-agent doctor
15
+ shift || true
16
+ exec /usr/local/bin/kaseki-agent --doctor
17
+ ;;
18
+
19
+ run-mode)
20
+ # One-command run with API key from environment variable
21
+ # Usage: docker run -e OPENROUTER_API_KEY=sk-or-... kaseki-agent run-mode <repo> <ref>
22
+ shift || true
23
+
24
+ # Validate API key is provided
25
+ if [ -z "${OPENROUTER_API_KEY:-}" ]; then
26
+ echo "Error: OPENROUTER_API_KEY environment variable is required for run-mode" >&2
27
+ exit 2
28
+ fi
29
+
30
+ # Create secrets directory and store key securely
31
+ mkdir -p /secrets
32
+ echo "$OPENROUTER_API_KEY" > /secrets/openrouter_api_key
33
+ chmod 600 /secrets/openrouter_api_key
34
+
35
+ # Clear env var to avoid exposure in child process
36
+ unset OPENROUTER_API_KEY
37
+
38
+ # Set required variables and execute agent
39
+ export OPENROUTER_API_KEY_FILE=/secrets/openrouter_api_key
40
+ export KASEKI_INSTANCE="${KASEKI_INSTANCE:-kaseki-run}"
41
+ export KASEKI_RESULTS_DIR="${KASEKI_RESULTS_DIR:-/results}"
42
+
43
+ exec /usr/local/bin/kaseki-agent "$@"
44
+ ;;
45
+
46
+ setup-remote)
47
+ # Remote host setup orchestration (runs from controller container)
48
+ # Usage: docker run kaseki-agent setup-remote <host> <api-key>
49
+ shift || true
50
+ exec /scripts/kaseki-container-setup-remote.sh "$@"
51
+ ;;
52
+
53
+ agent|kaseki-agent)
54
+ # Standard agent execution (existing mode)
55
+ # Usage: docker run kaseki-agent agent <repo> <ref>
56
+ shift || true
57
+ exec /usr/local/bin/kaseki-agent "$@"
58
+ ;;
59
+
60
+ api|kaseki-api)
61
+ # REST API service (existing mode)
62
+ # Usage: docker run kaseki-agent api
63
+ shift || true
64
+ exec node /app/dist/kaseki-api-service.js "$@"
65
+ ;;
66
+
67
+ *)
68
+ # Passthrough mode for debugging
69
+ exec "$@"
70
+ ;;
71
+ esac