hammerkit 1.6.0 → 1.8.0

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 (277) hide show
  1. package/README.md +7 -7
  2. package/build.schema.json +59 -15
  3. package/dist/cache/backends/local-cache-backend.js +58 -1
  4. package/dist/cache/backends/registry/registry-client.js +264 -0
  5. package/dist/cache/backends/registry/registry-credentials.js +81 -0
  6. package/dist/cache/backends/registry/registry-reference.js +36 -0
  7. package/dist/cache/backends/registry-cache-backend.js +145 -0
  8. package/dist/cache/backends/s3-cache-backend.js +99 -46
  9. package/dist/cache/cache-backend-registry.js +2 -0
  10. package/dist/cache/cache-inventory.js +84 -0
  11. package/dist/cache/cache-sync.js +77 -0
  12. package/dist/cache/explain.js +214 -0
  13. package/dist/cache/last-resolved.js +48 -0
  14. package/dist/cache/read-only.js +15 -0
  15. package/dist/cache/retention.js +61 -0
  16. package/dist/cli.js +43 -0
  17. package/dist/docker/using-container.js +17 -1
  18. package/dist/executer/archive-task-entry.js +21 -0
  19. package/dist/executer/await-completed-dependencies.js +32 -14
  20. package/dist/executer/cache-metadata.js +9 -2
  21. package/dist/executer/docker-service.js +2 -1
  22. package/dist/executer/docker-task.js +18 -3
  23. package/dist/executer/dry-run.js +73 -0
  24. package/dist/executer/event-cache.js +6 -5
  25. package/dist/executer/execute-command.js +21 -3
  26. package/dist/executer/execute-docker.js +18 -2
  27. package/dist/executer/execute-work-service.js +10 -1
  28. package/dist/executer/execute-work-task.js +111 -26
  29. package/dist/executer/execute-work-tree.js +26 -1
  30. package/dist/executer/execution-steps.js +3 -8
  31. package/dist/executer/get-container-binds.js +13 -1
  32. package/dist/executer/get-scheduler-execute-result.js +4 -1
  33. package/dist/executer/lazy-resolver.js +15 -3
  34. package/dist/executer/reset-work-tree.js +2 -0
  35. package/dist/executer/run-summary.js +102 -0
  36. package/dist/executer/scheduler/enqueue-next.js +15 -60
  37. package/dist/executer/scheduler/state-key.js +78 -0
  38. package/dist/index.js +14 -1
  39. package/dist/kubernetes/apply.js +6 -7
  40. package/dist/kubernetes/await-running-state.js +100 -60
  41. package/dist/kubernetes/ensure-http-route.js +7 -10
  42. package/dist/kubernetes/ensure-namespace.js +9 -10
  43. package/dist/kubernetes/ensure-persistent-data.js +6 -5
  44. package/dist/kubernetes/get-service-ip.js +2 -2
  45. package/dist/kubernetes/kubernetes-instance.js +0 -4
  46. package/dist/kubernetes/remove-persistent-data.js +16 -6
  47. package/dist/kubernetes/resolve-pod-name.js +7 -7
  48. package/dist/log.js +16 -6
  49. package/dist/logging/live-logger.js +2 -1
  50. package/dist/optimizer/calculate-checksum.js +8 -2
  51. package/dist/optimizer/get-work-cache-stats.js +66 -16
  52. package/dist/optimizer/work-task-cache-description.js +34 -5
  53. package/dist/planner/project-root.js +26 -0
  54. package/dist/planner/utils/append-work-environment.js +1 -1
  55. package/dist/planner/utils/append-work-service.js +2 -1
  56. package/dist/planner/utils/append-work-task.js +7 -1
  57. package/dist/planner/utils/get-outputs-to-reset.js +20 -0
  58. package/dist/planner/utils/parse-work-generate.js +2 -2
  59. package/dist/planner/utils/parse-work-source.js +35 -30
  60. package/dist/planner/utils/portable-path.js +30 -0
  61. package/dist/planner/work-cache-id.js +2 -2
  62. package/dist/planner/work-graph-serializer.js +103 -0
  63. package/dist/planner/work-instance-id.js +15 -0
  64. package/dist/planner/work-runtime-docker.js +58 -15
  65. package/dist/planner/work-runtime-kubernetes.js +95 -45
  66. package/dist/planner/work-runtime-local.js +31 -8
  67. package/dist/planner/work-service-id.js +16 -4
  68. package/dist/program.js +235 -1
  69. package/dist/schema/build-file-base-task-schema.js +4 -0
  70. package/dist/schema/build-file-environment-schema-http-route.js +15 -0
  71. package/dist/schema/build-file-environment-schema.js +8 -2
  72. package/dist/schema/build-file-schema.js +1 -1
  73. package/dist/schema/cache-schema.js +21 -2
  74. package/dist/schema/duration-schema.js +18 -0
  75. package/dist/schema/envs-schema.js +1 -1
  76. package/dist/schema/reference-parser.js +3 -0
  77. package/dist/schema/size-schema.js +18 -0
  78. package/dist/schema/work-scope-parser.js +15 -2
  79. package/dist/utils/units.js +87 -0
  80. package/package.json +20 -9
  81. package/.agents/FEEDBACK.md +0 -74
  82. package/.agents/skills/before-commit/SKILL.md +0 -101
  83. package/.agents/skills/do-the-work/SKILL.md +0 -64
  84. package/.agents/skills/fix-ci/SKILL.md +0 -98
  85. package/.agents/skills/speckit-git-commit/SKILL.md +0 -53
  86. package/.agents/skills/speckit-git-feature/SKILL.md +0 -72
  87. package/.agents/skills/speckit-git-initialize/SKILL.md +0 -54
  88. package/.agents/skills/speckit-git-remote/SKILL.md +0 -50
  89. package/.agents/skills/speckit-git-validate/SKILL.md +0 -54
  90. package/.devcontainer/Dockerfile +0 -5
  91. package/.devcontainer/devcontainer.json +0 -40
  92. package/.gitbook.yaml +0 -5
  93. package/.specify/extensions/.registry +0 -37
  94. package/.specify/extensions/git/README.md +0 -100
  95. package/.specify/extensions/git/commands/speckit.git.commit.md +0 -48
  96. package/.specify/extensions/git/commands/speckit.git.feature.md +0 -67
  97. package/.specify/extensions/git/commands/speckit.git.initialize.md +0 -49
  98. package/.specify/extensions/git/commands/speckit.git.remote.md +0 -45
  99. package/.specify/extensions/git/commands/speckit.git.validate.md +0 -49
  100. package/.specify/extensions/git/config-template.yml +0 -62
  101. package/.specify/extensions/git/extension.yml +0 -140
  102. package/.specify/extensions/git/git-config.yml +0 -62
  103. package/.specify/extensions.yml +0 -149
  104. package/.specify/feature.json +0 -3
  105. package/.specify/init-options.json +0 -10
  106. package/.specify/integration.json +0 -15
  107. package/.specify/integrations/claude.manifest.json +0 -16
  108. package/.specify/integrations/speckit.manifest.json +0 -17
  109. package/.specify/memory/constitution.md +0 -162
  110. package/.specify/templates/checklist-template.md +0 -40
  111. package/.specify/templates/constitution-template.md +0 -50
  112. package/.specify/templates/plan-template.md +0 -113
  113. package/.specify/templates/spec-template.md +0 -131
  114. package/.specify/templates/tasks-template.md +0 -252
  115. package/.specify/workflows/speckit/workflow.yml +0 -77
  116. package/.specify/workflows/workflow-registry.json +0 -13
  117. package/AGENTS.md +0 -94
  118. package/Dockerfile +0 -32
  119. package/FOLLOWUPS.md +0 -34
  120. package/SUMMARY.md +0 -68
  121. package/VALUES.md +0 -53
  122. package/dist/cache/auto-pull.spec.js +0 -123
  123. package/dist/cache/backends/local-cache-backend.spec.js +0 -72
  124. package/dist/cache/backends/s3-cache-backend.spec.js +0 -118
  125. package/dist/cache/cache-backend-registry.spec.js +0 -22
  126. package/dist/cache/resolve-cache.spec.js +0 -52
  127. package/dist/cli.spec.js +0 -23
  128. package/dist/console/get-logger.spec.js +0 -23
  129. package/dist/docker/get-default-platform.spec.js +0 -29
  130. package/dist/docker/longest-common-prefix.spec.js +0 -26
  131. package/dist/docker/package.spec.js +0 -145
  132. package/dist/docker/remove-container.spec.js +0 -32
  133. package/dist/docker/using-container.spec.js +0 -90
  134. package/dist/environment/merge-environment-variables.spec.js +0 -24
  135. package/dist/environment/replace-env-variables.spec.js +0 -47
  136. package/dist/executer/abort.spec.js +0 -18
  137. package/dist/executer/environment-mock.spec.js +0 -22
  138. package/dist/executer/execute.spec.js +0 -51
  139. package/dist/executer/get-service-containers.spec.js +0 -59
  140. package/dist/executer/get-service-env-hints.spec.js +0 -65
  141. package/dist/executer/label-values.spec.js +0 -61
  142. package/dist/executer/lazy-resolver.spec.js +0 -20
  143. package/dist/executer/process-manager.spec.js +0 -54
  144. package/dist/executer/scheduler/enqueue-next.spec.js +0 -136
  145. package/dist/executer/state-resolver.spec.js +0 -37
  146. package/dist/executer/state.spec.js +0 -66
  147. package/dist/executer/states.spec.js +0 -14
  148. package/dist/file/get-file-context.spec.js +0 -178
  149. package/dist/file/move-files.spec.js +0 -48
  150. package/dist/kubernetes/ensure-http-route.spec.js +0 -70
  151. package/dist/kubernetes/ensure-ingress.js +0 -54
  152. package/dist/kubernetes/ensure-namespace.spec.js +0 -39
  153. package/dist/kubernetes/resolve-pod-name.spec.js +0 -81
  154. package/dist/log.spec.js +0 -131
  155. package/dist/logging/grouped-logger.spec.js +0 -84
  156. package/dist/logging/interactive-logger.spec.js +0 -57
  157. package/dist/logging/live-logger.spec.js +0 -37
  158. package/dist/logging/loggers.spec.js +0 -154
  159. package/dist/optimizer/calculate-checksum.spec.js +0 -34
  160. package/dist/optimizer/get-cache-directory.spec.js +0 -59
  161. package/dist/optimizer/get-work-cache-stats.spec.js +0 -79
  162. package/dist/optimizer/work-task-cache-description.spec.js +0 -45
  163. package/dist/parser/default-build-file.spec.js +0 -48
  164. package/dist/parser/parse-label-arguments.spec.js +0 -27
  165. package/dist/parser/read-build-file.spec.js +0 -89
  166. package/dist/parser/read-env-file.spec.js +0 -42
  167. package/dist/planner/utils/append-work-service.spec.js +0 -71
  168. package/dist/planner/utils/get-container-user.spec.js +0 -30
  169. package/dist/planner/utils/get-default-kube-config.spec.js +0 -11
  170. package/dist/planner/utils/normalize-path.spec.js +0 -24
  171. package/dist/planner/utils/parse-work-command.spec.js +0 -21
  172. package/dist/planner/utils/parse-work-generate.spec.js +0 -45
  173. package/dist/planner/utils/parse-work-mount.spec.js +0 -62
  174. package/dist/planner/utils/parse-work-mounts.spec.js +0 -19
  175. package/dist/planner/utils/parse-work-port.spec.js +0 -24
  176. package/dist/planner/utils/parse-work-ports.spec.js +0 -24
  177. package/dist/planner/utils/parse-work-source.spec.js +0 -58
  178. package/dist/planner/utils/parse-work-volume.spec.js +0 -18
  179. package/dist/planner/utils/plan-work-tasks.spec.js +0 -30
  180. package/dist/planner/utils/plan-work-volume.spec.js +0 -33
  181. package/dist/planner/utils/split-name.spec.js +0 -16
  182. package/dist/planner/utils/template-value.spec.js +0 -14
  183. package/dist/planner/validate.spec.js +0 -251
  184. package/dist/planner/work-cache-id.spec.js +0 -173
  185. package/dist/planner/work-runtime-local.spec.js +0 -193
  186. package/dist/program-commands.spec.js +0 -84
  187. package/dist/program.spec.js +0 -43
  188. package/dist/schema/build-file-environment-schema-ingress.js +0 -14
  189. package/dist/schema/build-file-schema.spec.js +0 -61
  190. package/dist/schema/doc-build-files.spec.js +0 -223
  191. package/dist/schema/parse-error.spec.js +0 -18
  192. package/dist/schema/reference-parser.spec.js +0 -83
  193. package/dist/schema/schema-parser.spec.js +0 -80
  194. package/dist/schema/type-guards.spec.js +0 -23
  195. package/dist/schema/work-scope-parser.spec.js +0 -66
  196. package/dist/service/update-service-status.spec.js +0 -27
  197. package/dist/testing/ensure-local-registry.js +0 -134
  198. package/dist/testing/example-test-suite.js +0 -63
  199. package/dist/testing/expect.js +0 -82
  200. package/dist/testing/get-test-suite.js +0 -9
  201. package/dist/testing/http-get.js +0 -21
  202. package/dist/testing/integration/cache.spec.js +0 -49
  203. package/dist/testing/integration/cancellation.spec.js +0 -45
  204. package/dist/testing/integration/clean.spec.js +0 -43
  205. package/dist/testing/integration/cmd.spec.js +0 -15
  206. package/dist/testing/integration/concurrency.spec.js +0 -19
  207. package/dist/testing/integration/docker-package-registry.spec.js +0 -44
  208. package/dist/testing/integration/docker-service-crash.spec.js +0 -36
  209. package/dist/testing/integration/docker.spec.js +0 -18
  210. package/dist/testing/integration/env.spec.js +0 -48
  211. package/dist/testing/integration/environment.spec.js +0 -97
  212. package/dist/testing/integration/error.spec.js +0 -19
  213. package/dist/testing/integration/export.spec.js +0 -22
  214. package/dist/testing/integration/extend.spec.js +0 -29
  215. package/dist/testing/integration/glob.spec.js +0 -40
  216. package/dist/testing/integration/include.spec.js +0 -31
  217. package/dist/testing/integration/invalid.spec.js +0 -17
  218. package/dist/testing/integration/invalid_loop.spec.js +0 -56
  219. package/dist/testing/integration/k8s-state-cache.spec.js +0 -41
  220. package/dist/testing/integration/kubernetes-service.spec.js +0 -148
  221. package/dist/testing/integration/kubernetes.spec.js +0 -99
  222. package/dist/testing/integration/labels.spec.js +0 -42
  223. package/dist/testing/integration/local.spec.js +0 -14
  224. package/dist/testing/integration/monorepo.spec.js +0 -15
  225. package/dist/testing/integration/multi-line.spec.js +0 -17
  226. package/dist/testing/integration/reference.spec.js +0 -21
  227. package/dist/testing/integration/services.spec.js +0 -38
  228. package/dist/testing/integration/store.spec.js +0 -52
  229. package/dist/testing/integration/unknown.spec.js +0 -28
  230. package/dist/testing/integration/validate.spec.js +0 -160
  231. package/dist/testing/integration/watch-dependency.spec.js +0 -33
  232. package/dist/testing/integration/watch.spec.js +0 -45
  233. package/dist/testing/requires-kubernetes.js +0 -18
  234. package/dist/testing/requires-linux-containers.js +0 -18
  235. package/dist/testing/requires-windows-containers.js +0 -18
  236. package/dist/testing/test-case.js +0 -75
  237. package/dist/testing/test-streams.js +0 -28
  238. package/dist/testing/test-suite-setup.js +0 -3
  239. package/dist/testing/test-suite.js +0 -3
  240. package/dist/testing/testing-timeout.js +0 -32
  241. package/dist/utils/abort-event.spec.js +0 -46
  242. package/dist/utils/buffer-context.spec.js +0 -38
  243. package/dist/utils/ci.spec.js +0 -53
  244. package/dist/utils/debouncer.spec.js +0 -58
  245. package/dist/utils/emitter.spec.js +0 -34
  246. package/dist/utils/empty-writable.spec.js +0 -18
  247. package/dist/utils/environment-config.spec.js +0 -26
  248. package/dist/utils/fail-never.spec.js +0 -9
  249. package/dist/utils/sleep.spec.js +0 -22
  250. package/dist/version.spec.js +0 -12
  251. package/specs/build-file/caches/spec.md +0 -114
  252. package/specs/build-file/environment-variables/spec.md +0 -82
  253. package/specs/build-file/includes/spec.md +0 -60
  254. package/specs/build-file/references/spec.md +0 -56
  255. package/specs/build-file/spec.md +0 -62
  256. package/specs/cli/clean/spec.md +0 -85
  257. package/specs/cli/down/spec.md +0 -85
  258. package/specs/cli/execute/spec.md +0 -101
  259. package/specs/cli/init/spec.md +0 -64
  260. package/specs/cli/ls/spec.md +0 -66
  261. package/specs/cli/package/spec.md +0 -110
  262. package/specs/cli/spec.md +0 -73
  263. package/specs/cli/store-restore/spec.md +0 -74
  264. package/specs/cli/up/spec.md +0 -80
  265. package/specs/cli/validate/spec.md +0 -70
  266. package/specs/labels/spec.md +0 -91
  267. package/specs/service/container/spec.md +0 -120
  268. package/specs/service/kubernetes/spec.md +0 -97
  269. package/specs/service/spec.md +0 -105
  270. package/specs/task/caching/spec.md +0 -107
  271. package/specs/task/container/spec.md +0 -118
  272. package/specs/task/dependencies/spec.md +0 -70
  273. package/specs/task/extending/spec.md +0 -74
  274. package/specs/task/kubernetes/spec.md +0 -125
  275. package/specs/task/needs/spec.md +0 -59
  276. package/specs/task/spec.md +0 -87
  277. package/specs/task/watching/spec.md +0 -69
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hammerkit",
3
3
  "description": "Containerized build tool with incremental caching that runs the same build file locally, in Docker and on Kubernetes.",
