@khanhspring/forge-module 1.0.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/bin/install.js ADDED
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { cpSync, mkdirSync } from 'fs';
4
+ import { join, dirname } from 'path';
5
+ import { homedir } from 'os';
6
+ import { fileURLToPath } from 'url';
7
+
8
+ const __dirname = dirname(fileURLToPath(import.meta.url));
9
+ const ROOT = join(__dirname, '..');
10
+ const SKILLS_DIR = join(homedir(), '.claude', 'skills');
11
+
12
+ const SKILLS = [
13
+ 'forge-contract-test',
14
+ 'forge-done',
15
+ 'forge-implement',
16
+ 'forge-init',
17
+ 'forge-tasks',
18
+ ];
19
+
20
+ console.log('Installing @forge-workflow/module skills...\n');
21
+
22
+ mkdirSync(SKILLS_DIR, { recursive: true });
23
+
24
+ for (const skill of SKILLS) {
25
+ cpSync(join(ROOT, skill), join(SKILLS_DIR, skill), { recursive: true, force: true });
26
+ console.log(` ✓ ${skill}`);
27
+ }
28
+
29
+ console.log(`\nInstalled to ${SKILLS_DIR}`);
30
+ console.log('Restart Claude Code, then run /forge-init in your module repo.');
@@ -0,0 +1,60 @@
1
+ ---
2
+ name: "forge-contract-test"
3
+ description: "Outputs the specmatic test command to verify the running service against its contracts. If test output is pasted as argument, analyzes each failure with endpoint, mismatch type, and a one-line fix."
4
+ argument-hint: "Paste specmatic test failure output to analyze, or leave empty to get the test command"
5
+ compatibility: "Requires module repo with .forge/module.json; service must be running at test_base_url for live testing"
6
+ metadata:
7
+ author: "forge-workflow"
8
+ source: "module-skills/forge-contract-test/SKILL.md"
9
+ user-invocable: true
10
+ disable-model-invocation: true
11
+ ---
12
+
13
+ # Forge Contract Test
14
+
15
+ Run or analyze Specmatic contract tests for this module.
16
+
17
+ ## Pre-check
18
+ - Read `.forge/module.json` for `contract_glob` and `test_base_url`.
19
+ If missing, say "Run forge-init to set up this module repo first."
20
+
21
+ ## If $ARGUMENTS is empty — Output the test command
22
+
23
+ ```
24
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
25
+ Contract Tests: {module}
26
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
27
+
28
+ Make sure your server is running at {test_base_url}, then run:
29
+
30
+ specmatic test \
31
+ --contract "{contract_glob}" \
32
+ --testBaseURL {test_base_url}
33
+
34
+ Contracts under test:
35
+ {list files matching contract_glob}
36
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
37
+ ```
38
+
39
+ ## If $ARGUMENTS contains test output — Analyze failures
40
+
41
+ For each failure, provide:
42
+ 1. Which endpoint failed (method + path)
43
+ 2. What the mismatch is (missing field / wrong type / wrong status code / unexpected field)
44
+ 3. Where to fix it in the implementation (specific file/method if determinable from stack)
45
+ 4. One-line fix suggestion
46
+
47
+ Format:
48
+ ```
49
+ ❌ POST /api/v1/users/register
50
+ Issue: Response missing required field `createdAt` (string, date-time)
51
+ Fix: Add `createdAt` to the RegisterResponse DTO and include it in the response
52
+
53
+ ❌ GET /api/v1/users/{id}
54
+ Issue: Returns 200 when user not found — contract expects 404
55
+ Fix: Add a not-found check before returning the response
56
+ ```
57
+
58
+ ## Rule
59
+ Never suggest changing the contract to fix a failing test.
60
+ If the contract looks wrong: "Raise this in the spec repo — don't work around it here."
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: "forge-done"
3
+ description: "Confirms all tasks for this module are complete and generates the module repo commit message. Module repo only — run /forge-close in the spec repo afterward to mark tasks done there."
4
+ argument-hint: "Feature slug (e.g. 'user-registration')"
5
+ compatibility: "Requires module repo with .forge/module.json and an initialized specs/ git submodule"
6
+ metadata:
7
+ author: "forge-workflow"
8
+ source: "module-skills/forge-done/SKILL.md"
9
+ user-invocable: true
10
+ disable-model-invocation: true
11
+ ---
12
+
13
+ # Forge Done — Module Repo
14
+
15
+ Close out the implementation side of a feature: confirm all tasks are complete
16
+ and generate the module repo commit message.
17
+
18
+ This skill owns the module repo only. Updating task checkboxes in the spec repo
19
+ is handled separately by `/forge-close` in the spec repo.
20
+
21
+ ---
22
+
23
+ ## Pre-check
24
+
25
+ - Read `.forge/module.json` for `module` and `spec_submodule_path`.
26
+ If missing, say "Run `/forge-init` to set up this module repo first."
27
+ - Feature slug from $ARGUMENTS. If empty, ask: "Which feature are you done with?"
28
+
29
+ ---
30
+
31
+ ## Step 1 — Read task list (read-only from submodule)
32
+
33
+ Read `{spec_submodule_path}/features/{slug}/tasks.md`.
34
+ Find the `### {module}` section. Extract all tasks with their checkbox state.
35
+
36
+ If `tasks.md` is missing:
37
+ > "No tasks file found at `specs/features/{slug}/tasks.md`.
38
+ > Run `/forge-tasks {slug}` in the spec repo first."
39
+
40
+ Note: the submodule is read-only — task checkboxes cannot be updated from here.
41
+ That is handled by `/forge-close` in the spec repo.
42
+
43
+ ---
44
+
45
+ ## Step 2 — Confirm completion
46
+
47
+ Show the task list:
48
+
49
+ ```
50
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
51
+ Tasks: {module} / {feature-slug}
52
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
53
+ - [x] TASK-1 [api] POST /users/register endpoint
54
+ - [ ] TASK-2 [feat] Password hashing + validation
55
+ - [x] TASK-3 [test] Unit tests for UserService
56
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
57
+ ```
58
+
59
+ - All already ticked in submodule → note it and proceed.
60
+ - Some unticked → ask: "Are these actually finished? Say **yes** to proceed or tell me what's still in progress."
61
+
62
+ Wait for confirmation before continuing.
63
+
64
+ ---
65
+
66
+ ## Step 3 — Generate commit message
67
+
68
+ ```
69
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
70
+ Commit message
71
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
72
+ feat({module}): implement {feature-slug}
73
+
74
+ - TASK-1: {title}
75
+ - TASK-2: {title}
76
+ - TASK-3: {title}
77
+
78
+ Spec: specs/features/{slug}/spec.md
79
+ Tasks: specs/features/{slug}/tasks.md
80
+ Contract: specs/contracts/{module}/{slug}.yaml
81
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
82
+ ```
83
+
84
+ Then remind:
85
+ > "Once committed and pushed, go to the spec repo and run:
86
+ > `/forge-close {slug} {module}`
87
+ > to mark your tasks as done and check if the feature is fully complete."
@@ -0,0 +1,188 @@
1
+ ---
2
+ name: "forge-implement"
3
+ description: "Researches existing codebase patterns, clears ambiguities one at a time, challenges implementation concerns, then guides task-by-task implementation scoped to this module. No code written until plan is confirmed."
4
+ argument-hint: "Feature slug (e.g. 'user-registration')"
5
+ compatibility: "Requires module repo with .forge/module.json and an initialized specs/ git submodule"
6
+ metadata:
7
+ author: "forge-workflow"
8
+ source: "module-skills/forge-implement/SKILL.md"
9
+ user-invocable: true
10
+ disable-model-invocation: true
11
+ ---
12
+
13
+ # Forge Implement
14
+
15
+ Understand the feature fully before writing a single line of code. Research existing
16
+ patterns, surface ambiguities, flag conflicts — then implement with confidence.
17
+
18
+ <HARD-GATE>
19
+ Do NOT write any code, create any files, or modify any existing files until you have
20
+ presented the Implementation Plan and the user has explicitly confirmed it.
21
+ </HARD-GATE>
22
+
23
+ ---
24
+
25
+ ## Pre-check
26
+
27
+ - Read `.forge/module.json` — if missing, say "Run `/forge-init` to set up this module repo first."
28
+ - Get `module`, `spec_submodule_path`, `test_base_url`, `contract_glob` from module.json.
29
+ - Feature slug from $ARGUMENTS.
30
+ - If empty, scan `{spec_submodule_path}/features/*/tasks.md` for `### {module}` sections,
31
+ list features with pending tasks, ask which to implement.
32
+ - Check `git submodule status` — if specs/ is out of date, say:
33
+ > "Your specs submodule may be out of date. Run `git submodule update --remote specs` first, or continue with the current version?"
34
+
35
+ ---
36
+
37
+ ## Step 1 — Load & Research Context
38
+
39
+ Load the feature documents silently:
40
+ - `{spec_submodule_path}/features/{slug}/spec.md` — requirements and flows
41
+ - `{spec_submodule_path}/features/{slug}/tasks.md` — task list for this module
42
+
43
+ If `tasks.md` is missing → stop: "No tasks found. Run `/forge-tasks {slug}` in the spec repo first."
44
+
45
+ **Determine which contract(s) apply to this module:**
46
+ - Look for an own-module contract: `{spec_submodule_path}/contracts/{module}/{slug}.yaml`.
47
+ - **If it exists** → this module *provides* the API. Use it as the source of truth for the
48
+ endpoints you implement.
49
+ - **If it does NOT exist** (typical for frontend/consumer modules) → scan
50
+ `{spec_submodule_path}/contracts/*/{slug}.yaml` for sibling contracts. These are the APIs
51
+ this module *consumes*. Report:
52
+ > "No contract for `{module}` — this module consumes APIs from: {list backend modules}.
53
+ > I'll use their contracts as the integration source of truth."
54
+ - If no contract exists anywhere for this feature → note it and continue with spec + tasks only.
55
+
56
+ Then research the existing codebase — do this before asking any questions:
57
+
58
+ 1. **Read `CLAUDE.md`** — note architectural principles, conventions, and forbidden patterns.
59
+ 2. **Find similar existing endpoints** — look for controllers/routes with similar patterns to what the contract defines. Note how they're structured.
60
+ 3. **Find existing service/repository patterns** — how are services and data access layers organized in this codebase?
61
+ 4. **Find existing test patterns** — how are unit and integration tests structured? What test utilities exist?
62
+ 5. **Find existing error handling** — how does this service return errors? Does it match the `ApiError` schema (`shared/api-error.yaml`) in the contract — `code`, `message`, `traceId`, `details[]`?
63
+ 6. **Find existing auth/middleware** — how is authentication enforced on existing endpoints?
64
+
65
+ Report findings before asking questions:
66
+
67
+ > "Before we start, here's what I found in the codebase:
68
+ > - Existing pattern: {e.g. 'Controllers use @RestController with @RequestMapping, services are injected via constructor'}
69
+ > - Test pattern: {e.g. 'Integration tests use @SpringBootTest with TestContainers'}
70
+ > - Error handling: {e.g. 'GlobalExceptionHandler returns ApiError with code + message + traceId — matches contract'}
71
+ > - Auth: {e.g. 'JwtAuthFilter applied to all /api/v1/** routes via SecurityConfig'}
72
+ > - Potential conflict: {any mismatch found — or 'None found'}
73
+ >
74
+ > I'll follow these patterns in the implementation."
75
+
76
+ ---
77
+
78
+ ## Step 2 — Clarifying Questions (one at a time)
79
+
80
+ Ask questions ONE at a time. Only ask about things that are genuinely ambiguous or
81
+ missing — do not ask about things already answered by the spec, contract, or codebase.
82
+
83
+ Areas to clarify if unclear:
84
+
85
+ - **Ambiguous acceptance criteria** — any task AC that could be implemented multiple ways
86
+ - **Missing dependencies** — e.g. "TASK-3 requires sending an email but I don't see an email service in the codebase — is this in scope or should it be stubbed?"
87
+ - **Conflicting patterns** — e.g. "The contract uses snake_case field names but all existing DTOs use camelCase — which should we follow?"
88
+ - **Task ordering** — if task dependencies aren't obvious from the task list
89
+ - **Data ownership** — if the feature touches data owned by another module, how should that be accessed?
90
+
91
+ If a question cannot be answered without research outside this conversation, use the
92
+ research flag pattern:
93
+
94
+ > "🔍 **Research needed:** {what needs to be found out — e.g. 'whether the payment service supports idempotency keys'}
95
+ > Want to (a) pause and check, (b) proceed with an assumption, or (c) flag it and move on?"
96
+
97
+ If all tasks and the contract are clear, skip this step and say so.
98
+
99
+ ---
100
+
101
+ ## Step 3 — Challenge Round
102
+
103
+ Before presenting the plan, flag at least 2 implementation concerns specific to what
104
+ you've read. These should be real conflicts or risks, not generic warnings.
105
+
106
+ > "Before I lay out the plan, a couple of things to flag:
107
+ >
108
+ > **[Concern 1]:** {e.g. 'The contract requires `createdAt` as date-time in the response,
109
+ > but the existing User entity doesn't have this field — we'll need to add it or compute it.
110
+ > Does that sound right?'}
111
+ >
112
+ > **[Concern 2]:** {e.g. 'TASK-2 (password hashing) and TASK-1 (register endpoint) are listed
113
+ > independently, but TASK-1 depends on TASK-2 being done first. I'll do TASK-2 first — agreed?'}
114
+ >
115
+ > How should these be handled?"
116
+
117
+ Wait for resolution before presenting the plan.
118
+
119
+ ---
120
+
121
+ ## Step 4 — Implementation Plan & Gate
122
+
123
+ Present the full plan and wait for confirmation before writing any code:
124
+
125
+ ```
126
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
127
+ Implementation Plan: {Feature Name}
128
+ Module: {module}
129
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
130
+
131
+ TASKS (in order)
132
+ 1. TASK-2 [feat] Password hashing + validation
133
+ → {implementation approach}
134
+ 2. TASK-1 [api] POST /users/register endpoint
135
+ → {implementation approach, files to touch}
136
+ 3. TASK-3 [test] Unit tests for UserService
137
+ → {what will be tested}
138
+
139
+ KEY DECISIONS
140
+ - {pattern chosen and why, e.g. 'Following existing constructor injection pattern'}
141
+ - {any assumption recorded}
142
+
143
+ FILES TO TOUCH
144
+ - {file path} — {what changes}
145
+ - {file path} — {what changes}
146
+
147
+ CONTRACT ({provide | consume})
148
+ {METHOD} {path} — {key fields to implement, or to send/expect when consuming}
149
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
150
+ ```
151
+
152
+ End with:
153
+ > "Does this plan look right? Say **yes** to start, or tell me what to change."
154
+
155
+ Do NOT write any code until the user confirms.
156
+
157
+ ---
158
+
159
+ ## Step 5 — Implement Task by Task
160
+
161
+ Work through tasks in the agreed order. For each task:
162
+
163
+ - State which task you're starting: "Starting TASK-2: {title}"
164
+ - Use the contract YAML for exact field names, types, and response shapes
165
+ - Follow the patterns found in Step 1 — no new patterns unless discussed
166
+ - Write tests alongside the implementation, not after
167
+ - When a task is done, confirm: "TASK-2 done. Moving to TASK-1 — ready?"
168
+
169
+ If a new ambiguity surfaces mid-implementation:
170
+ > "Unexpected: {what came up}. I'd suggest {option A} or {option B}. Which do you prefer?"
171
+ Wait for the answer before continuing.
172
+
173
+ ---
174
+
175
+ ## Rules
176
+ - Contract is the source of truth for API shape — never change it to fix a failing test
177
+ - When **providing** an API: match the contract's request/response exactly
178
+ - When **consuming** an API (frontend/client): send requests and parse responses exactly as the
179
+ consumed contract defines — treat its shapes as fixed, code defensively against its error responses
180
+ - If the contract looks wrong: "This looks like a contract issue — raise a PR in the spec repo"
181
+ - Only implement tasks under `### {module}` in tasks.md — flag any cross-module work
182
+ - Follow existing codebase patterns found in Step 1 — consistency over personal preference
183
+ - No code before the user confirms the plan in Step 4
184
+
185
+ ## Parallel FE+BE Flow (mention when relevant)
186
+ If a consumer module needs the API before the provider has built it:
187
+ > "The provider's contract at `specs/contracts/{backend-module}/{slug}.yaml` fully defines the
188
+ > API — you can build and test against it (e.g. a stub server) before the backend is ready."
@@ -0,0 +1,240 @@
1
+ ---
2
+ name: "forge-init"
3
+ description: "One-time initialization for a Forge module repo (backend or frontend). Researches existing repo state, then walks through setup conversationally one question at a time before writing any files."
4
+ argument-hint: "Optional: module name to skip the first prompt"
5
+ compatibility: "Run once in a module repo before any other forge skills. Safe to re-run — never overwrites existing files."
6
+ when_to_use: >
7
+ ALWAYS activate when any of the following occur:
8
+ - User says init, initialize, setup, set up, bootstrap, configure + repo/forge/project
9
+ - User says "set this up", "get this started", "prepare this repo"
10
+ - No .forge/module.json exists AND user wants to start implementing specs
11
+ - User says "this is a new module repo" (or "service repo" / "code repo") or "add forge to this project"
12
+ Do NOT activate if .forge/module.json already exists — repo is already initialized.
13
+ metadata:
14
+ author: "forge-workflow"
15
+ source: "module-skills/forge-init/SKILL.md"
16
+ user-invocable: true
17
+ disable-model-invocation: false
18
+ ---
19
+
20
+ # Forge Init — Module Repo
21
+
22
+ Initialize this repo as a Forge module repo (one module — backend or frontend).
23
+ Research what's already in the codebase first, then ask one question at a time —
24
+ pre-filling anything already detectable. Write all files in one go after confirmation.
25
+
26
+ ## Pre-check
27
+ If `.forge/module.json` already exists → say "Module repo already initialized." and stop.
28
+
29
+ ---
30
+
31
+ ## Step 1 — Research existing repo state
32
+
33
+ Before asking anything, silently scan the repo and note:
34
+
35
+ 1. **Stack detection** — does `pom.xml`, `build.gradle`, `package.json`, `go.mod`, `requirements.txt`, or similar exist? What versions are declared?
36
+ 2. **Port detection** — is a port configured in `application.yml`, `application.properties`, `.env`, `.env.example`, or `docker-compose.yml`?
37
+ 3. **Submodule** — does `specs/` already exist as a directory or submodule?
38
+ 4. **CI** — does `.github/workflows/` already exist? Any contract test workflow present?
39
+ 5. **Existing CLAUDE.md** — already has project context written?
40
+
41
+ Report findings before asking anything:
42
+
43
+ > "Here's what I found in this repo:
44
+ > - Stack: {detected stack — or 'not detected'}
45
+ > - Port: {detected port — or 'not found in config'}
46
+ > - specs/ submodule: {exists / not present}
47
+ > - GitHub Actions: {exists / not present}
48
+ >
49
+ > I'll use these as defaults — just confirm or correct as we go."
50
+
51
+ ---
52
+
53
+ ## Step 2 — Questions (one at a time)
54
+
55
+ Ask one question per message. Wait for the answer before asking the next.
56
+ Where research already gives a confident answer, present it as a default to confirm
57
+ rather than asking from scratch.
58
+
59
+ **Q1 — Module name**
60
+ > "What's the module name for this repo?
61
+ > _(Must exactly match a `name` entry in the spec repo's `.forge/project.json`)_"
62
+
63
+ Do not suggest a default — module names must be exact matches. Warn clearly:
64
+ > "This name must match exactly. A mismatch will break `/forge-implement` and `/forge-done`."
65
+
66
+ **Q2 — Module description**
67
+ > "What does this module do? (one sentence)"
68
+
69
+ **Q3 — Spec repo URL**
70
+
71
+ If `specs/` already exists:
72
+ > "I see a `specs/` directory already — is that the spec repo submodule? (yes/no)
73
+ > If yes, what's the remote URL? (run `git remote -v` in `specs/` if unsure)"
74
+
75
+ If not:
76
+ > "What's the spec repo URL? (it will be added as a git submodule at `specs/`)"
77
+
78
+ **Q4 — Port**
79
+
80
+ If port was detected in Step 1:
81
+ > "I found port `{port}` in your config — is that the right local dev port? (yes / enter different port)"
82
+
83
+ If not detected:
84
+ > "What port does this module run on locally?"
85
+
86
+ **Q5 — Tech stack**
87
+
88
+ If stack was detected in Step 1:
89
+ > "Looks like this is a `{detected stack}` module — is that right? Anything to add?"
90
+
91
+ If not detected:
92
+ > "What's the tech stack? (e.g. 'Spring Boot 3, Java 21' or 'React, TypeScript')"
93
+
94
+ **Q6 — Principles**
95
+ > "What are the key architectural principles for this module?
96
+ > _(e.g. 'stateless', 'no business logic in controllers', 'repository pattern for DB access')
97
+ > Say 'none yet' to skip._"
98
+
99
+ **Q7 — Conventions**
100
+ > "Any coding conventions the team follows in this repo?
101
+ > _(e.g. 'constructor injection only', 'all public methods must have unit tests', 'no magic strings')
102
+ > Say 'none yet' to skip._"
103
+
104
+ **Q8 — Never**
105
+ > "Anything developers should never do in this codebase?
106
+ > _(e.g. 'no direct DB calls from the API layer', 'never change a contract to fix a failing test')
107
+ > Say 'none yet' to skip._"
108
+
109
+ **Q9 — GitHub Actions CI**
110
+
111
+ If `.github/workflows/` already exists with a contract test:
112
+ > "I see a CI workflow already exists — skip adding another? (yes to skip)"
113
+
114
+ If not present:
115
+ > "Add a GitHub Actions contract test workflow? (yes/no)"
116
+ > _(Backend modules that serve an API benefit most; a frontend that only consumes can skip.)_
117
+
118
+ ---
119
+
120
+ ## Step 3 — Preview & gate
121
+
122
+ Show a full preview of everything that will be created or run:
123
+
124
+ ```
125
+ Ready to initialize. Here's what I'll do:
126
+
127
+ {if specs/ not present}
128
+ git submodule add {spec-repo-url} specs
129
+ git submodule update --init --recursive
130
+
131
+ .forge/module.json
132
+ module: {module-name}
133
+ test_base_url: http://localhost:{port}
134
+ contract_glob: specs/contracts/{module-name}/*.yaml
135
+
136
+ CLAUDE.md
137
+ Module: {module-name}
138
+ Description: {description}
139
+ Stack: {stack} Port: {port}
140
+ Principles: {list or "none yet"}
141
+ Conventions: {list or "none yet"}
142
+ Never: {list or "none yet"}
143
+
144
+ {if yes} .github/workflows/contract-test.yml
145
+ .gitignore ← append Forge entries
146
+ ```
147
+
148
+ End with:
149
+ > "Does this look right? Say **yes** to initialize, or tell me what to change."
150
+
151
+ Wait for confirmation. Do not write files or run git commands before the user says yes.
152
+
153
+ ---
154
+
155
+ ## Step 4 — Write files
156
+
157
+ Run (if specs/ not already present):
158
+ ```bash
159
+ git submodule add {spec-repo-url} specs
160
+ git submodule update --init --recursive
161
+ ```
162
+
163
+ Write `.forge/module.json`:
164
+ ```json
165
+ {
166
+ "module": "{module-name}",
167
+ "spec_submodule_path": "specs",
168
+ "specmatic_version": "2.x",
169
+ "test_base_url": "http://localhost:{port}",
170
+ "contract_glob": "specs/contracts/{module-name}/*.yaml"
171
+ }
172
+ ```
173
+
174
+ Write `CLAUDE.md`:
175
+ ```markdown
176
+ # {module-name}
177
+
178
+ {description}
179
+
180
+ **Stack:** {stack}
181
+ **Port:** {port}
182
+
183
+ ## Forge Workflow
184
+ 1. `/forge-tasks` — see all pending tasks for this module
185
+ 2. `/forge-implement` — implement a feature task by task
186
+ 3. `/forge-contract-test` — run Specmatic contract tests
187
+ 4. `/forge-done` — confirm tasks done + generate commit message
188
+ 5. (then in the spec repo) `/forge-close {slug} {module}` — mark tasks done there
189
+
190
+ ## Spec repo
191
+ Linked via git submodule at `specs/`.
192
+ Run `git submodule update --remote specs` before starting a new feature,
193
+ and again after `/forge-close` is run in the spec repo to sync task status.
194
+
195
+ ## Principles
196
+ {list each as a bullet — or "None defined yet."}
197
+
198
+ ## Conventions
199
+ {list each as a bullet — or "None defined yet."}
200
+
201
+ ## Never
202
+ {list each as a bullet — or "None defined yet."}
203
+ ```
204
+
205
+ If GitHub Actions was requested, write `.github/workflows/contract-test.yml`:
206
+ ```yaml
207
+ name: Contract Tests
208
+ on: [push, pull_request]
209
+ jobs:
210
+ contract-test:
211
+ runs-on: ubuntu-latest
212
+ steps:
213
+ - uses: actions/checkout@v4
214
+ with:
215
+ submodules: recursive
216
+ - name: Run contract tests
217
+ run: |
218
+ specmatic test \
219
+ --contract "specs/contracts/{module-name}/*.yaml" \
220
+ --testBaseURL ${{ env.SERVICE_URL }}
221
+ ```
222
+
223
+ Append to `.gitignore` if not present:
224
+ ```
225
+ # Forge
226
+ .forge/secrets
227
+ ```
228
+
229
+ Run `git status` and confirm:
230
+ > "Module repo initialized. Run `/forge-tasks` to see what needs to be built."
231
+
232
+ ---
233
+
234
+ ## Rules
235
+ - One question per message — never ask multiple questions at once
236
+ - Never write files or run git commands before the user says yes in Step 3
237
+ - Never overwrite existing files
238
+ - All written files must be complete — no unfilled placeholders
239
+ - `module` in module.json must exactly match the name in the spec repo's project.json
240
+ - If the user provides multiple answers in one message, accept them gracefully and move forward
@@ -0,0 +1,49 @@
1
+ ---
2
+ name: "forge-tasks"
3
+ description: "Lists all tasks assigned to this module across every feature, with completion status, by scanning the spec submodule. Module repo task dashboard."
4
+ argument-hint: ""
5
+ compatibility: "Requires module repo with .forge/module.json and an initialized specs/ git submodule"
6
+ metadata:
7
+ author: "forge-workflow"
8
+ source: "module-skills/forge-tasks/SKILL.md"
9
+ user-invocable: true
10
+ disable-model-invocation: true
11
+ ---
12
+
13
+ # Forge Tasks — Module Repo
14
+
15
+ Show all tasks assigned to this module across all features.
16
+
17
+ ## Pre-check
18
+ - Read `.forge/module.json` for `module` and `spec_submodule_path`.
19
+ If missing: "Run `/forge-init` to set up this module repo first."
20
+ - If `specs/` is not initialized: suggest `git submodule update --init --recursive`
21
+ - Optionally suggest `git submodule update --remote specs` to get the latest task status.
22
+
23
+ ## Steps
24
+
25
+ Scan `{spec_submodule_path}/features/*/tasks.md` → find `### {module}` sections → extract tasks
26
+ with their checkbox state and the parent feature's `Status`.
27
+
28
+ ```
29
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
30
+ Tasks for: {module}
31
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
32
+
33
+ Feature: user-registration [Open]
34
+ - [ ] TASK-1 [api] POST /users/register endpoint
35
+ - [ ] TASK-2 [feat] Password hashing + validation
36
+ - [x] TASK-3 [test] Unit tests for UserService
37
+
38
+ Feature: user-profile [Open]
39
+ - [ ] TASK-5 [api] GET /users/{id} endpoint
40
+
41
+ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
+ 2 features · 4 remaining · 1 done
43
+ ```
44
+
45
+ If no tasks reference this module across any feature:
46
+ > "No tasks found for `{module}`. Either no feature targets this module yet, or the specs
47
+ > submodule is out of date — try `git submodule update --remote specs`."
48
+
49
+ After showing: "Tell me which feature to implement, or run `/forge-implement {slug}`."
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@khanhspring/forge-module",
3
+ "version": "1.0.0",
4
+ "description": "Forge module repo skills for Claude Code — implement, contract-test, done, and more",
5
+ "type": "module",
6
+ "bin": {
7
+ "forge-module": "bin/install.js"
8
+ },
9
+ "files": [
10
+ "bin",
11
+ "forge-contract-test",
12
+ "forge-done",
13
+ "forge-implement",
14
+ "forge-init",
15
+ "forge-tasks"
16
+ ],
17
+ "keywords": ["claude-code", "skills", "ai", "workflow", "microservices"],
18
+ "license": "MIT"
19
+ }