@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,682 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * kaseki-cli.ts
5
+ *
6
+ * Command-line interface for querying and monitoring kaseki instances.
7
+ * Provides commands for listing, status polling, log streaming, error detection,
8
+ * and post-run analysis.
9
+ *
10
+ * NOTE: Repo specification (URL, branch) is handled at invocation time via run-kaseki.sh.
11
+ * This tool monitors and analyzes instances after they are created.
12
+ *
13
+ * Usage:
14
+ * kaseki-cli list
15
+ * kaseki-cli status <instance>
16
+ * kaseki-cli logs <instance> [--tail=N]
17
+ * kaseki-cli progress <instance> [--tail=N]
18
+ * kaseki-cli errors <instance>
19
+ * kaseki-cli analysis <instance>
20
+ * kaseki-cli watch <instance> [--interval=S]
21
+ * kaseki-cli follow <instance> [--tail=<log_name>]
22
+ */
23
+
24
+ import * as kasekiCliLib from './kaseki-cli-lib';
25
+ import fs from 'fs';
26
+ import path from 'path';
27
+ import { Stats } from 'fs';
28
+
29
+ interface FileStats extends Stats {}
30
+
31
+ interface FollowCallbacks {
32
+ onInfo?: (message: string) => void;
33
+ onData?: (chunk: string) => void;
34
+ onError?: (error: Error) => void;
35
+ }
36
+
37
+ interface FollowPoller {
38
+ poll: () => void;
39
+ close: () => void;
40
+ }
41
+
42
+ function statsIdentity(stats: FileStats): string {
43
+ if (typeof stats.ino === 'number' && stats.ino > 0) {
44
+ return `ino:${stats.ino}`;
45
+ }
46
+
47
+ // Fallback for filesystems that do not expose stable inode numbers.
48
+ return `mtime-size:${stats.mtimeMs}:${stats.size}`;
49
+ }
50
+
51
+ function createFollowPoller(
52
+ fsModule: typeof fs,
53
+ logPath: string,
54
+ callbacks: FollowCallbacks = {}
55
+ ): FollowPoller {
56
+ const onInfo = callbacks.onInfo || (() => {});
57
+ const onData = callbacks.onData || (() => {});
58
+ const onError = callbacks.onError || (() => {});
59
+
60
+ let fd: number | null = null;
61
+ let lastPosition = 0;
62
+ let isReading = false;
63
+ let hasQueuedPoll = false;
64
+ let lastPathIdentity: string | null = null;
65
+ let retryTimer: NodeJS.Timeout | null = null;
66
+
67
+ function isRecoverableError(err: any): boolean {
68
+ if (!err || typeof err !== 'object') {
69
+ return false;
70
+ }
71
+
72
+ if (err.code === 'ENOENT' || err.code === 'ESTALE') {
73
+ return true;
74
+ }
75
+
76
+ return (
77
+ err.code === 'EIO' || err.code === 'EBUSY' || err.code === 'EMFILE' || err.code === 'ENFILE'
78
+ );
79
+ }
80
+
81
+ function scheduleRetry(): void {
82
+ if (retryTimer !== null) {
83
+ return;
84
+ }
85
+
86
+ retryTimer = setTimeout(() => {
87
+ retryTimer = null;
88
+ poll();
89
+ }, 200);
90
+ }
91
+
92
+ function closeFd(): void {
93
+ if (fd === null) {
94
+ return;
95
+ }
96
+
97
+ try {
98
+ fsModule.closeSync(fd);
99
+ } catch {
100
+ // Ignore close failures; next open/read will surface actionable errors.
101
+ }
102
+ fd = null;
103
+ }
104
+
105
+ function openFd(): void {
106
+ fd = fsModule.openSync(logPath, 'r');
107
+ }
108
+
109
+ function resetCursor(reason: string): void {
110
+ lastPosition = 0;
111
+ onInfo(`[follow] ${reason}; resetting cursor.`);
112
+ }
113
+
114
+ function poll(): void {
115
+ if (isReading) {
116
+ hasQueuedPoll = true;
117
+ return;
118
+ }
119
+
120
+ let pathStats: FileStats;
121
+ try {
122
+ pathStats = fsModule.statSync(logPath) as FileStats;
123
+ } catch (err: any) {
124
+ if (err.code === 'ENOENT' || err.code === 'ESTALE') {
125
+ closeFd();
126
+ return;
127
+ }
128
+ onError(err);
129
+ return;
130
+ }
131
+
132
+ const currentIdentity = statsIdentity(pathStats);
133
+
134
+ if (lastPathIdentity !== null && currentIdentity !== lastPathIdentity) {
135
+ closeFd();
136
+ resetCursor('log file replaced/rotated');
137
+ }
138
+ lastPathIdentity = currentIdentity;
139
+
140
+ if (fd === null) {
141
+ try {
142
+ openFd();
143
+ } catch (err: any) {
144
+ if (err.code !== 'ENOENT' && err.code !== 'ESTALE') {
145
+ onError(err);
146
+ }
147
+ return;
148
+ }
149
+ }
150
+
151
+ let fdStats: FileStats;
152
+ try {
153
+ fdStats = fsModule.fstatSync(fd as number) as FileStats;
154
+ } catch (err: any) {
155
+ closeFd();
156
+ if (err.code !== 'ENOENT' && err.code !== 'ESTALE') {
157
+ onError(err);
158
+ }
159
+ return;
160
+ }
161
+
162
+ if (statsIdentity(fdStats) !== currentIdentity) {
163
+ closeFd();
164
+ resetCursor('underlying file descriptor became stale');
165
+ return;
166
+ }
167
+
168
+ if (pathStats.size < lastPosition) {
169
+ resetCursor('log file truncated');
170
+ }
171
+
172
+ if (pathStats.size <= lastPosition) {
173
+ return;
174
+ }
175
+
176
+ const start = lastPosition;
177
+ const end = pathStats.size - 1;
178
+ if (end < start) {
179
+ return;
180
+ }
181
+
182
+ isReading = true;
183
+ const stream = fsModule.createReadStream(logPath, {
184
+ fd: fd as number,
185
+ autoClose: false,
186
+ start,
187
+ end,
188
+ });
189
+
190
+ let data = '';
191
+ let bytesRead = 0;
192
+ stream.on('data', (chunk: any) => {
193
+ bytesRead += (chunk as Buffer).length;
194
+ data += chunk;
195
+ });
196
+
197
+ stream.on('end', () => {
198
+ if (data.length > 0) {
199
+ onData(data);
200
+ }
201
+ lastPosition += bytesRead;
202
+ isReading = false;
203
+ if (hasQueuedPoll) {
204
+ hasQueuedPoll = false;
205
+ poll();
206
+ }
207
+ });
208
+
209
+ stream.on('error', (err: Error) => {
210
+ isReading = false;
211
+ closeFd();
212
+ onError(err);
213
+ if (isRecoverableError(err)) {
214
+ scheduleRetry();
215
+ } else if (hasQueuedPoll) {
216
+ hasQueuedPoll = false;
217
+ poll();
218
+ }
219
+ });
220
+ }
221
+
222
+ function close(): void {
223
+ if (retryTimer !== null) {
224
+ clearTimeout(retryTimer);
225
+ retryTimer = null;
226
+ }
227
+ closeFd();
228
+ }
229
+
230
+ return {
231
+ poll,
232
+ close,
233
+ };
234
+ }
235
+
236
+ // ============================================================================
237
+ // Utilities
238
+ // ============================================================================
239
+
240
+ function printJson(obj: any): void {
241
+ console.log(JSON.stringify(obj, null, 2));
242
+ }
243
+
244
+ function printError(msg: string): never {
245
+ console.error(`Error: ${msg}`);
246
+ process.exit(1);
247
+ }
248
+
249
+ function parsePositiveIntOption(name: string, raw: any, min: number = 1): number {
250
+ if (raw === undefined || raw === null || raw === '') {
251
+ printError(`Invalid value for --${name}: expected an integer >= ${min}, got empty value`);
252
+ }
253
+
254
+ if (!/^-?\d+$/.test(raw)) {
255
+ printError(`Invalid value for --${name}: expected an integer >= ${min}, got "${raw}"`);
256
+ }
257
+
258
+ const parsed = Number(raw);
259
+ if (parsed < min) {
260
+ printError(`Invalid value for --${name}: expected an integer >= ${min}, got ${parsed}`);
261
+ }
262
+
263
+ return parsed;
264
+ }
265
+
266
+ interface TableRow {
267
+ [key: string]: any;
268
+ }
269
+
270
+ function printTable(data: TableRow[]): void {
271
+ if (data.length === 0) {
272
+ console.log('(empty)');
273
+ return;
274
+ }
275
+
276
+ // Determine column widths
277
+ const headers = Object.keys(data[0]);
278
+ const widths: Record<string, number> = {};
279
+ for (const header of headers) {
280
+ widths[header] = Math.max(
281
+ header.length,
282
+ ...data.map((row) => String(row[header] ?? '').length)
283
+ );
284
+ }
285
+
286
+ // Print header
287
+ const headerRow = headers.map((h) => h.padEnd(widths[h])).join(' ');
288
+ console.log(headerRow);
289
+ console.log(headers.map((h) => '='.repeat(widths[h])).join(' '));
290
+
291
+ // Print rows
292
+ for (const row of data) {
293
+ const values = headers
294
+ .map((h) => String(row[h] ?? '').padEnd(widths[h]))
295
+ .join(' ');
296
+ console.log(values);
297
+ }
298
+ }
299
+
300
+ // ============================================================================
301
+ // Commands
302
+ // ============================================================================
303
+
304
+ /**
305
+ * List all kaseki instances with basic status
306
+ */
307
+ function cmdList(_args: string[]): void {
308
+ const instances = kasekiCliLib.listInstances();
309
+
310
+ if (instances.length === 0) {
311
+ console.log('No kaseki instances found.');
312
+ return;
313
+ }
314
+
315
+ const data = instances.map((inst) => ({
316
+ Instance: inst.name,
317
+ Status: inst.status,
318
+ Stage: inst.stage,
319
+ 'Elapsed (s)': inst.elapsedSeconds !== null ? inst.elapsedSeconds : '—',
320
+ 'Exit Code': inst.exitCode !== null ? inst.exitCode : '—',
321
+ Model: inst.model.substring(0, 30),
322
+ }));
323
+
324
+ printTable(data);
325
+ }
326
+
327
+ /**
328
+ * Get status of a specific instance
329
+ */
330
+ function cmdStatus(args: string[]): void {
331
+ if (args.length < 1) {
332
+ printError('status requires instance name argument');
333
+ }
334
+
335
+ const instance = args[0];
336
+ const status = kasekiCliLib.getInstanceStatus(instance);
337
+
338
+ if (status.error) {
339
+ printError(status.error.message);
340
+ }
341
+
342
+ printJson(status);
343
+ }
344
+
345
+ /**
346
+ * Read and display log file
347
+ */
348
+ function cmdLogs(args: string[]): void {
349
+ if (args.length < 1) {
350
+ printError('logs requires instance name argument');
351
+ }
352
+
353
+ const instance = args[0];
354
+ let tailLines = 50;
355
+ let logFile = 'stdout.log';
356
+
357
+ // Parse options
358
+ for (let i = 1; i < args.length; i++) {
359
+ if (args[i].startsWith('--tail=')) {
360
+ tailLines = parsePositiveIntOption('tail', args[i].split('=')[1]);
361
+ } else if (args[i].startsWith('--file=')) {
362
+ logFile = args[i].split('=')[1];
363
+ }
364
+ }
365
+
366
+ const logs = kasekiCliLib.readLiveLog(instance, logFile, tailLines);
367
+ if (logs === null) {
368
+ printError(`Log file not found: ${logFile}`);
369
+ }
370
+
371
+ console.log(logs);
372
+ }
373
+
374
+ /**
375
+ * Display sanitized progress events.
376
+ */
377
+ function cmdProgress(args: string[]): void {
378
+ if (args.length < 1) {
379
+ printError('progress requires instance name argument');
380
+ }
381
+
382
+ const instance = args[0];
383
+ let tailLines = 20;
384
+
385
+ for (let i = 1; i < args.length; i++) {
386
+ if (args[i].startsWith('--tail=')) {
387
+ tailLines = parsePositiveIntOption('tail', args[i].split('=')[1]);
388
+ }
389
+ }
390
+
391
+ const events = kasekiCliLib.readProgressEvents(instance, tailLines);
392
+ if (events === null) {
393
+ printError('Progress file not found: progress.jsonl');
394
+ }
395
+
396
+ for (const event of events) {
397
+ const timestamp = event.timestamp || 'unknown-time';
398
+ const stage = event.stage || 'progress';
399
+ const message = event.message || '';
400
+ console.log(`[${timestamp}] ${stage}: ${message}`);
401
+ }
402
+ }
403
+
404
+ /**
405
+ * Detect and display errors in an instance
406
+ */
407
+ function cmdErrors(args: string[]): void {
408
+ if (args.length < 1) {
409
+ printError('errors requires instance name argument');
410
+ }
411
+
412
+ const instance = args[0];
413
+ const errors = kasekiCliLib.detectErrors(instance);
414
+
415
+ if (errors.length === 0) {
416
+ console.log('No errors detected.');
417
+ return;
418
+ }
419
+
420
+ const output = {
421
+ instance,
422
+ errorCount: errors.length,
423
+ errors: errors.map((e) => ({
424
+ severity: e.severity,
425
+ source: e.source,
426
+ message: e.message,
427
+ line: e.line || null,
428
+ })),
429
+ };
430
+
431
+ printJson(output);
432
+ }
433
+
434
+ /**
435
+ * Get comprehensive post-run analysis
436
+ */
437
+ function cmdAnalysis(args: string[]): void {
438
+ if (args.length < 1) {
439
+ printError('analysis requires instance name argument');
440
+ }
441
+
442
+ const instance = args[0];
443
+ const analysis = kasekiCliLib.getAnalysis(instance);
444
+
445
+ if (analysis.error) {
446
+ printError(analysis.error.message);
447
+ }
448
+
449
+ printJson(analysis);
450
+ }
451
+
452
+ /**
453
+ * Watch an instance in real-time with periodic status updates
454
+ */
455
+ function cmdWatch(args: string[]): void {
456
+ if (args.length < 1) {
457
+ printError('watch requires instance name argument');
458
+ }
459
+
460
+ const instance = args[0];
461
+ let interval = 5; // Default 5 seconds
462
+
463
+ // Parse options
464
+ for (let i = 1; i < args.length; i++) {
465
+ if (args[i].startsWith('--interval=')) {
466
+ interval = parsePositiveIntOption('interval', args[i].split('=')[1]);
467
+ }
468
+ }
469
+
470
+ console.log(`Watching ${instance} (updating every ${interval}s, Ctrl+C to stop)...\n`);
471
+
472
+ const watch = (): void => {
473
+ const status = kasekiCliLib.getInstanceStatus(instance);
474
+
475
+ if (status.error) {
476
+ console.error(`Error: ${status.error}`);
477
+ process.exit(1);
478
+ }
479
+
480
+ const timestamp = new Date().toISOString();
481
+ console.log(`[${timestamp}] Stage: ${status.stage}`);
482
+ console.log(` Elapsed: ${status.elapsedSeconds}s / ${status.timeoutSeconds}s`);
483
+
484
+ if (status.timeoutRiskPercent !== undefined && status.timeoutRiskPercent >= 0) {
485
+ console.log(` Timeout: ${status.timeoutRiskPercent.toFixed(1)}%`);
486
+ }
487
+
488
+ if (status.running) {
489
+ console.log(' Status: RUNNING');
490
+ } else if (status.status === 'pending') {
491
+ console.log(' Status: PENDING (exit code: —)');
492
+ } else {
493
+ console.log(
494
+ ` Status: ${(status.status || '').toUpperCase()} (exit code: ${status.exitCode})`
495
+ );
496
+ }
497
+
498
+ // Show recent errors
499
+ const errors = kasekiCliLib.detectErrors(instance);
500
+ if (errors.length > 0) {
501
+ const criticalErrors = errors.filter((e) => e.severity === kasekiCliLib.ErrorSeverity.CRITICAL);
502
+ if (criticalErrors.length > 0) {
503
+ console.log(` ✗ ${criticalErrors.length} critical error(s) detected`);
504
+ }
505
+ }
506
+
507
+ console.log('');
508
+
509
+ if (!status.running && status.exitCode !== null) {
510
+ console.log('Instance completed. Exiting watch mode.');
511
+ process.exit(status.exitCode === 0 ? 0 : 1);
512
+ }
513
+ };
514
+
515
+ // Initial display
516
+ watch();
517
+
518
+ // Periodic updates
519
+ const timer = setInterval(watch, interval * 1000);
520
+
521
+ // Handle Ctrl+C gracefully
522
+ process.on('SIGINT', () => {
523
+ clearInterval(timer);
524
+ console.log('\nWatch mode stopped.');
525
+ process.exit(0);
526
+ });
527
+ }
528
+
529
+ /**
530
+ * Follow/stream logs from an instance in real-time
531
+ */
532
+ function cmdFollow(args: string[]): void {
533
+ if (args.length < 1) {
534
+ printError('follow requires instance name argument');
535
+ }
536
+
537
+ const instance = args[0];
538
+ let logFile = 'stdout.log';
539
+
540
+ // Parse options
541
+ for (let i = 1; i < args.length; i++) {
542
+ if (args[i].startsWith('--tail=')) {
543
+ logFile = args[i].split('=')[1];
544
+ }
545
+ }
546
+
547
+ const logPath = path.join(kasekiCliLib.config.KASEKI_RESULTS_DIR, instance, logFile);
548
+
549
+ if (!fs.existsSync(logPath)) {
550
+ printError(`Log file not found: ${logFile}`);
551
+ }
552
+
553
+ console.log(`Following ${logFile}...\n`);
554
+
555
+ const poller = createFollowPoller(fs, logPath, {
556
+ onInfo: (message) => console.log(message),
557
+ onData: (chunk) => process.stdout.write(chunk),
558
+ onError: (err) => console.error(`Error reading log: ${err.message}`),
559
+ });
560
+
561
+ // Initial read
562
+ poller.poll();
563
+
564
+ // Poll for new data
565
+ const timer = setInterval(() => poller.poll(), 1000);
566
+
567
+ // Handle Ctrl+C gracefully
568
+ process.on('SIGINT', () => {
569
+ clearInterval(timer);
570
+ poller.close();
571
+ console.log('\n\nFollow mode stopped.');
572
+ process.exit(0);
573
+ });
574
+ }
575
+
576
+ // ============================================================================
577
+ // Help
578
+ // ============================================================================
579
+
580
+ function showHelp(): void {
581
+ const help = `
582
+ kaseki-cli - Kaseki Agent instance monitoring and analysis
583
+
584
+ USAGE:
585
+ kaseki-cli <command> [args] [options]
586
+
587
+ COMMANDS:
588
+ list List all instances with status
589
+ status <instance> Get status of a specific instance (JSON)
590
+ logs <instance> Display recent log lines (tail)
591
+ Options: --tail=N --file=<name>
592
+ progress <instance> Display sanitized progress events
593
+ Options: --tail=N
594
+ errors <instance> Detect and list errors (JSON)
595
+ analysis <instance> Get post-run analysis (JSON)
596
+ watch <instance> Live monitor instance with status updates
597
+ Options: --interval=S
598
+ follow <instance> Stream logs in real-time
599
+ Options: --tail=<log_name>
600
+
601
+ OPTIONS:
602
+ --tail=N Number of lines to display (default: 50)
603
+ --file=<name> Log file name (stdout.log, validation.log, etc.)
604
+ --tail=<name> For follow: which log to stream
605
+ --interval=S For watch: polling interval in seconds (default: 5)
606
+
607
+ EXAMPLES:
608
+ # Start a kaseki run with custom repo (see run-kaseki.sh for more options)
609
+ ./run-kaseki.sh https://github.com/org/repo feature/branch
610
+
611
+ # Monitor the instance
612
+ kaseki-cli list
613
+ kaseki-cli status kaseki-1
614
+ kaseki-cli status kaseki-1 | jq .timeoutRiskPercent
615
+ kaseki-cli logs kaseki-1 --tail=100
616
+ kaseki-cli progress kaseki-1 --tail=25
617
+ kaseki-cli errors kaseki-1
618
+ kaseki-cli analysis kaseki-1
619
+ kaseki-cli watch kaseki-1 --interval=2
620
+ kaseki-cli follow kaseki-1
621
+ kaseki-cli follow kaseki-1 --tail=validation.log
622
+
623
+ SEE ALSO:
624
+ ./run-kaseki.sh --help Invocation options for kaseki-agent (repo, ref, etc.)
625
+ `;
626
+ console.log(help);
627
+ }
628
+
629
+ // ============================================================================
630
+ // Main
631
+ // ============================================================================
632
+
633
+ function main(): void {
634
+ const args = process.argv.slice(2);
635
+
636
+ if (args.length === 0 || args[0] === 'help' || args[0] === '-h' || args[0] === '--help') {
637
+ showHelp();
638
+ process.exit(0);
639
+ }
640
+
641
+ const command = args[0];
642
+ const cmdArgs = args.slice(1);
643
+
644
+ try {
645
+ switch (command) {
646
+ case 'list':
647
+ cmdList(cmdArgs);
648
+ break;
649
+ case 'status':
650
+ cmdStatus(cmdArgs);
651
+ break;
652
+ case 'logs':
653
+ cmdLogs(cmdArgs);
654
+ break;
655
+ case 'progress':
656
+ cmdProgress(cmdArgs);
657
+ break;
658
+ case 'errors':
659
+ cmdErrors(cmdArgs);
660
+ break;
661
+ case 'analysis':
662
+ cmdAnalysis(cmdArgs);
663
+ break;
664
+ case 'watch':
665
+ cmdWatch(cmdArgs);
666
+ break;
667
+ case 'follow':
668
+ cmdFollow(cmdArgs);
669
+ break;
670
+ default:
671
+ printError(`Unknown command: ${command}`);
672
+ }
673
+ } catch (err) {
674
+ printError((err as Error).message);
675
+ }
676
+ }
677
+
678
+ if (!process.env.JEST_WORKER_ID) {
679
+ main();
680
+ }
681
+
682
+ export { createFollowPoller, printTable };