@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,95 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ TMP_DIR="$(mktemp -d)"
6
+ trap 'rm -rf "$TMP_DIR"' EXIT
7
+
8
+ template_dir="$TMP_DIR/source-checkout"
9
+ fake_bin="$TMP_DIR/bin"
10
+ mkdir -p "$template_dir/scripts" "$fake_bin"
11
+ cp "$ROOT_DIR/run-kaseki.sh" "$template_dir/run-kaseki.sh"
12
+ cp "$ROOT_DIR/kaseki-agent.sh" "$template_dir/kaseki-agent.sh"
13
+ cp "$ROOT_DIR/scripts/kaseki-preflight.sh" "$template_dir/scripts/kaseki-preflight.sh"
14
+ chmod +x "$template_dir/run-kaseki.sh" "$template_dir/kaseki-agent.sh" "$template_dir/scripts/kaseki-preflight.sh"
15
+
16
+ cat > "$fake_bin/docker" <<'DOCKER'
17
+ #!/usr/bin/env bash
18
+ set -euo pipefail
19
+
20
+ if [ "${1:-}" = "--version" ]; then
21
+ printf 'Docker version test\n'
22
+ exit 0
23
+ fi
24
+
25
+ if [ "${1:-}" = "image" ] && [ "${2:-}" = "inspect" ]; then
26
+ exit 0
27
+ fi
28
+
29
+ if [ "${1:-}" = "run" ]; then
30
+ shift
31
+ if [ "${1:-}" = "--rm" ]; then shift; fi
32
+ if [ "${1:-}" = "--entrypoint" ]; then
33
+ entrypoint="${2:-}"
34
+ shift 2
35
+ else
36
+ entrypoint=""
37
+ fi
38
+ image="${1:-}"
39
+ shift || true
40
+ case "$entrypoint" in
41
+ test)
42
+ [ "${1:-}" = "-f" ] && [ "${2:-}" = "/app/run-kaseki.sh" ]
43
+ ;;
44
+ sha256sum)
45
+ case "${1:-}" in
46
+ /usr/local/bin/kaseki-agent)
47
+ sha256sum "$TEST_TEMPLATE_DIR/kaseki-agent.sh"
48
+ ;;
49
+ *)
50
+ printf '0000000000000000000000000000000000000000000000000000000000000000 %s\n' "${1:-}"
51
+ ;;
52
+ esac
53
+ ;;
54
+ *)
55
+ printf 'unexpected docker run entrypoint for %s: %s\n' "$image" "$entrypoint" >&2
56
+ exit 2
57
+ ;;
58
+ esac
59
+ exit 0
60
+ fi
61
+
62
+ printf 'unexpected docker invocation: %s\n' "$*" >&2
63
+ exit 2
64
+ DOCKER
65
+ chmod +x "$fake_bin/docker"
66
+
67
+ set +e
68
+ output="$(
69
+ cd "$template_dir" && env \
70
+ PATH="$fake_bin:/usr/bin:/bin" \
71
+ TEST_TEMPLATE_DIR="$template_dir" \
72
+ KASEKI_ROOT="$TMP_DIR/root" \
73
+ KASEKI_LOG_DIR="$TMP_DIR/logs" \
74
+ OPENROUTER_API_KEY="test-key" \
75
+ ./run-kaseki.sh --doctor 2>&1
76
+ )"
77
+ status=$?
78
+ set -e
79
+
80
+ if [ "$status" -eq 0 ]; then
81
+ printf 'Expected doctor to fail for missing deployed template files\nOutput:\n%s\n' "$output" >&2
82
+ exit 1
83
+ fi
84
+
85
+ for expected in \
86
+ 'Image/template parity: missing host file lib/pi-event-filter.js' \
87
+ 'Image/template parity: missing deployed template files; this looks like a source checkout or incomplete template.' \
88
+ 'sudo KASEKI_IMAGE_PULL_POLICY=missing ./scripts/deploy-pi-template.sh' \
89
+ '/agents/kaseki-template/run-kaseki.sh --doctor'
90
+ do
91
+ if ! printf '%s\n' "$output" | grep -Fq "$expected"; then
92
+ printf 'Expected doctor output to contain: %s\nOutput:\n%s\n' "$expected" "$output" >&2
93
+ exit 1
94
+ fi
95
+ done
@@ -0,0 +1,142 @@
1
+ #!/usr/bin/env bash
2
+ # Integration tests for github operations printf safety
3
+ # Tests that github operations skip logging doesn't break with variable substitution
4
+
5
+ set -euo pipefail
6
+
7
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
8
+ TMP_DIR="$(mktemp -d)"
9
+ trap 'rm -rf "$TMP_DIR"' EXIT
10
+
11
+ pass() { printf 'āœ“ %s\n' "$1"; }
12
+ fail() { printf 'āœ— %s\n' "$1" >&2; exit 1; }
13
+ info() { printf '[info] %s\n' "$1"; }
14
+
15
+ # Test setup
16
+ mkdir -p "$TMP_DIR/results"
17
+ RESULTS_DIR="$TMP_DIR/results"
18
+
19
+ # Test 1: printf with dash-containing variable doesn't fail
20
+ info "Test 1: printf with dash-containing skip reasons"
21
+ {
22
+ GITHUB_SKIP_REASONS=("agent_failed" "-validation_failed" "empty_diff")
23
+ printf -- 'GitHub operations: skipped (reasons: %s)\n' "$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]}")" > "$RESULTS_DIR/test1.log"
24
+ } && pass "printf with dash-containing reasons succeeded" || fail "printf with dash-containing reasons failed"
25
+
26
+ # Verify output contains all reasons
27
+ if grep -q "agent_failed,-validation_failed,empty_diff" "$RESULTS_DIR/test1.log"; then
28
+ pass "All skip reasons captured in output"
29
+ else
30
+ fail "Skip reasons not properly captured: $(cat "$RESULTS_DIR/test1.log")"
31
+ fi
32
+
33
+ # Test 2: printf with multi-argument substitution (github skip diagnostics)
34
+ info "Test 2: Multi-argument printf with exit code variables"
35
+ {
36
+ PI_EXIT=0
37
+ VALIDATION_EXIT=1
38
+ QUALITY_EXIT=0
39
+ SECRET_SCAN_EXIT=0
40
+ GITHUB_SKIP_REASONS=("validation_failed")
41
+ DIFF_NONEMPTY="true"
42
+ GITHUB_APP_ENABLED="0"
43
+
44
+ printf -- 'GitHub operations: skipped (reasons: %s; agent %s, validation %s, quality %s, secret_scan %s, diff %s, github_enabled %s)\n' \
45
+ "$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]}")" \
46
+ "$([ "$PI_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
47
+ "$([ "$VALIDATION_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
48
+ "$([ "$QUALITY_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
49
+ "$([ "$SECRET_SCAN_EXIT" -eq 0 ] && printf 'passed' || printf 'failed')" \
50
+ "$DIFF_NONEMPTY" \
51
+ "$GITHUB_APP_ENABLED" > "$RESULTS_DIR/test2.log"
52
+ } && pass "Multi-argument printf succeeded" || fail "Multi-argument printf failed"
53
+
54
+ # Verify output contains all placeholders properly filled
55
+ if grep -q "validation_failed; agent passed, validation failed, quality passed, secret_scan passed, diff true, github_enabled 0" "$RESULTS_DIR/test2.log"; then
56
+ pass "All arguments properly substituted in output"
57
+ else
58
+ fail "Arguments not properly substituted: $(cat "$RESULTS_DIR/test2.log")"
59
+ fi
60
+
61
+ # Test 3: printf with edge case: empty array expansion
62
+ info "Test 3: printf with empty skip reasons"
63
+ {
64
+ GITHUB_SKIP_REASONS=()
65
+ printf -- 'GitHub operations: skipped (reasons: %s)\n' "$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]:-none}")" > "$RESULTS_DIR/test3.log"
66
+ } && pass "printf with empty array succeeded" || fail "printf with empty array failed"
67
+
68
+ if grep -q "reasons: none" "$RESULTS_DIR/test3.log"; then
69
+ pass "Empty array handled correctly"
70
+ else
71
+ fail "Empty array not handled correctly: $(cat "$RESULTS_DIR/test3.log")"
72
+ fi
73
+
74
+ # Test 4: printf with special characters in variable values
75
+ info "Test 4: printf with special characters in REPO_URL"
76
+ {
77
+ REPO_URL="https://github.com/owner-name/repo-name.git"
78
+ printf -- 'Cannot parse GitHub repo URL: %s\n' "$REPO_URL" > "$RESULTS_DIR/test4.log"
79
+ } && pass "printf with special chars in URL succeeded" || fail "printf with special chars in URL failed"
80
+
81
+ if grep -q "owner-name/repo-name" "$RESULTS_DIR/test4.log"; then
82
+ pass "Special characters preserved in output"
83
+ else
84
+ fail "Special characters not preserved: $(cat "$RESULTS_DIR/test4.log")"
85
+ fi
86
+
87
+ # Test 5: printf with feature branch containing instance name
88
+ info "Test 5: printf with feature branch name containing dashes"
89
+ {
90
+ INSTANCE_NAME="kaseki-9142"
91
+ feature_branch="kaseki/$INSTANCE_NAME"
92
+ printf -- 'Creating feature branch: %s\n' "$feature_branch" > "$RESULTS_DIR/test5.log"
93
+ } && pass "printf with dash-containing branch name succeeded" || fail "printf with dash-containing branch name failed"
94
+
95
+ if grep -q "kaseki/kaseki-9142" "$RESULTS_DIR/test5.log"; then
96
+ pass "Feature branch name correctly output"
97
+ else
98
+ fail "Feature branch name not correct: $(cat "$RESULTS_DIR/test5.log")"
99
+ fi
100
+
101
+ # Test 6: Verify all printf calls have -- separator (source code check)
102
+ info "Test 6: Verify -- separator present in critical printf calls"
103
+ if grep -n "printf -- 'GitHub operations: skipped (reasons:" "$ROOT_DIR/kaseki-agent.sh" > /dev/null; then
104
+ pass "Primary github operations printf has -- separator"
105
+ else
106
+ fail "Primary github operations printf missing -- separator"
107
+ fi
108
+
109
+ if grep -n "printf -- 'GitHub operations: skipped (reasons:.*agent %s" "$ROOT_DIR/kaseki-agent.sh" > /dev/null; then
110
+ pass "Multi-argument github operations printf has -- separator"
111
+ else
112
+ fail "Multi-argument github operations printf missing -- separator"
113
+ fi
114
+
115
+ # Test 7: Integration test - simulate actual function behavior
116
+ info "Test 7: Simulate actual build_github_skip_reasons behavior"
117
+ {
118
+ # Simulate the skip reasons array logic
119
+ GITHUB_SKIP_REASONS=()
120
+ PI_EXIT=1
121
+ [ "$PI_EXIT" -eq 0 ] || GITHUB_SKIP_REASONS+=("agent_failed")
122
+
123
+ VALIDATION_EXIT=5
124
+ [ "$VALIDATION_EXIT" -eq 0 ] || GITHUB_SKIP_REASONS+=("validation_failed")
125
+
126
+ # Log the skip reasons safely
127
+ printf -- 'GitHub operations: skipped (reasons: %s)\n' \
128
+ "$(IFS=,; printf '%s' "${GITHUB_SKIP_REASONS[*]}")" > "$RESULTS_DIR/test7.log"
129
+ } && pass "Simulated skip reasons logic succeeded" || fail "Simulated skip reasons logic failed"
130
+
131
+ if grep -q "agent_failed,validation_failed" "$RESULTS_DIR/test7.log"; then
132
+ pass "Skip reasons correctly accumulated and logged"
133
+ else
134
+ fail "Skip reasons not correctly accumulated: $(cat "$RESULTS_DIR/test7.log")"
135
+ fi
136
+
137
+ # Summary
138
+ info "All tests passed!"
139
+ printf '\n==> Summary\n'
140
+ printf 'Tests run: 7\n'
141
+ printf 'Passed: 7\n'
142
+ printf 'Failed: 0\n'
@@ -0,0 +1,58 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+
6
+ # Load only the npm install flag helpers from kaseki-agent.sh.
7
+ eval "$(awk '
8
+ /^append_npm_install_flags\(\)/ { emit=1 }
9
+ /^dependency_cache_key\(\)/ { emit=0 }
10
+ emit { print }
11
+ ' "$ROOT_DIR/kaseki-agent.sh")"
12
+
13
+ fail() { printf 'āœ— %s\n' "$1" >&2; exit 1; }
14
+ pass() { printf 'āœ“ %s\n' "$1"; }
15
+
16
+ assert_flags() {
17
+ local label="$1"
18
+ local omit_dev="$2"
19
+ local ignore_scripts="$3"
20
+ local expected_display="$4"
21
+ shift 4
22
+ local -a expected_flags=("$@")
23
+ local -a install_flags=("stale")
24
+
25
+ KASEKI_NPM_OMIT_DEV="$omit_dev"
26
+ KASEKI_INSTALL_IGNORE_SCRIPTS="$ignore_scripts"
27
+ append_npm_install_flags install_flags
28
+
29
+ if [ "${#install_flags[@]}" -ne "${#expected_flags[@]}" ]; then
30
+ fail "$label: expected ${#expected_flags[@]} flags, got ${#install_flags[@]}"
31
+ fi
32
+
33
+ local i
34
+ for i in "${!expected_flags[@]}"; do
35
+ if [ "${install_flags[$i]}" != "${expected_flags[$i]}" ]; then
36
+ fail "$label: expected flag $i to be ${expected_flags[$i]}, got ${install_flags[$i]}"
37
+ fi
38
+ done
39
+
40
+ local display
41
+ display="$(render_npm_install_flags "${install_flags[@]}")"
42
+ if [ "$display" != "$expected_display" ]; then
43
+ fail "$label: expected display '$expected_display', got '$display'"
44
+ fi
45
+
46
+ local -a npm_args=(ci --prefer-offline "${install_flags[@]}")
47
+ local expected_count=$((2 + ${#expected_flags[@]}))
48
+ if [ "${#npm_args[@]}" -ne "$expected_count" ]; then
49
+ fail "$label: npm argument count changed during expansion"
50
+ fi
51
+
52
+ pass "$label"
53
+ }
54
+
55
+ assert_flags "no optional install flags" 0 0 "none"
56
+ assert_flags "one optional install flag (omit dev)" 1 0 "--omit=dev" "--omit=dev"
57
+ assert_flags "one optional install flag (ignore scripts)" 0 1 "--ignore-scripts" "--ignore-scripts"
58
+ assert_flags "both optional install flags" 1 1 "--omit=dev --ignore-scripts" "--omit=dev" "--ignore-scripts"
@@ -0,0 +1,178 @@
1
+ #!/usr/bin/env bash
2
+ # Integration tests for quality gate enforcement
3
+ # Tests diff size limits, allowlist validation, and secret scanning
4
+
5
+ set -euo pipefail
6
+
7
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
8
+ TMP_DIR="$(mktemp -d)"
9
+ trap 'rm -rf "$TMP_DIR"' EXIT
10
+
11
+ # Load quality gate logic from kaseki-agent.sh
12
+ eval "$(awk '
13
+ /^allowlist_pattern_to_regex\(\)/ { emit=1 }
14
+ /^compute_repo_memory_key\(\)/ { emit=0 }
15
+ emit { print }
16
+ ' "$ROOT_DIR/scripts/allowlist-helper.sh")"
17
+
18
+ pass() { printf 'āœ“ %s\n' "$1"; }
19
+ fail() { printf 'āœ— %s\n' "$1" >&2; exit 1; }
20
+
21
+ # Create a test results directory structure
22
+ mkdir -p "$TMP_DIR/results"
23
+ mkdir -p "$TMP_DIR/repo"
24
+
25
+ # Test 1: Diff size exceeds max bytes
26
+ echo "==> Test: Diff size check"
27
+ {
28
+ cd "$TMP_DIR/repo"
29
+ git init --initial-branch=main -q
30
+ git config user.email "test@kaseki.local"
31
+ git config user.name "Test User"
32
+
33
+ # Create initial commit
34
+ echo "initial" > file.txt
35
+ git add file.txt
36
+ git commit -q -m "initial"
37
+
38
+ # Generate a large diff (exceeds default 200KB)
39
+ # Create a file with 300KB of data
40
+ python3 -c "print('x' * 310000)" > large_file.txt
41
+ git add large_file.txt
42
+ git diff --cached > "$TMP_DIR/results/git.diff"
43
+
44
+ diff_size="$(wc -c < "$TMP_DIR/results/git.diff" | tr -d ' ')"
45
+ KASEKI_MAX_DIFF_BYTES=200000
46
+
47
+ if [ "$diff_size" -gt "$KASEKI_MAX_DIFF_BYTES" ]; then
48
+ pass "Diff size check: detects oversized diff ($diff_size > $KASEKI_MAX_DIFF_BYTES)"
49
+ else
50
+ fail "Diff size check: expected diff to exceed $KASEKI_MAX_DIFF_BYTES bytes, got $diff_size"
51
+ fi
52
+ }
53
+
54
+ # Test 2: Allowlist validation
55
+ echo "==> Test: Allowlist validation"
56
+ {
57
+ cd "$TMP_DIR/repo"
58
+ git diff --name-only > "$TMP_DIR/results/changed-files.txt"
59
+
60
+ # Test matching allowed files
61
+ KASEKI_CHANGED_FILES_ALLOWLIST="src/**/*.ts tests/**/*.test.ts"
62
+ allowlist_regex="$(build_allowlist_regex)"
63
+
64
+ # Should match
65
+ if printf 'src/index.ts\n' | grep -Eq "^(${allowlist_regex})$"; then
66
+ pass "Allowlist: allows src/index.ts pattern"
67
+ else
68
+ fail "Allowlist: should allow src/index.ts"
69
+ fi
70
+
71
+ # Should not match
72
+ if printf 'README.md\n' | grep -Eq "^(${allowlist_regex})$"; then
73
+ fail "Allowlist: should reject README.md"
74
+ else
75
+ pass "Allowlist: rejects README.md"
76
+ fi
77
+
78
+ # Test wildcard patterns
79
+ if printf 'src/lib/parser.ts\n' | grep -Eq "^(${allowlist_regex})$"; then
80
+ pass "Allowlist: allows nested src/lib/parser.ts"
81
+ else
82
+ fail "Allowlist: should allow src/lib/parser.ts"
83
+ fi
84
+ }
85
+
86
+ # Test 3: Secret scanning (pattern detection)
87
+ echo "==> Test: Secret scanning"
88
+ {
89
+ # Create a file with a fake API key
90
+ cat > "$TMP_DIR/results/secret-test.txt" <<'EOF'
91
+ This file has an OpenRouter API key: sk-or-aBcDeFgHiJkLmNoPqRsT
92
+ And some normal content
93
+ EOF
94
+
95
+ if grep -E 'sk-or-[A-Za-z0-9_-]{20,}' "$TMP_DIR/results/secret-test.txt" > /dev/null; then
96
+ pass "Secret scanning: detects sk-or-* pattern"
97
+ else
98
+ fail "Secret scanning: should detect sk-or-* pattern"
99
+ fi
100
+
101
+ # Create a clean file
102
+ cat > "$TMP_DIR/results/clean-test.txt" <<'EOF'
103
+ This file has no secrets
104
+ Just normal content here
105
+ EOF
106
+
107
+ if ! grep -E 'sk-or-[A-Za-z0-9_-]{20,}' "$TMP_DIR/results/clean-test.txt"; then
108
+ pass "Secret scanning: clean file passes"
109
+ else
110
+ fail "Secret scanning: clean file should pass"
111
+ fi
112
+ }
113
+
114
+ # Test 4: Overly broad allowlist patterns
115
+ echo "==> Test: Overly broad allowlist detection"
116
+ {
117
+ # Test that '*' pattern is too broad
118
+ KASEKI_CHANGED_FILES_ALLOWLIST="*"
119
+ allowlist_regex="$(build_allowlist_regex)"
120
+
121
+ # This would match everything, which is bad
122
+ test_cases=("package.json" "src/index.ts" "tests/foo.test.ts" "README.md" "Dockerfile")
123
+ all_match=true
124
+
125
+ for file in "${test_cases[@]}"; do
126
+ if ! printf '%s\n' "$file" | grep -Eq "^(${allowlist_regex})$"; then
127
+ all_match=false
128
+ break
129
+ fi
130
+ done
131
+
132
+ if [ "$all_match" = true ]; then
133
+ fail "Overly broad allowlist: '*' pattern matches everything (too permissive)"
134
+ else
135
+ pass "Allowlist prevents overly broad '*' patterns"
136
+ fi
137
+ }
138
+
139
+ # Test 5: Multiple file allowlist
140
+ echo "==> Test: Multiple file allowlist patterns"
141
+ {
142
+ KASEKI_CHANGED_FILES_ALLOWLIST="src/lib/parser.ts tests/parser.validation.ts docs/README.md"
143
+ allowlist_regex="$(build_allowlist_regex)"
144
+
145
+ allowed_files=("src/lib/parser.ts" "tests/parser.validation.ts" "docs/README.md")
146
+ rejected_files=("src/index.ts" "tests/other.test.ts" "CHANGELOG.md")
147
+
148
+ for file in "${allowed_files[@]}"; do
149
+ if printf '%s\n' "$file" | grep -Eq "^(${allowlist_regex})$"; then
150
+ pass "Allowlist: allows $file"
151
+ else
152
+ fail "Allowlist: should allow $file"
153
+ fi
154
+ done
155
+
156
+ for file in "${rejected_files[@]}"; do
157
+ if printf '%s\n' "$file" | grep -Eq "^(${allowlist_regex})$"; then
158
+ fail "Allowlist: should reject $file"
159
+ else
160
+ pass "Allowlist: rejects $file"
161
+ fi
162
+ done
163
+ }
164
+
165
+ # Test 6: Empty diff detection
166
+ echo "==> Test: Empty diff handling"
167
+ {
168
+ : > "$TMP_DIR/results/empty.diff"
169
+ empty_size="$(wc -c < "$TMP_DIR/results/empty.diff" | tr -d ' ')"
170
+
171
+ if [ "$empty_size" -eq 0 ]; then
172
+ pass "Empty diff detection: correctly identifies 0-byte diff"
173
+ else
174
+ fail "Empty diff detection: expected 0 bytes, got $empty_size"
175
+ fi
176
+ }
177
+
178
+ printf '\nāœ… All quality gate tests passed\n'
@@ -0,0 +1,103 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+ TMP_DIR="$(mktemp -d)"
6
+ trap 'rm -rf "$TMP_DIR"' EXIT
7
+
8
+ # Load only repository-memory and prompt helpers from kaseki-agent.sh.
9
+ eval "$(awk '
10
+ /^compute_repo_memory_key\(\)/ { emit=1 }
11
+ /^run_github_operations\(\)/ { emit=0 }
12
+ emit { print }
13
+ ' "$ROOT_DIR/kaseki-agent.sh")"
14
+
15
+ emit_event() { :; }
16
+ emit_error_event() { :; }
17
+
18
+ REPO_URL="https://example.com/acme/widgets.git"
19
+ GIT_REF="main"
20
+ TASK_PROMPT="Fix the widget parser."
21
+ KASEKI_AGENT_GUARDRAILS=1
22
+ KASEKI_REPO_MEMORY_MODE=summary
23
+ KASEKI_REPO_MEMORY_TTL_DAYS=30
24
+ KASEKI_REPO_MEMORY_MAX_BYTES=4096
25
+ KASEKI_DRY_RUN=0
26
+ REPO_MEMORY_KEY=""
27
+ REPO_MEMORY_DIR=""
28
+ REPO_MEMORY_FILE=""
29
+ REPO_MEMORY_STATUS="disabled"
30
+
31
+ init_repo_memory_paths
32
+ trap 'rm -rf "$TMP_DIR" "$REPO_MEMORY_DIR"' EXIT
33
+ rm -rf "$REPO_MEMORY_DIR"
34
+ mkdir -p "$REPO_MEMORY_DIR"
35
+ cat > "$REPO_MEMORY_FILE" <<'MEMORY'
36
+ # Repository Memory Summary
37
+
38
+ - Repo URL: https://example.com/acme/widgets.git
39
+ - Default ref: main
40
+ - Commit SHA: abc123
41
+ - Updated at: 2026-05-06T00:00:00Z
42
+
43
+ ## Changed files
44
+ - src/widget.ts
45
+ MEMORY
46
+
47
+ prompt="$(build_agent_prompt)"
48
+ if ! grep -q 'Prior repository context (opt-in cache' <<< "$prompt"; then
49
+ printf 'Expected build_agent_prompt to append labeled repository memory.\n' >&2
50
+ exit 1
51
+ fi
52
+ if ! grep -q 'Commit SHA: abc123' <<< "$prompt"; then
53
+ printf 'Expected appended memory to include cached metadata.\n' >&2
54
+ exit 1
55
+ fi
56
+
57
+ touch -d '45 days ago' "$REPO_MEMORY_FILE"
58
+ expired_prompt="$(build_agent_prompt)"
59
+ if grep -q 'Commit SHA: abc123' <<< "$expired_prompt"; then
60
+ printf 'Expected expired repository memory to be omitted.\n' >&2
61
+ exit 1
62
+ fi
63
+
64
+ mkdir -p /results
65
+ cat > /results/result-summary.md <<'SUMMARY'
66
+ # Kaseki Result: test
67
+ - Status: passed
68
+ - Secret scan: 0
69
+ - Task Prompt: do not persist this
70
+ SUMMARY
71
+ cat > /results/analysis.md <<'ANALYSIS'
72
+ Useful architecture note.
73
+ OPENROUTER_API_KEY=sk-or-should-not-persist
74
+ ANALYSIS
75
+ cat > /results/changed-files.txt <<'FILES'
76
+ src/widget.ts
77
+ tests/widget.test.ts
78
+ FILES
79
+ cat > /results/validation-timings.tsv <<'TIMINGS'
80
+ npm test 0 3
81
+ TIMINGS
82
+
83
+ STATUS=0
84
+ PI_EXIT=0
85
+ SECRET_SCAN_EXIT=0
86
+ KASEKI_TASK_MODE=patch
87
+ START_ISO="2026-05-06T12:00:00Z"
88
+ VALIDATION_EXIT=0
89
+ QUALITY_EXIT=0
90
+ write_repo_memory_summary
91
+
92
+ if grep -Eiq 'OPENROUTER|sk-or|Task Prompt|do not persist' "$REPO_MEMORY_FILE"; then
93
+ printf 'Expected repository memory writer to filter prompts and secrets.\n' >&2
94
+ exit 1
95
+ fi
96
+ if ! grep -q 'Useful architecture note' "$REPO_MEMORY_FILE"; then
97
+ printf 'Expected sanitized analysis note to be retained.\n' >&2
98
+ exit 1
99
+ fi
100
+ if ! grep -q 'npm test: exit 0, 3s' "$REPO_MEMORY_FILE"; then
101
+ printf 'Expected validation outcome to be summarized.\n' >&2
102
+ exit 1
103
+ fi
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env bash
2
+ # Tests for allowlist restoration behavior in kaseki-agent.sh.
3
+
4
+ set -euo pipefail
5
+
6
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
7
+ TMP_DIR="$(mktemp -d)"
8
+ trap 'rm -rf "$TMP_DIR"' EXIT
9
+
10
+ # Load allowlist helper functions used by restore_disallowed_changes().
11
+ # shellcheck source=../scripts/allowlist-helper.sh
12
+ . "$ROOT_DIR/scripts/allowlist-helper.sh"
13
+
14
+ pass() { printf 'āœ“ %s\n' "$1"; }
15
+ fail() { printf 'āœ— %s\n' "$1" >&2; exit 1; }
16
+
17
+ emit_event() {
18
+ printf '%s' "$1" >> "$TMP_DIR/results/events.log"
19
+ shift
20
+ while [ "$#" -gt 0 ]; do
21
+ printf ' %s' "$1" >> "$TMP_DIR/results/events.log"
22
+ shift
23
+ done
24
+ printf '\n' >> "$TMP_DIR/results/events.log"
25
+ }
26
+
27
+ collect_git_artifacts() {
28
+ printf 'collect_git_artifacts should not be called when restored_count=0\n' >&2
29
+ return 1
30
+ }
31
+
32
+ # Load restore_disallowed_changes() while redirecting its container-only absolute
33
+ # paths into this test's temporary workspace.
34
+ eval "$(awk '
35
+ /^restore_disallowed_changes\(\)/ { emit=1 }
36
+ /^generate_restoration_report\(\)/ { emit=0 }
37
+ emit { print }
38
+ ' "$ROOT_DIR/kaseki-agent.sh" | sed "s#/workspace/repo#$TMP_DIR/repo#g; s#/results#$TMP_DIR/results#g")"
39
+
40
+ mkdir -p "$TMP_DIR/results" "$TMP_DIR/repo"
41
+ {
42
+ cd "$TMP_DIR/repo"
43
+ git init --initial-branch=main -q
44
+ git config user.email "test@kaseki.local"
45
+ git config user.name "Test User"
46
+ printf 'original\n' > allowed.txt
47
+ git add allowed.txt
48
+ git commit -q -m "initial"
49
+ printf 'modified\n' > allowed.txt
50
+ }
51
+
52
+ printf 'allowed.txt\n' > "$TMP_DIR/results/changed-files.txt"
53
+ : > "$TMP_DIR/results/quality.log"
54
+ : > "$TMP_DIR/results/events.log"
55
+
56
+ KASEKI_RESTORE_DISALLOWED_CHANGES=1
57
+ KASEKI_CHANGED_FILES_ALLOWLIST='allowed.txt'
58
+
59
+ restore_disallowed_changes
60
+
61
+ if grep -Fq '[allowlist summary] Restored: 0 files; Kept: 1 files (coverage: 100%)' "$TMP_DIR/results/quality.log"; then
62
+ pass 'restore_disallowed_changes summarizes 0 restored / 1 kept with coverage under set -u'
63
+ else
64
+ fail 'restore_disallowed_changes did not write the expected 0 restored / 1 kept summary'
65
+ fi
66
+
67
+ if grep -Fq 'allowlist_restoration_complete restored=0 kept=1 coverage=100' "$TMP_DIR/results/events.log"; then
68
+ pass 'restore_disallowed_changes emits completion event with computed coverage'
69
+ else
70
+ fail 'restore_disallowed_changes did not emit expected coverage event'
71
+ fi
72
+
73
+
74
+ if grep -Fxq 'COPY kaseki-agent.sh /usr/local/bin/kaseki-agent' "$ROOT_DIR/Dockerfile"; then
75
+ pass 'Docker image installs /usr/local/bin/kaseki-agent directly from repository kaseki-agent.sh'
76
+ else
77
+ fail 'Dockerfile must copy repository kaseki-agent.sh to /usr/local/bin/kaseki-agent'
78
+ fi
79
+
80
+ printf '\nāœ… restore_disallowed_changes tests passed\n'