hammerkit 1.5.1 → 1.6.0-alpha.2

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 (480) hide show
  1. package/.agents/FEEDBACK.md +74 -0
  2. package/.agents/skills/before-commit/SKILL.md +101 -0
  3. package/.agents/skills/do-the-work/SKILL.md +64 -0
  4. package/.agents/skills/fix-ci/SKILL.md +98 -0
  5. package/.agents/skills/speckit-git-commit/SKILL.md +53 -0
  6. package/.agents/skills/speckit-git-feature/SKILL.md +72 -0
  7. package/.agents/skills/speckit-git-initialize/SKILL.md +54 -0
  8. package/.agents/skills/speckit-git-remote/SKILL.md +50 -0
  9. package/.agents/skills/speckit-git-validate/SKILL.md +54 -0
  10. package/.gitbook.yaml +5 -0
  11. package/.specify/extensions/.registry +37 -0
  12. package/.specify/extensions/git/README.md +100 -0
  13. package/.specify/extensions/git/commands/speckit.git.commit.md +48 -0
  14. package/.specify/extensions/git/commands/speckit.git.feature.md +67 -0
  15. package/.specify/extensions/git/commands/speckit.git.initialize.md +49 -0
  16. package/.specify/extensions/git/commands/speckit.git.remote.md +45 -0
  17. package/.specify/extensions/git/commands/speckit.git.validate.md +49 -0
  18. package/.specify/extensions/git/config-template.yml +62 -0
  19. package/.specify/extensions/git/extension.yml +140 -0
  20. package/.specify/extensions/git/git-config.yml +62 -0
  21. package/.specify/extensions.yml +149 -0
  22. package/.specify/feature.json +3 -0
  23. package/.specify/init-options.json +10 -0
  24. package/.specify/integration.json +15 -0
  25. package/.specify/integrations/claude.manifest.json +16 -0
  26. package/.specify/integrations/speckit.manifest.json +17 -0
  27. package/.specify/memory/constitution.md +162 -0
  28. package/.specify/templates/checklist-template.md +40 -0
  29. package/.specify/templates/constitution-template.md +50 -0
  30. package/.specify/templates/plan-template.md +113 -0
  31. package/.specify/templates/spec-template.md +131 -0
  32. package/.specify/templates/tasks-template.md +252 -0
  33. package/.specify/workflows/speckit/workflow.yml +77 -0
  34. package/.specify/workflows/workflow-registry.json +13 -0
  35. package/AGENTS.md +94 -0
  36. package/Dockerfile +3 -3
  37. package/FOLLOWUPS.md +34 -0
  38. package/README.md +9 -7
  39. package/SUMMARY.md +30 -5
  40. package/VALUES.md +53 -0
  41. package/build.schema.json +542 -408
  42. package/dist/cache/auto-pull.spec.js +123 -0
  43. package/dist/cache/backends/local-cache-backend.js +56 -0
  44. package/dist/cache/backends/local-cache-backend.spec.js +72 -0
  45. package/dist/cache/backends/s3-cache-backend.js +124 -0
  46. package/dist/cache/backends/s3-cache-backend.spec.js +118 -0
  47. package/dist/cache/cache-backend-registry.js +21 -0
  48. package/dist/cache/cache-backend-registry.spec.js +22 -0
  49. package/dist/cache/cache-backend.js +3 -0
  50. package/dist/cache/resolve-cache.js +60 -0
  51. package/dist/cache/resolve-cache.spec.js +52 -0
  52. package/dist/cli.js +112 -82
  53. package/dist/cli.spec.js +20 -2
  54. package/dist/console/get-logger.spec.js +23 -0
  55. package/dist/docker/get-default-platform.spec.js +29 -0
  56. package/dist/docker/longest-common-prefix.spec.js +26 -0
  57. package/dist/docker/package.js +283 -0
  58. package/dist/docker/package.spec.js +145 -0
  59. package/dist/docker/pull.js +4 -4
  60. package/dist/docker/remove-container.spec.js +32 -0
  61. package/dist/docker/stream.js +3 -3
  62. package/dist/docker/using-container.js +29 -11
  63. package/dist/docker/using-container.spec.js +90 -0
  64. package/dist/environment/merge-environment-variables.js +21 -0
  65. package/dist/environment/merge-environment-variables.spec.js +24 -0
  66. package/dist/environment/replace-env-variables.js +43 -10
  67. package/dist/environment/replace-env-variables.spec.js +47 -0
  68. package/dist/executer/abort.spec.js +18 -0
  69. package/dist/executer/await-completed-dependencies.js +56 -0
  70. package/dist/executer/cache-metadata.js +11 -0
  71. package/dist/executer/check-readiness.js +1 -1
  72. package/dist/{planner/work-node-port.js → executer/container-bind.js} +1 -1
  73. package/dist/executer/docker-service.js +110 -86
  74. package/dist/executer/docker-task.js +132 -0
  75. package/dist/executer/environment-mock.js +3 -4
  76. package/dist/executer/environment-mock.spec.js +22 -0
  77. package/dist/executer/event-cache.js +60 -127
  78. package/dist/executer/execute-command.js +4 -3
  79. package/dist/executer/execute-docker.js +32 -14
  80. package/dist/executer/execute-work-service.js +61 -0
  81. package/dist/executer/execute-work-task.js +107 -0
  82. package/dist/executer/execute-work-tree.js +27 -0
  83. package/dist/executer/execute.spec.js +14 -10
  84. package/dist/executer/execution-steps.js +47 -31
  85. package/dist/executer/get-container-binds.js +19 -0
  86. package/dist/executer/get-docker-executor.js +12 -12
  87. package/dist/executer/get-scheduler-down-result.js +12 -0
  88. package/dist/executer/get-scheduler-execute-result.js +28 -0
  89. package/dist/executer/get-scheduler-up-result.js +12 -0
  90. package/dist/executer/get-service-containers.js +14 -0
  91. package/dist/executer/get-service-containers.spec.js +59 -0
  92. package/dist/executer/get-service-env-hints.js +35 -0
  93. package/dist/executer/get-service-env-hints.spec.js +65 -0
  94. package/dist/executer/kubernetes-service.js +116 -48
  95. package/dist/executer/label-values.js +29 -46
  96. package/dist/executer/label-values.spec.js +61 -0
  97. package/dist/executer/lazy-resolver.js +16 -0
  98. package/dist/executer/lazy-resolver.spec.js +20 -0
  99. package/dist/executer/local-task.js +44 -0
  100. package/dist/executer/process-manager.js +16 -70
  101. package/dist/executer/process-manager.spec.js +39 -76
  102. package/dist/executer/reset-work-tree.js +30 -0
  103. package/dist/executer/scheduler/check-for-loop.js +17 -7
  104. package/dist/executer/scheduler/{scheduler-state.js → dependency-state.js} +1 -1
  105. package/dist/executer/scheduler/enqueue-next.js +83 -19
  106. package/dist/executer/scheduler/enqueue-next.spec.js +136 -0
  107. package/dist/executer/scheduler/{node-state.js → need-state.js} +1 -1
  108. package/dist/{parser/build-file.js → executer/scheduler/task-state.js} +1 -1
  109. package/dist/executer/set-user-permission.js +1 -1
  110. package/dist/executer/state-resolver.js +61 -0
  111. package/dist/executer/state-resolver.spec.js +37 -0
  112. package/dist/executer/state.js +37 -31
  113. package/dist/executer/state.spec.js +66 -0
  114. package/dist/executer/states.spec.js +14 -0
  115. package/dist/executer/watch-loop.js +68 -0
  116. package/dist/executer/watch-state-key.js +44 -0
  117. package/dist/executer/work-scope.js +1 -5
  118. package/dist/file/get-file-context.js +24 -3
  119. package/dist/file/get-file-context.spec.js +178 -0
  120. package/dist/file/move-files.js +2 -2
  121. package/dist/file/move-files.spec.js +48 -0
  122. package/dist/index.js +7 -8
  123. package/dist/json-schema.js +12 -0
  124. package/dist/kubernetes/apply.js +34 -0
  125. package/dist/kubernetes/await-running-state.js +71 -0
  126. package/dist/kubernetes/ensure-http-route.js +53 -0
  127. package/dist/kubernetes/ensure-http-route.spec.js +70 -0
  128. package/dist/kubernetes/ensure-ingress.js +54 -0
  129. package/dist/kubernetes/ensure-kubernetes-deployment-exists.js +105 -0
  130. package/dist/kubernetes/ensure-kubernetes-persistent-volume-claim-exists.js +40 -0
  131. package/dist/kubernetes/ensure-kubernetes-service-exists.js +36 -0
  132. package/dist/kubernetes/ensure-namespace.js +43 -0
  133. package/dist/kubernetes/ensure-namespace.spec.js +39 -0
  134. package/dist/kubernetes/ensure-persistent-data.js +158 -0
  135. package/dist/kubernetes/get-service-ip.js +11 -0
  136. package/dist/kubernetes/kubernetes-instance.js +48 -0
  137. package/dist/kubernetes/remove-persistent-data.js +19 -0
  138. package/dist/kubernetes/resolve-pod-name.js +42 -0
  139. package/dist/kubernetes/resolve-pod-name.spec.js +81 -0
  140. package/dist/kubernetes/resources.js +12 -0
  141. package/dist/kubernetes/restore-kubernetes-data.js +42 -0
  142. package/dist/kubernetes/store-kubernetes-data.js +39 -0
  143. package/dist/kubernetes/volumes.js +64 -0
  144. package/dist/log.js +69 -69
  145. package/dist/log.spec.js +131 -0
  146. package/dist/logging/grouped-logger.js +17 -15
  147. package/dist/logging/grouped-logger.spec.js +84 -0
  148. package/dist/logging/interactive-logger.js +1 -1
  149. package/dist/logging/interactive-logger.spec.js +57 -0
  150. package/dist/logging/live-logger.js +2 -2
  151. package/dist/logging/live-logger.spec.js +37 -0
  152. package/dist/logging/loggers.spec.js +154 -0
  153. package/dist/optimizer/calculate-checksum.spec.js +34 -0
  154. package/dist/optimizer/get-cache-directory.js +6 -6
  155. package/dist/optimizer/get-cache-directory.spec.js +59 -0
  156. package/dist/optimizer/get-work-cache-stats.js +53 -0
  157. package/dist/optimizer/get-work-cache-stats.spec.js +79 -0
  158. package/dist/{parser/build-file-task.js → optimizer/work-cache-stats.js} +1 -1
  159. package/dist/optimizer/work-task-cache-description.js +25 -0
  160. package/dist/optimizer/work-task-cache-description.spec.js +45 -0
  161. package/dist/parser/default-build-file.js +14 -7
  162. package/dist/parser/default-build-file.spec.js +48 -0
  163. package/dist/parser/parse-label-arguments.spec.js +27 -0
  164. package/dist/parser/read-build-file.js +2 -13
  165. package/dist/parser/read-build-file.spec.js +89 -0
  166. package/dist/parser/read-env-file.js +4 -5
  167. package/dist/parser/read-env-file.spec.js +42 -0
  168. package/dist/planner/utils/append-work-dependencies.js +55 -0
  169. package/dist/planner/utils/append-work-environment.js +22 -0
  170. package/dist/planner/utils/append-work-needs.js +18 -0
  171. package/dist/planner/utils/append-work-service.js +107 -0
  172. package/dist/planner/utils/append-work-service.spec.js +71 -0
  173. package/dist/planner/utils/append-work-task.js +81 -0
  174. package/dist/planner/utils/get-container-user.js +14 -0
  175. package/dist/planner/utils/get-container-user.spec.js +30 -0
  176. package/dist/planner/utils/get-default-kube-config.js +10 -0
  177. package/dist/planner/utils/get-default-kube-config.spec.js +11 -0
  178. package/dist/planner/utils/get-work-runtime.js +44 -0
  179. package/dist/planner/utils/normalize-path.js +1 -1
  180. package/dist/planner/utils/normalize-path.spec.js +24 -0
  181. package/dist/planner/utils/parse-work-command.js +80 -0
  182. package/dist/planner/utils/parse-work-command.spec.js +21 -0
  183. package/dist/planner/utils/parse-work-generate.js +38 -0
  184. package/dist/planner/utils/parse-work-generate.spec.js +45 -0
  185. package/dist/planner/utils/{parse-work-node-mount.js → parse-work-mount.js} +10 -7
  186. package/dist/planner/utils/{parse-work-node-mount.spec.js → parse-work-mount.spec.js} +14 -11
  187. package/dist/planner/utils/parse-work-mounts.js +13 -0
  188. package/dist/planner/utils/parse-work-mounts.spec.js +19 -0
  189. package/dist/planner/utils/{parse-work-node-port.js → parse-work-port.js} +11 -8
  190. package/dist/planner/utils/parse-work-port.spec.js +24 -0
  191. package/dist/planner/utils/parse-work-ports.js +10 -0
  192. package/dist/planner/utils/parse-work-ports.spec.js +24 -0
  193. package/dist/planner/utils/parse-work-source.js +72 -0
  194. package/dist/planner/utils/parse-work-source.spec.js +58 -0
  195. package/dist/planner/utils/parse-work-volume.js +45 -0
  196. package/dist/planner/utils/parse-work-volume.spec.js +18 -0
  197. package/dist/planner/utils/plan-work-tasks.js +41 -0
  198. package/dist/planner/utils/plan-work-tasks.spec.js +30 -0
  199. package/dist/planner/utils/plan-work-volume.js +1 -0
  200. package/dist/planner/utils/plan-work-volume.spec.js +33 -0
  201. package/dist/planner/utils/split-name.js +2 -2
  202. package/dist/planner/utils/split-name.spec.js +16 -0
  203. package/dist/planner/utils/template-value.js +1 -2
  204. package/dist/planner/utils/template-value.spec.js +14 -0
  205. package/dist/planner/validate.js +71 -38
  206. package/dist/planner/validate.spec.js +251 -0
  207. package/dist/planner/work-cache-id.js +12 -0
  208. package/dist/planner/work-cache-id.spec.js +173 -0
  209. package/dist/planner/work-command.js +3 -0
  210. package/dist/planner/work-environment.js +3 -0
  211. package/dist/planner/work-healthcheck.js +3 -0
  212. package/dist/planner/{work-node-status.js → work-item-status.js} +16 -62
  213. package/dist/{parser/build-file-service.js → planner/work-item-validation.js} +1 -1
  214. package/dist/planner/work-item.js +16 -0
  215. package/dist/{optimizer/work-node-cache-stats.js → planner/work-kubernetes-selector.js} +1 -1
  216. package/dist/planner/{work-nodes.js → work-port.js} +1 -1
  217. package/dist/planner/work-runtime-docker.js +224 -0
  218. package/dist/planner/work-runtime-kubernetes.js +264 -0
  219. package/dist/planner/work-runtime-local.js +109 -0
  220. package/dist/planner/work-runtime-local.spec.js +193 -0
  221. package/dist/planner/work-service-id.js +15 -5
  222. package/dist/planner/work-source.js +3 -0
  223. package/dist/planner/work-task.js +8 -0
  224. package/dist/program-commands.spec.js +84 -0
  225. package/dist/program.js +219 -73
  226. package/dist/program.spec.js +34 -11
  227. package/dist/run-program.js +28 -0
  228. package/dist/{executer/process.js → runtime/runtime.js} +1 -1
  229. package/dist/schema/build-file-base-task-schema.js +27 -0
  230. package/dist/schema/build-file-container-service-schema.js +28 -0
  231. package/dist/schema/build-file-container-task-schema.js +13 -0
  232. package/dist/schema/build-file-environment-schema-ingress.js +14 -0
  233. package/dist/schema/build-file-environment-schema.js +23 -0
  234. package/dist/schema/build-file-kubernetes-service-schema.js +17 -0
  235. package/dist/schema/build-file-kubernetes-service-selector-schema.js +9 -0
  236. package/dist/schema/build-file-local-platform-schema.js +9 -0
  237. package/dist/schema/build-file-local-task-schema.js +12 -0
  238. package/dist/schema/build-file-need-schema.js +12 -0
  239. package/dist/schema/build-file-schema.js +23 -0
  240. package/dist/schema/build-file-schema.spec.js +61 -0
  241. package/dist/schema/build-file-service-container-healthcheck.js +8 -0
  242. package/dist/schema/build-file-service-schema.js +15 -0
  243. package/dist/schema/build-file-task-command-schema.js +12 -0
  244. package/dist/schema/build-file-task-schema.js +12 -0
  245. package/dist/schema/build-file-volume-schema.js +14 -0
  246. package/dist/schema/cache-schema.js +31 -0
  247. package/dist/schema/doc-build-files.spec.js +223 -0
  248. package/dist/schema/envs-schema.js +6 -0
  249. package/dist/schema/labels-schema.js +6 -0
  250. package/dist/schema/parse-context.js +3 -0
  251. package/dist/schema/parse-error.js +12 -0
  252. package/dist/schema/parse-error.spec.js +18 -0
  253. package/dist/schema/reference-parser.js +209 -0
  254. package/dist/schema/reference-parser.spec.js +83 -0
  255. package/dist/schema/schema-parser.js +66 -0
  256. package/dist/schema/schema-parser.spec.js +80 -0
  257. package/dist/schema/type-guards.spec.js +23 -0
  258. package/dist/schema/work-scope-parser.js +77 -0
  259. package/dist/schema/work-scope-parser.spec.js +66 -0
  260. package/dist/service/update-service-status.js +11 -0
  261. package/dist/service/update-service-status.spec.js +27 -0
  262. package/dist/testing/ensure-local-registry.js +134 -0
  263. package/dist/testing/example-test-suite.js +16 -18
  264. package/dist/testing/expect.js +46 -22
  265. package/dist/testing/http-get.js +21 -0
  266. package/dist/testing/integration/cache.spec.js +13 -14
  267. package/dist/testing/integration/cancellation.spec.js +14 -9
  268. package/dist/testing/integration/clean.spec.js +14 -11
  269. package/dist/testing/integration/cmd.spec.js +1 -1
  270. package/dist/testing/integration/concurrency.spec.js +3 -3
  271. package/dist/testing/integration/docker-package-registry.spec.js +44 -0
  272. package/dist/testing/integration/docker-service-crash.spec.js +36 -0
  273. package/dist/testing/integration/docker.spec.js +4 -3
  274. package/dist/testing/integration/env.spec.js +9 -8
  275. package/dist/testing/integration/environment.spec.js +97 -0
  276. package/dist/testing/integration/error.spec.js +5 -4
  277. package/dist/testing/integration/export.spec.js +22 -0
  278. package/dist/testing/integration/extend.spec.js +9 -12
  279. package/dist/testing/integration/glob.spec.js +12 -20
  280. package/dist/testing/integration/include.spec.js +3 -3
  281. package/dist/testing/integration/invalid.spec.js +2 -3
  282. package/dist/testing/integration/invalid_loop.spec.js +49 -6
  283. package/dist/testing/integration/k8s-state-cache.spec.js +41 -0
  284. package/dist/testing/integration/kubernetes-service.spec.js +148 -0
  285. package/dist/testing/integration/kubernetes.spec.js +93 -9
  286. package/dist/testing/integration/labels.spec.js +6 -11
  287. package/dist/testing/integration/local.spec.js +1 -1
  288. package/dist/testing/integration/monorepo.spec.js +4 -4
  289. package/dist/testing/integration/multi-line.spec.js +3 -3
  290. package/dist/testing/integration/reference.spec.js +4 -5
  291. package/dist/testing/integration/services.spec.js +22 -4
  292. package/dist/testing/integration/store.spec.js +15 -16
  293. package/dist/testing/integration/unknown.spec.js +20 -18
  294. package/dist/testing/integration/validate.spec.js +143 -26
  295. package/dist/testing/integration/watch-dependency.spec.js +11 -8
  296. package/dist/testing/integration/watch.spec.js +15 -16
  297. package/dist/testing/requires-kubernetes.js +18 -0
  298. package/dist/testing/requires-linux-containers.js +18 -0
  299. package/dist/testing/requires-windows-containers.js +18 -0
  300. package/dist/testing/test-case.js +75 -0
  301. package/dist/testing/test-streams.js +28 -0
  302. package/dist/testing/testing-timeout.js +32 -0
  303. package/dist/utils/abort-event.js +10 -4
  304. package/dist/utils/abort-event.spec.js +46 -0
  305. package/dist/utils/buffer-context.js +44 -0
  306. package/dist/utils/buffer-context.spec.js +38 -0
  307. package/dist/utils/ci.spec.js +53 -0
  308. package/dist/utils/emitter.spec.js +34 -0
  309. package/dist/utils/empty-writable.spec.js +18 -0
  310. package/dist/utils/environment-config.js +4 -1
  311. package/dist/utils/environment-config.spec.js +26 -0
  312. package/dist/utils/fail-never.spec.js +9 -0
  313. package/dist/version.js +9 -0
  314. package/dist/version.spec.js +12 -0
  315. package/package.json +41 -23
  316. package/specs/build-file/caches/spec.md +114 -0
  317. package/specs/build-file/environment-variables/spec.md +82 -0
  318. package/specs/build-file/includes/spec.md +60 -0
  319. package/specs/build-file/references/spec.md +56 -0
  320. package/specs/build-file/spec.md +62 -0
  321. package/specs/cli/clean/spec.md +85 -0
  322. package/specs/cli/down/spec.md +85 -0
  323. package/specs/cli/execute/spec.md +101 -0
  324. package/specs/cli/init/spec.md +64 -0
  325. package/specs/cli/ls/spec.md +66 -0
  326. package/specs/cli/package/spec.md +110 -0
  327. package/specs/cli/spec.md +73 -0
  328. package/specs/cli/store-restore/spec.md +74 -0
  329. package/specs/cli/up/spec.md +80 -0
  330. package/specs/cli/validate/spec.md +70 -0
  331. package/specs/labels/spec.md +91 -0
  332. package/specs/service/container/spec.md +120 -0
  333. package/specs/service/kubernetes/spec.md +97 -0
  334. package/specs/service/spec.md +105 -0
  335. package/specs/task/caching/spec.md +107 -0
  336. package/specs/task/container/spec.md +118 -0
  337. package/specs/task/dependencies/spec.md +70 -0
  338. package/specs/task/extending/spec.md +74 -0
  339. package/specs/task/kubernetes/spec.md +125 -0
  340. package/specs/task/needs/spec.md +59 -0
  341. package/specs/task/spec.md +87 -0
  342. package/specs/task/watching/spec.md +69 -0
  343. package/dist/console/console-context-mock.js +0 -14
  344. package/dist/environment/get-process-env.js +0 -15
  345. package/dist/executer/create-scheduler-state.js +0 -32
  346. package/dist/executer/docker-node.js +0 -123
  347. package/dist/executer/hierarchy-scheduler.js +0 -94
  348. package/dist/executer/local-node.js +0 -57
  349. package/dist/executer/schedule.js +0 -137
  350. package/dist/executer/start-node.js +0 -67
  351. package/dist/executer/watch-node.js +0 -56
  352. package/dist/executer/watch-service.js +0 -54
  353. package/dist/file/get-file-context-mock.js +0 -187
  354. package/dist/file/get-file-context-mock.spec.js +0 -56
  355. package/dist/get-work-context.js +0 -29
  356. package/dist/optimizer/get-work-node-cache-stats.js +0 -104
  357. package/dist/optimizer/read-work-node-cache.js +0 -19
  358. package/dist/optimizer/work-node-cache-description.js +0 -32
  359. package/dist/optimizer/write-work-node-cache.js +0 -21
  360. package/dist/parser/build-file-task-command.js +0 -3
  361. package/dist/parser/build-file-task-platform.js +0 -3
  362. package/dist/parser/build-file-task-source.js +0 -3
  363. package/dist/parser/get-build-file.js +0 -9
  364. package/dist/parser/parse-boolean.js +0 -29
  365. package/dist/parser/parse-boolean.spec.js +0 -48
  366. package/dist/parser/parse-build-file-references.js +0 -35
  367. package/dist/parser/parse-build-file-services.js +0 -58
  368. package/dist/parser/parse-build-file-task-command.js +0 -36
  369. package/dist/parser/parse-build-file-task-source.js +0 -63
  370. package/dist/parser/parse-build-file.js +0 -125
  371. package/dist/parser/parse-context.js +0 -13
  372. package/dist/parser/parse-envs.js +0 -29
  373. package/dist/parser/parse-healthcheck.js +0 -28
  374. package/dist/parser/parse-service-selector.js +0 -39
  375. package/dist/parser/parse-string-array.js +0 -20
  376. package/dist/parser/parse-string-map.js +0 -30
  377. package/dist/parser/parse-string.js +0 -20
  378. package/dist/planner/utils/get-container-mounts.js +0 -24
  379. package/dist/planner/utils/parse-work-service-volume.js +0 -23
  380. package/dist/planner/utils/plan-work-command.js +0 -21
  381. package/dist/planner/utils/plan-work-dependency.js +0 -36
  382. package/dist/planner/utils/plan-work-node.js +0 -293
  383. package/dist/planner/utils/plan-work-nodes.js +0 -78
  384. package/dist/planner/utils/plan-work-tree.js +0 -15
  385. package/dist/planner/work-context.js +0 -23
  386. package/dist/planner/work-node-command.js +0 -3
  387. package/dist/planner/work-node-id.js +0 -12
  388. package/dist/planner/work-node-id.spec.js +0 -106
  389. package/dist/planner/work-node-path.js +0 -2
  390. package/dist/planner/work-node-source.js +0 -3
  391. package/dist/planner/work-node-validation.js +0 -3
  392. package/dist/planner/work-node.js +0 -8
  393. package/dist/planner/work-service-volume.js +0 -3
  394. package/dist/planner/work-services.js +0 -3
  395. package/dist/start-watch-processes.js +0 -28
  396. package/dist/testing/cli.js +0 -73
  397. package/dist/testing/create-build-file.js +0 -9
  398. package/dist/testing/get-logger.js +0 -23
  399. package/dist/testing/get-node.js +0 -12
  400. package/dist/testing/get-test-context.js +0 -19
  401. package/dist/testing/integration/program.spec.js +0 -25
  402. package/dist/testing/lazy.js +0 -17
  403. package/dist/testing/start-watch-processes.js +0 -29
  404. package/dist/testing/test-suite-options.js +0 -3
  405. package/dist/utils/abortable-function.js +0 -71
  406. package/logs/cache-console.log +0 -0
  407. package/logs/cache-status.log +0 -6
  408. package/logs/cache-stout.log +0 -0
  409. package/logs/cancellation-console.log +0 -0
  410. package/logs/cancellation-status.log +0 -3
  411. package/logs/cancellation-stout.log +0 -3
  412. package/logs/clean-console.log +0 -0
  413. package/logs/clean-status.log +0 -37
  414. package/logs/clean-stout.log +0 -95
  415. package/logs/cmd-console.log +0 -0
  416. package/logs/cmd-status.log +0 -8
  417. package/logs/cmd-stout.log +0 -9
  418. package/logs/concurrency-console.log +0 -0
  419. package/logs/concurrency-status.log +0 -14
  420. package/logs/concurrency-stout.log +0 -88
  421. package/logs/docker-console.log +0 -0
  422. package/logs/docker-status.log +0 -14
  423. package/logs/docker-stout.log +0 -39
  424. package/logs/env-console.log +0 -1
  425. package/logs/env-status.log +0 -1
  426. package/logs/env-stout.log +0 -0
  427. package/logs/error-console.log +0 -0
  428. package/logs/error-status.log +0 -10
  429. package/logs/error-stout.log +0 -36
  430. package/logs/extend-console.log +0 -0
  431. package/logs/extend-status.log +0 -1
  432. package/logs/extend-stout.log +0 -0
  433. package/logs/glob-console.log +0 -28
  434. package/logs/glob-status.log +0 -23
  435. package/logs/glob-stout.log +0 -52
  436. package/logs/hello-world-node-console.log +0 -0
  437. package/logs/hello-world-node-status.log +0 -37
  438. package/logs/hello-world-node-stout.log +0 -41
  439. package/logs/include-console.log +0 -0
  440. package/logs/include-status.log +0 -3
  441. package/logs/include-stout.log +0 -0
  442. package/logs/invalid-console.log +0 -0
  443. package/logs/invalid-status.log +0 -1
  444. package/logs/invalid-stout.log +0 -0
  445. package/logs/invalid_loop-console.log +0 -0
  446. package/logs/invalid_loop-status.log +0 -1
  447. package/logs/invalid_loop-stout.log +0 -11
  448. package/logs/labels-console.log +0 -0
  449. package/logs/labels-status.log +0 -1
  450. package/logs/labels-stout.log +0 -0
  451. package/logs/local-console.log +0 -0
  452. package/logs/local-status.log +0 -7
  453. package/logs/local-stout.log +0 -8
  454. package/logs/monorepo-console.log +0 -0
  455. package/logs/monorepo-status.log +0 -152
  456. package/logs/monorepo-stout.log +0 -2354
  457. package/logs/multi-line-console.log +0 -0
  458. package/logs/multi-line-status.log +0 -1
  459. package/logs/multi-line-stout.log +0 -0
  460. package/logs/reference-console.log +0 -0
  461. package/logs/reference-status.log +0 -5
  462. package/logs/reference-stout.log +0 -0
  463. package/logs/services-console.log +0 -0
  464. package/logs/services-status.log +0 -129
  465. package/logs/services-stout.log +0 -639
  466. package/logs/store-restore-console.log +0 -0
  467. package/logs/store-restore-status.log +0 -40
  468. package/logs/store-restore-stout.log +0 -97
  469. package/logs/unknown-console.log +0 -3
  470. package/logs/unknown-status.log +0 -1
  471. package/logs/unknown-stout.log +0 -0
  472. package/logs/validate-console.log +0 -0
  473. package/logs/validate-status.log +0 -2
  474. package/logs/validate-stout.log +0 -0
  475. package/logs/watch-console.log +0 -0
  476. package/logs/watch-dependency-console.log +0 -0
  477. package/logs/watch-dependency-status.log +0 -176
  478. package/logs/watch-dependency-stout.log +0 -779
  479. package/logs/watch-status.log +0 -100
  480. package/logs/watch-stout.log +0 -349
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileKubernetesServiceSelectorSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.buildFileKubernetesServiceSelectorSchema = (0, zod_1.object)({
6
+ type: (0, zod_1.string)(),
7
+ name: (0, zod_1.string)(),
8
+ });
9
+ //# sourceMappingURL=build-file-kubernetes-service-selector-schema.js.map
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileLocalPlatformSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.buildFileLocalPlatformSchema = (0, zod_1.object)({
6
+ os: (0, zod_1.union)([(0, zod_1.literal)('win'), (0, zod_1.literal)('macos'), (0, zod_1.literal)('linux')]).optional(),
7
+ arch: (0, zod_1.union)([(0, zod_1.literal)('arm64'), (0, zod_1.literal)('arm')]).optional(),
8
+ });
9
+ //# sourceMappingURL=build-file-local-platform-schema.js.map
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileLocalTaskSchema = void 0;
4
+ const build_file_base_task_schema_1 = require("./build-file-base-task-schema");
5
+ const build_file_local_platform_schema_1 = require("./build-file-local-platform-schema");
6
+ exports.buildFileLocalTaskSchema = build_file_base_task_schema_1.buildFileBaseTaskSchema
7
+ .extend({
8
+ platform: build_file_local_platform_schema_1.buildFileLocalPlatformSchema.optional(),
9
+ })
10
+ .strict()
11
+ .describe('local task');
12
+ //# sourceMappingURL=build-file-local-task-schema.js.map
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileNeedSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.buildFileNeedSchema = (0, zod_1.union)([
6
+ (0, zod_1.string)(),
7
+ (0, zod_1.object)({
8
+ service: (0, zod_1.string)(),
9
+ name: (0, zod_1.string)(),
10
+ }),
11
+ ]);
12
+ //# sourceMappingURL=build-file-need-schema.js.map
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const envs_schema_1 = require("./envs-schema");
6
+ const build_file_service_schema_1 = require("./build-file-service-schema");
7
+ const build_file_environment_schema_1 = require("./build-file-environment-schema");
8
+ const build_file_task_schema_1 = require("./build-file-task-schema");
9
+ const labels_schema_1 = require("./labels-schema");
10
+ const cache_schema_1 = require("./cache-schema");
11
+ exports.buildFileSchema = (0, zod_1.object)({
12
+ envs: envs_schema_1.envsSchema.optional(),
13
+ tasks: (0, zod_1.record)(build_file_task_schema_1.buildFileTaskSchema).optional(),
14
+ services: (0, zod_1.record)(build_file_service_schema_1.buildFileServiceSchema).optional(),
15
+ references: (0, zod_1.record)((0, zod_1.string)()).optional(),
16
+ includes: (0, zod_1.record)((0, zod_1.string)()).optional(),
17
+ environments: (0, zod_1.record)(build_file_environment_schema_1.buildFileEnvironmentSchema).optional(),
18
+ caches: (0, zod_1.record)(cache_schema_1.buildFileCacheSchema).optional(),
19
+ labels: labels_schema_1.labelsSchema.optional(),
20
+ })
21
+ .strict()
22
+ .describe('Build file with support for containerization\nhttps://no0dles.gitbook.io/hammerkit/build-file');
23
+ //# sourceMappingURL=build-file-schema.js.map
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const build_file_schema_1 = require("./build-file-schema");
4
+ function parse(input) {
5
+ return build_file_schema_1.buildFileSchema.safeParseAsync(input);
6
+ }
7
+ describe('buildFileSchema', () => {
8
+ describe('container services', () => {
9
+ it('accepts a service without ports (reachable via needs/DNS)', async () => {
10
+ const result = await parse({
11
+ services: { postgres: { image: 'postgres:12-alpine', healthcheck: { cmd: 'pg_isready -U postgres' } } },
12
+ });
13
+ expect(result.success).toBe(true);
14
+ });
15
+ it('accepts a service with numeric and string ports', async () => {
16
+ const result = await parse({ services: { api: { image: 'node:alpine', ports: [':3000', 8080] } } });
17
+ expect(result.success).toBe(true);
18
+ });
19
+ it('rejects a service that is neither a container nor a kubernetes service', async () => {
20
+ const result = await parse({ services: { broken: { ports: [80] } } });
21
+ expect(result.success).toBe(false);
22
+ });
23
+ });
24
+ describe('kubernetes services', () => {
25
+ it('accepts a service with a selector', async () => {
26
+ const result = await parse({
27
+ services: { db: { selector: { type: 'deployment', name: 'db' }, ports: [5432] } },
28
+ });
29
+ expect(result.success).toBe(true);
30
+ });
31
+ });
32
+ describe('continuous tasks', () => {
33
+ it('accepts a container task marked continuous', async () => {
34
+ const result = await parse({ tasks: { serve: { image: 'node:16', continuous: true, cmds: ['ng serve'] } } });
35
+ expect(result.success).toBe(true);
36
+ });
37
+ it('accepts a local task marked continuous', async () => {
38
+ const result = await parse({ tasks: { serve: { continuous: true, cmds: ['ng serve'] } } });
39
+ expect(result.success).toBe(true);
40
+ });
41
+ it('rejects a non-boolean continuous', async () => {
42
+ const result = await parse({ tasks: { serve: { continuous: 'yes', cmds: ['x'] } } });
43
+ expect(result.success).toBe(false);
44
+ });
45
+ });
46
+ describe('strictness', () => {
47
+ it('rejects unknown top-level keys', async () => {
48
+ const result = await parse({ bogus: true });
49
+ expect(result.success).toBe(false);
50
+ });
51
+ it('rejects unknown task keys', async () => {
52
+ const result = await parse({ tasks: { build: { cmds: ['x'], bogus: 1 } } });
53
+ expect(result.success).toBe(false);
54
+ });
55
+ it('accepts an empty build file', async () => {
56
+ const result = await parse({});
57
+ expect(result.success).toBe(true);
58
+ });
59
+ });
60
+ });
61
+ //# sourceMappingURL=build-file-schema.spec.js.map
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileServiceContainerHealthcheck = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.buildFileServiceContainerHealthcheck = (0, zod_1.object)({
6
+ cmd: (0, zod_1.string)(),
7
+ });
8
+ //# sourceMappingURL=build-file-service-container-healthcheck.js.map
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isBuildFileContainerSchema = exports.isBuildFileKubernetesServiceSchema = exports.buildFileServiceSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const build_file_container_service_schema_1 = require("./build-file-container-service-schema");
6
+ const build_file_kubernetes_service_schema_1 = require("./build-file-kubernetes-service-schema");
7
+ exports.buildFileServiceSchema = (0, zod_1.union)([
8
+ build_file_container_service_schema_1.buildFileContainerServiceSchema,
9
+ build_file_kubernetes_service_schema_1.buildFileKubernetesServiceSchema,
10
+ ]).describe('service');
11
+ const isBuildFileKubernetesServiceSchema = (val) => 'selector' in val;
12
+ exports.isBuildFileKubernetesServiceSchema = isBuildFileKubernetesServiceSchema;
13
+ const isBuildFileContainerSchema = (val) => 'image' in val;
14
+ exports.isBuildFileContainerSchema = isBuildFileContainerSchema;
15
+ //# sourceMappingURL=build-file-service-schema.js.map
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileTaskCommandSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.buildFileTaskCommandSchema = (0, zod_1.union)([
6
+ (0, zod_1.string)(),
7
+ (0, zod_1.object)({
8
+ cmd: (0, zod_1.string)(),
9
+ path: (0, zod_1.string)().optional(),
10
+ }),
11
+ ]);
12
+ //# sourceMappingURL=build-file-task-command-schema.js.map
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isBuildFileLocalTaskSchema = exports.isBuildFileContainerTaskSchema = exports.buildFileTaskSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ const build_file_container_task_schema_1 = require("./build-file-container-task-schema");
6
+ const build_file_local_task_schema_1 = require("./build-file-local-task-schema");
7
+ exports.buildFileTaskSchema = (0, zod_1.union)([build_file_container_task_schema_1.buildFileContainerTaskSchema, build_file_local_task_schema_1.buildFileLocalTaskSchema]);
8
+ const isBuildFileContainerTaskSchema = (val) => 'image' in val;
9
+ exports.isBuildFileContainerTaskSchema = isBuildFileContainerTaskSchema;
10
+ const isBuildFileLocalTaskSchema = (val) => !('image' in val);
11
+ exports.isBuildFileLocalTaskSchema = isBuildFileLocalTaskSchema;
12
+ //# sourceMappingURL=build-file-task-schema.js.map
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.buildFileVolumeSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.buildFileVolumeSchema = (0, zod_1.union)([
6
+ (0, zod_1.string)(),
7
+ (0, zod_1.object)({
8
+ export: (0, zod_1.boolean)().optional(),
9
+ resetOnChange: (0, zod_1.boolean)().optional(),
10
+ path: (0, zod_1.string)(),
11
+ name: (0, zod_1.string)().optional(),
12
+ }),
13
+ ]);
14
+ //# sourceMappingURL=build-file-volume-schema.js.map
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cacheSchema = exports.taskCacheRefSchema = exports.buildFileCacheSchema = exports.cacheBackendSchema = exports.cacheBackendS3Schema = exports.cacheBackendLocalSchema = exports.cacheMethodSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.cacheMethodSchema = (0, zod_1.union)([(0, zod_1.literal)('checksum'), (0, zod_1.literal)('modify-date'), (0, zod_1.literal)('none')]);
6
+ exports.cacheBackendLocalSchema = (0, zod_1.object)({
7
+ type: (0, zod_1.literal)('local'),
8
+ path: (0, zod_1.string)().optional(),
9
+ }).strict();
10
+ exports.cacheBackendS3Schema = (0, zod_1.object)({
11
+ type: (0, zod_1.literal)('s3'),
12
+ bucket: (0, zod_1.string)(),
13
+ region: (0, zod_1.string)().optional(),
14
+ endpoint: (0, zod_1.string)().optional(),
15
+ prefix: (0, zod_1.string)().optional(),
16
+ forcePathStyle: zod_1.z.boolean().optional(),
17
+ }).strict();
18
+ exports.cacheBackendSchema = (0, zod_1.union)([exports.cacheBackendLocalSchema, exports.cacheBackendS3Schema]);
19
+ exports.buildFileCacheSchema = (0, zod_1.object)({
20
+ method: exports.cacheMethodSchema,
21
+ backend: exports.cacheBackendSchema,
22
+ }).strict();
23
+ exports.taskCacheRefSchema = (0, zod_1.union)([
24
+ exports.cacheMethodSchema,
25
+ (0, zod_1.object)({
26
+ name: (0, zod_1.string)(),
27
+ method: exports.cacheMethodSchema.optional(),
28
+ }).strict(),
29
+ ]);
30
+ exports.cacheSchema = exports.taskCacheRefSchema;
31
+ //# sourceMappingURL=cache-schema.js.map
@@ -0,0 +1,223 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const fs_1 = require("fs");
4
+ const path_1 = require("path");
5
+ const yaml_1 = require("yaml");
6
+ const build_file_schema_1 = require("./build-file-schema");
7
+ /*
8
+ * Documentation coverage: every hammerkit build-file example that ships in the
9
+ * docs must stay valid against the real schema, so the docs cannot silently
10
+ * drift to config the tool would reject.
11
+ *
12
+ * The harness is self-discovering: it walks docs/ at collection time and turns
13
+ * every fenced ```yaml block into its own assertion. A block is treated as a
14
+ * hammerkit build file when it parses to an object whose top-level keys are all
15
+ * part of the schema (envs/tasks/services/...). Anything else (a GitLab/GitHub
16
+ * CI snippet, a design-doc proposal) is "foreign" and must be listed in
17
+ * FOREIGN_BLOCKS with a reason — a foreign block that is NOT listed fails the
18
+ * audit, so a new build-file example is validated rather than quietly ignored,
19
+ * and a typo'd example (unknown key) is surfaced instead of skipped.
20
+ */
21
+ const repoRoot = (0, path_1.join)(__dirname, '..', '..');
22
+ const docsDir = (0, path_1.join)(repoRoot, 'docs');
23
+ const bestPracticesDir = (0, path_1.join)(repoRoot, 'best-practices');
24
+ // Top-level keys the build-file schema understands. Mirrors buildFileSchema's
25
+ // shape; kept here only to classify "is this block a hammerkit build file at all".
26
+ const KNOWN_TOP_KEYS = new Set([
27
+ 'envs',
28
+ 'tasks',
29
+ 'services',
30
+ 'references',
31
+ 'includes',
32
+ 'environments',
33
+ 'caches',
34
+ 'labels',
35
+ ]);
36
+ // A doc block can declare itself intentionally invalid by putting this comment
37
+ // on its first line; the harness then asserts the schema REJECTS it.
38
+ const EXPECT_INVALID = '# hammerkit:expect-invalid';
39
+ // Directories that document a specific past version, not the current build-file
40
+ // reference. Their snippets are expected to use the syntax of their release and
41
+ // must not be validated against today's schema.
42
+ const HISTORICAL_DIRS = ['release-blog', 'change-log'];
43
+ // yaml blocks in docs/ that are deliberately NOT hammerkit build files. Each is
44
+ // matched by a unique snippet of its body. Keep the reason — these are the only
45
+ // blocks allowed to be unrecognized.
46
+ const FOREIGN_BLOCKS = [
47
+ {
48
+ file: (0, path_1.join)('installation.md'),
49
+ snippet: 'DOCKER_DRIVER',
50
+ reason: 'GitLab CI (.gitlab-ci.yml) example, not a hammerkit build file',
51
+ },
52
+ {
53
+ file: (0, path_1.join)('installation.md'),
54
+ snippet: 'no0dles/hammerkit-github-action',
55
+ reason: 'GitHub Actions workflow example, not a hammerkit build file',
56
+ },
57
+ {
58
+ file: (0, path_1.join)('cli', 'store-restore.md'),
59
+ snippet: 'before_script',
60
+ reason: 'GitLab CI (gitlab-ci.yml) caching example, not a hammerkit build file',
61
+ },
62
+ {
63
+ file: (0, path_1.join)('guides', 'ci-caching.md'),
64
+ snippet: 'actions/cache@v4',
65
+ reason: 'GitHub Actions workflow example, not a hammerkit build file',
66
+ },
67
+ {
68
+ file: (0, path_1.join)('contribution', 'secret-managers.md'),
69
+ snippet: 'secret://vault',
70
+ reason: 'design-doc proposal for an unimplemented secrets: provider; not valid against the current schema',
71
+ },
72
+ ];
73
+ function walkMarkdown(dir) {
74
+ const out = [];
75
+ for (const entry of (0, fs_1.readdirSync)(dir, { withFileTypes: true })) {
76
+ const full = (0, path_1.join)(dir, entry.name);
77
+ if (entry.isDirectory()) {
78
+ out.push(...walkMarkdown(full));
79
+ }
80
+ else if (entry.name.endsWith('.md')) {
81
+ out.push(full);
82
+ }
83
+ }
84
+ return out;
85
+ }
86
+ // Extract the body of every fenced ```yaml / ```yml block. GitBook's
87
+ // `{% code %}` wrappers and `{% hint %}`/`{% tabs %}` around a block are
88
+ // irrelevant — only the fence matters.
89
+ function extractYamlBlocks(content) {
90
+ const lines = content.split(/\r?\n/);
91
+ const blocks = [];
92
+ for (let i = 0; i < lines.length; i++) {
93
+ if (!/^\s*```ya?ml\s*$/.test(lines[i])) {
94
+ continue;
95
+ }
96
+ const start = i + 1;
97
+ const body = [];
98
+ let j = start;
99
+ while (j < lines.length && !/^\s*```\s*$/.test(lines[j])) {
100
+ body.push(lines[j]);
101
+ j++;
102
+ }
103
+ blocks.push({ body: body.join('\n'), startLine: start + 1 });
104
+ i = j;
105
+ }
106
+ return blocks;
107
+ }
108
+ function firstNonEmptyLine(body) {
109
+ for (const line of body.split(/\r?\n/)) {
110
+ if (line.trim() !== '') {
111
+ return line.trim();
112
+ }
113
+ }
114
+ return '';
115
+ }
116
+ // A block is a hammerkit build file when it parses to a non-empty object whose
117
+ // top-level keys are all part of the schema.
118
+ function isBuildFileShaped(parsed) {
119
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
120
+ return false;
121
+ }
122
+ const keys = Object.keys(parsed);
123
+ return keys.length > 0 && keys.every((k) => KNOWN_TOP_KEYS.has(k));
124
+ }
125
+ const docFiles = walkMarkdown(docsDir).sort();
126
+ const allBlocks = [];
127
+ for (const file of docFiles) {
128
+ const relFile = (0, path_1.relative)(docsDir, file);
129
+ const topDir = relFile.split(/[\\/]/)[0];
130
+ if (HISTORICAL_DIRS.includes(topDir)) {
131
+ continue;
132
+ }
133
+ extractYamlBlocks((0, fs_1.readFileSync)(file, 'utf8')).forEach((block, index) => {
134
+ allBlocks.push({ ...block, relFile, index });
135
+ });
136
+ }
137
+ const foreignMatches = new Set();
138
+ let buildFileBlockCount = 0;
139
+ describe('docs build-file examples', () => {
140
+ // Group assertions per doc file for readable failures.
141
+ const byFile = new Map();
142
+ for (const block of allBlocks) {
143
+ const list = byFile.get(block.relFile) ?? [];
144
+ list.push(block);
145
+ byFile.set(block.relFile, list);
146
+ }
147
+ for (const [relFile, blocks] of byFile) {
148
+ describe(relFile, () => {
149
+ blocks.forEach((block) => {
150
+ const label = `yaml block at line ${block.startLine}`;
151
+ const foreignIndex = FOREIGN_BLOCKS.findIndex((f) => f.file === relFile && block.body.includes(f.snippet));
152
+ if (foreignIndex >= 0) {
153
+ foreignMatches.add(foreignIndex);
154
+ it(`${label} is a documented non-hammerkit block`, () => {
155
+ // Listed in FOREIGN_BLOCKS with a reason — nothing to validate.
156
+ expect(FOREIGN_BLOCKS[foreignIndex].reason).toBeTruthy();
157
+ });
158
+ return;
159
+ }
160
+ if (firstNonEmptyLine(block.body) === EXPECT_INVALID) {
161
+ it(`${label} is rejected by the schema (marked expect-invalid)`, async () => {
162
+ const parsed = (0, yaml_1.parse)(block.body);
163
+ const result = await build_file_schema_1.buildFileSchema.safeParseAsync(parsed);
164
+ expect(result.success).toBe(false);
165
+ });
166
+ buildFileBlockCount++;
167
+ return;
168
+ }
169
+ it(`${label} is a valid build file`, async () => {
170
+ let parsed;
171
+ try {
172
+ parsed = (0, yaml_1.parse)(block.body);
173
+ }
174
+ catch (e) {
175
+ throw new Error(`${relFile}:${block.startLine} is not valid YAML: ${e.message}`);
176
+ }
177
+ if (!isBuildFileShaped(parsed)) {
178
+ const keys = parsed && typeof parsed === 'object' && !Array.isArray(parsed)
179
+ ? Object.keys(parsed).join(', ')
180
+ : typeof parsed;
181
+ throw new Error(`${relFile}:${block.startLine} is not a recognized hammerkit build file (top-level: ${keys}).\n` +
182
+ `If this is intentionally foreign yaml (a CI config, a proposal), add it to FOREIGN_BLOCKS with a reason.\n` +
183
+ `Otherwise fix the example so its top-level keys are one of: ${[...KNOWN_TOP_KEYS].join(', ')}.`);
184
+ }
185
+ const result = await build_file_schema_1.buildFileSchema.safeParseAsync(parsed);
186
+ if (!result.success) {
187
+ throw new Error(`${relFile}:${block.startLine} fails the build-file schema:\n` +
188
+ result.error.issues.map((iss) => ` - ${iss.path.join('.')}: ${iss.message}`).join('\n'));
189
+ }
190
+ });
191
+ buildFileBlockCount++;
192
+ });
193
+ });
194
+ }
195
+ // Guard against a regex/discovery regression silently matching nothing, and
196
+ // against a build-file example dropping out of validation unnoticed.
197
+ it('discovers the documented build-file examples', () => {
198
+ expect(buildFileBlockCount).toBeGreaterThanOrEqual(60);
199
+ });
200
+ // Every documented exclusion must still match a real block, so stale entries
201
+ // are removed when the doc changes.
202
+ it('has no stale FOREIGN_BLOCKS entries', () => {
203
+ const unmatched = FOREIGN_BLOCKS.filter((_, i) => !foreignMatches.has(i)).map((f) => `${f.file} (${f.snippet})`);
204
+ expect(unmatched).toEqual([]);
205
+ });
206
+ });
207
+ describe('best-practices build configs', () => {
208
+ const files = (0, fs_1.readdirSync)(bestPracticesDir)
209
+ .filter((f) => f.endsWith('.yaml') || f.endsWith('.yml'))
210
+ .sort();
211
+ it('finds the best-practices templates', () => {
212
+ expect(files.length).toBeGreaterThanOrEqual(10);
213
+ });
214
+ it.each(files)('%s is a valid build file', async (name) => {
215
+ const parsed = (0, yaml_1.parse)((0, fs_1.readFileSync)((0, path_1.join)(bestPracticesDir, name), 'utf8'));
216
+ const result = await build_file_schema_1.buildFileSchema.safeParseAsync(parsed);
217
+ if (!result.success) {
218
+ throw new Error(`best-practices/${name} fails the build-file schema:\n` +
219
+ result.error.issues.map((iss) => ` - ${iss.path.join('.')}: ${iss.message}`).join('\n'));
220
+ }
221
+ });
222
+ });
223
+ //# sourceMappingURL=doc-build-files.spec.js.map
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.envsSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.envsSchema = (0, zod_1.record)((0, zod_1.union)([(0, zod_1.string)(), (0, zod_1.number)()])).describe('Environment values for the current build task\nhttps://no0dles.gitbook.io/hammerkit/build-file/environment-variables');
6
+ //# sourceMappingURL=envs-schema.js.map
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.labelsSchema = void 0;
4
+ const zod_1 = require("zod");
5
+ exports.labelsSchema = (0, zod_1.record)((0, zod_1.union)([(0, zod_1.string)(), (0, zod_1.number)()]));
6
+ //# sourceMappingURL=labels-schema.js.map
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=parse-context.js.map
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ParseError = void 0;
4
+ class ParseError extends Error {
5
+ constructor(zod, buildFilePath) {
6
+ super('parse error');
7
+ this.zod = zod;
8
+ this.buildFilePath = buildFilePath;
9
+ }
10
+ }
11
+ exports.ParseError = ParseError;
12
+ //# sourceMappingURL=parse-error.js.map
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const zod_1 = require("zod");
4
+ const parse_error_1 = require("./parse-error");
5
+ describe('ParseError', () => {
6
+ it('wraps a ZodError with the offending build-file path', () => {
7
+ const result = zod_1.z.object({ name: zod_1.z.string() }).safeParse({});
8
+ if (result.success) {
9
+ throw new Error('precondition: expected the safeParse to fail');
10
+ }
11
+ const err = new parse_error_1.ParseError(result.error, '/work/.hammerkit.yaml');
12
+ expect(err).toBeInstanceOf(Error);
13
+ expect(err.zod).toBe(result.error);
14
+ expect(err.buildFilePath).toBe('/work/.hammerkit.yaml');
15
+ expect(err.message).toBe('parse error');
16
+ });
17
+ });
18
+ //# sourceMappingURL=parse-error.spec.js.map