@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,488 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { RunRequest, RunResponse, StatusResponse, AnalysisResponse, RunsListResponse, ValidationResponse } from './kaseki-api-types';
4
+
5
+ /**
6
+ * Zod schemas for response validation.
7
+ * Replaces manual type-checking with declarative schema validation.
8
+ */
9
+ const HealthResponseSchema = z.object({
10
+ status: z.string(),
11
+ errors: z.array(z.string()).optional(),
12
+ });
13
+
14
+ const ValidationResponseSchema = z.object({
15
+ isValid: z.boolean(),
16
+ checks: z.array(z.any()),
17
+ warnings: z.array(z.any()),
18
+ errors: z.array(z.any()),
19
+ });
20
+
21
+ const StructuredProgressSchema = z.object({
22
+ stage: z.string(),
23
+ percentComplete: z.number().optional(),
24
+ message: z.string().optional(),
25
+ updatedAt: z.string().optional(),
26
+ });
27
+
28
+ const StatusResponseSchema = z.object({
29
+ id: z.string(),
30
+ status: z.enum(['queued', 'running', 'completed', 'failed']),
31
+ failureClass: z.string().optional(),
32
+ error: z.string().optional(),
33
+ exitCode: z.number().optional(),
34
+ elapsedSeconds: z.number().optional(),
35
+ timeoutRiskPercent: z.number().optional(),
36
+ correlationId: z.string().optional(),
37
+ requestId: z.string().optional(),
38
+ resultDir: z.string().optional(),
39
+ progress: StructuredProgressSchema.optional(),
40
+ artifacts: z.object({
41
+ metadataJson: z.boolean(),
42
+ analysisMd: z.boolean(),
43
+ resultSummaryMd: z.boolean(),
44
+ failureJson: z.boolean(),
45
+ stderrLog: z.boolean(),
46
+ availableFiles: z.array(z.string()),
47
+ }).optional(),
48
+ diagnosticEntryPoint: z.enum(['failure.json', 'analysis.md', 'result-summary.md']).optional(),
49
+ });
50
+
51
+ const RunResponseSchema = z.object({
52
+ id: z.string(),
53
+ createdAt: z.string(),
54
+ status: z.enum(['queued', 'running', 'completed', 'failed']),
55
+ error: z.string().optional(),
56
+ });
57
+
58
+ const ProgressResponseSchema = z.object({
59
+ events: z.array(z.record(z.unknown())),
60
+ });
61
+
62
+ const AnalysisResponseSchema = z.object({
63
+ id: z.string(),
64
+ createdAt: z.string(),
65
+ status: z.enum(['queued', 'running', 'completed', 'failed']),
66
+ completedAt: z.string().optional(),
67
+ elapsedSeconds: z.number().optional(),
68
+ exitCode: z.number().optional(),
69
+ failureClass: z.string().optional(),
70
+ metadata: z.object({
71
+ model: z.string().optional(),
72
+ instance: z.string().optional(),
73
+ repo: z.string().optional(),
74
+ ref: z.string().optional(),
75
+ }).optional(),
76
+ changes: z.object({
77
+ changedFiles: z.array(z.string()),
78
+ diffSize: z.number(),
79
+ }).optional(),
80
+ validation: z.object({
81
+ passed: z.boolean(),
82
+ commandResults: z.array(z.object({
83
+ command: z.string(),
84
+ exitCode: z.number(),
85
+ elapsed: z.number(),
86
+ })),
87
+ }).optional(),
88
+ errors: z.array(z.string()).optional(),
89
+ });
90
+
91
+ const LogResponseSchema = z.object({
92
+ content: z.string(),
93
+ });
94
+
95
+ const ArtifactResponseSchema = z.object({
96
+ content: z.string(),
97
+ });
98
+
99
+ const RunsListResponseSchema = z.object({
100
+ runs: z.array(z.object({
101
+ id: z.string(),
102
+ status: z.enum(['queued', 'running', 'completed', 'failed']),
103
+ createdAt: z.string(),
104
+ completedAt: z.string().optional(),
105
+ resultDir: z.string().optional(),
106
+ exitCode: z.number().optional(),
107
+ failureClass: z.string().optional(),
108
+ error: z.string().optional(),
109
+ })),
110
+ total: z.number(),
111
+ retention: z.object({
112
+ terminalJobIndexMaxEntries: z.number(),
113
+ note: z.string(),
114
+ }).optional(),
115
+ });
116
+
117
+ /**
118
+ * Kaseki API client for TypeScript/Node.js applications.
119
+ * Simplifies integration with the Kaseki API service.
120
+ *
121
+ * Example:
122
+ * ```typescript
123
+ * const client = new KasekiApiClient('http://localhost:8080', 'sk-api-key');
124
+ *
125
+ * const run = await client.submit({
126
+ * repoUrl: 'https://github.com/org/repo',
127
+ * taskPrompt: 'Fix the bug'
128
+ * });
129
+ *
130
+ * console.log(`Run started: ${run.id}`);
131
+ *
132
+ * // Monitor
133
+ * const status = await client.getStatus(run.id);
134
+ * console.log(`Status: ${status.status}, elapsed: ${status.elapsedSeconds}s`);
135
+ * ```
136
+ */
137
+ export class KasekiApiClient {
138
+ private baseUrl: string;
139
+ private baseHeaders: Record<string, string>;
140
+ private retryConfig = {
141
+ maxAttempts: 3,
142
+ initialDelayMs: 1000,
143
+ maxDelayMs: 8000,
144
+ };
145
+
146
+ constructor(baseUrl: string, apiKey: string, retryConfig?: Partial<typeof KasekiApiClient.prototype.retryConfig>) {
147
+ this.baseUrl = baseUrl.replace(/\/$/, ''); // Remove trailing slash
148
+ this.baseHeaders = {
149
+ 'Content-Type': 'application/json',
150
+ Authorization: `Bearer ${apiKey}`,
151
+ };
152
+ if (retryConfig) {
153
+ this.retryConfig = { ...this.retryConfig, ...retryConfig };
154
+ }
155
+ }
156
+
157
+ private parseErrorDetail(value: unknown): string | undefined {
158
+ try {
159
+ const parsed = z.object({ detail: z.string() }).safeParse(value);
160
+ return parsed.success ? parsed.data.detail : undefined;
161
+ } catch {
162
+ return undefined;
163
+ }
164
+ }
165
+
166
+ /**
167
+ * Check API health.
168
+ */
169
+ async getHealth(): Promise<{ status: string; errors?: string[] }> {
170
+ const res = await fetch(`${this.baseUrl}/api/health`, {
171
+ method: 'GET',
172
+ headers: {},
173
+ });
174
+
175
+ if (!res.ok) {
176
+ throw new Error(`Health check failed: ${res.status}`);
177
+ }
178
+
179
+ const data = await res.json();
180
+ return HealthResponseSchema.parse(data);
181
+ }
182
+
183
+ /**
184
+ * Retry helper with exponential backoff.
185
+ */
186
+ private async retryWithBackoff<T>(
187
+ fn: () => Promise<T>,
188
+ description: string = 'Operation'
189
+ ): Promise<T> {
190
+ let lastError: Error | undefined;
191
+
192
+ for (let attempt = 0; attempt < this.retryConfig.maxAttempts; attempt++) {
193
+ try {
194
+ return await fn();
195
+ } catch (error) {
196
+ lastError = error instanceof Error ? error : new Error(String(error));
197
+
198
+ // Don't retry on 4xx errors (except 429 Too Many Requests)
199
+ if (
200
+ lastError.message.includes('400') ||
201
+ lastError.message.includes('401') ||
202
+ lastError.message.includes('403') ||
203
+ lastError.message.includes('404')
204
+ ) {
205
+ throw lastError;
206
+ }
207
+
208
+ // If this is the last attempt, throw
209
+ if (attempt === this.retryConfig.maxAttempts - 1) {
210
+ throw lastError;
211
+ }
212
+
213
+ // Calculate backoff
214
+ const delayMs = Math.min(
215
+ this.retryConfig.initialDelayMs * Math.pow(2, attempt),
216
+ this.retryConfig.maxDelayMs
217
+ );
218
+
219
+ // Wait before retrying
220
+ await new Promise((resolve) => setTimeout(resolve, delayMs));
221
+ }
222
+ }
223
+
224
+ throw lastError || new Error(`${description} failed after ${this.retryConfig.maxAttempts} attempts`);
225
+ }
226
+
227
+ /**
228
+ * Validate a job request before submission.
229
+ */
230
+ async validate(request: RunRequest): Promise<ValidationResponse> {
231
+ const res = await fetch(`${this.baseUrl}/api/validate`, {
232
+ method: 'POST',
233
+ headers: this.baseHeaders,
234
+ body: JSON.stringify(request),
235
+ });
236
+
237
+ if (!res.ok) {
238
+ let errorDetail: string | undefined;
239
+ try {
240
+ const errorData = await res.json();
241
+ errorDetail = this.parseErrorDetail(errorData);
242
+ } catch {
243
+ // Ignore
244
+ }
245
+ throw new Error(`Validation failed: ${errorDetail ?? res.statusText}`);
246
+ }
247
+
248
+ const data = await res.json();
249
+ return ValidationResponseSchema.parse(data);
250
+ }
251
+
252
+ /**
253
+ * Submit a new kaseki run with automatic retry and idempotency support.
254
+ */
255
+ async submit(request: RunRequest): Promise<RunResponse> {
256
+ // Auto-generate idempotency key if not provided
257
+ const idempotencyKey = request.idempotencyKey || randomUUID();
258
+ const requestWithIdempotency = { ...request, idempotencyKey };
259
+
260
+ // Perform submission with retry logic
261
+ return this.retryWithBackoff(async () => {
262
+ const res = await fetch(`${this.baseUrl}/api/runs`, {
263
+ method: 'POST',
264
+ headers: this.baseHeaders,
265
+ body: JSON.stringify(requestWithIdempotency),
266
+ });
267
+
268
+ if (!res.ok) {
269
+ let errorDetail: string | undefined;
270
+ try {
271
+ const errorData = await res.json();
272
+ errorDetail = this.parseErrorDetail(errorData);
273
+ } catch {
274
+ // Ignore non-JSON error payloads and fall back to statusText.
275
+ }
276
+ throw new Error(`Failed to submit run: ${errorDetail ?? res.statusText}`);
277
+ }
278
+
279
+ const data = await res.json();
280
+ return RunResponseSchema.parse(data);
281
+ }, 'Run submission');
282
+ }
283
+
284
+ /**
285
+ * Get the status of a run.
286
+ */
287
+ async getStatus(runId: string): Promise<StatusResponse> {
288
+ const res = await fetch(`${this.baseUrl}/api/runs/${runId}/status`, {
289
+ method: 'GET',
290
+ headers: this.baseHeaders,
291
+ });
292
+
293
+ if (res.status === 404) {
294
+ throw new Error(`Run not found: ${runId}`);
295
+ }
296
+
297
+ if (!res.ok) {
298
+ throw new Error(`Failed to get status: ${res.status}`);
299
+ }
300
+
301
+ const data = await res.json();
302
+ return StatusResponseSchema.parse(data);
303
+ }
304
+
305
+ /**
306
+ * Cancel a queued or running run.
307
+ */
308
+ async cancel(runId: string): Promise<StatusResponse> {
309
+ const res = await fetch(`${this.baseUrl}/api/runs/${runId}/cancel`, {
310
+ method: 'POST',
311
+ headers: this.baseHeaders,
312
+ });
313
+
314
+ if (res.status === 404) {
315
+ throw new Error(`Run not found: ${runId}`);
316
+ }
317
+
318
+ if (!res.ok) {
319
+ throw new Error(`Failed to cancel run: ${res.status}`);
320
+ }
321
+
322
+ const data = await res.json();
323
+ return StatusResponseSchema.parse(data);
324
+ }
325
+
326
+ /**
327
+ * Get sanitized progress events for a run.
328
+ */
329
+ async getProgress(runId: string, tail?: number): Promise<Array<Record<string, unknown>>> {
330
+ const suffix = typeof tail === 'number' ? `?tail=${encodeURIComponent(String(tail))}` : '';
331
+ const res = await fetch(`${this.baseUrl}/api/runs/${runId}/progress${suffix}`, {
332
+ method: 'GET',
333
+ headers: this.baseHeaders,
334
+ });
335
+
336
+ if (res.status === 404) {
337
+ throw new Error(`Progress not found: ${runId}`);
338
+ }
339
+
340
+ if (!res.ok) {
341
+ throw new Error(`Failed to get progress: ${res.status}`);
342
+ }
343
+
344
+ const data = await res.json();
345
+ const parsed = ProgressResponseSchema.parse(data);
346
+ return parsed.events;
347
+ }
348
+
349
+ /**
350
+ * Get comprehensive analysis of a run.
351
+ */
352
+ async getAnalysis(runId: string): Promise<AnalysisResponse> {
353
+ const res = await fetch(`${this.baseUrl}/api/runs/${runId}/analysis`, {
354
+ method: 'GET',
355
+ headers: this.baseHeaders,
356
+ });
357
+
358
+ if (res.status === 404) {
359
+ throw new Error(`Run not found: ${runId}`);
360
+ }
361
+
362
+ if (!res.ok) {
363
+ throw new Error(`Failed to get analysis: ${res.status}`);
364
+ }
365
+
366
+ const data = await res.json();
367
+ return AnalysisResponseSchema.parse(data);
368
+ }
369
+
370
+ /**
371
+ * Get a log from a run.
372
+ */
373
+ async getLog(
374
+ runId: string,
375
+ logType: 'stdout' | 'stderr' | 'validation' | 'progress' | 'quality' | 'secret-scan'
376
+ ): Promise<string> {
377
+ const res = await fetch(`${this.baseUrl}/api/runs/${runId}/logs/${logType}`, {
378
+ method: 'GET',
379
+ headers: this.baseHeaders,
380
+ });
381
+
382
+ if (res.status === 404) {
383
+ throw new Error(`Log not found: ${runId}/${logType}`);
384
+ }
385
+
386
+ if (!res.ok) {
387
+ throw new Error(`Failed to get log: ${res.status}`);
388
+ }
389
+
390
+ const data = await res.json();
391
+ const parsed = LogResponseSchema.parse(data);
392
+ return parsed.content;
393
+ }
394
+
395
+ /**
396
+ * Get an artifact (diff, metadata, etc.).
397
+ */
398
+ async getArtifact(
399
+ runId: string,
400
+ file: 'git.diff' | 'metadata.json' | 'result-summary.md' | 'pi-events.jsonl' | 'pi-summary.json'
401
+ ): Promise<string> {
402
+ const res = await fetch(`${this.baseUrl}/api/results/${runId}/${file}`, {
403
+ method: 'GET',
404
+ headers: this.baseHeaders,
405
+ });
406
+
407
+ if (res.status === 404) {
408
+ throw new Error(`Artifact not found: ${runId}/${file}`);
409
+ }
410
+
411
+ if (!res.ok) {
412
+ throw new Error(`Failed to get artifact: ${res.status}`);
413
+ }
414
+
415
+ const data = await res.json();
416
+ const parsed = ArtifactResponseSchema.parse(data);
417
+ return parsed.content;
418
+ }
419
+
420
+ /**
421
+ * List all recent runs.
422
+ */
423
+ async listRuns(): Promise<RunsListResponse> {
424
+ const res = await fetch(`${this.baseUrl}/api/runs`, {
425
+ method: 'GET',
426
+ headers: this.baseHeaders,
427
+ });
428
+
429
+ if (!res.ok) {
430
+ throw new Error(`Failed to list runs: ${res.status}`);
431
+ }
432
+
433
+ const data = await res.json();
434
+ return RunsListResponseSchema.parse(data);
435
+ }
436
+
437
+ /**
438
+ * Poll a run until completion.
439
+ * Useful for automated workflows.
440
+ */
441
+ async waitForCompletion(
442
+ runId: string,
443
+ options?: {
444
+ timeout?: number; // Max time to wait (ms)
445
+ interval?: number; // Poll interval (ms)
446
+ onProgress?: (status: StatusResponse) => void; // Progress callback
447
+ }
448
+ ): Promise<StatusResponse> {
449
+ const timeoutMs = options?.timeout || 95 * 60 * 1000; // 95 min default
450
+ const intervalMs = options?.interval || 5000; // 5 sec default
451
+ const startTime = Date.now();
452
+
453
+ // eslint-disable-next-line no-constant-condition
454
+ while (true) {
455
+ const status = await this.getStatus(runId);
456
+
457
+ if (options?.onProgress) {
458
+ options.onProgress(status);
459
+ }
460
+
461
+ if (status.status !== 'running' && status.status !== 'queued') {
462
+ return status;
463
+ }
464
+
465
+ const elapsed = Date.now() - startTime;
466
+ if (elapsed > timeoutMs) {
467
+ throw new Error(`Timeout waiting for run: ${runId}`);
468
+ }
469
+
470
+ // Sleep before next poll
471
+ await new Promise((resolve) => setTimeout(resolve, intervalMs));
472
+ }
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Helper to create a client with sensible defaults.
478
+ */
479
+ export function createKasekiClient(baseUrl?: string, apiKey?: string): KasekiApiClient {
480
+ const url = baseUrl || process.env.KASEKI_API_URL || 'http://localhost:8080';
481
+ const key = apiKey || process.env.KASEKI_API_KEY;
482
+
483
+ if (!key) {
484
+ throw new Error('KASEKI_API_KEY environment variable is required');
485
+ }
486
+
487
+ return new KasekiApiClient(url, key);
488
+ }