hammerkit 1.6.0 → 1.7.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.
- package/README.md +4 -4
- package/build.schema.json +49 -2
- package/dist/cache/backends/local-cache-backend.js +58 -1
- package/dist/cache/backends/registry/registry-client.js +264 -0
- package/dist/cache/backends/registry/registry-credentials.js +81 -0
- package/dist/cache/backends/registry/registry-reference.js +36 -0
- package/dist/cache/backends/registry-cache-backend.js +145 -0
- package/dist/cache/backends/s3-cache-backend.js +99 -46
- package/dist/cache/cache-backend-registry.js +2 -0
- package/dist/cache/cache-inventory.js +84 -0
- package/dist/cache/cache-sync.js +77 -0
- package/dist/cache/explain.js +214 -0
- package/dist/cache/last-resolved.js +48 -0
- package/dist/cache/read-only.js +15 -0
- package/dist/cache/retention.js +61 -0
- package/dist/cli.js +43 -0
- package/dist/docker/using-container.js +5 -1
- package/dist/executer/archive-task-entry.js +21 -0
- package/dist/executer/await-completed-dependencies.js +32 -14
- package/dist/executer/cache-metadata.js +9 -2
- package/dist/executer/docker-service.js +2 -1
- package/dist/executer/docker-task.js +2 -1
- package/dist/executer/dry-run.js +73 -0
- package/dist/executer/event-cache.js +6 -5
- package/dist/executer/execute-command.js +21 -3
- package/dist/executer/execute-work-service.js +10 -1
- package/dist/executer/execute-work-task.js +95 -25
- package/dist/executer/execute-work-tree.js +26 -1
- package/dist/executer/get-scheduler-execute-result.js +4 -1
- package/dist/executer/lazy-resolver.js +15 -3
- package/dist/executer/reset-work-tree.js +2 -0
- package/dist/executer/run-summary.js +102 -0
- package/dist/executer/scheduler/enqueue-next.js +15 -60
- package/dist/executer/scheduler/state-key.js +78 -0
- package/dist/kubernetes/await-running-state.js +73 -19
- package/dist/log.js +16 -6
- package/dist/logging/live-logger.js +2 -1
- package/dist/optimizer/calculate-checksum.js +8 -2
- package/dist/optimizer/get-work-cache-stats.js +66 -16
- package/dist/optimizer/work-task-cache-description.js +34 -5
- package/dist/planner/project-root.js +26 -0
- package/dist/planner/utils/append-work-service.js +2 -1
- package/dist/planner/utils/append-work-task.js +7 -1
- package/dist/planner/utils/parse-work-source.js +35 -30
- package/dist/planner/utils/portable-path.js +30 -0
- package/dist/planner/work-cache-id.js +2 -2
- package/dist/planner/work-graph-serializer.js +103 -0
- package/dist/planner/work-instance-id.js +15 -0
- package/dist/planner/work-runtime-docker.js +53 -15
- package/dist/planner/work-runtime-kubernetes.js +35 -3
- package/dist/planner/work-runtime-local.js +9 -3
- package/dist/planner/work-service-id.js +16 -4
- package/dist/program.js +235 -1
- package/dist/schema/build-file-base-task-schema.js +4 -0
- package/dist/schema/cache-schema.js +21 -2
- package/dist/schema/duration-schema.js +18 -0
- package/dist/schema/reference-parser.js +3 -0
- package/dist/schema/size-schema.js +18 -0
- package/dist/schema/work-scope-parser.js +15 -2
- package/dist/utils/units.js +87 -0
- package/package.json +12 -1
- package/.agents/FEEDBACK.md +0 -74
- package/.agents/skills/before-commit/SKILL.md +0 -101
- package/.agents/skills/do-the-work/SKILL.md +0 -64
- package/.agents/skills/fix-ci/SKILL.md +0 -98
- package/.agents/skills/speckit-git-commit/SKILL.md +0 -53
- package/.agents/skills/speckit-git-feature/SKILL.md +0 -72
- package/.agents/skills/speckit-git-initialize/SKILL.md +0 -54
- package/.agents/skills/speckit-git-remote/SKILL.md +0 -50
- package/.agents/skills/speckit-git-validate/SKILL.md +0 -54
- package/.devcontainer/Dockerfile +0 -5
- package/.devcontainer/devcontainer.json +0 -40
- package/.gitbook.yaml +0 -5
- package/.specify/extensions/.registry +0 -37
- package/.specify/extensions/git/README.md +0 -100
- package/.specify/extensions/git/commands/speckit.git.commit.md +0 -48
- package/.specify/extensions/git/commands/speckit.git.feature.md +0 -67
- package/.specify/extensions/git/commands/speckit.git.initialize.md +0 -49
- package/.specify/extensions/git/commands/speckit.git.remote.md +0 -45
- package/.specify/extensions/git/commands/speckit.git.validate.md +0 -49
- package/.specify/extensions/git/config-template.yml +0 -62
- package/.specify/extensions/git/extension.yml +0 -140
- package/.specify/extensions/git/git-config.yml +0 -62
- package/.specify/extensions.yml +0 -149
- package/.specify/feature.json +0 -3
- package/.specify/init-options.json +0 -10
- package/.specify/integration.json +0 -15
- package/.specify/integrations/claude.manifest.json +0 -16
- package/.specify/integrations/speckit.manifest.json +0 -17
- package/.specify/memory/constitution.md +0 -162
- package/.specify/templates/checklist-template.md +0 -40
- package/.specify/templates/constitution-template.md +0 -50
- package/.specify/templates/plan-template.md +0 -113
- package/.specify/templates/spec-template.md +0 -131
- package/.specify/templates/tasks-template.md +0 -252
- package/.specify/workflows/speckit/workflow.yml +0 -77
- package/.specify/workflows/workflow-registry.json +0 -13
- package/AGENTS.md +0 -94
- package/Dockerfile +0 -32
- package/FOLLOWUPS.md +0 -34
- package/SUMMARY.md +0 -68
- package/VALUES.md +0 -53
- package/dist/cache/auto-pull.spec.js +0 -123
- package/dist/cache/backends/local-cache-backend.spec.js +0 -72
- package/dist/cache/backends/s3-cache-backend.spec.js +0 -118
- package/dist/cache/cache-backend-registry.spec.js +0 -22
- package/dist/cache/resolve-cache.spec.js +0 -52
- package/dist/cli.spec.js +0 -23
- package/dist/console/get-logger.spec.js +0 -23
- package/dist/docker/get-default-platform.spec.js +0 -29
- package/dist/docker/longest-common-prefix.spec.js +0 -26
- package/dist/docker/package.spec.js +0 -145
- package/dist/docker/remove-container.spec.js +0 -32
- package/dist/docker/using-container.spec.js +0 -90
- package/dist/environment/merge-environment-variables.spec.js +0 -24
- package/dist/environment/replace-env-variables.spec.js +0 -47
- package/dist/executer/abort.spec.js +0 -18
- package/dist/executer/environment-mock.spec.js +0 -22
- package/dist/executer/execute.spec.js +0 -51
- package/dist/executer/get-service-containers.spec.js +0 -59
- package/dist/executer/get-service-env-hints.spec.js +0 -65
- package/dist/executer/label-values.spec.js +0 -61
- package/dist/executer/lazy-resolver.spec.js +0 -20
- package/dist/executer/process-manager.spec.js +0 -54
- package/dist/executer/scheduler/enqueue-next.spec.js +0 -136
- package/dist/executer/state-resolver.spec.js +0 -37
- package/dist/executer/state.spec.js +0 -66
- package/dist/executer/states.spec.js +0 -14
- package/dist/file/get-file-context.spec.js +0 -178
- package/dist/file/move-files.spec.js +0 -48
- package/dist/kubernetes/ensure-http-route.spec.js +0 -70
- package/dist/kubernetes/ensure-namespace.spec.js +0 -39
- package/dist/kubernetes/resolve-pod-name.spec.js +0 -81
- package/dist/log.spec.js +0 -131
- package/dist/logging/grouped-logger.spec.js +0 -84
- package/dist/logging/interactive-logger.spec.js +0 -57
- package/dist/logging/live-logger.spec.js +0 -37
- package/dist/logging/loggers.spec.js +0 -154
- package/dist/optimizer/calculate-checksum.spec.js +0 -34
- package/dist/optimizer/get-cache-directory.spec.js +0 -59
- package/dist/optimizer/get-work-cache-stats.spec.js +0 -79
- package/dist/optimizer/work-task-cache-description.spec.js +0 -45
- package/dist/parser/default-build-file.spec.js +0 -48
- package/dist/parser/parse-label-arguments.spec.js +0 -27
- package/dist/parser/read-build-file.spec.js +0 -89
- package/dist/parser/read-env-file.spec.js +0 -42
- package/dist/planner/utils/append-work-service.spec.js +0 -71
- package/dist/planner/utils/get-container-user.spec.js +0 -30
- package/dist/planner/utils/get-default-kube-config.spec.js +0 -11
- package/dist/planner/utils/normalize-path.spec.js +0 -24
- package/dist/planner/utils/parse-work-command.spec.js +0 -21
- package/dist/planner/utils/parse-work-generate.spec.js +0 -45
- package/dist/planner/utils/parse-work-mount.spec.js +0 -62
- package/dist/planner/utils/parse-work-mounts.spec.js +0 -19
- package/dist/planner/utils/parse-work-port.spec.js +0 -24
- package/dist/planner/utils/parse-work-ports.spec.js +0 -24
- package/dist/planner/utils/parse-work-source.spec.js +0 -58
- package/dist/planner/utils/parse-work-volume.spec.js +0 -18
- package/dist/planner/utils/plan-work-tasks.spec.js +0 -30
- package/dist/planner/utils/plan-work-volume.spec.js +0 -33
- package/dist/planner/utils/split-name.spec.js +0 -16
- package/dist/planner/utils/template-value.spec.js +0 -14
- package/dist/planner/validate.spec.js +0 -251
- package/dist/planner/work-cache-id.spec.js +0 -173
- package/dist/planner/work-runtime-local.spec.js +0 -193
- package/dist/program-commands.spec.js +0 -84
- package/dist/program.spec.js +0 -43
- package/dist/schema/build-file-schema.spec.js +0 -61
- package/dist/schema/doc-build-files.spec.js +0 -223
- package/dist/schema/parse-error.spec.js +0 -18
- package/dist/schema/reference-parser.spec.js +0 -83
- package/dist/schema/schema-parser.spec.js +0 -80
- package/dist/schema/type-guards.spec.js +0 -23
- package/dist/schema/work-scope-parser.spec.js +0 -66
- package/dist/service/update-service-status.spec.js +0 -27
- package/dist/testing/ensure-local-registry.js +0 -134
- package/dist/testing/example-test-suite.js +0 -63
- package/dist/testing/expect.js +0 -82
- package/dist/testing/get-test-suite.js +0 -9
- package/dist/testing/http-get.js +0 -21
- package/dist/testing/integration/cache.spec.js +0 -49
- package/dist/testing/integration/cancellation.spec.js +0 -45
- package/dist/testing/integration/clean.spec.js +0 -43
- package/dist/testing/integration/cmd.spec.js +0 -15
- package/dist/testing/integration/concurrency.spec.js +0 -19
- package/dist/testing/integration/docker-package-registry.spec.js +0 -44
- package/dist/testing/integration/docker-service-crash.spec.js +0 -36
- package/dist/testing/integration/docker.spec.js +0 -18
- package/dist/testing/integration/env.spec.js +0 -48
- package/dist/testing/integration/environment.spec.js +0 -97
- package/dist/testing/integration/error.spec.js +0 -19
- package/dist/testing/integration/export.spec.js +0 -22
- package/dist/testing/integration/extend.spec.js +0 -29
- package/dist/testing/integration/glob.spec.js +0 -40
- package/dist/testing/integration/include.spec.js +0 -31
- package/dist/testing/integration/invalid.spec.js +0 -17
- package/dist/testing/integration/invalid_loop.spec.js +0 -56
- package/dist/testing/integration/k8s-state-cache.spec.js +0 -41
- package/dist/testing/integration/kubernetes-service.spec.js +0 -148
- package/dist/testing/integration/kubernetes.spec.js +0 -99
- package/dist/testing/integration/labels.spec.js +0 -42
- package/dist/testing/integration/local.spec.js +0 -14
- package/dist/testing/integration/monorepo.spec.js +0 -15
- package/dist/testing/integration/multi-line.spec.js +0 -17
- package/dist/testing/integration/reference.spec.js +0 -21
- package/dist/testing/integration/services.spec.js +0 -38
- package/dist/testing/integration/store.spec.js +0 -52
- package/dist/testing/integration/unknown.spec.js +0 -28
- package/dist/testing/integration/validate.spec.js +0 -160
- package/dist/testing/integration/watch-dependency.spec.js +0 -33
- package/dist/testing/integration/watch.spec.js +0 -45
- package/dist/testing/requires-kubernetes.js +0 -18
- package/dist/testing/requires-linux-containers.js +0 -18
- package/dist/testing/requires-windows-containers.js +0 -18
- package/dist/testing/test-case.js +0 -75
- package/dist/testing/test-streams.js +0 -28
- package/dist/testing/test-suite-setup.js +0 -3
- package/dist/testing/test-suite.js +0 -3
- package/dist/testing/testing-timeout.js +0 -32
- package/dist/utils/abort-event.spec.js +0 -46
- package/dist/utils/buffer-context.spec.js +0 -38
- package/dist/utils/ci.spec.js +0 -53
- package/dist/utils/debouncer.spec.js +0 -58
- package/dist/utils/emitter.spec.js +0 -34
- package/dist/utils/empty-writable.spec.js +0 -18
- package/dist/utils/environment-config.spec.js +0 -26
- package/dist/utils/fail-never.spec.js +0 -9
- package/dist/utils/sleep.spec.js +0 -22
- package/dist/version.spec.js +0 -12
- package/specs/build-file/caches/spec.md +0 -114
- package/specs/build-file/environment-variables/spec.md +0 -82
- package/specs/build-file/includes/spec.md +0 -60
- package/specs/build-file/references/spec.md +0 -56
- package/specs/build-file/spec.md +0 -62
- package/specs/cli/clean/spec.md +0 -85
- package/specs/cli/down/spec.md +0 -85
- package/specs/cli/execute/spec.md +0 -101
- package/specs/cli/init/spec.md +0 -64
- package/specs/cli/ls/spec.md +0 -66
- package/specs/cli/package/spec.md +0 -110
- package/specs/cli/spec.md +0 -73
- package/specs/cli/store-restore/spec.md +0 -74
- package/specs/cli/up/spec.md +0 -80
- package/specs/cli/validate/spec.md +0 -70
- package/specs/labels/spec.md +0 -91
- package/specs/service/container/spec.md +0 -120
- package/specs/service/kubernetes/spec.md +0 -97
- package/specs/service/spec.md +0 -105
- package/specs/task/caching/spec.md +0 -107
- package/specs/task/container/spec.md +0 -118
- package/specs/task/dependencies/spec.md +0 -70
- package/specs/task/extending/spec.md +0 -74
- package/specs/task/kubernetes/spec.md +0 -125
- package/specs/task/needs/spec.md +0 -59
- package/specs/task/spec.md +0 -87
- package/specs/task/watching/spec.md +0 -69
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
# Feature Specification: [FEATURE NAME]
|
|
2
|
-
|
|
3
|
-
**Feature Branch**: `[###-feature-name]`
|
|
4
|
-
|
|
5
|
-
**Created**: [DATE]
|
|
6
|
-
|
|
7
|
-
**Status**: Draft
|
|
8
|
-
|
|
9
|
-
**Input**: User description: "$ARGUMENTS"
|
|
10
|
-
|
|
11
|
-
## User Scenarios & Testing *(mandatory)*
|
|
12
|
-
|
|
13
|
-
<!--
|
|
14
|
-
IMPORTANT: User stories should be PRIORITIZED as user journeys ordered by importance.
|
|
15
|
-
Each user story/journey must be INDEPENDENTLY TESTABLE - meaning if you implement just ONE of them,
|
|
16
|
-
you should still have a viable MVP (Minimum Viable Product) that delivers value.
|
|
17
|
-
|
|
18
|
-
Assign priorities (P1, P2, P3, etc.) to each story, where P1 is the most critical.
|
|
19
|
-
Think of each story as a standalone slice of functionality that can be:
|
|
20
|
-
- Developed independently
|
|
21
|
-
- Tested independently
|
|
22
|
-
- Deployed independently
|
|
23
|
-
- Demonstrated to users independently
|
|
24
|
-
-->
|
|
25
|
-
|
|
26
|
-
### User Story 1 - [Brief Title] (Priority: P1)
|
|
27
|
-
|
|
28
|
-
[Describe this user journey in plain language]
|
|
29
|
-
|
|
30
|
-
**Why this priority**: [Explain the value and why it has this priority level]
|
|
31
|
-
|
|
32
|
-
**Independent Test**: [Describe how this can be tested independently - e.g., "Can be fully tested by [specific action] and delivers [specific value]"]
|
|
33
|
-
|
|
34
|
-
**Acceptance Scenarios**:
|
|
35
|
-
|
|
36
|
-
1. **Given** [initial state], **When** [action], **Then** [expected outcome]
|
|
37
|
-
2. **Given** [initial state], **When** [action], **Then** [expected outcome]
|
|
38
|
-
|
|
39
|
-
---
|
|
40
|
-
|
|
41
|
-
### User Story 2 - [Brief Title] (Priority: P2)
|
|
42
|
-
|
|
43
|
-
[Describe this user journey in plain language]
|
|
44
|
-
|
|
45
|
-
**Why this priority**: [Explain the value and why it has this priority level]
|
|
46
|
-
|
|
47
|
-
**Independent Test**: [Describe how this can be tested independently]
|
|
48
|
-
|
|
49
|
-
**Acceptance Scenarios**:
|
|
50
|
-
|
|
51
|
-
1. **Given** [initial state], **When** [action], **Then** [expected outcome]
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
### User Story 3 - [Brief Title] (Priority: P3)
|
|
56
|
-
|
|
57
|
-
[Describe this user journey in plain language]
|
|
58
|
-
|
|
59
|
-
**Why this priority**: [Explain the value and why it has this priority level]
|
|
60
|
-
|
|
61
|
-
**Independent Test**: [Describe how this can be tested independently]
|
|
62
|
-
|
|
63
|
-
**Acceptance Scenarios**:
|
|
64
|
-
|
|
65
|
-
1. **Given** [initial state], **When** [action], **Then** [expected outcome]
|
|
66
|
-
|
|
67
|
-
---
|
|
68
|
-
|
|
69
|
-
[Add more user stories as needed, each with an assigned priority]
|
|
70
|
-
|
|
71
|
-
### Edge Cases
|
|
72
|
-
|
|
73
|
-
<!--
|
|
74
|
-
ACTION REQUIRED: The content in this section represents placeholders.
|
|
75
|
-
Fill them out with the right edge cases.
|
|
76
|
-
-->
|
|
77
|
-
|
|
78
|
-
- What happens when [boundary condition]?
|
|
79
|
-
- How does system handle [error scenario]?
|
|
80
|
-
|
|
81
|
-
## Requirements *(mandatory)*
|
|
82
|
-
|
|
83
|
-
<!--
|
|
84
|
-
ACTION REQUIRED: The content in this section represents placeholders.
|
|
85
|
-
Fill them out with the right functional requirements.
|
|
86
|
-
-->
|
|
87
|
-
|
|
88
|
-
### Functional Requirements
|
|
89
|
-
|
|
90
|
-
- **FR-001**: System MUST [specific capability, e.g., "allow users to create accounts"]
|
|
91
|
-
- **FR-002**: System MUST [specific capability, e.g., "validate email addresses"]
|
|
92
|
-
- **FR-003**: Users MUST be able to [key interaction, e.g., "reset their password"]
|
|
93
|
-
- **FR-004**: System MUST [data requirement, e.g., "persist user preferences"]
|
|
94
|
-
- **FR-005**: System MUST [behavior, e.g., "log all security events"]
|
|
95
|
-
|
|
96
|
-
*Example of marking unclear requirements:*
|
|
97
|
-
|
|
98
|
-
- **FR-006**: System MUST authenticate users via [NEEDS CLARIFICATION: auth method not specified - email/password, SSO, OAuth?]
|
|
99
|
-
- **FR-007**: System MUST retain user data for [NEEDS CLARIFICATION: retention period not specified]
|
|
100
|
-
|
|
101
|
-
### Key Entities *(include if feature involves data)*
|
|
102
|
-
|
|
103
|
-
- **[Entity 1]**: [What it represents, key attributes without implementation]
|
|
104
|
-
- **[Entity 2]**: [What it represents, relationships to other entities]
|
|
105
|
-
|
|
106
|
-
## Success Criteria *(mandatory)*
|
|
107
|
-
|
|
108
|
-
<!--
|
|
109
|
-
ACTION REQUIRED: Define measurable success criteria.
|
|
110
|
-
These must be technology-agnostic and measurable.
|
|
111
|
-
-->
|
|
112
|
-
|
|
113
|
-
### Measurable Outcomes
|
|
114
|
-
|
|
115
|
-
- **SC-001**: [Measurable metric, e.g., "Users can complete account creation in under 2 minutes"]
|
|
116
|
-
- **SC-002**: [Measurable metric, e.g., "System handles 1000 concurrent users without degradation"]
|
|
117
|
-
- **SC-003**: [User satisfaction metric, e.g., "90% of users successfully complete primary task on first attempt"]
|
|
118
|
-
- **SC-004**: [Business metric, e.g., "Reduce support tickets related to [X] by 50%"]
|
|
119
|
-
|
|
120
|
-
## Assumptions
|
|
121
|
-
|
|
122
|
-
<!--
|
|
123
|
-
ACTION REQUIRED: The content in this section represents placeholders.
|
|
124
|
-
Fill them out with the right assumptions based on reasonable defaults
|
|
125
|
-
chosen when the feature description did not specify certain details.
|
|
126
|
-
-->
|
|
127
|
-
|
|
128
|
-
- [Assumption about target users, e.g., "Users have stable internet connectivity"]
|
|
129
|
-
- [Assumption about scope boundaries, e.g., "Mobile support is out of scope for v1"]
|
|
130
|
-
- [Assumption about data/environment, e.g., "Existing authentication system will be reused"]
|
|
131
|
-
- [Dependency on existing system/service, e.g., "Requires access to the existing user profile API"]
|
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
|
|
3
|
-
description: "Task list template for feature implementation"
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Tasks: [FEATURE NAME]
|
|
7
|
-
|
|
8
|
-
**Input**: Design documents from `/specs/[###-feature-name]/`
|
|
9
|
-
|
|
10
|
-
**Prerequisites**: plan.md (required), spec.md (required for user stories), research.md, data-model.md, contracts/
|
|
11
|
-
|
|
12
|
-
**Tests**: The examples below include test tasks. Tests are OPTIONAL - only include them if explicitly requested in the feature specification.
|
|
13
|
-
|
|
14
|
-
**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story.
|
|
15
|
-
|
|
16
|
-
## Format: `[ID] [P?] [Story] Description`
|
|
17
|
-
|
|
18
|
-
- **[P]**: Can run in parallel (different files, no dependencies)
|
|
19
|
-
- **[Story]**: Which user story this task belongs to (e.g., US1, US2, US3)
|
|
20
|
-
- Include exact file paths in descriptions
|
|
21
|
-
|
|
22
|
-
## Path Conventions
|
|
23
|
-
|
|
24
|
-
- **Single project**: `src/`, `tests/` at repository root
|
|
25
|
-
- **Web app**: `backend/src/`, `frontend/src/`
|
|
26
|
-
- **Mobile**: `api/src/`, `ios/src/` or `android/src/`
|
|
27
|
-
- Paths shown below assume single project - adjust based on plan.md structure
|
|
28
|
-
|
|
29
|
-
<!--
|
|
30
|
-
============================================================================
|
|
31
|
-
IMPORTANT: The tasks below are SAMPLE TASKS for illustration purposes only.
|
|
32
|
-
|
|
33
|
-
The /speckit-tasks command MUST replace these with actual tasks based on:
|
|
34
|
-
- User stories from spec.md (with their priorities P1, P2, P3...)
|
|
35
|
-
- Feature requirements from plan.md
|
|
36
|
-
- Entities from data-model.md
|
|
37
|
-
- Endpoints from contracts/
|
|
38
|
-
|
|
39
|
-
Tasks MUST be organized by user story so each story can be:
|
|
40
|
-
- Implemented independently
|
|
41
|
-
- Tested independently
|
|
42
|
-
- Delivered as an MVP increment
|
|
43
|
-
|
|
44
|
-
DO NOT keep these sample tasks in the generated tasks.md file.
|
|
45
|
-
============================================================================
|
|
46
|
-
-->
|
|
47
|
-
|
|
48
|
-
## Phase 1: Setup (Shared Infrastructure)
|
|
49
|
-
|
|
50
|
-
**Purpose**: Project initialization and basic structure
|
|
51
|
-
|
|
52
|
-
- [ ] T001 Create project structure per implementation plan
|
|
53
|
-
- [ ] T002 Initialize [language] project with [framework] dependencies
|
|
54
|
-
- [ ] T003 [P] Configure linting and formatting tools
|
|
55
|
-
|
|
56
|
-
---
|
|
57
|
-
|
|
58
|
-
## Phase 2: Foundational (Blocking Prerequisites)
|
|
59
|
-
|
|
60
|
-
**Purpose**: Core infrastructure that MUST be complete before ANY user story can be implemented
|
|
61
|
-
|
|
62
|
-
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
|
|
63
|
-
|
|
64
|
-
Examples of foundational tasks (adjust based on your project):
|
|
65
|
-
|
|
66
|
-
- [ ] T004 Setup database schema and migrations framework
|
|
67
|
-
- [ ] T005 [P] Implement authentication/authorization framework
|
|
68
|
-
- [ ] T006 [P] Setup API routing and middleware structure
|
|
69
|
-
- [ ] T007 Create base models/entities that all stories depend on
|
|
70
|
-
- [ ] T008 Configure error handling and logging infrastructure
|
|
71
|
-
- [ ] T009 Setup environment configuration management
|
|
72
|
-
|
|
73
|
-
**Checkpoint**: Foundation ready - user story implementation can now begin in parallel
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Phase 3: User Story 1 - [Title] (Priority: P1) 🎯 MVP
|
|
78
|
-
|
|
79
|
-
**Goal**: [Brief description of what this story delivers]
|
|
80
|
-
|
|
81
|
-
**Independent Test**: [How to verify this story works on its own]
|
|
82
|
-
|
|
83
|
-
### Tests for User Story 1 (OPTIONAL - only if tests requested) ⚠️
|
|
84
|
-
|
|
85
|
-
> **NOTE: Write these tests FIRST, ensure they FAIL before implementation**
|
|
86
|
-
|
|
87
|
-
- [ ] T010 [P] [US1] Contract test for [endpoint] in tests/contract/test_[name].py
|
|
88
|
-
- [ ] T011 [P] [US1] Integration test for [user journey] in tests/integration/test_[name].py
|
|
89
|
-
|
|
90
|
-
### Implementation for User Story 1
|
|
91
|
-
|
|
92
|
-
- [ ] T012 [P] [US1] Create [Entity1] model in src/models/[entity1].py
|
|
93
|
-
- [ ] T013 [P] [US1] Create [Entity2] model in src/models/[entity2].py
|
|
94
|
-
- [ ] T014 [US1] Implement [Service] in src/services/[service].py (depends on T012, T013)
|
|
95
|
-
- [ ] T015 [US1] Implement [endpoint/feature] in src/[location]/[file].py
|
|
96
|
-
- [ ] T016 [US1] Add validation and error handling
|
|
97
|
-
- [ ] T017 [US1] Add logging for user story 1 operations
|
|
98
|
-
|
|
99
|
-
**Checkpoint**: At this point, User Story 1 should be fully functional and testable independently
|
|
100
|
-
|
|
101
|
-
---
|
|
102
|
-
|
|
103
|
-
## Phase 4: User Story 2 - [Title] (Priority: P2)
|
|
104
|
-
|
|
105
|
-
**Goal**: [Brief description of what this story delivers]
|
|
106
|
-
|
|
107
|
-
**Independent Test**: [How to verify this story works on its own]
|
|
108
|
-
|
|
109
|
-
### Tests for User Story 2 (OPTIONAL - only if tests requested) ⚠️
|
|
110
|
-
|
|
111
|
-
- [ ] T018 [P] [US2] Contract test for [endpoint] in tests/contract/test_[name].py
|
|
112
|
-
- [ ] T019 [P] [US2] Integration test for [user journey] in tests/integration/test_[name].py
|
|
113
|
-
|
|
114
|
-
### Implementation for User Story 2
|
|
115
|
-
|
|
116
|
-
- [ ] T020 [P] [US2] Create [Entity] model in src/models/[entity].py
|
|
117
|
-
- [ ] T021 [US2] Implement [Service] in src/services/[service].py
|
|
118
|
-
- [ ] T022 [US2] Implement [endpoint/feature] in src/[location]/[file].py
|
|
119
|
-
- [ ] T023 [US2] Integrate with User Story 1 components (if needed)
|
|
120
|
-
|
|
121
|
-
**Checkpoint**: At this point, User Stories 1 AND 2 should both work independently
|
|
122
|
-
|
|
123
|
-
---
|
|
124
|
-
|
|
125
|
-
## Phase 5: User Story 3 - [Title] (Priority: P3)
|
|
126
|
-
|
|
127
|
-
**Goal**: [Brief description of what this story delivers]
|
|
128
|
-
|
|
129
|
-
**Independent Test**: [How to verify this story works on its own]
|
|
130
|
-
|
|
131
|
-
### Tests for User Story 3 (OPTIONAL - only if tests requested) ⚠️
|
|
132
|
-
|
|
133
|
-
- [ ] T024 [P] [US3] Contract test for [endpoint] in tests/contract/test_[name].py
|
|
134
|
-
- [ ] T025 [P] [US3] Integration test for [user journey] in tests/integration/test_[name].py
|
|
135
|
-
|
|
136
|
-
### Implementation for User Story 3
|
|
137
|
-
|
|
138
|
-
- [ ] T026 [P] [US3] Create [Entity] model in src/models/[entity].py
|
|
139
|
-
- [ ] T027 [US3] Implement [Service] in src/services/[service].py
|
|
140
|
-
- [ ] T028 [US3] Implement [endpoint/feature] in src/[location]/[file].py
|
|
141
|
-
|
|
142
|
-
**Checkpoint**: All user stories should now be independently functional
|
|
143
|
-
|
|
144
|
-
---
|
|
145
|
-
|
|
146
|
-
[Add more user story phases as needed, following the same pattern]
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## Phase N: Polish & Cross-Cutting Concerns
|
|
151
|
-
|
|
152
|
-
**Purpose**: Improvements that affect multiple user stories
|
|
153
|
-
|
|
154
|
-
- [ ] TXXX [P] Documentation updates in docs/
|
|
155
|
-
- [ ] TXXX Code cleanup and refactoring
|
|
156
|
-
- [ ] TXXX Performance optimization across all stories
|
|
157
|
-
- [ ] TXXX [P] Additional unit tests (if requested) in tests/unit/
|
|
158
|
-
- [ ] TXXX Security hardening
|
|
159
|
-
- [ ] TXXX Run quickstart.md validation
|
|
160
|
-
|
|
161
|
-
---
|
|
162
|
-
|
|
163
|
-
## Dependencies & Execution Order
|
|
164
|
-
|
|
165
|
-
### Phase Dependencies
|
|
166
|
-
|
|
167
|
-
- **Setup (Phase 1)**: No dependencies - can start immediately
|
|
168
|
-
- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
|
|
169
|
-
- **User Stories (Phase 3+)**: All depend on Foundational phase completion
|
|
170
|
-
- User stories can then proceed in parallel (if staffed)
|
|
171
|
-
- Or sequentially in priority order (P1 → P2 → P3)
|
|
172
|
-
- **Polish (Final Phase)**: Depends on all desired user stories being complete
|
|
173
|
-
|
|
174
|
-
### User Story Dependencies
|
|
175
|
-
|
|
176
|
-
- **User Story 1 (P1)**: Can start after Foundational (Phase 2) - No dependencies on other stories
|
|
177
|
-
- **User Story 2 (P2)**: Can start after Foundational (Phase 2) - May integrate with US1 but should be independently testable
|
|
178
|
-
- **User Story 3 (P3)**: Can start after Foundational (Phase 2) - May integrate with US1/US2 but should be independently testable
|
|
179
|
-
|
|
180
|
-
### Within Each User Story
|
|
181
|
-
|
|
182
|
-
- Tests (if included) MUST be written and FAIL before implementation
|
|
183
|
-
- Models before services
|
|
184
|
-
- Services before endpoints
|
|
185
|
-
- Core implementation before integration
|
|
186
|
-
- Story complete before moving to next priority
|
|
187
|
-
|
|
188
|
-
### Parallel Opportunities
|
|
189
|
-
|
|
190
|
-
- All Setup tasks marked [P] can run in parallel
|
|
191
|
-
- All Foundational tasks marked [P] can run in parallel (within Phase 2)
|
|
192
|
-
- Once Foundational phase completes, all user stories can start in parallel (if team capacity allows)
|
|
193
|
-
- All tests for a user story marked [P] can run in parallel
|
|
194
|
-
- Models within a story marked [P] can run in parallel
|
|
195
|
-
- Different user stories can be worked on in parallel by different team members
|
|
196
|
-
|
|
197
|
-
---
|
|
198
|
-
|
|
199
|
-
## Parallel Example: User Story 1
|
|
200
|
-
|
|
201
|
-
```bash
|
|
202
|
-
# Launch all tests for User Story 1 together (if tests requested):
|
|
203
|
-
Task: "Contract test for [endpoint] in tests/contract/test_[name].py"
|
|
204
|
-
Task: "Integration test for [user journey] in tests/integration/test_[name].py"
|
|
205
|
-
|
|
206
|
-
# Launch all models for User Story 1 together:
|
|
207
|
-
Task: "Create [Entity1] model in src/models/[entity1].py"
|
|
208
|
-
Task: "Create [Entity2] model in src/models/[entity2].py"
|
|
209
|
-
```
|
|
210
|
-
|
|
211
|
-
---
|
|
212
|
-
|
|
213
|
-
## Implementation Strategy
|
|
214
|
-
|
|
215
|
-
### MVP First (User Story 1 Only)
|
|
216
|
-
|
|
217
|
-
1. Complete Phase 1: Setup
|
|
218
|
-
2. Complete Phase 2: Foundational (CRITICAL - blocks all stories)
|
|
219
|
-
3. Complete Phase 3: User Story 1
|
|
220
|
-
4. **STOP and VALIDATE**: Test User Story 1 independently
|
|
221
|
-
5. Deploy/demo if ready
|
|
222
|
-
|
|
223
|
-
### Incremental Delivery
|
|
224
|
-
|
|
225
|
-
1. Complete Setup + Foundational → Foundation ready
|
|
226
|
-
2. Add User Story 1 → Test independently → Deploy/Demo (MVP!)
|
|
227
|
-
3. Add User Story 2 → Test independently → Deploy/Demo
|
|
228
|
-
4. Add User Story 3 → Test independently → Deploy/Demo
|
|
229
|
-
5. Each story adds value without breaking previous stories
|
|
230
|
-
|
|
231
|
-
### Parallel Team Strategy
|
|
232
|
-
|
|
233
|
-
With multiple developers:
|
|
234
|
-
|
|
235
|
-
1. Team completes Setup + Foundational together
|
|
236
|
-
2. Once Foundational is done:
|
|
237
|
-
- Developer A: User Story 1
|
|
238
|
-
- Developer B: User Story 2
|
|
239
|
-
- Developer C: User Story 3
|
|
240
|
-
3. Stories complete and integrate independently
|
|
241
|
-
|
|
242
|
-
---
|
|
243
|
-
|
|
244
|
-
## Notes
|
|
245
|
-
|
|
246
|
-
- [P] tasks = different files, no dependencies
|
|
247
|
-
- [Story] label maps task to specific user story for traceability
|
|
248
|
-
- Each user story should be independently completable and testable
|
|
249
|
-
- Verify tests fail before implementing
|
|
250
|
-
- Commit after each task or logical group
|
|
251
|
-
- Stop at any checkpoint to validate story independently
|
|
252
|
-
- Avoid: vague tasks, same file conflicts, cross-story dependencies that break independence
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
schema_version: "1.0"
|
|
2
|
-
workflow:
|
|
3
|
-
id: "speckit"
|
|
4
|
-
name: "Full SDD Cycle"
|
|
5
|
-
version: "1.0.0"
|
|
6
|
-
author: "GitHub"
|
|
7
|
-
description: "Runs specify → plan → tasks → implement with review gates"
|
|
8
|
-
|
|
9
|
-
requires:
|
|
10
|
-
# 0.8.5 is the first release with engine-side resolution of the
|
|
11
|
-
# ``integration: "auto"`` default. Older versions would treat "auto"
|
|
12
|
-
# as a literal integration key and fail at dispatch.
|
|
13
|
-
speckit_version: ">=0.8.5"
|
|
14
|
-
integrations:
|
|
15
|
-
# The four commands below (specify, plan, tasks, implement) are core
|
|
16
|
-
# spec-kit commands provided by every integration. The list here is an
|
|
17
|
-
# advisory, non-exhaustive compatibility hint following the documented
|
|
18
|
-
# ``any: [...]`` schema -- it is NOT a closed set. The workflow runs
|
|
19
|
-
# against any integration the project was initialized with, including
|
|
20
|
-
# ones not listed below, as long as that integration provides the four
|
|
21
|
-
# core commands referenced in ``steps``.
|
|
22
|
-
any:
|
|
23
|
-
- "claude"
|
|
24
|
-
- "copilot"
|
|
25
|
-
- "gemini"
|
|
26
|
-
- "opencode"
|
|
27
|
-
|
|
28
|
-
inputs:
|
|
29
|
-
spec:
|
|
30
|
-
type: string
|
|
31
|
-
required: true
|
|
32
|
-
prompt: "Describe what you want to build"
|
|
33
|
-
integration:
|
|
34
|
-
type: string
|
|
35
|
-
default: "auto"
|
|
36
|
-
prompt: "Integration to use (e.g. claude, copilot, gemini; 'auto' uses the project's initialized integration)"
|
|
37
|
-
scope:
|
|
38
|
-
type: string
|
|
39
|
-
default: "full"
|
|
40
|
-
enum: ["full", "backend-only", "frontend-only"]
|
|
41
|
-
|
|
42
|
-
steps:
|
|
43
|
-
- id: specify
|
|
44
|
-
command: speckit.specify
|
|
45
|
-
integration: "{{ inputs.integration }}"
|
|
46
|
-
input:
|
|
47
|
-
args: "{{ inputs.spec }}"
|
|
48
|
-
|
|
49
|
-
- id: review-spec
|
|
50
|
-
type: gate
|
|
51
|
-
message: "Review the generated spec before planning."
|
|
52
|
-
options: [approve, reject]
|
|
53
|
-
on_reject: abort
|
|
54
|
-
|
|
55
|
-
- id: plan
|
|
56
|
-
command: speckit.plan
|
|
57
|
-
integration: "{{ inputs.integration }}"
|
|
58
|
-
input:
|
|
59
|
-
args: "{{ inputs.spec }}"
|
|
60
|
-
|
|
61
|
-
- id: review-plan
|
|
62
|
-
type: gate
|
|
63
|
-
message: "Review the plan before generating tasks."
|
|
64
|
-
options: [approve, reject]
|
|
65
|
-
on_reject: abort
|
|
66
|
-
|
|
67
|
-
- id: tasks
|
|
68
|
-
command: speckit.tasks
|
|
69
|
-
integration: "{{ inputs.integration }}"
|
|
70
|
-
input:
|
|
71
|
-
args: "{{ inputs.spec }}"
|
|
72
|
-
|
|
73
|
-
- id: implement
|
|
74
|
-
command: speckit.implement
|
|
75
|
-
integration: "{{ inputs.integration }}"
|
|
76
|
-
input:
|
|
77
|
-
args: "{{ inputs.spec }}"
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schema_version": "1.0",
|
|
3
|
-
"workflows": {
|
|
4
|
-
"speckit": {
|
|
5
|
-
"name": "Full SDD Cycle",
|
|
6
|
-
"version": "1.0.0",
|
|
7
|
-
"description": "Runs specify \u2192 plan \u2192 tasks \u2192 implement with review gates",
|
|
8
|
-
"source": "bundled",
|
|
9
|
-
"installed_at": "2026-05-30T06:27:46.912039+00:00",
|
|
10
|
-
"updated_at": "2026-05-30T06:27:46.912046+00:00"
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
package/AGENTS.md
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
Guidance for AI coding agents (Claude Code, Cursor, Copilot, etc.) working in this repository.
|
|
4
|
-
|
|
5
|
-
## What this is
|
|
6
|
-
|
|
7
|
-
Hammerkit is a containerized build tool (CLI distributed as `dist/index.js`). It reads a `.hammerkit.yaml` build file, plans a graph of tasks and services, and executes them locally, in Docker, or on Kubernetes. Source/output files are explicitly declared per task, which is what enables hammerkit's incremental caching and "store/restore" workflow for CI.
|
|
8
|
-
|
|
9
|
-
User-facing docs live at https://no0dles.gitbook.io/hammerkit/ (see [SUMMARY.md](SUMMARY.md) for the structure).
|
|
10
|
-
|
|
11
|
-
## Working agreement
|
|
12
|
-
|
|
13
|
-
Read [VALUES.md](./VALUES.md) first. That file covers what hammerkit optimizes for; this file covers agent-specific operating rules.
|
|
14
|
-
|
|
15
|
-
How to work in this repo (see the `do-the-work` skill for detail):
|
|
16
|
-
|
|
17
|
-
- **Do the work; don't avoid it.** When the task is to fix something — CI, a test,
|
|
18
|
-
the build, a check — fixing the root cause *is* the deliverable. Never resolve a
|
|
19
|
-
failure by skipping, disabling, excluding, `.skip`/`xfail`, weakening an
|
|
20
|
-
assertion, or stopping early (unless the user explicitly asks).
|
|
21
|
-
- **Ask implementation questions, not permission to avoid work.** Design and
|
|
22
|
-
ambiguity questions are welcome; "can I skip/disable/leave this?" is not — that's
|
|
23
|
-
the work, do it. Escalate only when genuinely blocked (access, a product
|
|
24
|
-
decision, contradictory requirements), and propose the fix path.
|
|
25
|
-
- **Don't make the user repeat himself.** Read [.agents/FEEDBACK.md](.agents/FEEDBACK.md)
|
|
26
|
-
before working and apply it; when corrected, append the correction there so it's
|
|
27
|
-
not re-litigated.
|
|
28
|
-
|
|
29
|
-
## Commands
|
|
30
|
-
|
|
31
|
-
- `npm run build` — `tsc -b tsconfig.json`, outputs to `dist/`
|
|
32
|
-
- `npm test` — runs jest across `src/**/*.spec.ts`. Tests run with `maxConcurrency: 1` and a 45s timeout; expect a full run to be slow.
|
|
33
|
-
- `npm run lint` / `npm run format` — eslint / prettier+eslint --fix.
|
|
34
|
-
- Single test: `node_modules/.bin/jest src/path/to/file.spec.ts -t "test name"`. CI uses `jest --runInBand`.
|
|
35
|
-
|
|
36
|
-
### Test environment flags
|
|
37
|
-
|
|
38
|
-
Many integration tests in [src/testing/integration/](src/testing/integration/) gate themselves on env vars (see [requires-linux-containers.ts](src/testing/requires-linux-containers.ts), [requires-windows-containers.ts](src/testing/requires-windows-containers.ts), [requires-kubernetes.ts](src/testing/requires-kubernetes.ts)). In CI, when the flag is unset the test is replaced with a no-op:
|
|
39
|
-
|
|
40
|
-
- `LINUX_CONTAINERS=true` — enable docker/linux-container tests (set on Linux + macOS in CI)
|
|
41
|
-
- `WINDOWS_CONTAINERS=true` — enable windows-container tests
|
|
42
|
-
- `CLUSTER_NAME=<ctx>` — enable kubernetes tests (CI uses minikube)
|
|
43
|
-
- `VERBOSE=true` — verbose test output
|
|
44
|
-
|
|
45
|
-
Locally these gates are bypassed (`isCI` is false), so tests will attempt to talk to Docker/k8s and fail if those aren't available. Use the env flags to opt-in selectively.
|
|
46
|
-
|
|
47
|
-
## Architecture
|
|
48
|
-
|
|
49
|
-
The CLI flows roughly: **parse → plan → schedule → execute**. Knowing this pipeline is the fastest way to orient in the codebase.
|
|
50
|
-
|
|
51
|
-
### Entry points
|
|
52
|
-
|
|
53
|
-
- [src/index.ts](src/index.ts) — bin entry, builds an `Environment` (cwd, file ctx, console, stdout/stderr, abortCtrl) and calls `runProgram`.
|
|
54
|
-
- [src/run-program.ts](src/run-program.ts) → [src/program.ts](src/program.ts) — commander CLI definition. Subcommands: `ls`, `exec`, `up`, `down`, `clean`, `store`, `restore`, `validate`, `package`. Each subcommand builds a `Cli` via `createCli(fileName, environment, workScope)`.
|
|
55
|
-
- [src/cli.ts](src/cli.ts) — the programmatic façade (`Cli` class) wrapping a `WorkTree` + `Environment`. Library consumers use `getCli()`; the CLI in `program.ts` is just a thin shell around this.
|
|
56
|
-
|
|
57
|
-
### Parse: `schema/` and `parser/`
|
|
58
|
-
|
|
59
|
-
- [src/schema/](src/schema/) — zod schemas for the build file (`build-file-*-schema.ts`) plus the parse pipeline: `schema-parser.ts` → `reference-parser.ts` → `work-scope-parser.ts`. `parse-error.ts` carries zod errors back to the CLI for pretty-printing.
|
|
60
|
-
- [src/parser/](src/parser/) — `read-build-file.ts`, `read-env-file.ts`, `default-build-file.ts`, label parsing. JSON schema published at [build.schema.json](build.schema.json) is generated from these zod schemas (see `src/json-schema.ts`).
|
|
61
|
-
|
|
62
|
-
### Plan: `planner/`
|
|
63
|
-
|
|
64
|
-
Parsing produces a **WorkTree** ([src/planner/work-tree.ts](src/planner/work-tree.ts)) of `WorkItem`s — `WorkTask` and `WorkService` indexed by id. `work-cache-id.ts` computes the per-task cache hash from sources + command + needs + image; this is what makes incremental builds work. Validation lives in `validate.ts` and `work-item-validation.ts`.
|
|
65
|
-
|
|
66
|
-
### Runtime selection
|
|
67
|
-
|
|
68
|
-
Each task/service is bound to a runtime: `local`, `docker`, or `kubernetes` (see `work-runtime-*.ts` in `planner/`, plus [src/runtime/runtime.ts](src/runtime/runtime.ts)). The runtime decides where execution happens.
|
|
69
|
-
|
|
70
|
-
### Schedule + execute: `executer/`
|
|
71
|
-
|
|
72
|
-
- [src/executer/execute-work-tree.ts](src/executer/execute-work-tree.ts) is the top-level loop. It builds a `ProcessManager` (worker pool), walks the work tree, and dispatches items.
|
|
73
|
-
- `scheduler/` holds the state machines (`task-state.ts`, `service-state.ts`, `dependency-state.ts`, `need-state.ts`) and cycle detection (`check-for-loop.ts`).
|
|
74
|
-
- `execute-work-task.ts` / `execute-work-service.ts` are the per-item drivers. They call into `local-task.ts`, `docker-task.ts`, or `docker-service.ts` / `kubernetes-service.ts` depending on runtime.
|
|
75
|
-
- `event-cache.ts` implements `clean`/`store`/`restore` — the cache directory hammerkit uses to ship build outputs between machines.
|
|
76
|
-
- State propagation is observable via the `State<T>` wrapper ([state.ts](src/executer/state.ts)) and `state-listener.ts`. `watch-loop.ts` powers `--watch` mode.
|
|
77
|
-
|
|
78
|
-
### Docker + Kubernetes layers
|
|
79
|
-
|
|
80
|
-
- [src/docker/](src/docker/) — `dockerode`-based helpers: `using-container.ts` (lifecycle), `pull.ts`, `stream.ts`, `package.ts` (image build/push for `hammerkit package`).
|
|
81
|
-
- [src/kubernetes/](src/kubernetes/) — `@kubernetes/client-node` helpers for deployments, services, ingress, PVCs, and store/restore of persistent data. Used for `kubernetes-service` items.
|
|
82
|
-
|
|
83
|
-
### Testing infrastructure
|
|
84
|
-
|
|
85
|
-
- [src/testing/example-test-suite.ts](src/testing/example-test-suite.ts) — most integration tests copy a fixture from [examples/](examples/) into `temp/<example>/`, build a synthetic `Environment` with in-memory streams, and exercise the CLI through `createCli(...)`. There is one example directory per spec file in `src/testing/integration/`.
|
|
86
|
-
- [src/executer/environment-mock.ts](src/executer/environment-mock.ts) is used for unit tests that don't need a real fs.
|
|
87
|
-
- `test-streams.ts` provides `emptyStream` / `memoryStream` for capturing console/status output in assertions.
|
|
88
|
-
|
|
89
|
-
## Conventions
|
|
90
|
-
|
|
91
|
-
- Prettier: no semicolons, single quotes, 120 cols, 2-space tabs, trailing commas `es5`.
|
|
92
|
-
- ESLint: `no-console: error` — never write to `console.*` in `src/` (the `Environment` carries `stdout`/`stderr`/`console`/`status` writables; route output through those).
|
|
93
|
-
- TS strict mode is on; `@typescript-eslint/no-explicit-any` is **off**, so `any` is permitted where useful.
|
|
94
|
-
- Library consumers import from `src/index.ts` → `dist/index.js`; keep that surface stable.
|
package/Dockerfile
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
FROM node:24-alpine AS build
|
|
2
|
-
|
|
3
|
-
ARG TARGETPLATFORM
|
|
4
|
-
|
|
5
|
-
WORKDIR /app
|
|
6
|
-
|
|
7
|
-
# install dependencies
|
|
8
|
-
COPY package.json .
|
|
9
|
-
COPY package-lock.json .
|
|
10
|
-
RUN npm ci
|
|
11
|
-
|
|
12
|
-
# build source code
|
|
13
|
-
COPY tsconfig.json .
|
|
14
|
-
COPY src src
|
|
15
|
-
RUN node_modules/.bin/tsc -b
|
|
16
|
-
RUN export ARCH=$(echo $TARGETPLATFORM | cut -c7-11)
|
|
17
|
-
RUN node_modules/.bin/pkg . --targets "node24-alpine-$ARCH" --compress Brotli
|
|
18
|
-
|
|
19
|
-
######################################
|
|
20
|
-
# Minimal runtime: hammerkit talks to the daemon via dockerode and to k8s via
|
|
21
|
-
# @kubernetes/client-node — both bundled into the binary — so it needs only a
|
|
22
|
-
# shell, CA certs and libstdc++ (for the embedded node), not the full
|
|
23
|
-
# docker-cli image with buildx/compose. docker-cli is kept for users who exec
|
|
24
|
-
# into the image. Cuts the image roughly in half vs docker:*-cli-alpine.
|
|
25
|
-
FROM alpine:3.21
|
|
26
|
-
|
|
27
|
-
RUN apk add --no-cache docker-cli ca-certificates libstdc++
|
|
28
|
-
|
|
29
|
-
WORKDIR /app
|
|
30
|
-
COPY --from=build /app/hammerkit /usr/local/bin/hammerkit
|
|
31
|
-
|
|
32
|
-
ENTRYPOINT ["hammerkit"]
|
package/FOLLOWUPS.md
DELETED
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
# Runtime follow-ups
|
|
2
|
-
|
|
3
|
-
Tracking what's done on `feature/runtime-followups` and what remains. The integration-test work is tracked separately in [INTEGRATION-TESTS.md](INTEGRATION-TESTS.md).
|
|
4
|
-
|
|
5
|
-
## Done on this branch
|
|
6
|
-
|
|
7
|
-
- [x] **Cross-cycle validation** — new `hasMixedCycle` walks deps and needs together; wired into both [validate.ts](src/planner/validate.ts) and [check-for-loop.ts](src/executer/scheduler/check-for-loop.ts). Tests in [validate.spec.ts](src/planner/validate.spec.ts).
|
|
8
|
-
- [x] **Local task pidfile** — [work-runtime-local.ts](src/planner/work-runtime-local.ts) writes `.hammerkit/<id>.pid` for the duration of `execute()`. A live PID (`find-process`) blocks re-entry with an `error` state; a stale PID is silently swept. Tests in [work-runtime-local.spec.ts](src/planner/work-runtime-local.spec.ts).
|
|
9
|
-
- [x] **Docker service crash detection** — [docker-service.ts](src/executer/docker-service.ts) now races `container.wait()` against `abort`. A container that exits before abort is reported as `{ type: 'end', reason: 'crash' }` instead of `terminated`.
|
|
10
|
-
- [x] **Service env hints for local tasks** — [get-service-env-hints.ts](src/executer/get-service-env-hints.ts) emits `HAMMERKIT_<NAME>_HOST` / `_PORT` / `_PORT_<containerPort>` for each running need. Merged into the local task's command env in [local-task.ts](src/executer/local-task.ts). Tests in [get-service-env-hints.spec.ts](src/executer/get-service-env-hints.spec.ts).
|
|
11
|
-
- [x] **K8s deployment healthcheck** — `service.data.healthcheck.cmd` is translated to an `exec` `readinessProbe`/`livenessProbe` in [ensure-kubernetes-deployment-exists.ts](src/kubernetes/ensure-kubernetes-deployment-exists.ts). No more silently-ignored healthchecks on k8s.
|
|
12
|
-
- [x] **Kubernetes port-forward without `kubectl`** — [kubernetes-service.ts](src/executer/kubernetes-service.ts) now uses `@kubernetes/client-node`'s `PortForward` class with a local `net.createServer` listener per port. Selector → pod resolution lives in [resolve-pod-name.ts](src/kubernetes/resolve-pod-name.ts) and supports `service`, `deployment`, and `pod` selectors. A new optional `namespace` field on the `kubernetes-service` schema (defaults to `'default'`) makes per-job namespace isolation possible from a build file.
|
|
13
|
-
|
|
14
|
-
## Done in 1.6.0 hardening (branch `hardening/1.6.0`)
|
|
15
|
-
|
|
16
|
-
- [x] **Transitive dependency cache invalidation** — `checkCacheState` now folds each task's own state key together with the recursively-computed state keys of its dependencies ([src/executer/scheduler/enqueue-next.ts](src/executer/scheduler/enqueue-next.ts) `combineStateKeys`/`resolveEffectiveStateKey`). A change to an upstream source now invalidates downstream tasks even when their own sources are unchanged. Because `currentStateKey` reads back the stored key, the round-trip stays consistent (one expected cache miss on first run after upgrade). Tests in [enqueue-next.spec.ts](src/executer/scheduler/enqueue-next.spec.ts).
|
|
17
|
-
- [x] **K8s stale upload/download pod cleanup** — `getPodForPersistence` force-deletes and waits for any leftover pod of the same name before scheduling a fresh one ([src/kubernetes/ensure-persistent-data.ts](src/kubernetes/ensure-persistent-data.ts) `removeStalePod`), so a pod leaked by a crashed run no longer gets patched in place and stuck. `statusCodeOf` is now shared from [apply.ts](src/kubernetes/apply.ts).
|
|
18
|
-
|
|
19
|
-
## Open
|
|
20
|
-
|
|
21
|
-
**Release triage (1.6.0):** none of the items below block the 1.6.0 release — they
|
|
22
|
-
are tracked as post-1.6.0 cleanup. They are error-message, code-placement, and
|
|
23
|
-
operational-efficiency improvements (no longer any known correctness gap that
|
|
24
|
-
yields wrong build outputs).
|
|
25
|
-
|
|
26
|
-
### Smaller TODOs (lower priority)
|
|
27
|
-
|
|
28
|
-
- [src/planner/utils/append-work-dependencies.ts:39](src/planner/utils/append-work-dependencies.ts) — `// TODO check if thats correct` (skipping `isFile` generates when inheriting).
|
|
29
|
-
- **K8s persistence dedupe + real matcher/stateKey** — [src/kubernetes/ensure-persistent-data.ts](src/kubernetes/ensure-persistent-data.ts) and [src/kubernetes/volumes.ts:89](src/kubernetes/volumes.ts) `:91`. Skipping re-upload when the persisted state already matches needs an in-cluster state marker per volume, and the `matcher: () => true` / `stateKey: ''` placeholders must be replaced with the work item's real source matcher/key. Deferred deliberately: it is a new in-cluster-state feature (not a localized fix) and the k8s persistence path is only exercisable on the self-hosted integration runner, so it was kept out of the release-hardening pass to keep 1.6.0 verifiable. Until then uploads include the full source path (over-upload, still correct).
|
|
30
|
-
- [src/schema/reference-parser.ts:276](src/schema/reference-parser.ts) `:305` — generic "unable to find" errors should include resolution path.
|
|
31
|
-
- [src/executer/event-cache.ts:15](src/executer/event-cache.ts) `:28` — clean/store logic ought to live in the local runtime, not the cache module.
|
|
32
|
-
- [src/executer/state.ts:41](src/executer/state.ts) — emit a warn when removing a listener that isn't registered.
|
|
33
|
-
- [src/planner/work-item-status.ts:33](src/planner/work-item-status.ts) `:50` `:58` — `LogContext` should replace with `WorkItem` reference; two `cleanup` markers.
|
|
34
|
-
- [src/kubernetes/await-running-state.ts:66](src/kubernetes/await-running-state.ts) — `awaitDeployRunningState` has a confusing `(... && obj.status?.readyReplicas) ?? 0 > 0` operator-precedence expression. It happens to behave correctly (resolves only when `readyReplicas` is truthy) but reads as a bug; rewrite as `((obj.status?.readyReplicas ?? 0) > 0)`. Cosmetic — left untouched in 1.6.0 to avoid changing the k8s path that is only exercised on the integration runner.
|