@khanhspring/forge-module 1.2.0 → 1.4.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/package.json
CHANGED
|
@@ -15,11 +15,17 @@ disable-model-invocation: true
|
|
|
15
15
|
Run or analyze Specmatic contract tests for this module.
|
|
16
16
|
|
|
17
17
|
## Pre-check
|
|
18
|
-
- Read `.forge/module.json`.
|
|
18
|
+
- Read `.forge/module.json` for `module` and `spec_submodule_path`.
|
|
19
19
|
If missing, say "Run forge-init to set up this module repo first."
|
|
20
|
+
- Read `{spec_submodule_path}/.forge/project.json` and find the `modules[]` entry where
|
|
21
|
+
`name == module` — port and submodule structure live there, not in module.json.
|
|
20
22
|
- Determine scope:
|
|
21
|
-
-
|
|
22
|
-
|
|
23
|
+
- Entry has no `submodules[]` → single module; derive `contract_glob =
|
|
24
|
+
{spec_submodule_path}/contracts/{module}/*.yaml` and `test_base_url =
|
|
25
|
+
http://localhost:{entry.port}`.
|
|
26
|
+
- Entry has `submodules[]` → module with submodules; show one command block per submodule,
|
|
27
|
+
deriving each one's `contract_glob = {spec_submodule_path}/contracts/{submodule.name}/*.yaml`
|
|
28
|
+
and `test_base_url = http://localhost:{submodule.port}`.
|
|
23
29
|
|
|
24
30
|
## If $ARGUMENTS is empty — Output the test command(s)
|
|
25
31
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: "forge-done"
|
|
3
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
4
|
argument-hint: "Feature slug (e.g. 'user-registration')"
|
|
5
|
-
compatibility: "Requires module repo with .forge/module.json and an initialized specs/ git submodule"
|
|
5
|
+
compatibility: "Requires module repo with .forge/module.json and an initialized specs/ link (git submodule or junction)"
|
|
6
6
|
metadata:
|
|
7
7
|
author: "forge-workflow"
|
|
8
8
|
source: "module-skills/forge-done/SKILL.md"
|
|
@@ -28,20 +28,22 @@ is handled separately by `/forge-close` in the spec repo.
|
|
|
28
28
|
|
|
29
29
|
---
|
|
30
30
|
|
|
31
|
-
## Step 1 — Read task list (read-only from
|
|
31
|
+
## Step 1 — Read task list (read-only from specs/)
|
|
32
32
|
|
|
33
33
|
Read `{spec_submodule_path}/features/{slug}/tasks.md`.
|
|
34
34
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
Read `{spec_submodule_path}/.forge/project.json` and find the `modules[]` entry where
|
|
36
|
+
`name == module` — submodule structure lives there, not in module.json:
|
|
37
|
+
- Entry has no `submodules[]`: find the `### {module}` section.
|
|
38
|
+
- Entry has `submodules[]`: find the `### {submodule.name}` section for each entry; show them
|
|
39
|
+
grouped by submodule name in Step 2.
|
|
38
40
|
|
|
39
41
|
If `tasks.md` is missing:
|
|
40
42
|
> "No tasks file found at `specs/features/{slug}/tasks.md`.
|
|
41
43
|
> Run `/forge-tasks {slug}` in the spec repo first."
|
|
42
44
|
|
|
43
|
-
Note:
|
|
44
|
-
That is handled by `/forge-close` in the spec repo.
|
|
45
|
+
Note: `specs/` is read-only from here regardless of link type — task checkboxes cannot be
|
|
46
|
+
updated from this repo. That is handled by `/forge-close` in the spec repo.
|
|
45
47
|
|
|
46
48
|
---
|
|
47
49
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: "forge-implement"
|
|
3
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
4
|
argument-hint: "Feature slug (e.g. 'user-registration')"
|
|
5
|
-
compatibility: "Requires module repo with .forge/module.json and an initialized specs/ git submodule"
|
|
5
|
+
compatibility: "Requires module repo with .forge/module.json and an initialized specs/ link (git submodule or junction)"
|
|
6
6
|
metadata:
|
|
7
7
|
author: "forge-workflow"
|
|
8
8
|
source: "module-skills/forge-implement/SKILL.md"
|
|
@@ -25,17 +25,24 @@ presented the Implementation Plan and the user has explicitly confirmed it.
|
|
|
25
25
|
## Pre-check
|
|
26
26
|
|
|
27
27
|
- Read `.forge/module.json` — if missing, say "Run `/forge-init` to set up this module repo first."
|
|
28
|
-
- Get `spec_submodule_path` from module.json.
|
|
29
|
-
- **Determine working scope
|
|
30
|
-
- `
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
- Get `module`, `spec_submodule_path`, and `spec_link_type` from module.json.
|
|
29
|
+
- **Determine working scope** from the spec repo, not module.json:
|
|
30
|
+
- Read `{spec_submodule_path}/.forge/project.json` and find the `modules[]` entry where
|
|
31
|
+
`name == module`. If not found, warn: "`{module}` isn't registered in the spec repo's
|
|
32
|
+
`project.json` — check the name matches, or add it there via `/forge-config`."
|
|
33
|
+
- Entry has no `submodules[]` → scope = the module itself; `test_base_url =
|
|
34
|
+
http://localhost:{entry.port}`, `contract_glob = {spec_submodule_path}/contracts/{module}/*.yaml`.
|
|
35
|
+
- Entry has `submodules[]` → ask "Which submodule are you implementing? ({list submodule names
|
|
36
|
+
from the entry})", then use that submodule's `path`, and derive `test_base_url =
|
|
37
|
+
http://localhost:{submodule.port}`, `contract_glob =
|
|
38
|
+
{spec_submodule_path}/contracts/{submodule.name}/*.yaml`.
|
|
33
39
|
- Feature slug from $ARGUMENTS.
|
|
34
40
|
- If empty, scan `{spec_submodule_path}/features/*/tasks.md` for `### {scope-name}` headings
|
|
35
41
|
(module name for simple modules, submodule name for submodules), list features with pending
|
|
36
42
|
tasks, ask which to implement.
|
|
37
|
-
-
|
|
43
|
+
- If `spec_link_type` is `"submodule"` (or unset), check `git submodule status` — if specs/ is out of date, say:
|
|
38
44
|
> "Your specs submodule may be out of date. Run `git submodule update --remote specs` first, or continue with the current version?"
|
|
45
|
+
- If `spec_link_type` is `"junction"`, skip this check — a junction/symlink always reflects the live spec folder.
|
|
39
46
|
|
|
40
47
|
---
|
|
41
48
|
|
|
@@ -34,7 +34,9 @@ Before asking anything, silently scan the repo and note:
|
|
|
34
34
|
|
|
35
35
|
1. **Stack detection** — does `pom.xml`, `build.gradle`, `package.json`, `go.mod`, `requirements.txt`, or similar exist? What versions are declared?
|
|
36
36
|
2. **Port detection** — is a port configured in `application.yml`, `application.properties`, `.env`, `.env.example`, or `docker-compose.yml`?
|
|
37
|
-
3. **Specs
|
|
37
|
+
3. **Specs link** — does `specs/` already exist? If so, determine how: a git submodule
|
|
38
|
+
(check `.gitmodules` / `git submodule status`) or a junction/symlink (check if it's a
|
|
39
|
+
reparse point / symlink, e.g. `git submodule status` reports nothing but the dir exists).
|
|
38
40
|
4. **CI** — does `.github/workflows/` already exist? Any contract test workflow present?
|
|
39
41
|
5. **Existing CLAUDE.md** — already has project context written?
|
|
40
42
|
6. **Monorepo signals** — does `nx.json`, `turbo.json`, `lerna.json`, `pnpm-workspace.yaml`, or
|
|
@@ -47,39 +49,20 @@ Report findings before asking anything:
|
|
|
47
49
|
> "Here's what I found in this repo:
|
|
48
50
|
> - Stack: {detected stack — or 'not detected'}
|
|
49
51
|
> - Port: {detected port — or 'not found in config'}
|
|
50
|
-
> - specs/ submodule
|
|
52
|
+
> - specs/: {not present / exists — git submodule / exists — junction or symlink}
|
|
51
53
|
> - GitHub Actions: {exists / not present}
|
|
52
54
|
> {if monorepo signals}: - Looks like a monorepo — detected sub-apps: {list of dir names}
|
|
53
55
|
>
|
|
54
56
|
> I'll use these as defaults — just confirm or correct as we go."
|
|
55
57
|
|
|
56
|
-
**If monorepo/multi-module signals were found**,
|
|
57
|
-
> "This looks like a module with submodules ({names}).
|
|
58
|
-
>
|
|
58
|
+
**If monorepo/multi-module signals were found**, note it in passing — no question needed:
|
|
59
|
+
> "This looks like a module with submodules ({names}). Submodule structure (ports, stack,
|
|
60
|
+
> paths) lives in the spec repo's `project.json`, not here — I'll cross-check against that
|
|
61
|
+
> once `specs/` is linked."
|
|
59
62
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
---
|
|
64
|
-
|
|
65
|
-
## Step 2-B — Submodule collection (only when confirmed)
|
|
66
|
-
|
|
67
|
-
Submodules share the parent module's repo — they are not separate repos.
|
|
68
|
-
Collect them one at a time. Pre-fill from what was detected and ask the user to confirm or correct:
|
|
69
|
-
|
|
70
|
-
- "Submodule name? _(Must match a `name` under this module's `submodules` in the spec repo's `project.json`; default: `{detected-dir-name}`)_"
|
|
71
|
-
- "Type? (backend / frontend / worker)"
|
|
72
|
-
- "Stack? (detected: {stack-if-found} — or enter manually)"
|
|
73
|
-
- "Port? _(each submodule has its own port — detected: {port-if-found})_"
|
|
74
|
-
- "Path within this repo? (default: `{detected-path}`)"
|
|
75
|
-
|
|
76
|
-
Confirm: "`{sub}` — {type} — {stack} — :{port} — {path}. Another submodule? (yes / no)"
|
|
77
|
-
|
|
78
|
-
**Rules enforced here:**
|
|
79
|
-
- Submodules have no `repo` field — they are in the same repo as the parent module
|
|
80
|
-
- Port is collected per submodule; the parent module has no `port`
|
|
81
|
-
|
|
82
|
-
After collecting all submodules, continue to Step 2 (Q4 port will be skipped automatically).
|
|
63
|
+
Submodule structure is never collected or stored in this repo's `.forge/module.json`. It's
|
|
64
|
+
configured once in the spec repo via `/forge-config` there, and every module skill reads it
|
|
65
|
+
from `specs/.forge/project.json` at runtime. This repo only needs to know its own module name.
|
|
83
66
|
|
|
84
67
|
---
|
|
85
68
|
|
|
@@ -89,57 +72,70 @@ Ask one question per message. Wait for the answer before asking the next.
|
|
|
89
72
|
Where research already gives a confident answer, present it as a default to confirm
|
|
90
73
|
rather than asking from scratch.
|
|
91
74
|
|
|
92
|
-
**Q1 — Module name**
|
|
75
|
+
**Q1 — Module name**
|
|
93
76
|
> "What's the module name for this repo?
|
|
94
77
|
> _(Must exactly match a `name` entry in the spec repo's `.forge/project.json`)_"
|
|
95
78
|
|
|
96
79
|
Do not suggest a default — module names must be exact matches. Warn clearly:
|
|
97
80
|
> "This name must match exactly. A mismatch will break `/forge-implement` and `/forge-done`."
|
|
98
81
|
|
|
82
|
+
If `specs/` was already detected in Step 1 (already linked), read
|
|
83
|
+
`{specs-path}/.forge/project.json` now and find the `modules[]` entry where `name` matches
|
|
84
|
+
this answer. If found, silently keep its `port`, `stack`, `type`, and `submodules[]` (if any)
|
|
85
|
+
for use in the Step 3 preview and the CLAUDE.md content written in Step 4 — do not re-ask for
|
|
86
|
+
any of it. If not found, note it and continue: "Heads up — `{module}` isn't in the spec repo's
|
|
87
|
+
`project.json` yet. Add it there with `/forge-config`, or continue and I'll leave stack/port
|
|
88
|
+
as TBD in CLAUDE.md for now." If `specs/` isn't linked yet, this lookup happens later, in
|
|
89
|
+
Step 4, right after the link is created.
|
|
90
|
+
|
|
99
91
|
**Q2 — Module description**
|
|
100
92
|
> "What does this module do? (one sentence)"
|
|
101
93
|
|
|
102
|
-
**Q3 — Spec repo
|
|
103
|
-
|
|
104
|
-
If `specs/` already exists:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
>
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
>
|
|
118
|
-
|
|
119
|
-
**
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
94
|
+
**Q3 — Spec repo link**
|
|
95
|
+
|
|
96
|
+
If `specs/` already exists, confirm what was detected in Step 1 instead of asking from scratch:
|
|
97
|
+
- Detected as a git submodule → "I see `specs/` is already a git submodule — is that the spec
|
|
98
|
+
repo? (yes/no). If yes, what's the remote URL? (run `git remote -v` in `specs/` if unsure)"
|
|
99
|
+
- Detected as a junction/symlink → "I see `specs/` is already a local junction/symlink — what
|
|
100
|
+
local path does it point at? (confirm or correct)"
|
|
101
|
+
- Set `spec_link_type` accordingly and skip straight to Q4.
|
|
102
|
+
|
|
103
|
+
If `specs/` does not exist, ask how to link it:
|
|
104
|
+
> "How should this repo link to the spec repo?
|
|
105
|
+
> 1. **Git submodule** (default) — versioned and works across machines/CI, but needs
|
|
106
|
+
> `git submodule update --remote specs` to sync after spec repo changes.
|
|
107
|
+
> 2. **Junction / local link** — for when the spec repo and this module repo live on the same
|
|
108
|
+
> machine (solo/local dev). `specs/` always reflects the live folder, no sync command needed —
|
|
109
|
+
> but it won't survive being cloned elsewhere or used in CI, and skips version pinning."
|
|
110
|
+
|
|
111
|
+
- **If git submodule (or no answer / "default")**:
|
|
112
|
+
> "What's the spec repo URL? (it will be added as a git submodule at `specs/`)"
|
|
113
|
+
Set `spec_link_type: "submodule"`.
|
|
114
|
+
- **If junction/local link**:
|
|
115
|
+
> "What's the local path to the spec repo folder? (absolute path, e.g. `D:\Workspace\my-specs`
|
|
116
|
+
> or `/home/me/my-specs`)"
|
|
117
|
+
Set `spec_link_type: "junction"` and `spec_source_path` to the given absolute path.
|
|
118
|
+
|
|
119
|
+
Note: port, stack, and submodule structure are never asked here — they come from the spec
|
|
120
|
+
repo's `project.json` (looked up in Q1 if `specs/` already existed, or in Step 4 right after
|
|
121
|
+
linking otherwise). `.forge/module.json` doesn't store any of it either way.
|
|
122
|
+
|
|
123
|
+
**Q4 — Principles**
|
|
128
124
|
> "What are the key architectural principles for this module?
|
|
129
125
|
> _(e.g. 'stateless', 'no business logic in controllers', 'repository pattern for DB access')
|
|
130
126
|
> Say 'none yet' to skip._"
|
|
131
127
|
|
|
132
|
-
**
|
|
128
|
+
**Q5 — Conventions**
|
|
133
129
|
> "Any coding conventions the team follows in this repo?
|
|
134
130
|
> _(e.g. 'constructor injection only', 'all public methods must have unit tests', 'no magic strings')
|
|
135
131
|
> Say 'none yet' to skip._"
|
|
136
132
|
|
|
137
|
-
**
|
|
133
|
+
**Q6 — Never**
|
|
138
134
|
> "Anything developers should never do in this codebase?
|
|
139
135
|
> _(e.g. 'no direct DB calls from the API layer', 'never change a contract to fix a failing test')
|
|
140
136
|
> Say 'none yet' to skip._"
|
|
141
137
|
|
|
142
|
-
**
|
|
138
|
+
**Q7 — GitHub Actions CI**
|
|
143
139
|
|
|
144
140
|
If `.github/workflows/` already exists with a contract test:
|
|
145
141
|
> "I see a CI workflow already exists — skip adding another? (yes to skip)"
|
|
@@ -157,24 +153,25 @@ Show a full preview of everything that will be created or run:
|
|
|
157
153
|
```
|
|
158
154
|
Ready to initialize. Here's what I'll do:
|
|
159
155
|
|
|
160
|
-
{if specs/ not present}
|
|
156
|
+
{if specs/ not present, spec_link_type = submodule}
|
|
161
157
|
git submodule add {spec-repo-url} specs
|
|
162
158
|
git submodule update --init --recursive
|
|
163
159
|
|
|
160
|
+
{if specs/ not present, spec_link_type = junction}
|
|
161
|
+
{Windows} mklink /J specs "{spec-source-path}"
|
|
162
|
+
{macOS/Linux} ln -s "{spec-source-path}" specs
|
|
163
|
+
append `specs/` to .gitignore (junction contents aren't tracked by this repo)
|
|
164
|
+
|
|
164
165
|
.forge/module.json
|
|
165
|
-
{
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
{if submodules}
|
|
170
|
-
submodules:
|
|
171
|
-
{sub-name} path:{path} :{port} contract: specs/contracts/{sub-name}/*.yaml
|
|
172
|
-
...
|
|
166
|
+
module: {module-name}
|
|
167
|
+
spec_submodule_path: specs
|
|
168
|
+
spec_link_type: {submodule | junction}
|
|
169
|
+
{if junction} spec_source_path: {spec-source-path}
|
|
173
170
|
|
|
174
171
|
CLAUDE.md
|
|
175
172
|
Module: {module-name}
|
|
176
173
|
Description: {description}
|
|
177
|
-
Stack:
|
|
174
|
+
Stack/Port: {from spec repo's project.json, or "TBD — set via /forge-config in the spec repo"}
|
|
178
175
|
Principles: {list or "none yet"}
|
|
179
176
|
Conventions: {list or "none yet"}
|
|
180
177
|
Never: {list or "none yet"}
|
|
@@ -192,50 +189,51 @@ Wait for confirmation. Do not write files or run git commands before the user sa
|
|
|
192
189
|
|
|
193
190
|
## Step 4 — Write files
|
|
194
191
|
|
|
195
|
-
Run (if specs/ not already present)
|
|
192
|
+
Run (if specs/ not already present), based on the chosen `spec_link_type`:
|
|
193
|
+
|
|
194
|
+
**`submodule`:**
|
|
196
195
|
```bash
|
|
197
196
|
git submodule add {spec-repo-url} specs
|
|
198
197
|
git submodule update --init --recursive
|
|
199
198
|
```
|
|
200
199
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
"spec_submodule_path": "specs",
|
|
208
|
-
"specmatic_version": "2.x",
|
|
209
|
-
"test_base_url": "http://localhost:{port}",
|
|
210
|
-
"contract_glob": "specs/contracts/{module-name}/*.yaml"
|
|
211
|
-
}
|
|
200
|
+
**`junction`:**
|
|
201
|
+
```bash
|
|
202
|
+
# Windows
|
|
203
|
+
mklink /J specs "{spec-source-path}"
|
|
204
|
+
# macOS/Linux
|
|
205
|
+
ln -s "{spec-source-path}" specs
|
|
212
206
|
```
|
|
207
|
+
Then append `specs/` to `.gitignore` — a junction/symlink's contents belong to the spec repo,
|
|
208
|
+
not this one, and must not be tracked or committed here.
|
|
213
209
|
|
|
214
|
-
|
|
215
|
-
|
|
210
|
+
If the Q1 lookup didn't already happen (i.e. `specs/` was just created above, not already
|
|
211
|
+
present in Step 1), read `{spec_submodule_path}/.forge/project.json` now and find the
|
|
212
|
+
`modules[]` entry where `name` matches the module name from Q1. Use its `port`, `stack`, and
|
|
213
|
+
`submodules[]` (if any) to fill the CLAUDE.md content below. If the module still isn't found
|
|
214
|
+
there, write "TBD — set via `/forge-config` in the spec repo" for the stack/port line instead.
|
|
215
|
+
|
|
216
|
+
Write `.forge/module.json` — same shape whether or not the module has submodules in the spec
|
|
217
|
+
repo, since submodule structure is never duplicated here:
|
|
216
218
|
```json
|
|
217
219
|
{
|
|
218
220
|
"module": "{module-name}",
|
|
219
221
|
"spec_submodule_path": "specs",
|
|
220
|
-
"
|
|
221
|
-
"submodules": [
|
|
222
|
-
{
|
|
223
|
-
"name": "{sub-name}",
|
|
224
|
-
"path": "{relative-path}",
|
|
225
|
-
"test_base_url": "http://localhost:{port}",
|
|
226
|
-
"contract_glob": "specs/contracts/{sub-name}/*.yaml"
|
|
227
|
-
}
|
|
228
|
-
]
|
|
222
|
+
"spec_link_type": "submodule"
|
|
229
223
|
}
|
|
230
224
|
```
|
|
225
|
+
`spec_link_type` is `"submodule"` (default) or `"junction"`. When `"junction"`, also write
|
|
226
|
+
`"spec_source_path": "{absolute-local-path}"` so the link can be recreated if it's ever lost.
|
|
231
227
|
|
|
232
|
-
Write `CLAUDE.md
|
|
228
|
+
Write `CLAUDE.md`. `{stack}`/`{port}`/`{path}` below come from the spec repo's `project.json`
|
|
229
|
+
lookup above (or "TBD" if not found there yet) — never from a question asked in this skill:
|
|
233
230
|
```markdown
|
|
234
231
|
# {module-name}
|
|
235
232
|
|
|
236
233
|
{description}
|
|
237
234
|
|
|
238
|
-
_(Single app: show Stack + Port inline. Monorepo: replace with a table
|
|
235
|
+
_(Single app: show Stack + Port inline. Monorepo: replace with a table, one row per submodule
|
|
236
|
+
found in the spec repo's project.json.)_
|
|
239
237
|
|
|
240
238
|
**Stack:** {stack} **Port:** {port}
|
|
241
239
|
|
|
@@ -253,9 +251,15 @@ _(Single app: show Stack + Port inline. Monorepo: replace with a table.)_
|
|
|
253
251
|
5. (then in the spec repo) `/forge-close {slug} {module}` — mark tasks done there
|
|
254
252
|
|
|
255
253
|
## Spec repo
|
|
256
|
-
Linked via git submodule at `specs/`.
|
|
254
|
+
_(submodule)_ Linked via git submodule at `specs/`.
|
|
257
255
|
Run `git submodule update --remote specs` before starting a new feature,
|
|
258
256
|
and again after `/forge-close` is run in the spec repo to sync task status.
|
|
257
|
+
|
|
258
|
+
_(junction)_ Linked via local junction/symlink at `specs/` → `{spec-source-path}`.
|
|
259
|
+
Always reflects the live spec repo folder — no sync command needed. This only works while
|
|
260
|
+
both repos are on the same machine; switch to a git submodule (`/forge-init` again, or
|
|
261
|
+
re-run link setup) before cloning this repo elsewhere or using it in CI.
|
|
262
|
+
|
|
259
263
|
Project-wide domain context (actors, glossary, principles) lives at `specs/CONTEXT.md`
|
|
260
264
|
— read it before implementing.
|
|
261
265
|
|
|
@@ -304,6 +308,9 @@ Run `git status` and confirm:
|
|
|
304
308
|
- Never overwrite existing files
|
|
305
309
|
- All written files must be complete — no unfilled placeholders
|
|
306
310
|
- `module` in module.json must exactly match the name in the spec repo's project.json
|
|
311
|
+
- `module.json` never stores `port`, `stack`, or submodule structure — those live only in the
|
|
312
|
+
spec repo's `project.json`; every module skill resolves them at runtime by reading
|
|
313
|
+
`specs/.forge/project.json`
|
|
307
314
|
- **Extract, don't re-ask**: if the user's answer contains information for upcoming fields
|
|
308
315
|
(e.g. "it's a NestJS app on port 3000 at apps/auth-ui"), extract and fill those fields
|
|
309
316
|
silently — only ask about what is genuinely missing. Never ask a question the user has
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: "forge-tasks"
|
|
3
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
4
|
argument-hint: ""
|
|
5
|
-
compatibility: "Requires module repo with .forge/module.json and an initialized specs/ git submodule"
|
|
5
|
+
compatibility: "Requires module repo with .forge/module.json and an initialized specs/ link (git submodule or junction)"
|
|
6
6
|
metadata:
|
|
7
7
|
author: "forge-workflow"
|
|
8
8
|
source: "module-skills/forge-tasks/SKILL.md"
|
|
@@ -15,16 +15,23 @@ disable-model-invocation: true
|
|
|
15
15
|
Show all tasks assigned to this module across all features.
|
|
16
16
|
|
|
17
17
|
## Pre-check
|
|
18
|
-
- Read `.forge/module.json` for `module` and `
|
|
18
|
+
- Read `.forge/module.json` for `module`, `spec_submodule_path`, and `spec_link_type`.
|
|
19
19
|
If missing: "Run `/forge-init` to set up this module repo first."
|
|
20
|
-
- If `
|
|
21
|
-
-
|
|
20
|
+
- If `spec_link_type` is `"submodule"` (or unset, for repos initialized before this field existed):
|
|
21
|
+
- If `specs/` is not initialized: suggest `git submodule update --init --recursive`
|
|
22
|
+
- Optionally suggest `git submodule update --remote specs` to get the latest task status.
|
|
23
|
+
- If `spec_link_type` is `"junction"`:
|
|
24
|
+
- If `specs/` is missing or broken, suggest recreating the link at `spec_source_path`
|
|
25
|
+
(Windows: `mklink /J specs "{spec_source_path}"`; macOS/Linux: `ln -s "{spec_source_path}" specs`).
|
|
26
|
+
- No sync command needed — a junction/symlink always reflects the live folder.
|
|
22
27
|
|
|
23
28
|
## Steps
|
|
24
29
|
|
|
25
|
-
Determine the set of task headings to look for
|
|
26
|
-
|
|
27
|
-
|
|
30
|
+
Determine the set of task headings to look for. Read `{spec_submodule_path}/.forge/project.json`
|
|
31
|
+
and find the `modules[]` entry where `name == module` (from module.json) — submodule structure
|
|
32
|
+
is never stored in module.json itself:
|
|
33
|
+
- Entry has no `submodules[]` → look for `### {module}` (one heading).
|
|
34
|
+
- Entry has `submodules[]` → look for `### {submodule.name}` for each entry.
|
|
28
35
|
Submodule task headings use the submodule's own name — no parent prefix — so they are
|
|
29
36
|
identical to standalone module headings and can be promoted without touching tasks.md.
|
|
30
37
|
|
|
@@ -65,7 +72,8 @@ Feature: user-registration [Open]
|
|
|
65
72
|
```
|
|
66
73
|
|
|
67
74
|
If no tasks reference this module across any feature:
|
|
68
|
-
> "No tasks found for `{module}`. Either no feature targets this module yet,
|
|
69
|
-
> submodule is out of date — try `git submodule update --remote specs`.
|
|
75
|
+
> "No tasks found for `{module}`. Either no feature targets this module yet, {if submodule}
|
|
76
|
+
> or the specs submodule is out of date — try `git submodule update --remote specs`.
|
|
77
|
+
> {if junction} or the linked spec folder doesn't have it yet."
|
|
70
78
|
|
|
71
79
|
After showing: "Tell me which feature to implement, or run `/forge-implement {slug}`."
|