4
- "version": "1.6.0",
4
+ "version": "1.8.0",
5
5
  "keywords": [
6
6
  "build",
7
7
  "build-tool",
@@ -12,8 +12,15 @@
12
12
  "monorepo",
13
13
  "task-runner"
14
14
  ],
15
- "homepage": "https://no0dles.gitbook.io/hammerkit/",
15
+ "homepage": "https://hammerkit.dev",
16
16
  "bin": "dist/index.js",
17
+ "files": [
18
+ "dist",
19
+ "!dist/**/*.spec.*",
20
+ "!dist/testing",
21
+ "!dist/**/*.map",
22
+ "build.schema.json"
23
+ ],
17
24
  "bugs": {
18
25
  "url": "https://github.com/no0dles/hammerkit/issues"
19
26
  },
@@ -34,32 +41,36 @@
34
41
  "build": "tsc -b tsconfig.json",
35
42
  "test": "vitest run",
36
43
  "test:integration": "vitest run --mode integration",
44
+ "test:mutation": "stryker run",
37
45
  "format": "prettier -w src/** && eslint . --fix --ext .ts",
38
46
  "lint": "eslint . --ext .ts"
39
47
  },
40
48
  "dependencies": {
41
49
  "@aws-sdk/client-s3": "^3.470.0",
42
- "@kubernetes/client-node": "^0.20.0",
43
- "chokidar": "^3.5.3",
50
+ "@kubernetes/client-node": "^2.0.0",
51
+ "chokidar": "^3.6.0",
44
52
  "colors": "^1.4.0",
45
53
  "commander": "^11.1.0",
46
- "dockerode": "^4.0.2",
54
+ "dockerode": "^4.0.12",
47
55
  "find-process": "^1.4.7",
48
- "minimatch": "^6.1.5",
49
- "tar": "^6.2.0",
50
- "yaml": "^2.3.4",
56
+ "minimatch": "^6.2.3",
57
+ "tar": "^7.5.22",
58
+ "yaml": "^2.9.1",
51
59
  "zod": "^3.22.4"
52
60
  },
