@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,119 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # kaseki-container-entrypoint-wrapper.sh — Credential handling helper
4
+ #
5
+ # Internal helper used by docker-entrypoint.sh to safely handle credentials
6
+ # in container entry point modes (setup, run-mode, etc).
7
+ #
8
+ # Not directly invoked by users; called from docker-entrypoint.sh
9
+
10
+ set -euo pipefail
11
+
12
+ # Securely handle credentials from environment variable
13
+ # Args: <env_var_name> <target_file> [mode]
14
+ handle_env_credential() {
15
+ local env_var="$1"
16
+ local target_file="$2"
17
+ local mode="${3:-600}"
18
+
19
+ # Read from environment
20
+ local credential="${!env_var:-}"
21
+
22
+ if [ -z "$credential" ]; then
23
+ echo "Error: $env_var environment variable is empty" >&2
24
+ return 1
25
+ fi
26
+
27
+ # Ensure directory exists
28
+ mkdir -p "$(dirname "$target_file")"
29
+
30
+ # Write to file with restricted permissions
31
+ # Using a temp file first to avoid truncation on error
32
+ local temp_file="$target_file.tmp.$$"
33
+ echo "$credential" > "$temp_file"
34
+ chmod "$mode" "$temp_file"
35
+ mv "$temp_file" "$target_file"
36
+
37
+ # Clear environment variable (security: avoid exposure in process list)
38
+ export "${env_var}="
39
+
40
+ return 0
41
+ }
42
+
43
+ # Verify credential file exists and is readable
44
+ verify_credential() {
45
+ local credential_file="$1"
46
+ local description="${2:-Credential}"
47
+
48
+ if [ ! -f "$credential_file" ]; then
49
+ echo "Error: $description file not found: $credential_file" >&2
50
+ return 1
51
+ fi
52
+
53
+ if [ ! -r "$credential_file" ]; then
54
+ echo "Error: $description file not readable: $credential_file" >&2
55
+ return 1
56
+ fi
57
+
58
+ return 0
59
+ }
60
+
61
+ # Check if credential file has valid format
62
+ validate_credential_format() {
63
+ local credential_file="$1"
64
+ local pattern="$2" # regex pattern to match
65
+
66
+ if ! grep -q "$pattern" "$credential_file" 2>/dev/null; then
67
+ echo "Error: Credential file has invalid format" >&2
68
+ return 1
69
+ fi
70
+
71
+ return 0
72
+ }
73
+
74
+ # Export credential as environment variable for child processes
75
+ # (only for backward compatibility; prefer file-based approach)
76
+ export_credential_env() {
77
+ local credential_file="$1"
78
+ local env_var_name="$2"
79
+
80
+ if [ ! -f "$credential_file" ]; then
81
+ echo "Error: Credential file not found: $credential_file" >&2
82
+ return 1
83
+ fi
84
+
85
+ local credential
86
+ credential=$(<"$credential_file")
87
+ export "$env_var_name=$credential"
88
+
89
+ return 0
90
+ }
91
+
92
+ # Main router: called from docker-entrypoint.sh
93
+ case "${1:-}" in
94
+ handle-env)
95
+ shift
96
+ handle_env_credential "$@"
97
+ ;;
98
+ verify)
99
+ shift
100
+ verify_credential "$@"
101
+ ;;
102
+ validate-format)
103
+ shift
104
+ validate_credential_format "$@"
105
+ ;;
106
+ export-env)
107
+ shift
108
+ export_credential_env "$@"
109
+ ;;
110
+ *)
111
+ echo "Usage: $0 <command> [args]"
112
+ echo "Commands:"
113
+ echo " handle-env <env_var> <target_file> [mode] # Read from env, write to file"
114
+ echo " verify <file> [description] # Verify file exists and readable"
115
+ echo " validate-format <file> <regex> # Validate file content format"
116
+ echo " export-env <file> <env_var> # Export file to env var"
117
+ exit 1
118
+ ;;
119
+ esac
@@ -0,0 +1,172 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # kaseki-container-setup-remote.sh — Remote host setup orchestrator
4
+ #
5
+ # This script runs INSIDE the kaseki-agent container to orchestrate
6
+ # setup of remote Pi/host instances via SSH.
7
+ #
8
+ # It:
9
+ # 1. Validates SSH connectivity
10
+ # 2. Securely transfers API key
11
+ # 3. Triggers setup on remote host (via Docker or script)
12
+ # 4. Validates remote readiness
13
+ #
14
+ # Entry point: docker run kaseki-agent setup-remote <host> <api-key>
15
+
16
+ set -euo pipefail
17
+
18
+ # Colors
19
+ RED='\033[0;31m'
20
+ GREEN='\033[0;32m'
21
+ YELLOW='\033[1;33m'
22
+ BLUE='\033[0;34m'
23
+ NC='\033[0m'
24
+
25
+ # Helpers
26
+ print_header() { echo -e "${BLUE}=== $1 ===${NC}"; }
27
+ print_success() { echo -e "${GREEN}✓ $1${NC}"; }
28
+ print_error() { echo -e "${RED}✗ $1${NC}" >&2; }
29
+ print_warning() { echo -e "${YELLOW}⚠ $1${NC}"; }
30
+
31
+ # Argument validation
32
+ if [ $# -lt 2 ]; then
33
+ echo "Usage: $0 <remote-host> <api-key-or-file>"
34
+ echo ""
35
+ echo "Examples:"
36
+ echo " $0 pi@192.168.88.201 sk-or-v1-your-key"
37
+ echo " $0 pi@192.168.88.201 /path/to/api-key-file"
38
+ echo ""
39
+ exit 1
40
+ fi
41
+
42
+ REMOTE_HOST="$1"
43
+ API_KEY_SOURCE="$2"
44
+
45
+ # Resolve API key
46
+ if [ -f "$API_KEY_SOURCE" ]; then
47
+ # It's a file
48
+ API_KEY=$(<"$API_KEY_SOURCE")
49
+ elif [[ "$API_KEY_SOURCE" =~ ^sk-or ]]; then
50
+ # It's an inline key
51
+ API_KEY="$API_KEY_SOURCE"
52
+ else
53
+ print_error "Invalid API key source: must be a file or start with 'sk-or'"
54
+ exit 1
55
+ fi
56
+
57
+ # Validate key format
58
+ if [[ ! "$API_KEY" =~ ^sk-or ]]; then
59
+ print_error "Invalid API key format: must start with 'sk-or'"
60
+ exit 1
61
+ fi
62
+
63
+ main() {
64
+ echo ""
65
+ echo "╔════════════════════════════════════════════════════════════╗"
66
+ echo "║ Kaseki Agent - Remote Setup Orchestrator ║"
67
+ echo "╚════════════════════════════════════════════════════════════╝"
68
+ echo ""
69
+
70
+ print_header "Configuration"
71
+ echo "Remote host: $REMOTE_HOST"
72
+ echo ""
73
+
74
+ # Step 1: SSH connectivity check
75
+ print_header "SSH Connectivity Check"
76
+ if ssh -o ConnectTimeout=5 "$REMOTE_HOST" "echo 'OK'" >/dev/null 2>&1; then
77
+ print_success "SSH connectivity to $REMOTE_HOST verified"
78
+ else
79
+ print_error "Cannot connect to $REMOTE_HOST via SSH"
80
+ print_warning "Make sure:"
81
+ print_warning " 1. Host is reachable"
82
+ print_warning " 2. SSH keys are configured"
83
+ print_warning " 3. User has permission"
84
+ exit 1
85
+ fi
86
+ echo ""
87
+
88
+ # Step 2: Create secrets directory on remote
89
+ print_header "Creating Secrets Directory on Remote Host"
90
+ if ssh "$REMOTE_HOST" "
91
+ mkdir -p ~/.kaseki/secrets
92
+ chmod 700 ~/.kaseki/secrets
93
+ [ -d ~/.kaseki/secrets ] && echo 'Secrets directory created'
94
+ " >/dev/null 2>&1; then
95
+ print_success "Secrets directory created on $REMOTE_HOST"
96
+ else
97
+ print_error "Failed to create secrets directory on remote host"
98
+ exit 1
99
+ fi
100
+ echo ""
101
+
102
+ # Step 3: Transfer API key securely via SSH
103
+ print_header "Transferring OpenRouter API Key Securely"
104
+ if echo "$API_KEY" | ssh "$REMOTE_HOST" "
105
+ cat > ~/.kaseki/secrets/openrouter_api_key
106
+ chmod 600 ~/.kaseki/secrets/openrouter_api_key
107
+ [ -f ~/.kaseki/secrets/openrouter_api_key ] && echo 'API key transferred'
108
+ " >/dev/null 2>&1; then
109
+ print_success "API key transferred and secured on $REMOTE_HOST"
110
+ else
111
+ print_error "Failed to transfer API key to remote host"
112
+ exit 1
113
+ fi
114
+ echo ""
115
+
116
+ # Step 4: Try Docker-based setup on remote (if Docker available)
117
+ print_header "Attempting Remote Setup"
118
+
119
+ # Check if Docker is available on remote
120
+ if ssh "$REMOTE_HOST" "command -v docker >/dev/null 2>&1" >/dev/null 2>&1; then
121
+ print_success "Docker available on remote host"
122
+
123
+ # Try to pull image and run setup
124
+ echo "Pulling kaseki-agent image on remote host (may take a few minutes)..."
125
+ if ssh "$REMOTE_HOST" "
126
+ docker pull docker.io/cyanautomation/kaseki-agent:latest >/dev/null 2>&1 && \
127
+ docker run -it \
128
+ -v ~/.kaseki/secrets:/secrets \
129
+ -v /var/run/docker.sock:/var/run/docker.sock \
130
+ docker.io/cyanautomation/kaseki-agent:latest \
131
+ doctor >/dev/null 2>&1
132
+ " 2>&1 | tail -10; then
133
+ print_success "Docker-based setup successful on $REMOTE_HOST"
134
+ else
135
+ print_warning "Docker-based setup had issues. Continuing..."
136
+ fi
137
+ else
138
+ print_warning "Docker not available on $REMOTE_HOST"
139
+ print_warning "Manual setup required. Guide:"
140
+ echo ""
141
+ echo " SSH to $REMOTE_HOST and run:"
142
+ echo " mkdir -p ~/.kaseki/secrets"
143
+ echo " chmod 700 ~/.kaseki/secrets"
144
+ echo " curl -fsSL https://raw.githubusercontent.com/CyanAutomation/kaseki-agent/main/scripts/kaseki-install.sh | KASEKI_CONTROLLER_MODE=1 KASEKI_REPLACE_STALE=1 sh"
145
+ echo ""
146
+ fi
147
+ echo ""
148
+
149
+ # Final status
150
+ echo "╔════════════════════════════════════════════════════════════╗"
151
+ echo -e "${GREEN}║ Setup Complete for $REMOTE_HOST! ✓${NC}"
152
+ echo "╚════════════════════════════════════════════════════════════╝"
153
+ echo ""
154
+ echo "Next steps:"
155
+ echo " 1. Verify readiness on remote host:"
156
+ echo " ssh $REMOTE_HOST 'docker run -v ~/.kaseki/secrets:/secrets docker.io/cyanautomation/kaseki-agent:latest doctor'"
157
+ echo ""
158
+ echo " 2. Run your first task on remote host:"
159
+ echo " ssh $REMOTE_HOST '"
160
+ echo " docker run -it \\"
161
+ echo " -v ~/.kaseki/secrets:/secrets \\"
162
+ echo " -v /var/run/docker.sock:/var/run/docker.sock \\"
163
+ echo " docker.io/cyanautomation/kaseki-agent:latest \\"
164
+ echo " agent https://github.com/your-org/your-repo main"
165
+ echo " '"
166
+ echo ""
167
+ echo " 3. For additional hosts:"
168
+ echo " docker run kaseki-agent setup-remote pi@192.168.88.202 \$(cat ~/.kaseki/secrets/openrouter_api_key)"
169
+ echo ""
170
+ }
171
+
172
+ main "$@"
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env bash
2
+ #
3
+ # kaseki-container-setup.sh — Setup wizard inside the container
4
+ #
5
+ # This script runs INSIDE the kaseki-agent container during setup mode.
6
+ # It:
7
+ # 1. Securely prompts for OpenRouter API key (or accepts from env var)
8
+ # 2. Creates /secrets directory with proper permissions
9
+ # 3. Validates the API key
10
+ # 4. Runs health checks
11
+ #
12
+ # Entry point: docker run -it kaseki-agent setup
13
+ # Or: docker run -e OPENROUTER_API_KEY=sk-or-... kaseki-agent setup
14
+
15
+ set -euo pipefail
16
+
17
+ # Colors for output
18
+ RED='\033[0;31m'
19
+ GREEN='\033[0;32m'
20
+ YELLOW='\033[1;33m'
21
+ BLUE='\033[0;34m'
22
+ NC='\033[0m'
23
+
24
+ # Helper functions
25
+ print_header() {
26
+ echo -e "${BLUE}=== $1 ===${NC}"
27
+ }
28
+
29
+ print_success() {
30
+ echo -e "${GREEN}✓ $1${NC}"
31
+ }
32
+
33
+ print_error() {
34
+ echo -e "${RED}✗ $1${NC}" >&2
35
+ }
36
+
37
+ print_warning() {
38
+ echo -e "${YELLOW}⚠ $1${NC}"
39
+ }
40
+
41
+ # Setup secrets directory
42
+ setup_secrets_dir() {
43
+ SECRETS_DIR="${1:-.}/secrets"
44
+ mkdir -p "$SECRETS_DIR"
45
+ chmod 700 "$SECRETS_DIR"
46
+ print_success "Secrets directory ready: $SECRETS_DIR"
47
+ }
48
+
49
+ # Get API key from various sources
50
+ get_api_key() {
51
+ print_header "OpenRouter API Key Configuration"
52
+
53
+ # Priority 1: Check if API key file already exists (mounted)
54
+ if [ -f "/secrets/openrouter_api_key" ] && [ -s "/secrets/openrouter_api_key" ]; then
55
+ print_warning "API key file already exists at /secrets/openrouter_api_key"
56
+ read -p "Use existing key? (y/n) " -n 1 -r
57
+ echo
58
+ if [[ $REPLY =~ ^[Yy]$ ]]; then
59
+ API_KEY=$(<"/secrets/openrouter_api_key")
60
+ return 0
61
+ fi
62
+ fi
63
+
64
+ # Priority 2: Check environment variable
65
+ if [ -n "${OPENROUTER_API_KEY:-}" ]; then
66
+ print_success "Using API key from OPENROUTER_API_KEY environment variable"
67
+ API_KEY="$OPENROUTER_API_KEY"
68
+ return 0
69
+ fi
70
+
71
+ # Priority 3: Prompt interactively
72
+ echo "You can obtain an API key from: https://openrouter.ai/keys"
73
+ echo ""
74
+ read -rsp "Enter your OpenRouter API key (sk-or-v1-...): " API_KEY
75
+ echo
76
+
77
+ # Validate key format
78
+ if [[ ! "$API_KEY" =~ ^sk-or ]]; then
79
+ print_error "Invalid API key format. Must start with 'sk-or'"
80
+ return 1
81
+ fi
82
+
83
+ return 0
84
+ }
85
+
86
+ # Store API key securely
87
+ store_api_key() {
88
+ local api_key="$1"
89
+ local secrets_dir="${2:-/secrets}"
90
+ local key_file="$secrets_dir/openrouter_api_key"
91
+
92
+ # Write key to file with restrictive permissions
93
+ echo "$api_key" > "$key_file"
94
+ chmod 600 "$key_file"
95
+
96
+ # Verify
97
+ if [ ! -f "$key_file" ] || [ ! -r "$key_file" ]; then
98
+ print_error "Failed to write API key to $key_file"
99
+ return 1
100
+ fi
101
+
102
+ print_success "API key stored securely at $key_file (mode 600)"
103
+ return 0
104
+ }
105
+
106
+ # Run health checks
107
+ run_health_checks() {
108
+ print_header "Running Health Checks"
109
+
110
+ # Check Docker daemon
111
+ if docker ps >/dev/null 2>&1; then
112
+ print_success "Docker daemon is accessible"
113
+ else
114
+ print_error "Docker daemon is not accessible"
115
+ print_warning "Make sure Docker socket is mounted: -v /var/run/docker.sock:/var/run/docker.sock"
116
+ return 1
117
+ fi
118
+
119
+ # Check Pi CLI
120
+ if command -v pi >/dev/null 2>&1; then
121
+ print_success "Pi CLI is available"
122
+ else
123
+ print_error "Pi CLI is not available"
124
+ return 1
125
+ fi
126
+
127
+ # Check API key file is readable
128
+ if [ -f "/secrets/openrouter_api_key" ] && [ -r "/secrets/openrouter_api_key" ]; then
129
+ print_success "API key file is readable"
130
+ else
131
+ print_error "API key file is missing or unreadable"
132
+ return 1
133
+ fi
134
+
135
+ print_success "All health checks passed"
136
+ return 0
137
+ }
138
+
139
+ # Main workflow
140
+ main() {
141
+ echo ""
142
+ echo "╔════════════════════════════════════════════════════════════╗"
143
+ echo "║ Kaseki Agent - Container Setup Wizard ║"
144
+ echo "╚════════════════════════════════════════════════════════════╝"
145
+ echo ""
146
+
147
+ # Step 1: Setup secrets directory
148
+ setup_secrets_dir "/secrets"
149
+ echo ""
150
+
151
+ # Step 2: Get API key
152
+ if ! get_api_key; then
153
+ print_error "Failed to configure API key"
154
+ exit 1
155
+ fi
156
+ echo ""
157
+
158
+ # Step 3: Store API key
159
+ if ! store_api_key "$API_KEY" "/secrets"; then
160
+ print_error "Failed to store API key"
161
+ exit 1
162
+ fi
163
+ echo ""
164
+
165
+ # Step 4: Run health checks
166
+ if ! run_health_checks; then
167
+ print_warning "Some health checks failed. Setup may have issues."
168
+ fi
169
+ echo ""
170
+
171
+ # Success message
172
+ echo "╔════════════════════════════════════════════════════════════╗"
173
+ echo -e "${GREEN}║ Setup Complete! ✓ ║${NC}"
174
+ echo "╚════════════════════════════════════════════════════════════╝"
175
+ echo ""
176
+ echo "Next steps:"
177
+ echo " 1. Run your first task:"
178
+ echo " docker run -it \\"
179
+ echo " -v ~/.kaseki/secrets:/secrets \\"
180
+ echo " -v /var/run/docker.sock:/var/run/docker.sock \\"
181
+ echo " docker.io/cyanautomation/kaseki-agent:latest \\"
182
+ echo " agent https://github.com/your-org/your-repo main"
183
+ echo ""
184
+ echo " 2. Or use the convenience wrapper (if installed):"
185
+ echo " ./kaseki agent https://github.com/your-org/your-repo main"
186
+ echo ""
187
+ echo " 3. For help:"
188
+ echo " docker run kaseki-agent --help"
189
+ echo ""
190
+ }
191
+
192
+ # Run main
193
+ main "$@"
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ TARGET_FILE="${1:-${KASEKI_HEARTBEAT_FILE:-/var/log/kaseki/heartbeat.json}}"
5
+ CHECK_CONTAINERS="${KASEKI_HEALTHCHECK_CONTAINERS:-1}"
6
+
7
+ json_encode() {
8
+ local value
9
+ value="$(cat)"
10
+ value="${value//\\/\\\\}"
11
+ value="${value//\"/\\\"}"
12
+ value="${value//$'\b'/\\b}"
13
+ value="${value//$'\f'/\\f}"
14
+ value="${value//$'\n'/\\n}"
15
+ value="${value//$'\r'/\\r}"
16
+ value="${value//$'\t'/\\t}"
17
+ printf '"%s"' "$value"
18
+ }
19
+
20
+ json_string() {
21
+ printf '%s' "$1" | json_encode
22
+ }
23
+
24
+ status_ok="true"
25
+ ts="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
26
+
27
+ has_docker="false"
28
+ docker_cmd=""
29
+ daemon_ok="false"
30
+ daemon_error=""
31
+ container_check_enabled="false"
32
+ container_count="0"
33
+ container_names_json="[]"
34
+
35
+ if command -v docker >/dev/null 2>&1; then
36
+ has_docker="true"
37
+ docker_cmd="$(command -v docker)"
38
+ fi
39
+
40
+ if [ "$has_docker" = "true" ]; then
41
+ if docker info >/dev/null 2>&1; then
42
+ daemon_ok="true"
43
+ else
44
+ daemon_error="$(docker info 2>&1 || true)"
45
+ status_ok="false"
46
+ fi
47
+ else
48
+ status_ok="false"
49
+ fi
50
+
51
+ if [ "$CHECK_CONTAINERS" = "1" ] && [ "$daemon_ok" = "true" ]; then
52
+ container_check_enabled="true"
53
+ mapfile -t names < <(docker ps --filter 'name=^kaseki-' --format '{{.Names}}' || true)
54
+ container_count="${#names[@]}"
55
+ if [ "${#names[@]}" -gt 0 ]; then
56
+ json_items=()
57
+ for n in "${names[@]}"; do
58
+ json_items+=("$(json_string "$n")")
59
+ done
60
+ container_names_json="[$(IFS=,; echo "${json_items[*]}")]"
61
+ fi
62
+ fi
63
+
64
+ overall_status="ok"
65
+ if [ "$status_ok" != "true" ]; then
66
+ overall_status="degraded"
67
+ fi
68
+
69
+ mkdir -p "$(dirname "$TARGET_FILE")"
70
+ tmp_file="$(mktemp "${TARGET_FILE}.XXXXXX")"
71
+
72
+ cat > "$tmp_file" <<JSON
73
+ {
74
+ "timestamp": $(json_string "$ts"),
75
+ "status": $(json_string "$overall_status"),
76
+ "checks": {
77
+ "docker_command": {
78
+ "ok": $has_docker,
79
+ "path": $(json_string "$docker_cmd")
80
+ },
81
+ "docker_daemon": {
82
+ "ok": $daemon_ok,
83
+ "error": $(json_string "$daemon_error")
84
+ },
85
+ "kaseki_containers": {
86
+ "enabled": $container_check_enabled,
87
+ "active_count": $container_count,
88
+ "active_names": $container_names_json
89
+ }
90
+ }
91
+ }
92
+ JSON
93
+
94
+ mv "$tmp_file" "$TARGET_FILE"
95
+ printf '%s\n' "$TARGET_FILE"
@@ -0,0 +1,50 @@
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_LOG_DIR="${KASEKI_LOG_DIR:-/var/log/kaseki}"
9
+ KASEKI_CONTROLLER_MODE="${KASEKI_CONTROLLER_MODE:-0}"
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_REPLACE_STALE="${KASEKI_REPLACE_STALE:-0}"
13
+
14
+ if [ "$KASEKI_CONTROLLER_MODE" = "1" ]; then
15
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="0"
16
+ KASEKI_IMAGE_PULL_POLICY="always"
17
+ fi
18
+
19
+ if ! command -v git >/dev/null 2>&1; then
20
+ printf 'Error: git is required to install kaseki-agent.\n' >&2
21
+ exit 1
22
+ fi
23
+
24
+ mkdir -p "$(dirname "$KASEKI_CHECKOUT_DIR")"
25
+
26
+ if [ -d "$KASEKI_CHECKOUT_DIR/.git" ]; then
27
+ if [ -n "$(git -C "$KASEKI_CHECKOUT_DIR" status --porcelain)" ]; then
28
+ if [ "$KASEKI_REPLACE_STALE" = "1" ]; then
29
+ git -C "$KASEKI_CHECKOUT_DIR" reset --hard HEAD
30
+ git -C "$KASEKI_CHECKOUT_DIR" clean -fdx
31
+ else
32
+ printf 'Error: dirty kaseki-agent checkout at %s. Set KASEKI_REPLACE_STALE=1 to reset stale local files.\n' "$KASEKI_CHECKOUT_DIR" >&2
33
+ exit 3
34
+ fi
35
+ fi
36
+ git -C "$KASEKI_CHECKOUT_DIR" fetch --prune origin
37
+ else
38
+ rm -rf "$KASEKI_CHECKOUT_DIR"
39
+ git clone "$KASEKI_REPO_URL" "$KASEKI_CHECKOUT_DIR"
40
+ fi
41
+
42
+ git -C "$KASEKI_CHECKOUT_DIR" checkout "$KASEKI_REF"
43
+ git -C "$KASEKI_CHECKOUT_DIR" pull --ff-only origin "$KASEKI_REF" 2>/dev/null || true
44
+
45
+ KASEKI_LOG_DIR="$KASEKI_LOG_DIR" \
46
+ KASEKI_CONTROLLER_MODE="$KASEKI_CONTROLLER_MODE" \
47
+ KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING="$KASEKI_BUILD_IMAGE_IF_TEMPLATE_MISSING" \
48
+ KASEKI_IMAGE_PULL_POLICY="$KASEKI_IMAGE_PULL_POLICY" \
49
+ KASEKI_REPLACE_STALE="$KASEKI_REPLACE_STALE" \
50
+ "$KASEKI_CHECKOUT_DIR/scripts/kaseki-activate.sh" --json bootstrap