@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,297 @@
1
+ #!/usr/bin/env bash
2
+ # Test suite for printf safety and restoration report generation fixes
3
+ # Tests edge cases that could cause the "printf: - : invalid option" error
4
+
5
+ set -uo pipefail
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
8
+ TEST_RESULTS_DIR="${TMPDIR:-/tmp}/kaseki-agent-printf-safety-results.$$"
9
+ KASEKI_SCRIPT="${SCRIPT_DIR}/kaseki-agent.sh"
10
+
11
+ # Colors for output
12
+ RED='\033[0;31m'
13
+ GREEN='\033[0;32m'
14
+ YELLOW='\033[1;33m'
15
+ NC='\033[0m' # No Color
16
+
17
+ # Test counters
18
+ TESTS_RUN=0
19
+ TESTS_PASSED=0
20
+ TESTS_FAILED=0
21
+
22
+ # Setup and teardown
23
+ setup() {
24
+ mkdir -p "$TEST_RESULTS_DIR"
25
+ mkdir -p "$TEST_RESULTS_DIR/results"
26
+ cd "$TEST_RESULTS_DIR"
27
+ }
28
+
29
+ teardown() {
30
+ rm -rf "$TEST_RESULTS_DIR"
31
+ }
32
+
33
+ # Test helpers
34
+ run_test() {
35
+ local test_name="$1"
36
+ local test_func="$2"
37
+
38
+ TESTS_RUN=$((TESTS_RUN + 1))
39
+ printf '[%3d] %-60s ' "$TESTS_RUN" "$test_name"
40
+
41
+ if "$test_func" 2>/dev/null; then
42
+ printf "${GREEN}PASS${NC}\n"
43
+ TESTS_PASSED=$((TESTS_PASSED + 1))
44
+ return 0
45
+ else
46
+ printf "${RED}FAIL${NC}\n"
47
+ TESTS_FAILED=$((TESTS_FAILED + 1))
48
+ return 1
49
+ fi
50
+ }
51
+
52
+ source_validate_numeric() {
53
+ source <(sed -n '/^validate_numeric()/,/^}/p' "$KASEKI_SCRIPT")
54
+ }
55
+
56
+ source_generate_restoration_report() {
57
+ source <(sed -n '/^generate_restoration_report()/,/^}/p' "$KASEKI_SCRIPT" | sed "s#/results#${PWD}/results#g")
58
+ }
59
+
60
+ # Test: validate_numeric with valid input
61
+ test_validate_numeric_valid() {
62
+ source_validate_numeric
63
+ validate_numeric "test_var" "42"
64
+ }
65
+
66
+ # Test: validate_numeric with dash (the bug trigger)
67
+ test_validate_numeric_dash() {
68
+ source_validate_numeric
69
+ ! validate_numeric "test_var" "-"
70
+ }
71
+
72
+ # Test: validate_numeric with non-numeric input
73
+ test_validate_numeric_non_numeric() {
74
+ source_validate_numeric
75
+ ! validate_numeric "test_var" "not-a-number"
76
+ }
77
+
78
+ # Test: validate_numeric with empty input
79
+ test_validate_numeric_empty() {
80
+ source_validate_numeric
81
+ ! validate_numeric "test_var" ""
82
+ }
83
+
84
+ # Test: validate_numeric rejects values containing multiple lines
85
+ test_validate_numeric_multiline() {
86
+ source_validate_numeric
87
+ ! validate_numeric "restored_count" $'0\n0'
88
+ }
89
+
90
+ # Test: restoration report with missing file
91
+ test_restoration_report_missing_file() {
92
+ source_validate_numeric
93
+ source_generate_restoration_report
94
+
95
+ rm -f results/restoration.jsonl
96
+ generate_restoration_report # Should return 0 (skip silently)
97
+ [ $? -eq 0 ]
98
+ }
99
+
100
+ # Test: restoration report with empty file
101
+ test_restoration_report_empty_file() {
102
+ source_validate_numeric
103
+ source_generate_restoration_report
104
+
105
+ : > results/restoration.jsonl
106
+ generate_restoration_report # Should return 0 (no changes to report)
107
+ [ $? -eq 0 ]
108
+ }
109
+
110
+ # Test: restoration report with valid entries
111
+ test_restoration_report_valid_entries() {
112
+ source_validate_numeric
113
+ source_generate_restoration_report
114
+
115
+ cat > results/restoration.jsonl <<'EOF'
116
+ {"timestamp":"2026-05-07T10:00:00Z","event":"file_evaluated","file":"src/test.ts","status":"kept","reason":"matched_allowlist"}
117
+ {"timestamp":"2026-05-07T10:00:01Z","event":"file_restored","file":"docs/readme.md","status":"restored","reason":"not_in_allowlist"}
118
+ EOF
119
+
120
+ generate_restoration_report && [ -f results/restoration-report.md ] && \
121
+ grep -Fq 'Total Files Changed:** 2' results/restoration-report.md && \
122
+ grep -Fq 'Files Kept (in allowlist):** 1' results/restoration-report.md && \
123
+ grep -Fq 'Files Restored (outside allowlist):** 1' results/restoration-report.md
124
+ }
125
+
126
+ # Test: restoration report with only kept files
127
+ test_restoration_report_only_kept() {
128
+ source_validate_numeric
129
+ source_generate_restoration_report
130
+
131
+ cat > results/restoration.jsonl <<'EOF'
132
+ {"timestamp":"2026-05-07T10:00:00Z","event":"file_evaluated","file":"src/test.ts","status":"kept","reason":"matched_allowlist"}
133
+ {"timestamp":"2026-05-07T10:00:01Z","event":"file_evaluated","file":"src/lib.ts","status":"kept","reason":"matched_allowlist"}
134
+ EOF
135
+
136
+ local stderr_file=results/restoration-report.stderr
137
+ generate_restoration_report 2>"$stderr_file" && [ -f results/restoration-report.md ] && \
138
+ grep -Fq 'Total Files Changed:** 2' results/restoration-report.md && \
139
+ grep -Fq 'Files Restored (outside allowlist):** 0' results/restoration-report.md && \
140
+ grep -Fq 'Allowlist Coverage:** 100' results/restoration-report.md && \
141
+ grep -Fq 'restored_count="0"' "$stderr_file" && \
142
+ ! grep -qx '0"' "$stderr_file"
143
+ }
144
+
145
+ # Test: restoration report with only restored files
146
+ test_restoration_report_only_restored() {
147
+ source_validate_numeric
148
+ source_generate_restoration_report
149
+
150
+ cat > results/restoration.jsonl <<'EOF'
151
+ {"timestamp":"2026-05-07T10:00:00Z","event":"file_restored","file":"docs/readme.md","status":"restored","reason":"not_in_allowlist"}
152
+ {"timestamp":"2026-05-07T10:00:01Z","event":"file_restored","file":"CHANGELOG.md","status":"restored","reason":"not_in_allowlist"}
153
+ EOF
154
+
155
+ generate_restoration_report && [ -f results/restoration-report.md ] && \
156
+ grep -Fq 'Total Files Changed:** 2' results/restoration-report.md && \
157
+ grep -Fq 'Allowlist Coverage:** 0' results/restoration-report.md && \
158
+ grep -Fq 'Low Allowlist Coverage' results/restoration-report.md
159
+ }
160
+
161
+ # Test: restoration report with low coverage warning
162
+ test_restoration_report_low_coverage_warning() {
163
+ source_validate_numeric
164
+ source_generate_restoration_report
165
+
166
+ # Create scenario: 1 kept, 9 restored = 10% coverage (< 50%)
167
+ printf '{"timestamp":"2026-05-07T10:00:00Z","event":"file_evaluated","file":"src/test.ts","status":"kept","reason":"matched_allowlist"}\n' > results/restoration.jsonl
168
+ for i in {1..9}; do
169
+ printf '{"timestamp":"2026-05-07T10:00:%02d","event":"file_restored","file":"file%d.txt","status":"restored","reason":"not_in_allowlist"}\n' "$i" "$i" >> results/restoration.jsonl
170
+ done
171
+
172
+ generate_restoration_report && [ -f results/restoration-report.md ] && \
173
+ grep -Fq 'Low Allowlist Coverage' results/restoration-report.md && \
174
+ grep -Fq 'Allowlist Coverage:** 10' results/restoration-report.md
175
+ }
176
+
177
+ # Test: printf with valid numeric argument (should not fail)
178
+ test_printf_valid_numeric() {
179
+ local test_var=42
180
+ printf 'test: %d\n' "$test_var" > /dev/null 2>&1
181
+ [ $? -eq 0 ]
182
+ }
183
+
184
+ # Test: printf with dash argument (should fail without quoting)
185
+ test_printf_dash_unquoted_fails() {
186
+ local test_var="-"
187
+ # This SHOULD fail with unquoted expansion
188
+ ! printf '%d\n' $test_var > /dev/null 2>&1
189
+ }
190
+
191
+ # Test: printf with dash argument quoted (should fail with validation)
192
+ test_printf_dash_quoted_validation() {
193
+ source_validate_numeric
194
+ local test_var="-"
195
+ ! validate_numeric "test_var" "$test_var"
196
+ }
197
+
198
+ # Test: grep count fallback works
199
+ test_grep_count_fallback() {
200
+ # Empty file, grep should print one 0 and the fallback should not append another 0.
201
+ : > results/test.jsonl
202
+ local count
203
+ count=$(grep -c 'pattern' results/test.jsonl 2>/dev/null || true)
204
+ count=${count:-0}
205
+ [ "$count" = "0" ]
206
+ }
207
+
208
+ # Test: grep count fallback on missing file
209
+ test_grep_count_fallback_missing() {
210
+ # Missing file, fallback should normalize empty output to one 0.
211
+ local count
212
+ count=$(grep -c 'pattern' results/nonexistent.jsonl 2>/dev/null || true)
213
+ count=${count:-0}
214
+ [ "$count" = "0" ]
215
+ }
216
+
217
+ # Test: json_encode function availability
218
+ test_json_encode_exists() {
219
+ source <(sed -n '/^json_encode()/,/^}/p' "$KASEKI_SCRIPT")
220
+ local output=$(printf 'test' | json_encode)
221
+ [ "$output" = '"test"' ]
222
+ }
223
+
224
+ # Test: json_encode fallback when node unavailable
225
+ test_json_encode_fallback() {
226
+ source <(sed -n '/^json_encode()/,/^}/p' "$KASEKI_SCRIPT")
227
+
228
+ # Temporarily override PATH to hide node
229
+ local old_path="$PATH"
230
+ export PATH="/usr/bin:/bin" # Minimal PATH without node
231
+
232
+ local output=$(printf 'test' | json_encode 2>/dev/null || true)
233
+ # Should return empty JSON string "" or handle gracefully
234
+ export PATH="$old_path"
235
+
236
+ # Test passes if it doesn't crash
237
+ true
238
+ }
239
+
240
+ # Main test execution
241
+ main() {
242
+ printf '\n%s\n' "$(printf '=%.0s' {1..70})"
243
+ printf 'Testing Printf Safety & Restoration Report Generation Fixes\n'
244
+ printf '%s\n' "$(printf '=%.0s' {1..70})"
245
+ printf '\n'
246
+
247
+ setup
248
+
249
+ # validate_numeric tests
250
+ printf '\n%s\n' '### validate_numeric() tests'
251
+ run_test "validate_numeric with valid integer" test_validate_numeric_valid
252
+ run_test "validate_numeric rejects dash (-)" test_validate_numeric_dash
253
+ run_test "validate_numeric rejects non-numeric" test_validate_numeric_non_numeric
254
+ run_test "validate_numeric rejects empty" test_validate_numeric_empty
255
+ run_test "validate_numeric rejects multi-line value" test_validate_numeric_multiline
256
+
257
+ # restoration report tests
258
+ printf '\n%s\n' '### generate_restoration_report() tests'
259
+ run_test "restoration report skips missing file" test_restoration_report_missing_file
260
+ run_test "restoration report handles empty file" test_restoration_report_empty_file
261
+ run_test "restoration report with valid entries" test_restoration_report_valid_entries
262
+ run_test "restoration report with only kept files" test_restoration_report_only_kept
263
+ run_test "restoration report with only restored files" test_restoration_report_only_restored
264
+ run_test "restoration report low coverage warning" test_restoration_report_low_coverage_warning
265
+
266
+ # printf safety tests
267
+ printf '\n%s\n' '### printf safety tests'
268
+ run_test "printf with valid numeric argument" test_printf_valid_numeric
269
+ run_test "printf with dash (unquoted) should fail" test_printf_dash_unquoted_fails
270
+ run_test "printf with dash (validation) should fail" test_printf_dash_quoted_validation
271
+
272
+ # grep fallback tests
273
+ printf '\n%s\n' '### grep fallback tests'
274
+ run_test "grep count fallback on empty file" test_grep_count_fallback
275
+ run_test "grep count fallback on missing file" test_grep_count_fallback_missing
276
+
277
+ # json_encode tests
278
+ printf '\n%s\n' '### json_encode() tests'
279
+ run_test "json_encode function works" test_json_encode_exists
280
+ run_test "json_encode handles node unavailable" test_json_encode_fallback
281
+
282
+ # Summary
283
+ printf '\n%s\n' "$(printf '=%.0s' {1..70})"
284
+ printf 'Test Results: %d/%d passed, %d failed\n' "$TESTS_PASSED" "$TESTS_RUN" "$TESTS_FAILED"
285
+
286
+ if [ "$TESTS_FAILED" -eq 0 ]; then
287
+ printf "${GREEN}✓ All tests passed!${NC}\n"
288
+ teardown
289
+ return 0
290
+ else
291
+ printf "${RED}✗ Some tests failed${NC}\n"
292
+ printf 'Results directory: %s\n' "$TEST_RESULTS_DIR"
293
+ return 1
294
+ fi
295
+ }
296
+
297
+ main "$@"
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env bash
2
+ # Test for validation shell fix (non-login shell + directory checkpoint)
3
+ set -euo pipefail
4
+
5
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
6
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
7
+ RUNNER="$REPO_ROOT/run-kaseki.sh"
8
+
9
+ pass() { printf '✓ %s\n' "$1"; }
10
+ fail() { printf '✗ %s\n' "$1" >&2; exit 1; }
11
+
12
+ # Test 1: Verify non-login shell syntax in kaseki-agent.sh
13
+ test_non_login_shell_syntax() {
14
+ local line
15
+ line=$(grep -n 'bash -c "\$trimmed"' "$REPO_ROOT/kaseki-agent.sh" | head -1 | cut -d: -f1)
16
+ [ -n "$line" ] || fail "Non-login shell (bash -c) not found in kaseki-agent.sh"
17
+ pass "Non-login shell syntax found at line $line"
18
+
19
+ # Ensure old login shell is gone
20
+ if grep -q 'bash -lc "\$trimmed"' "$REPO_ROOT/kaseki-agent.sh"; then
21
+ fail "Old login shell syntax (bash -lc) still present in kaseki-agent.sh"
22
+ fi
23
+ pass "Old login shell syntax removed"
24
+ }
25
+
26
+ # Test 2: Verify directory checkpoint exists
27
+ test_directory_checkpoint() {
28
+ if grep -q 'Working directory /workspace/repo does not exist before validation' "$REPO_ROOT/kaseki-agent.sh"; then
29
+ pass "Directory checkpoint found in kaseki-agent.sh"
30
+ else
31
+ fail "Directory checkpoint not found"
32
+ fi
33
+ }
34
+
35
+ # Test 3: Verify enhanced diagnostics exist
36
+ test_enhanced_diagnostics() {
37
+ if grep -q 'getcwd.*No such file or directory.*cannot access parent directories' "$REPO_ROOT/kaseki-agent.sh"; then
38
+ pass "Enhanced diagnostics for getcwd errors found"
39
+ else
40
+ fail "Enhanced diagnostics not found"
41
+ fi
42
+ }
43
+
44
+ # Test 4: Verify script syntax is still valid
45
+ test_script_syntax() {
46
+ if bash -n "$REPO_ROOT/kaseki-agent.sh" >/dev/null 2>&1; then
47
+ pass "kaseki-agent.sh bash syntax is valid"
48
+ else
49
+ fail "kaseki-agent.sh has syntax errors"
50
+ fi
51
+ }
52
+
53
+ # Test 5: Verify non-login shell works for npm commands (integration test)
54
+ test_non_login_npm_command() {
55
+ local tmpdir exit_code
56
+ tmpdir=$(mktemp -d)
57
+ trap "rm -rf '$tmpdir'" EXIT
58
+
59
+ cd "$tmpdir"
60
+ npm init -y >/dev/null 2>&1
61
+ npm install eslint >/dev/null 2>&1
62
+
63
+ # Test that non-login bash can run npm commands
64
+ if bash -c "npm --version" >/dev/null 2>&1; then
65
+ pass "Non-login shell can execute npm commands"
66
+ else
67
+ fail "Non-login shell cannot execute npm commands"
68
+ fi
69
+ }
70
+
71
+ # Run all tests
72
+ printf '==> Validation Fix Tests\n'
73
+ test_non_login_shell_syntax
74
+ test_directory_checkpoint
75
+ test_enhanced_diagnostics
76
+ test_script_syntax
77
+ test_non_login_npm_command
78
+
79
+ printf '\n✓ All validation fix tests passed\n'
@@ -0,0 +1,109 @@
1
+ #!/usr/bin/env bash
2
+ # Integration test: Verify validation with non-login shell works
3
+ # This simulates the matmetrics scenario where validation commands need to run
4
+ set -euo pipefail
5
+
6
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
7
+ REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
8
+
9
+ pass() { printf '✓ %s\n' "$1"; }
10
+ fail() { printf '✗ %s\n' "$1" >&2; exit 1; }
11
+
12
+ # Create temporary test directory with npm project
13
+ setup_test_repo() {
14
+ local tmpdir="$1"
15
+ cd "$tmpdir"
16
+
17
+ # Initialize npm project with validation scripts
18
+ cat > package.json <<'EOF'
19
+ {
20
+ "name": "validation-test",
21
+ "version": "1.0.0",
22
+ "scripts": {
23
+ "check": "npm ls --depth=0",
24
+ "test": "node -e 'console.log(\"test passed\")'",
25
+ "build": "node -e 'console.log(\"build passed\")'"
26
+ }
27
+ }
28
+ EOF
29
+
30
+ # Create a simple lockfile
31
+ cat > package-lock.json <<'EOF'
32
+ {
33
+ "name": "validation-test",
34
+ "version": "1.0.0",
35
+ "lockfileVersion": 3
36
+ }
37
+ EOF
38
+ }
39
+
40
+ # Test non-login shell validation execution
41
+ test_non_login_validation() {
42
+ local tmpdir exit_code
43
+ tmpdir=$(mktemp -d)
44
+ trap "rm -rf '$tmpdir'" EXIT
45
+
46
+ setup_test_repo "$tmpdir"
47
+ cd "$tmpdir"
48
+
49
+ # Simulate the validation command execution with non-login shell
50
+ # This is what happens in kaseki-agent.sh after the fix
51
+ if bash -c "npm run check" >/dev/null 2>&1; then
52
+ pass "Non-login validation command succeeded (npm run check)"
53
+ else
54
+ fail "Non-login validation command failed"
55
+ fi
56
+ }
57
+
58
+ # Test that directory errors are caught early (checkpoint test)
59
+ test_directory_checkpoint() {
60
+ local tmpdir validation_log exit_code
61
+ tmpdir=$(mktemp -d)
62
+ trap "rm -rf '$tmpdir'" EXIT
63
+ validation_log="$tmpdir/validation.log"
64
+
65
+ # Simulate the checkpoint logic from kaseki-agent.sh
66
+ if ! [ -d /nonexistent/repo ]; then
67
+ {
68
+ printf 'ERROR: Working directory /nonexistent/repo does not exist before validation\n'
69
+ printf 'Current pwd: %s\n' "$(pwd 2>&1 || echo '<pwd failed>')"
70
+ } > "$validation_log"
71
+
72
+ if grep -q 'does not exist before validation' "$validation_log"; then
73
+ pass "Directory checkpoint properly detects missing directories"
74
+ else
75
+ fail "Directory checkpoint did not detect missing directory"
76
+ fi
77
+ fi
78
+ }
79
+
80
+ # Test enhanced diagnostics capture
81
+ test_diagnostics_capture() {
82
+ local tmpdir quality_log
83
+ tmpdir=$(mktemp -d)
84
+ trap "rm -rf '$tmpdir'" EXIT
85
+ quality_log="$tmpdir/quality.log"
86
+
87
+ # Simulate a getcwd error and verify diagnostics capture
88
+ if grep -q 'getcwd' <<< "Error: ENOENT: process.cwd failed"; then
89
+ {
90
+ printf '\n[DIAGNOSTICS] Validation command failed with directory access error:\n'
91
+ printf 'Working directory status:\n'
92
+ printf ' Current pwd: %s\n' "$(pwd 2>&1 || echo '<pwd failed>')"
93
+ printf ' /workspace/repo exists: %s\n' "$([ -d /workspace/repo ] && echo 'yes' || echo 'no')"
94
+ } > "$quality_log"
95
+
96
+ if grep -q 'DIAGNOSTICS' "$quality_log"; then
97
+ pass "Enhanced diagnostics properly captured"
98
+ else
99
+ fail "Enhanced diagnostics not captured"
100
+ fi
101
+ fi
102
+ }
103
+
104
+ printf '==> Validation Integration Tests\n'
105
+ test_non_login_validation
106
+ test_directory_checkpoint
107
+ test_diagnostics_capture
108
+
109
+ printf '\n✓ All integration tests passed\n'
@@ -0,0 +1,61 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
5
+
6
+ # Source only the allowlist matcher helpers, without running a full Kaseki job.
7
+ # shellcheck source=scripts/allowlist-helper.sh
8
+ . "$ROOT_DIR/scripts/allowlist-helper.sh"
9
+
10
+ matches_allowlist() {
11
+ local allowlist="$1" file="$2" regex
12
+ KASEKI_CHANGED_FILES_ALLOWLIST="$allowlist"
13
+ regex="$(build_allowlist_regex)"
14
+ [ -n "$regex" ] && printf '%s\n' "$file" | grep -Eq "^(${regex})$"
15
+ }
16
+
17
+ assert_matches() {
18
+ local allowlist="$1" file="$2"
19
+ if ! matches_allowlist "$allowlist" "$file"; then
20
+ printf 'Expected allowlist pattern to match file:\n pattern: %s\n file: %s\n' "$allowlist" "$file" >&2
21
+ exit 1
22
+ fi
23
+ }
24
+
25
+ assert_not_matches() {
26
+ local allowlist="$1" file="$2"
27
+ if matches_allowlist "$allowlist" "$file"; then
28
+ printf 'Expected allowlist pattern not to match file:\n pattern: %s\n file: %s\n' "$allowlist" "$file" >&2
29
+ exit 1
30
+ fi
31
+ }
32
+
33
+ assert_matches 'src/lib/parser.ts' 'src/lib/parser.ts'
34
+ assert_not_matches 'src/lib/parser.ts' 'src/lib/parser.tsx'
35
+ assert_not_matches 'src/lib/parser.ts' 'src/lib/parserats'
36
+ assert_not_matches 'src/lib/parser.ts' 'README.md'
37
+ assert_not_matches 'src/lib/parser.ts' 'package.json'
38
+
39
+ assert_matches 'src/**/*.ts' 'src/index.ts'
40
+ assert_matches 'src/**/*.ts' 'src/lib/file-storage.ts'
41
+ assert_not_matches 'src/**/*.ts' 'src/lib/file-storage.tsx'
42
+ assert_not_matches 'src/**/*.ts' 'README.md'
43
+ assert_not_matches 'src/**/*.ts' 'package.json'
44
+
45
+ assert_matches 'src/**/*.tsx' 'src/app/page.tsx'
46
+ assert_matches 'src/**/*.tsx' 'src/components/plugin-manager.tsx'
47
+ assert_not_matches 'src/**/*.tsx' 'src/components/plugin-manager.ts'
48
+ assert_not_matches 'src/**/*.tsx' 'README.md'
49
+ assert_not_matches 'src/**/*.tsx' 'package.json'
50
+
51
+ assert_matches 'docs/v?.md' 'docs/v1.md'
52
+ assert_not_matches 'docs/v?.md' 'docs/v10.md'
53
+ assert_not_matches 'docs/v?.md' 'docs/nested/v1.md'
54
+
55
+ assert_matches 'src/file+(test).ts' 'src/file+(test).ts'
56
+ assert_not_matches 'src/file+(test).ts' 'src/fileeeeeeeee.ts'
57
+ assert_not_matches 'src/file+(test).ts' 'src/filetest.ts'
58
+ assert_matches 'src/{literal}|^$.ts' 'src/{literal}|^$.ts'
59
+ assert_not_matches 'src/{literal}|^$.ts' 'src/literal.ts'
60
+ assert_matches 'src/[draft]/file.name(1).ts' 'src/[draft]/file.name(1).ts'
61
+ assert_not_matches 'src/[draft]/file.name(1).ts' 'src/d/filexname1.ts'
@@ -0,0 +1,48 @@
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 the pure dependency-cache key helpers from kaseki-agent.sh.
9
+ eval "$(awk '
10
+ /^dependency_cache_flags_identity\(\)/ { emit=1 }
11
+ /^build_agent_prompt\(\)/ { emit=0 }
12
+ emit { print }
13
+ ' "$ROOT_DIR/kaseki-agent.sh")"
14
+
15
+ cat > "$TMP_DIR/package-lock.json" <<'LOCK'
16
+ {"lockfileVersion":3,"packages":{}}
17
+ LOCK
18
+
19
+ lock_hash="$(sha256sum "$TMP_DIR/package-lock.json" | awk '{print $1}')"
20
+ node_major="24"
21
+ KASEKI_NPM_OMIT_DEV=0
22
+ KASEKI_INSTALL_IGNORE_SCRIPTS=1
23
+ flags_hash="$(dependency_cache_flags_hash)"
24
+ cache_root="$TMP_DIR/cache"
25
+
26
+ REPO_URL="https://example.com/project.git" GIT_REF="feature-a"
27
+ path_a="$cache_root/$(dependency_cache_key "$lock_hash" "$node_major" "$flags_hash")/node_modules"
28
+ REPO_URL="https://example.com/project.git" GIT_REF="feature-b"
29
+ path_b="$cache_root/$(dependency_cache_key "$lock_hash" "$node_major" "$flags_hash")/node_modules"
30
+
31
+ if [ "$path_a" != "$path_b" ]; then
32
+ printf 'Expected identical lockfile cache paths across refs:\n %s\n %s\n' "$path_a" "$path_b" >&2
33
+ exit 1
34
+ fi
35
+
36
+ expected_prefix="$cache_root/npm/$lock_hash/node-$node_major/flags-$flags_hash/node_modules"
37
+ if [ "$path_a" != "$expected_prefix" ]; then
38
+ printf 'Unexpected dependency cache path:\n expected: %s\n actual: %s\n' "$expected_prefix" "$path_a" >&2
39
+ exit 1
40
+ fi
41
+
42
+ KASEKI_NPM_OMIT_DEV=1
43
+ omit_dev_flags_hash="$(dependency_cache_flags_hash)"
44
+ omit_dev_path="$cache_root/$(dependency_cache_key "$lock_hash" "$node_major" "$omit_dev_flags_hash")/node_modules"
45
+ if [ "$path_a" = "$omit_dev_path" ]; then
46
+ printf 'Expected install flags to produce a distinct dependency cache path: %s\n' "$path_a" >&2
47
+ exit 1
48
+ fi
@@ -0,0 +1,48 @@
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 dependency restore/cache helper functions from kaseki-agent.sh.
9
+ eval "$(awk '
10
+ /^set_dependency_cache_status\(\)/ { emit=1 }
11
+ /^dependency_cache_flags_identity\(\)/ { emit=0 }
12
+ emit { print }
13
+ ' "$ROOT_DIR/kaseki-agent.sh")"
14
+
15
+ fail() { printf '✗ %s\n' "$1" >&2; exit 1; }
16
+ pass() { printf '✓ %s\n' "$1"; }
17
+
18
+ DEPENDENCY_CACHE_LOG="$TMP_DIR/dependency-cache.log"
19
+ : > "$DEPENDENCY_CACHE_LOG"
20
+
21
+ mkdir -p "$TMP_DIR/cache/node_modules/pkg" "$TMP_DIR/workspace"
22
+ printf 'cached package\n' > "$TMP_DIR/cache/node_modules/pkg/index.js"
23
+
24
+ (
25
+ cd "$TMP_DIR/workspace"
26
+ cp() {
27
+ if [ "${1:-}" = "-al" ]; then
28
+ return 1
29
+ fi
30
+ command cp "$@"
31
+ }
32
+ restore_node_modules_from_cache "$TMP_DIR/cache/node_modules" ./node_modules hardlink
33
+ [ "${DEPENDENCY_RESTORE_METHOD:-}" = "hardlink_fallback_copy" ] || fail "Expected hardlink fallback method, got ${DEPENDENCY_RESTORE_METHOD:-unset}"
34
+ )
35
+
36
+ [ -f "$TMP_DIR/workspace/node_modules/pkg/index.js" ] || fail "Fallback copy did not restore package file"
37
+ if ! grep -q 'hardlink restore failed; falling back to copy' "$DEPENDENCY_CACHE_LOG"; then
38
+ fail "Expected dependency-cache.log to include hardlink fallback message"
39
+ fi
40
+ pass "hardlink restore falls back to copy when cp -al fails"
41
+
42
+ rm -rf "$TMP_DIR/workspace/node_modules" "$TMP_DIR/published"
43
+ ln -s "$TMP_DIR/cache/node_modules" "$TMP_DIR/workspace/node_modules"
44
+ publish_node_modules_cache "$TMP_DIR/workspace/node_modules" "$TMP_DIR/published"
45
+ [ -d "$TMP_DIR/published" ] || fail "Published cache path is not a directory"
46
+ [ ! -L "$TMP_DIR/published" ] || fail "Published cache path must not be a symlink"
47
+ [ -f "$TMP_DIR/published/pkg/index.js" ] || fail "Published real directory is missing package file"
48
+ pass "cache publication materializes a real directory from symlinked node_modules"