@khanhspring/forge-spec 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 +33 -0
- package/forge-brainstorm/SKILL.md +332 -0
- package/forge-close/SKILL.md +129 -0
- package/forge-config/SKILL.md +113 -0
- package/forge-contract/SKILL.md +221 -0
- package/forge-contract/reference/best-practices.md +223 -0
- package/forge-contract/reference/contract-template.yaml +282 -0
- package/forge-init/SKILL.md +205 -0
- package/forge-spec/SKILL.md +279 -0
- package/forge-status/SKILL.md +55 -0
- package/forge-tasks/SKILL.md +79 -0
- package/package.json +22 -0
package/bin/install.js
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
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-brainstorm',
|
|
14
|
+
'forge-close',
|
|
15
|
+
'forge-config',
|
|
16
|
+
'forge-contract',
|
|
17
|
+
'forge-init',
|
|
18
|
+
'forge-spec',
|
|
19
|
+
'forge-status',
|
|
20
|
+
'forge-tasks',
|
|
21
|
+
];
|
|
22
|
+
|
|
23
|
+
console.log('Installing @forge-workflow/spec skills...\n');
|
|
24
|
+
|
|
25
|
+
mkdirSync(SKILLS_DIR, { recursive: true });
|
|
26
|
+
|
|
27
|
+
for (const skill of SKILLS) {
|
|
28
|
+
cpSync(join(ROOT, skill), join(SKILLS_DIR, skill), { recursive: true, force: true });
|
|
29
|
+
console.log(` ✓ ${skill}`);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log(`\nInstalled to ${SKILLS_DIR}`);
|
|
33
|
+
console.log('Restart Claude Code, then run /forge-init in your spec repo.');
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "forge-brainstorm"
|
|
3
|
+
description: "Phase 1 of 4. Interrogates a feature idea through structured questioning, a challenge round, and 2–3 design approaches before writing a gated summary. Proactively researches existing context and surfaces research-blocked items before writing the spec."
|
|
4
|
+
argument-hint: "Feature idea to brainstorm (e.g. 'user notifications')"
|
|
5
|
+
compatibility: "Requires spec repo with .forge/project.json"
|
|
6
|
+
metadata:
|
|
7
|
+
author: "forge-workflow"
|
|
8
|
+
source: "spec-skills/forge-brainstorm/SKILL.md"
|
|
9
|
+
user-invocable: true
|
|
10
|
+
disable-model-invocation: true
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Forge Brainstorm
|
|
14
|
+
|
|
15
|
+
Phase 1 of 4. Your job is to fully understand a feature before any spec is written.
|
|
16
|
+
The goal is zero ambiguity — every concern surfaced, every edge case accounted for,
|
|
17
|
+
every unknown either resolved or explicitly accepted as an assumption.
|
|
18
|
+
|
|
19
|
+
<HARD-GATE>
|
|
20
|
+
Do NOT generate a spec, break down tasks, or write any contracts in this phase.
|
|
21
|
+
The ONLY file this skill writes is `features/{slug}/brainstorm.md`, and only AFTER
|
|
22
|
+
the user has explicitly approved the Brainstorm Summary at the gate (Step 7).
|
|
23
|
+
"Simple" features are where unexamined assumptions cause the most wasted work — no feature
|
|
24
|
+
skips this phase.
|
|
25
|
+
</HARD-GATE>
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## Step 1 — Load & Research Context
|
|
30
|
+
|
|
31
|
+
Before asking the user anything, research the existing codebase silently:
|
|
32
|
+
|
|
33
|
+
1. Read `.forge/project.json` — note module names, types, stacks, ports.
|
|
34
|
+
2. Scan `features/*/spec.md` — are there related or similar features already specced?
|
|
35
|
+
Note any patterns, naming conventions, or prior decisions relevant to this idea.
|
|
36
|
+
3. Scan `contracts/*/` — are there existing API contracts this feature will touch or extend?
|
|
37
|
+
Note existing endpoint shapes, error formats, auth patterns.
|
|
38
|
+
4. Read `CLAUDE.md` — note project principles, conventions, and forbidden patterns
|
|
39
|
+
that will constrain design choices.
|
|
40
|
+
|
|
41
|
+
Report your findings before starting questions:
|
|
42
|
+
|
|
43
|
+
> "Before we dive in, here's what I found in the codebase:
|
|
44
|
+
> - [relevant existing feature or contract, or "No related features found"]
|
|
45
|
+
> - [relevant principle from CLAUDE.md, or "No constraints found"]
|
|
46
|
+
>
|
|
47
|
+
> I'll use this as context. Here's my understanding of the feature: {1–2 sentence restatement}
|
|
48
|
+
> Is that right?"
|
|
49
|
+
|
|
50
|
+
Then check scope:
|
|
51
|
+
|
|
52
|
+
> If the idea spans multiple unrelated concerns: "This sounds like 2–3 separate features.
|
|
53
|
+
> Shall we split and brainstorm each one, or treat it as a single feature?"
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## Step 2 — Mandatory questions (one at a time)
|
|
58
|
+
|
|
59
|
+
These MUST all be answered before moving to Step 4. Ask one at a time.
|
|
60
|
+
Skip any sub-question already answered by your research in Step 1.
|
|
61
|
+
|
|
62
|
+
**If a question hits an unknown** — something the user can't answer without researching —
|
|
63
|
+
use the Research Flag pattern (see Research Handling below).
|
|
64
|
+
|
|
65
|
+
**1. Problem & users**
|
|
66
|
+
- What specific pain does this solve?
|
|
67
|
+
- Who experiences it, and how often?
|
|
68
|
+
- What happens today without this feature?
|
|
69
|
+
|
|
70
|
+
**2. Actors & permissions**
|
|
71
|
+
- Who are the actors? (end user / admin / system / external service)
|
|
72
|
+
- Does each actor have different access levels or see different data?
|
|
73
|
+
- Is any part restricted by role or ownership? (e.g. "users can only edit their own records")
|
|
74
|
+
|
|
75
|
+
**3. Happy path**
|
|
76
|
+
- Walk through the exact steps from trigger to completion.
|
|
77
|
+
- What does the user see/receive at the end?
|
|
78
|
+
|
|
79
|
+
**4. Data & state**
|
|
80
|
+
- What data is created, read, updated, or deleted?
|
|
81
|
+
- What persists after the action completes?
|
|
82
|
+
- Is any of this shared with or derived from other modules?
|
|
83
|
+
|
|
84
|
+
**5. Failure cases** — ask explicitly about each:
|
|
85
|
+
- Invalid or missing input → what happens?
|
|
86
|
+
- The same request submitted twice (idempotency)?
|
|
87
|
+
- A downstream service or dependency is unavailable?
|
|
88
|
+
- The user doesn't have permission?
|
|
89
|
+
- Partial failure mid-flow — is rollback needed?
|
|
90
|
+
|
|
91
|
+
**6. Modules & APIs**
|
|
92
|
+
- Which modules are involved?
|
|
93
|
+
- Does this extend existing APIs or is it net-new?
|
|
94
|
+
- Does anything need to be deprecated or changed?
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## Step 3 — Conditional questions (ask if not already answered)
|
|
99
|
+
|
|
100
|
+
- **Integrations** — emails, push notifications, webhooks, third-party APIs?
|
|
101
|
+
- **Async / background work** — any deferred or eventually consistent parts?
|
|
102
|
+
- **Scale & performance** — volume expectations or SLA requirements?
|
|
103
|
+
- **Consistency** — similar existing feature to follow for patterns?
|
|
104
|
+
|
|
105
|
+
Skip any that are clearly irrelevant.
|
|
106
|
+
|
|
107
|
+
---
|
|
108
|
+
|
|
109
|
+
## Research Handling
|
|
110
|
+
|
|
111
|
+
Use this pattern whenever a question surfaces something that cannot be answered
|
|
112
|
+
through discussion alone.
|
|
113
|
+
|
|
114
|
+
### When the user doesn't know the answer
|
|
115
|
+
|
|
116
|
+
> "🔍 **Research needed:** {what needs to be found out}
|
|
117
|
+
>
|
|
118
|
+
> To answer this, you'd need to: {specific action — e.g. 'check if Stripe supports partial
|
|
119
|
+
> refunds in your plan', 'ask the product team what the UX should be', 'look at how
|
|
120
|
+
> user-service currently handles token expiry'}
|
|
121
|
+
>
|
|
122
|
+
> How do you want to proceed?
|
|
123
|
+
> **(a) Pause here** — I'll give you a research checklist and we resume when you have answers
|
|
124
|
+
> **(b) Proceed with an assumption** — I'll state an explicit assumption and flag it for validation
|
|
125
|
+
> **(c) Keep going** — we'll leave this as an open question and resolve it before writing the spec"
|
|
126
|
+
|
|
127
|
+
### When Claude can research it
|
|
128
|
+
|
|
129
|
+
If the answer can be found by reading existing files in the repo:
|
|
130
|
+
|
|
131
|
+
> "🔍 Let me check the existing codebase for this — one moment."
|
|
132
|
+
|
|
133
|
+
Read the relevant file(s), then report what you found and whether it resolves the question.
|
|
134
|
+
|
|
135
|
+
### Research pause
|
|
136
|
+
|
|
137
|
+
If the user chooses **(a) Pause**:
|
|
138
|
+
|
|
139
|
+
Output a research checklist:
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
⏸ Brainstorm paused — research needed before continuing.
|
|
143
|
+
|
|
144
|
+
Research checklist:
|
|
145
|
+
□ {item 1} — {where to look / who to ask}
|
|
146
|
+
□ {item 2} — {where to look / who to ask}
|
|
147
|
+
|
|
148
|
+
Resume by coming back and saying: "forge-brainstorm {slug} — resuming with answers:
|
|
149
|
+
- {item 1}: [your answer]
|
|
150
|
+
- {item 2}: [your answer]"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Stop here. Do not continue the brainstorm until the user resumes with answers.
|
|
154
|
+
|
|
155
|
+
### Proceed with assumption
|
|
156
|
+
|
|
157
|
+
If the user chooses **(b) Assumption**:
|
|
158
|
+
|
|
159
|
+
State it explicitly and add it to the Assumptions section in the summary:
|
|
160
|
+
|
|
161
|
+
> "✅ Assumption recorded: {clear statement of what we're assuming}
|
|
162
|
+
> This will need validation before or during implementation."
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
166
|
+
## Step 4 — Challenge round
|
|
167
|
+
|
|
168
|
+
Actively probe for hidden problems. Raise at least 2 concerns specific to the answers given:
|
|
169
|
+
|
|
170
|
+
> "Before I propose approaches, I want to flag a couple of things:
|
|
171
|
+
>
|
|
172
|
+
> **[Concern 1]:** {specific concern from the conversation}
|
|
173
|
+
>
|
|
174
|
+
> **[Concern 2]:** {specific concern from the conversation}
|
|
175
|
+
>
|
|
176
|
+
> How should these be handled?"
|
|
177
|
+
|
|
178
|
+
Wait for resolution before moving on. If a concern can't be resolved without research,
|
|
179
|
+
apply the Research Handling pattern.
|
|
180
|
+
|
|
181
|
+
---
|
|
182
|
+
|
|
183
|
+
## Step 5 — Propose approaches
|
|
184
|
+
|
|
185
|
+
Propose **2–3 design approaches** with trade-offs. Base them on the researched context
|
|
186
|
+
from Step 1 — flag if an approach conflicts with existing patterns or CLAUDE.md principles.
|
|
187
|
+
|
|
188
|
+
```
|
|
189
|
+
I see 2–3 ways to approach this:
|
|
190
|
+
|
|
191
|
+
**Option A (Recommended): {name}**
|
|
192
|
+
{1–2 sentences}
|
|
193
|
+
✓ {pro} ✗ {con}
|
|
194
|
+
{note if consistent/inconsistent with existing patterns}
|
|
195
|
+
|
|
196
|
+
**Option B: {name}**
|
|
197
|
+
{1–2 sentences}
|
|
198
|
+
✓ {pro} ✗ {con}
|
|
199
|
+
|
|
200
|
+
**Option C: {name}** (if relevant)
|
|
201
|
+
{1–2 sentences}
|
|
202
|
+
✓ {pro} ✗ {con}
|
|
203
|
+
|
|
204
|
+
I'd go with Option A because {reason}. What do you think?
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
After the user picks, ask one follow-up:
|
|
208
|
+
> "What's the main risk you see with this approach? Anything that makes you hesitant?"
|
|
209
|
+
|
|
210
|
+
Resolve concerns before moving on.
|
|
211
|
+
|
|
212
|
+
---
|
|
213
|
+
|
|
214
|
+
## Step 6 — Synthesize
|
|
215
|
+
|
|
216
|
+
Write the brainstorm summary in the conversation (no file):
|
|
217
|
+
|
|
218
|
+
```
|
|
219
|
+
## Brainstorm Summary: {Feature Name}
|
|
220
|
+
**Slug:** {kebab-case-slug}
|
|
221
|
+
**Approach:** {chosen option name}
|
|
222
|
+
|
|
223
|
+
### Problem
|
|
224
|
+
{1–2 sentences}
|
|
225
|
+
|
|
226
|
+
### Actors & Permissions
|
|
227
|
+
- **{Role}**: {what they do and what they can access}
|
|
228
|
+
|
|
229
|
+
### Happy Path
|
|
230
|
+
1. {step}
|
|
231
|
+
2. {step}
|
|
232
|
+
|
|
233
|
+
### Data & State
|
|
234
|
+
- {what is created/read/updated/deleted}
|
|
235
|
+
- {what persists and where}
|
|
236
|
+
|
|
237
|
+
### Edge Cases & Failures
|
|
238
|
+
- **{case}**: {handling}
|
|
239
|
+
|
|
240
|
+
### Constraints
|
|
241
|
+
- {constraint — or "None identified"}
|
|
242
|
+
|
|
243
|
+
### Modules Involved
|
|
244
|
+
- **{module-name}** ({type}): {responsibility in this feature}
|
|
245
|
+
|
|
246
|
+
### Out of Scope
|
|
247
|
+
- {explicitly excluded items}
|
|
248
|
+
|
|
249
|
+
### Assumptions
|
|
250
|
+
- {assumption}: {what it means if this is wrong}
|
|
251
|
+
- (empty if no assumptions were made)
|
|
252
|
+
|
|
253
|
+
### Research Needed
|
|
254
|
+
- {item}: {what to check and where}
|
|
255
|
+
- (empty if nothing is pending)
|
|
256
|
+
|
|
257
|
+
### Open Questions
|
|
258
|
+
- {unresolved concern — must be empty or moved to Research Needed before spec is written}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
**Self-review before presenting:**
|
|
262
|
+
- Any requirement readable two ways → pick one interpretation, state it explicitly
|
|
263
|
+
- Any happy path step with no failure case → add it
|
|
264
|
+
- Any "nice to have" → move to Out of Scope
|
|
265
|
+
- Any contradiction between sections → resolve it
|
|
266
|
+
- Anything in Open Questions that's actually a research item → move it to Research Needed
|
|
267
|
+
- Open Questions not truly empty → do not write "None"
|
|
268
|
+
|
|
269
|
+
Do not mention the self-review to the user.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Step 7 — Gate
|
|
274
|
+
|
|
275
|
+
Check all three blocking sections before accepting "yes":
|
|
276
|
+
|
|
277
|
+
**If Open Questions is not empty:**
|
|
278
|
+
> "Let's resolve these before writing the spec:
|
|
279
|
+
> - {question}
|
|
280
|
+
> How would you handle each?"
|
|
281
|
+
Do NOT proceed until resolved.
|
|
282
|
+
|
|
283
|
+
**If Research Needed is not empty:**
|
|
284
|
+
> "There are items that need research before the spec can be finalized:
|
|
285
|
+
> - {item}: {where to look}
|
|
286
|
+
>
|
|
287
|
+
> Do you want to:
|
|
288
|
+
> **(a) Pause and research first** — I'll give you the checklist
|
|
289
|
+
> **(b) Proceed and treat these as assumptions** — I'll add them to the spec as risks to validate"
|
|
290
|
+
|
|
291
|
+
Wait for the user's choice. If (a), output the research checklist and stop.
|
|
292
|
+
If (b), convert each item to an explicit assumption in the summary.
|
|
293
|
+
|
|
294
|
+
**If Assumptions is not empty, warn:**
|
|
295
|
+
> "Note: this spec will include {n} assumption(s) that need validation:
|
|
296
|
+
> - {assumption}: {risk if wrong}"
|
|
297
|
+
|
|
298
|
+
**Once all three sections are resolved or accepted:**
|
|
299
|
+
> "Does this capture the feature correctly? Clarify anything above, or say **yes** to save it and move to the spec."
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Step 8 — Persist the summary (after approval only)
|
|
304
|
+
|
|
305
|
+
Once the user says **yes**, write the approved summary to `features/{slug}/brainstorm.md`
|
|
306
|
+
so it survives across sessions and forge-spec can pick it up later.
|
|
307
|
+
|
|
308
|
+
```markdown
|
|
309
|
+
# Brainstorm: {Feature Name}
|
|
310
|
+
|
|
311
|
+
**Slug:** {slug}
|
|
312
|
+
**Approach:** {chosen option name}
|
|
313
|
+
**Captured:** {YYYY-MM-DD}
|
|
314
|
+
|
|
315
|
+
{the full Brainstorm Summary body from Step 6 — all sections}
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
Then hand off:
|
|
319
|
+
> "Saved to `features/{slug}/brainstorm.md`. Run `/forge-spec {slug}` to write the spec."
|
|
320
|
+
|
|
321
|
+
---
|
|
322
|
+
|
|
323
|
+
## Rules
|
|
324
|
+
- One question per message — never list multiple at once
|
|
325
|
+
- Prefer multiple-choice when options are predictable
|
|
326
|
+
- Never skip Step 2 mandatory areas — even for "simple" features
|
|
327
|
+
- Never skip the challenge round (Step 4)
|
|
328
|
+
- Never skip the approaches step (Step 5)
|
|
329
|
+
- YAGNI: move anything non-core to Out of Scope
|
|
330
|
+
- The ONLY file written is `features/{slug}/brainstorm.md`, and only after approval (Step 8)
|
|
331
|
+
- Do NOT skip Step 1 research — always check existing context first
|
|
332
|
+
- Do NOT ask questions that could be answered by reading the existing codebase
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "forge-close"
|
|
3
|
+
description: "Marks a module's tasks as done in features/{slug}/tasks.md, generates the spec repo commit message, and checks whether all modules have completed — closing the feature if so."
|
|
4
|
+
argument-hint: "Feature slug and module name (e.g. 'user-registration user-service')"
|
|
5
|
+
compatibility: "Requires spec repo with .forge/project.json and features/{slug}/tasks.md"
|
|
6
|
+
metadata:
|
|
7
|
+
author: "forge-workflow"
|
|
8
|
+
source: "spec-skills/forge-close/SKILL.md"
|
|
9
|
+
user-invocable: true
|
|
10
|
+
disable-model-invocation: true
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Forge Close — Spec Repo
|
|
14
|
+
|
|
15
|
+
Mark a module's implementation tasks as done in the spec repo.
|
|
16
|
+
Run this after `/forge-done` in the module repo.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Pre-check
|
|
21
|
+
|
|
22
|
+
- Read `.forge/project.json` — get module list.
|
|
23
|
+
If missing: "Run `/forge-init` to set up this spec repo first."
|
|
24
|
+
- Parse $ARGUMENTS:
|
|
25
|
+
- First word → feature slug
|
|
26
|
+
- Second word → module name
|
|
27
|
+
- If slug missing → ask: "Which feature are you closing?"
|
|
28
|
+
- If module missing → ask: "Which module are you marking as done?
|
|
29
|
+
_(Available modules: {list from project.json})_"
|
|
30
|
+
- Read `features/{slug}/tasks.md` — must exist.
|
|
31
|
+
If missing: "No tasks file found. Run `/forge-tasks {slug}` first."
|
|
32
|
+
- Validate module name exists in `### {module}` section of tasks.md.
|
|
33
|
+
If not found: "No tasks for `{module}` in `{slug}`. Check the module name matches exactly."
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Step 1 — Show current task state
|
|
38
|
+
|
|
39
|
+
Display the module's current tasks:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
43
|
+
Closing: {module} / {feature-slug}
|
|
44
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
45
|
+
- [ ] TASK-1 [api] POST /users/register endpoint
|
|
46
|
+
- [ ] TASK-2 [feat] Password hashing + validation
|
|
47
|
+
- [x] TASK-3 [test] Unit tests for UserService
|
|
48
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
If all tasks are already ticked:
|
|
52
|
+
> "All tasks for `{module}` are already marked done. Nothing to update."
|
|
53
|
+
Check overall feature status (Step 3) and stop.
|
|
54
|
+
|
|
55
|
+
Otherwise ask:
|
|
56
|
+
> "Mark all {n} tasks for `{module}` as done? Say **yes** to update, or tell me which ones to skip."
|
|
57
|
+
|
|
58
|
+
Wait for confirmation before writing.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Step 2 — Update tasks.md
|
|
63
|
+
|
|
64
|
+
In `features/{slug}/tasks.md`, tick all confirmed tasks under `### {module}`:
|
|
65
|
+
- Change `- [ ]` → `- [x]` for each confirmed task
|
|
66
|
+
- Leave any explicitly skipped tasks untouched
|
|
67
|
+
- Update the `**Last updated:**` date at the top of the file to today
|
|
68
|
+
|
|
69
|
+
Show a diff summary:
|
|
70
|
+
```
|
|
71
|
+
Updated features/{slug}/tasks.md:
|
|
72
|
+
- [x] TASK-1 [api] POST /users/register endpoint ← ticked
|
|
73
|
+
- [x] TASK-2 [feat] Password hashing + validation ← ticked
|
|
74
|
+
- [x] TASK-3 [test] Unit tests for UserService (was already done)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## Step 3 — Check overall feature completion
|
|
80
|
+
|
|
81
|
+
Scan ALL `### {module}` sections in `tasks.md`.
|
|
82
|
+
Count ticked vs unticked tasks per module:
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
86
|
+
Feature progress: {feature-slug}
|
|
87
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
88
|
+
- [x] user-service — 3/3 tasks done
|
|
89
|
+
- [ ] web-app — 0/2 tasks done
|
|
90
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**If all modules are complete:**
|
|
94
|
+
Update `features/{slug}/tasks.md` header status to `Done`
|
|
95
|
+
and `features/{slug}/spec.md` header status to `Done`.
|
|
96
|
+
|
|
97
|
+
> "🎉 All modules done — feature `{slug}` is complete."
|
|
98
|
+
|
|
99
|
+
**If modules still remain:**
|
|
100
|
+
|
|
101
|
+
List what's left:
|
|
102
|
+
> "{module} still has {n} task(s) remaining.
|
|
103
|
+
> Once they run `/forge-done {slug}` in their module repo,
|
|
104
|
+
> they can run `/forge-close {slug} {module}` here to close out."
|
|
105
|
+
|
|
106
|
+
---
|
|
107
|
+
|
|
108
|
+
## Step 4 — Generate commit message
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
112
|
+
Commit message
|
|
113
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
114
|
+
chore(tasks): mark {module} done for {feature-slug}
|
|
115
|
+
|
|
116
|
+
Completed tasks:
|
|
117
|
+
- TASK-1: {title}
|
|
118
|
+
- TASK-2: {title}
|
|
119
|
+
- TASK-3: {title}
|
|
120
|
+
|
|
121
|
+
{if all modules done}
|
|
122
|
+
Feature {feature-slug} fully implemented across all modules.
|
|
123
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Then remind:
|
|
127
|
+
> "After committing and pushing, module repos should run:
|
|
128
|
+
> `git submodule update --remote specs`
|
|
129
|
+
> to sync the updated task status."
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: "forge-config"
|
|
3
|
+
description: "View and interactively update .forge/project.json: add or remove modules, update ports, change stack info, or update the spec repo URL. Asks one question at a time and previews changes before writing."
|
|
4
|
+
argument-hint: "Optional hint: 'add module', 'update user-service port', 'remove web-app'"
|
|
5
|
+
compatibility: "Requires spec repo with .forge/project.json"
|
|
6
|
+
metadata:
|
|
7
|
+
author: "forge-workflow"
|
|
8
|
+
source: "spec-skills/forge-config/SKILL.md"
|
|
9
|
+
user-invocable: true
|
|
10
|
+
disable-model-invocation: true
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Forge Config
|
|
14
|
+
|
|
15
|
+
View and update the project configuration at `.forge/project.json`.
|
|
16
|
+
|
|
17
|
+
## Step 1 — Load & display
|
|
18
|
+
|
|
19
|
+
Read `.forge/project.json`.
|
|
20
|
+
If missing: "No project config found. Run `/forge-init` to set up this repo first."
|
|
21
|
+
|
|
22
|
+
Display the current config:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
Project: {project-name}
|
|
26
|
+
Spec repo: {spec_repo}
|
|
27
|
+
Contract tool: {contract_tool}
|
|
28
|
+
|
|
29
|
+
Modules ({n}):
|
|
30
|
+
· user-service backend Spring Boot 3, Java 21 :8081
|
|
31
|
+
· web-app frontend React, TypeScript :3000
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## Step 2 — Determine the change
|
|
35
|
+
|
|
36
|
+
From $ARGUMENTS, infer the intent if given (e.g. "add module", "update user-service port").
|
|
37
|
+
If empty, ask: "What do you want to change? (add a module / remove a module / update a field / change spec repo URL)"
|
|
38
|
+
|
|
39
|
+
## Step 3 — Collect details (one question at a time)
|
|
40
|
+
|
|
41
|
+
Ask one question per message — never batch.
|
|
42
|
+
|
|
43
|
+
**Adding a module** — ask in order, one at a time:
|
|
44
|
+
1. "Module name? (kebab-case, must be unique)"
|
|
45
|
+
2. "Type? (backend / frontend / worker / gateway)"
|
|
46
|
+
3. "Tech stack? (e.g. 'Spring Boot 3, Java 21')"
|
|
47
|
+
4. "Local dev port?"
|
|
48
|
+
5. "Git repo URL? (or 'none')"
|
|
49
|
+
6. "One-sentence description? (or 'none')"
|
|
50
|
+
|
|
51
|
+
**Removing a module:**
|
|
52
|
+
- Check whether any `features/*/tasks.md` has a `### {module}` section.
|
|
53
|
+
If so, warn: "`{module}` has tasks in {feature(s)}. Removing it from config won't delete those tasks. Remove anyway? (yes/no)"
|
|
54
|
+
- Otherwise confirm: "Remove `{module}` from the project? (yes/no)"
|
|
55
|
+
|
|
56
|
+
**Updating a field:**
|
|
57
|
+
- Show the current value, then ask for the new one:
|
|
58
|
+
"`{module}.{field}` is currently `{old}`. What should it be?"
|
|
59
|
+
|
|
60
|
+
**Changing spec repo URL:**
|
|
61
|
+
- "Current spec_repo is `{old}`. New URL?"
|
|
62
|
+
|
|
63
|
+
## Step 4 — Preview & gate
|
|
64
|
+
|
|
65
|
+
Show the before/after of exactly what will change:
|
|
66
|
+
|
|
67
|
+
```
|
|
68
|
+
Change preview:
|
|
69
|
+
modules[user-service].port: 8081 → 8090
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
> "Apply this change to `.forge/project.json`? Say **yes** to write, or tell me what to adjust."
|
|
73
|
+
|
|
74
|
+
Wait for confirmation. Do not write before the user says yes.
|
|
75
|
+
|
|
76
|
+
## Step 5 — Write & confirm
|
|
77
|
+
|
|
78
|
+
Apply the change, preserving all other fields and formatting.
|
|
79
|
+
Confirm: "Updated `.forge/project.json` — {summary of what changed}."
|
|
80
|
+
|
|
81
|
+
If a module name changed, warn:
|
|
82
|
+
> "Heads up: `{module}` is referenced by the module repo's `.forge/module.json` and by
|
|
83
|
+
> `### {module}` headings in tasks.md. Update those to match, or `/forge-implement` and
|
|
84
|
+
> `/forge-close` will break."
|
|
85
|
+
|
|
86
|
+
## Schema Reference
|
|
87
|
+
|
|
88
|
+
```jsonc
|
|
89
|
+
{
|
|
90
|
+
"project": "my-project", // short slug, no spaces
|
|
91
|
+
"version": "1.0",
|
|
92
|
+
"modules": [
|
|
93
|
+
{
|
|
94
|
+
"name": "user-service", // kebab-case, matches module.json in module repos
|
|
95
|
+
"repo": "git@github.com:org/user-service.git",
|
|
96
|
+
"type": "backend", // backend | frontend | worker | gateway
|
|
97
|
+
"stack": ["Spring Boot 3", "Java 21"],
|
|
98
|
+
"port": 8081,
|
|
99
|
+
"description": "" // optional, one sentence
|
|
100
|
+
}
|
|
101
|
+
],
|
|
102
|
+
"spec_repo": "git@github.com:org/specs.git",
|
|
103
|
+
"contract_format": "openapi3",
|
|
104
|
+
"contract_tool": "specmatic"
|
|
105
|
+
}
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Rules
|
|
109
|
+
- One question per message — never batch
|
|
110
|
+
- Never write before the user confirms the preview in Step 4
|
|
111
|
+
- `module.name` must be kebab-case and unique
|
|
112
|
+
- `module.name` must match the `module` field in the module repo's `.forge/module.json`
|
|
113
|
+
- Never silently remove a module that has tasks referencing it — warn first
|