53
61
  "devDependencies": {
62
+ "@stryker-mutator/core": "^10.0.0",
63
+ "@stryker-mutator/vitest-runner": "^10.0.0",
54
64
  "@types/dockerode": "^3.3.23",
55
65
  "@types/minimatch": "^5.1.2",
56
66
  "@types/node": "^24.0.0",
57
- "@types/tar": "^6.1.3",
67
+ "@types/ws": "^8.18.2",
58
68
  "@typescript-eslint/eslint-plugin": "^6.16.0",
59
69
  "@typescript-eslint/parser": "^6.16.0",
60
70
  "@vitest/coverage-istanbul": "^2.1.8",
61
71
  "@yao-pkg/pkg": "^6.20.0",
62
72
  "eslint": "^8.56.0",
73
+ "fast-check": "^4.10.2",
63
74
  "prettier": "^3.1.1",
64
75
  "typescript": "^5.3.3",
65
76
  "vitest": "^2.1.8",
@@ -1,74 +0,0 @@
1
- # Feedback log
2
-
3
- Durable record of corrections and preferences the user has given AI agents working
4
- in this repo. The point of this file is that the user should **not have to repeat
5
- himself**.
6
-
7
- **Contract — every agent, every session:**
8
-
9
- 1. **Read this file before you start working.** Apply every rule here without being
10
- reminded.
11
- 2. **Don't re-ask anything already answered here.** If a rule covers the situation,
12
- follow it instead of asking.
13
- 3. **When the user corrects you or states a preference, append an entry here
14
- immediately** — same session, before moving on — so it is captured for next
15
- time. Keep entries short: a rule, **Why**, **How to apply**, and a date.
16
-
17
- Related: the companion `do-the-work` skill explains the behavior; this file is the
18
- running record.
19
-
20
- ---
21
-
22
- ## Rules
23
-
24
- ### Do the work — don't propose avoiding it _(2026-05-25)_
25
-
26
- Skipping, disabling, excluding, `.skip` / `it.skip` / `xfail`, commenting-out,
27
- deleting, loosening/weakening an assertion, or stopping early is **never** an
28
- acceptable way to resolve a failing test or a red build. Fix the root cause.
29
-
30
- - **Why:** The user asked for the thing to be *fixed*. Avoiding the work is not a
31
- smaller version of the job — it's not doing the job, and it hides a regression.
32
- Avoidance being the agent's default reflex is what the user finds worrying.
33
- - **How to apply:** Diagnose the underlying cause (timing, environment,
34
- file-watching, resource leaks, ordering, a real bug) and fix it so the check
35
- passes legitimately. Only ever skip/disable something if the user *explicitly*
36
- asks for it in that conversation.
37
-
38
- ### "Fix CI" means fix the failure, not remove the test _(2026-05-25)_
39
-
40
- When the task is to get CI green, the deliverable is a green run achieved by
41
- fixing what is broken — not by removing, skipping, or muting the failing check.
42
-
43
- - **Why:** Fixing CI *is* the requested work. Removing the test makes CI green
44
- while leaving the actual problem in place.
45
- - **How to apply:** Use the `fix-ci` skill loop (diagnose → fix → verify →
46
- commit → push → watch). If a failure is genuinely container/k8s/infra-only and
47
- cannot be reproduced on this host, say so explicitly and rely on CI to confirm
48
- the fix — that is not the same as skipping the test.
49
-
50
- ### Prefer configurable timeouts over skips or huge fixed values _(2026-05-25)_
51
-
52
- When a test hangs or flakes, make the timeout configurable (e.g. via env var)
53
- rather than skipping the test or hardcoding a giant timeout.
54
-
55
- - **Why:** CI is slower than local; a configurable budget lets local fail fast
56
- (surfacing hangs quickly) while CI gets the time it needs. Reducing flake is
57
- always desirable; skipping never is.
58
- - **How to apply:** Drive the timeout from an env var with a sensible local
59
- default and a longer CI value; fix the underlying cause of the hang/flake.
60
-
61
- ### Ask implementation questions freely; never ask permission to avoid work _(2026-05-25)_
62
-
63
- Questions about *how* to implement something — design, approach, ambiguity,
64
- trade-offs — are welcome and encouraged. Questions that are really requests to
65
- *not do* the assigned work are not.
66
-
67
- - **Why:** The user repeatedly got asked variants of "can I skip/stop/disable
68
- this?" instead of getting the work done. He doesn't want to keep saying "no, do
69
- it."
70
- - **How to apply:** If a question's effect is to avoid the work (skip a test,
71
- drop a requirement, leave the failure), don't ask it — do the work. Only
72
- escalate when *genuinely* blocked: missing access/credentials, a product
73
- decision only the user can make, or contradictory requirements — and even then,
74
- propose the fix path, not the avoidance.
@@ -1,101 +0,0 @@
1
- ---
2
- name: before-commit
3
- description: Pre-commit checklist for the hammerkit repo. Run the same gates CI enforces — prettier, eslint, tsc build, and the unit suite — before committing, so a push doesn't fail the build/test workflows. Use before any git commit in this repository.
4
- ---
5
-
6
- # Before committing (hammerkit)
7
-
8
- Run these locally before `git commit`/`git push`. Each maps to a GitHub Actions
9
- gate; passing them locally is the difference between a green push and a red one.
10
- Run from the repo root.
11
-
12
- Making a gate pass means **fixing the cause**, not disabling the check (no skipped
13
- tests, no relaxed lint/prettier config to dodge an error) — see the `do-the-work`
14
- skill.
15
-
16
- ## 1. Prettier — the most common CI break
17
-
18
- The `build` workflow runs `prettier --check 'src/**'`, and it is **strict**: a
19
- single unformatted file fails the entire `build` workflow (even if your own
20
- changes are clean — it checks all of `src/`).
21
-
22
- ```bash
23
- node_modules/.bin/prettier --check 'src/**'
24
- ```
25
-
26
- If it reports issues, fix them:
27
-
28
- ```bash
29
- npm run format # prettier -w src/** && eslint . --fix --ext .ts
30
- ```
31
-
32
- Style is enforced: no semicolons, single quotes, 120 cols, 2-space indent,
33
- trailing commas `es5`.
34
-
35
- ## 2. ESLint
36
-
37
- ```bash
38
- npm run lint # eslint . --ext .ts
39
- ```
40
-
41
- Note `no-console: error` — never write to `console.*` in `src/`. Route output
42
- through the `Environment` (`stdout`/`stderr`/`console`/`status`).
43
-
44
- ## 3. Typecheck / build
45
-
46
- ```bash
47
- npm run build # tsc -b tsconfig.json
48
- ```
49
-
50
- This typechecks spec files too, so it catches test-only type errors.
51
-
52
- ## 4. Unit tests — mirror CI with `CI=true`
53
-
54
- ```bash
55
- CI=true npm test
56
- ```
57
-
58
- Run with `CI=true`. In CI the container/k8s tests gate themselves to a no-op
59
- when their env flag is unset (see `src/testing/requires-*.ts`); **without**
60
- `CI=true` those same tests try to talk to Docker/Kubernetes locally and fail.
61
- The unit suite (`jest`) excludes `src/testing/integration/`, so it needs no
62
- Docker.
63
-
64
- Single test while iterating:
65
-
66
- ```bash
67
- node_modules/.bin/jest src/path/to/file.spec.ts -t "test name"
68
- ```
69
-
70
- ## 5. Integration tests — only when you touched docker / k8s / execution
71
-
72
- These need a running Docker daemon (and are slow). They are **not** required for
73
- most commits; the self-hosted `integration` workflow covers them. Run locally
74
- only if your change affects container/k8s execution:
75
-
76
- ```bash
77
- # Docker must be running. CI runs this --runInBand.
78
- LINUX_CONTAINERS=true npm run test:integration -- --runInBand
79
- ```
80
-
81
- Add `CLUSTER_NAME=<kube-context>` to also exercise the kubernetes specs.
82
-
83
- ## Cross-platform note
84
-
85
- The `test` workflow runs the unit suite on **ubuntu, windows, and macos**, plus
86
- a `macos-containers` job. Keep changes portable:
87
-
88
- - Build paths with `path` helpers; in tests, make separator-sensitive
89
- expectations native (`val.split(posix.sep).join(sep)`) rather than hardcoding
90
- `/` — see `src/planner/utils/parse-work-mount.spec.ts`.
91
- - File-watch + repeated process-spawn tests are unreliable on Windows hosted
92
- runners; the watch-restart cases in `src/executer/execute.spec.ts` are gated
93
- off win32. If you add similar tests, expect to gate them too.
94
-
95
- ## One-liner
96
-
97
- ```bash
98
- node_modules/.bin/prettier --check 'src/**' && npm run lint && npm run build && CI=true npm test
99
- ```
100
-
101
- If all four pass, the `build` and `test` workflows should pass on push.
@@ -1,64 +0,0 @@
1
- ---
2
- name: do-the-work
3
- description: >-
4
- Do the actual work instead of avoiding it, and don't make the user repeat
5
- feedback. Use whenever the task is to fix something — fix CI, fix a failing or
6
- flaky test, fix the build, make a check green, resolve a bug — or any time you
7
- are tempted to skip, disable, exclude, defer, or stop early. Read and apply the
8
- repo feedback log before working; append to it when corrected.
9
- ---
10
-
11
- # Do the work (hammerkit)
12
-
13
- The job is to **fix the thing**, not to find a way around fixing it. This skill
14
- exists because avoidance kept showing up as the default reflex, and because the
15
- user does not want to repeat feedback he has already given.
16
-
17
- ## The contract
18
-
19
- When the task is to make something pass — CI, a test, the build, a check — the
20
- deliverable is that it passes **because the underlying problem is fixed**. The
21
- following are *never* the resolution (only do them if the user explicitly asks in
22
- this conversation):
23
-
24
- - `.skip` / `it.skip` / `describe.skip` / `xfail` / `test.todo`
25
- - excluding files or paths from a suite, or commenting-out / deleting a test
26
- - loosening or removing an assertion so it stops failing
27
- - raising a timeout to a giant fixed value to paper over a hang
28
- - declaring something "flaky locally" and moving on
29
- - stopping early and handing back an unfixed failure as if it were done
30
-
31
- Instead: diagnose the root cause (timing, environment, file-watching, resource
32
- leaks, ordering, a real bug) and fix it so the check passes legitimately. If a
33
- failure is genuinely container/k8s/infra-only and can't be reproduced on this
34
- host, **say so explicitly** and rely on CI to confirm — that is honest reporting,
35
- not skipping.
36
-
37
- ## Good questions vs. avoidance dressed as a question
38
-
39
- - **Ask freely:** how to implement something, which design/approach to take,
40
- genuine ambiguity in the requirements, trade-offs that change the outcome. These
41
- are welcome.
42
- - **Don't ask — just do it:** "Can I skip this test?", "Is it ok to leave this
43
- failing?", "Should I just remove/disable it?", "Want me to stop here?" If the
44
- effect of the question is to *avoid the assigned work*, the answer is already no
45
- — do the work.
46
- - **Only escalate when truly blocked:** missing access/credentials, a product
47
- decision only the user can make, or contradictory requirements. Even then,
48
- propose the fix path, not the avoidance.
49
-
50
- ## Feedback discipline (don't make the user repeat himself)
51
-
52
- The repo keeps a durable log at `.agents/FEEDBACK.md`.
53
-
54
- 1. **Read it before you start working** and apply every rule there.
55
- 2. **Don't re-ask anything it already answers.**
56
- 3. **When the user corrects you or states a preference, append an entry to it
57
- immediately** (rule + **Why** + **How to apply** + date), so it's never
58
- re-litigated.
59
-
60
- ## Canonical instance
61
-
62
- "Never skip tests to go green" is the sharpest example of the contract — see the
63
- `never skip tests` rule in `.agents/FEEDBACK.md`. The `fix-ci` and `before-commit`
64
- skills are how you actually fix CI without skipping.
@@ -1,98 +0,0 @@
1
- ---
2
- name: fix-ci
3
- description: >-
4
- Iterate until CI is green on the current branch. Use when GitHub Actions is red, a push
5
- broke the build, or the user asks to "fix CI" / "get CI green". Loop: read the failing run
6
- via gh -> diagnose the root cause from the logs -> implement a fix -> verify locally with
7
- the before-commit skill -> commit -> push -> watch the run -> repeat on failure.
8
- ---
9
-
10
- # Fix CI (hammerkit)
11
-
12
- Drive CI to green on the current branch. This skill is the **loop around a fix**; for the
13
- actual local checks, use the **`before-commit`** skill — do not re-run an ad-hoc checklist
14
- here.
15
-
16
- Repeat until the run is green:
17
- **check status → diagnose → fix → verify (before-commit) → commit → push → watch → repeat.**
18
-
19
- ## Step 1 — Check CI status
20
-
21
- ```bash
22
- git branch --show-current
23
- gh run list --branch "$(git branch --show-current)" --limit 5
24
- gh run view <run-id> --log-failed # or: gh pr checks (if a PR is open)
25
- ```
26
-
27
- Identify the failing **job** and **step**, then read its log to pin the root cause. Use this
28
- workflow → gate map only to decide which `before-commit` gate to re-run (the command details
29
- live in `before-commit`, not here):
30
-
31
- - `build` → prettier (strict over all of `src/`), eslint, tsc build.
32
- - `test` → the jest unit matrix on **ubuntu, windows, macos** (+ a `macos-containers` job).
33
- - `integration` / `macos-containers` → docker/k8s tests; need Docker/Kubernetes and usually
34
- **cannot** be reproduced locally.
35
-
36
- ## Step 2 — Implement a fix
37
-
38
- Make the **smallest** change that addresses the identified root cause. Repo conventions are
39
- enforced by `before-commit`'s gates, so don't restate them — just keep the change clean. For
40
- OS-specific (e.g. windows-only) or container/k8s failures, note that the fix may only be
41
- verifiable in CI, not on this host.
42
-
43
- ## Step 3 — Verify locally (use `before-commit`)
44
-
45
- Run the **`before-commit` skill** to run the same gates CI enforces, then re-run the
46
- specific failing case while iterating (e.g.
47
- `node_modules/.bin/jest src/path/to/file.spec.ts -t "test name"`).
48
-
49
- If the failure is container/k8s-only and can't be reproduced on this host, **say so
50
- explicitly** and rely on CI to confirm — never claim a gate passed that you didn't run.
51
-
52
- ## Step 4 — Commit
53
-
54
- Stage only the files relevant to the fix and commit with a clear `type(scope): summary`
55
- message describing the CI problem fixed (matching the repo's git-log style, e.g.
56
- `fix: ...`, `test(ci): ...`, `style: ...`).
57
-
58
- ## Step 5 — Push
59
-
60
- Push the current branch to its remote. (Never force-push.)
61
-
62
- ## Step 6 — Wait for CI
63
-
64
- Watch the run produced by the push to completion:
65
-
66
- ```bash
67
- gh run watch <run-id> --exit-status # resolve <run-id> from the just-pushed commit
68
- ```
69
-
70
- Or poll `gh run list --branch <branch>` / `gh pr checks` until the run finishes.
71
-
72
- ## Step 7 — Loop on red
73
-
74
- - **Green** → report success and stop.
75
- - **Red** → go back to Step 1 with the new failing logs and repeat.
76
-
77
- ## Guardrails
78
-
79
- - **Fix the failure; never skip it.** Getting CI green means fixing what's broken —
80
- not skipping, disabling, excluding, `.skip`/`xfail`, weakening an assertion, or
81
- deleting the failing test. That defeats the whole point of this skill. See the
82
- `do-the-work` skill and `.agents/FEEDBACK.md`.
83
- - Cap attempts (~3–5). If the **same** failure recurs across iterations, stop and surface it.
84
- - Treat infra/flake as not-your-bug: the `integration` workflow runs on a self-hosted runner,
85
- and the `macos-containers` job uses colima (flaky, slow). If a failure looks like infra,
86
- stop and tell the user rather than looping.
87
- - Never force-push and never touch files unrelated to the fix.
88
-
89
- ## Quick reference (gh — unique to this skill)
90
-
91
- ```bash
92
- gh run list --branch <branch> --limit 5 # latest runs for the branch
93
- gh run view <run-id> --log-failed # failing logs only
94
- gh pr checks # status when a PR is open
95
- gh run watch <run-id> --exit-status # block until done; non-zero on failure
96
- ```
97
-
98
- For local verification commands, see the **`before-commit`** skill.
@@ -1,53 +0,0 @@
1
- ---
2
- name: speckit-git-commit
3
- description: Auto-commit changes after a Spec Kit command completes
4
- compatibility: Requires spec-kit project structure with .specify/ directory
5
- metadata:
6
- author: github-spec-kit
7
- source: git:commands/speckit.git.commit.md
8
- ---
9
-
10
- # Auto-Commit Changes
11
-
12
- Automatically stage and commit all changes after a Spec Kit command completes.
13
-
14
- ## Behavior
15
-
16
- This command is invoked as a hook after (or before) core commands. It:
17
-
18
- 1. Determines the event name from the hook context (e.g., if invoked as an `after_specify` hook, the event is `after_specify`; if `before_plan`, the event is `before_plan`)
19
- 2. Checks `.specify/extensions/git/git-config.yml` for the `auto_commit` section
20
- 3. Looks up the specific event key to see if auto-commit is enabled
21
- 4. Falls back to `auto_commit.default` if no event-specific key exists
22
- 5. Uses the per-command `message` if configured, otherwise a default message
23
- 6. If enabled and there are uncommitted changes, runs `git add .` + `git commit`
24
-
25
- ## Execution
26
-
27
- Determine the event name from the hook that triggered this command, then run the script:
28
-
29
- - **Bash**: `.specify/extensions/git/scripts/bash/auto-commit.sh <event_name>`
30
- - **PowerShell**: `.specify/extensions/git/scripts/powershell/auto-commit.ps1 <event_name>`
31
-
32
- Replace `<event_name>` with the actual hook event (e.g., `after_specify`, `before_plan`, `after_implement`).
33
-
34
- ## Configuration
35
-
36
- In `.specify/extensions/git/git-config.yml`:
37
-
38
- ```yaml
39
- auto_commit:
40
- default: false # Global toggle — set true to enable for all commands
41
- after_specify:
42
- enabled: true # Override per-command
43
- message: "[Spec Kit] Add specification"
44
- after_plan:
45
- enabled: false
46
- message: "[Spec Kit] Add implementation plan"
47
- ```
48
-
49
- ## Graceful Degradation
50
-
51
- - If Git is not available or the current directory is not a repository: skips with a warning
52
- - If no config file exists: skips (disabled by default)
53
- - If no changes to commit: skips with a message
@@ -1,72 +0,0 @@
1
- ---
2
- name: speckit-git-feature
3
- description: Create a feature branch with sequential or timestamp numbering
4
- compatibility: Requires spec-kit project structure with .specify/ directory
5
- metadata:
6
- author: github-spec-kit
7
- source: git:commands/speckit.git.feature.md
8
- ---
9
-
10
- # Create Feature Branch
11
-
12
- Create and switch to a new git feature branch for the given specification. This command handles **branch creation only** — the spec directory and files are created by the core `/speckit-specify` workflow.
13
-
14
- ## User Input
15
-
16
- ```text
17
- $ARGUMENTS
18
- ```
19
-
20
- You **MUST** consider the user input before proceeding (if not empty).
21
-
22
- ## Environment Variable Override
23
-
24
- If the user explicitly provided `GIT_BRANCH_NAME` (e.g., via environment variable, argument, or in their request), pass it through to the script by setting the `GIT_BRANCH_NAME` environment variable before invoking the script. When `GIT_BRANCH_NAME` is set:
25
- - The script uses the exact value as the branch name, bypassing all prefix/suffix generation
26
- - `--short-name`, `--number`, and `--timestamp` flags are ignored
27
- - `FEATURE_NUM` is extracted from the name if it starts with a numeric prefix, otherwise set to the full branch name
28
-
29
- ## Prerequisites
30
-
31
- - Verify Git is available by running `git rev-parse --is-inside-work-tree 2>/dev/null`
32
- - If Git is not available, warn the user and skip branch creation
33
-
34
- ## Branch Numbering Mode
35
-
36
- Determine the branch numbering strategy by checking configuration in this order:
37
-
38
- 1. Check `.specify/extensions/git/git-config.yml` for `branch_numbering` value
39
- 2. Check `.specify/init-options.json` for `branch_numbering` value (backward compatibility)
40
- 3. Default to `sequential` if neither exists
41
-
42
- ## Execution
43
-
44
- Generate a concise short name (2-4 words) for the branch:
45
- - Analyze the feature description and extract the most meaningful keywords
46
- - Use action-noun format when possible (e.g., "add-user-auth", "fix-payment-bug")
47
- - Preserve technical terms and acronyms (OAuth2, API, JWT, etc.)
48
-
49
- Run the appropriate script based on your platform:
50
-
51
- - **Bash**: `.specify/extensions/git/scripts/bash/create-new-feature.sh --json --short-name "<short-name>" "<feature description>"`
52
- - **Bash (timestamp)**: `.specify/extensions/git/scripts/bash/create-new-feature.sh --json --timestamp --short-name "<short-name>" "<feature description>"`
53
- - **PowerShell**: `.specify/extensions/git/scripts/powershell/create-new-feature.ps1 -Json -ShortName "<short-name>" "<feature description>"`
54
- - **PowerShell (timestamp)**: `.specify/extensions/git/scripts/powershell/create-new-feature.ps1 -Json -Timestamp -ShortName "<short-name>" "<feature description>"`
55
-
56
- **IMPORTANT**:
57
- - Do NOT pass `--number` — the script determines the correct next number automatically
58
- - Always include the JSON flag (`--json` for Bash, `-Json` for PowerShell) so the output can be parsed reliably
59
- - You must only ever run this script once per feature
60
- - The JSON output will contain `BRANCH_NAME` and `FEATURE_NUM`
61
-
62
- ## Graceful Degradation
63
-
64
- If Git is not installed or the current directory is not a Git repository:
65
- - Branch creation is skipped with a warning: `[specify] Warning: Git repository not detected; skipped branch creation`
66
- - The script still outputs `BRANCH_NAME` and `FEATURE_NUM` so the caller can reference them
67
-
68
- ## Output
69
-
70
- The script outputs JSON with:
71
- - `BRANCH_NAME`: The branch name (e.g., `003-user-auth` or `20260319-143022-user-auth`)
72
- - `FEATURE_NUM`: The numeric or timestamp prefix used
@@ -1,54 +0,0 @@
1
- ---
2
- name: speckit-git-initialize
3
- description: Initialize a Git repository with an initial commit
4
- compatibility: Requires spec-kit project structure with .specify/ directory
5
- metadata:
6
- author: github-spec-kit
7
- source: git:commands/speckit.git.initialize.md
8
- ---
9
-
10
- # Initialize Git Repository
11
-
12
- Initialize a Git repository in the current project directory if one does not already exist.
13
-
14
- ## Execution
15
-
16
- Run the appropriate script from the project root:
17
-
18
- - **Bash**: `.specify/extensions/git/scripts/bash/initialize-repo.sh`
19
- - **PowerShell**: `.specify/extensions/git/scripts/powershell/initialize-repo.ps1`
20
-
21
- If the extension scripts are not found, fall back to:
22
- - **Bash**: `git init && git add . && git commit -m "Initial commit from Specify template"`
23
- - **PowerShell**: `git init; git add .; git commit -m "Initial commit from Specify template"`
24
-
25
- The script handles all checks internally:
26
- - Skips if Git is not available
27
- - Skips if already inside a Git repository
28
- - Runs `git init`, `git add .`, and `git commit` with an initial commit message
29
-
30
- ## Customization
31
-
32
- Replace the script to add project-specific Git initialization steps:
33
- - Custom `.gitignore` templates
34
- - Default branch naming (`git config init.defaultBranch`)
35
- - Git LFS setup
36
- - Git hooks installation
37
- - Commit signing configuration
38
- - Git Flow initialization
39
-
40
- ## Output
41
-
42
- On success:
43
- - `[OK] Git repository initialized`
44
-
45
- ## Graceful Degradation
46
-
47
- If Git is not installed:
48
- - Warn the user
49
- - Skip repository initialization
50
- - The project continues to function without Git (specs can still be created under `specs/`)
51
-
52
- If Git is installed but `git init`, `git add .`, or `git commit` fails:
53
- - Surface the error to the user
54
- - Stop this command rather than continuing with a partially initialized repository
@@ -1,50 +0,0 @@
1
- ---
2
- name: speckit-git-remote
3
- description: Detect Git remote URL for GitHub integration
4
- compatibility: Requires spec-kit project structure with .specify/ directory
5
- metadata:
6
- author: github-spec-kit
7
- source: git:commands/speckit.git.remote.md
8
- ---
9
-
10
- # Detect Git Remote URL
11
-
12
- Detect the Git remote URL for integration with GitHub services (e.g., issue creation).
13
-
14
- ## Prerequisites
15
-
16
- - Check if Git is available by running `git rev-parse --is-inside-work-tree 2>/dev/null`
17
- - If Git is not available, output a warning and return empty:
18
- ```
19
- [specify] Warning: Git repository not detected; cannot determine remote URL
20
- ```
21
-
22
- ## Execution
23
-
24
- Run the following command to get the remote URL:
25
-
26
- ```bash
27
- git config --get remote.origin.url
28
- ```
29
-
30
- ## Output
31
-
32
- Parse the remote URL and determine:
33
-
34
- 1. **Repository owner**: Extract from the URL (e.g., `github` from `https://github.com/github/spec-kit.git`)
35
- 2. **Repository name**: Extract from the URL (e.g., `spec-kit` from `https://github.com/github/spec-kit.git`)
36
- 3. **Is GitHub**: Whether the remote points to a GitHub repository
37
-
38
- Supported URL formats:
39
- - HTTPS: `https://github.com/<owner>/<repo>.git`
40
- - SSH: `git@github.com:<owner>/<repo>.git`
41
-
42
- > [!CAUTION]
43
- > ONLY report a GitHub repository if the remote URL actually points to github.com.
44
- > Do NOT assume the remote is GitHub if the URL format doesn't match.
45
-
46
- ## Graceful Degradation
47
-
48
- If Git is not installed, the directory is not a Git repository, or no remote is configured:
49
- - Return an empty result
50
- - Do NOT error — other workflows should continue without Git remote information