@speclife/cli 0.9.0 → 0.9.1
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 +1 -1
- package/templates/commands/convert.md +22 -159
- package/templates/commands/land.md +20 -241
- package/templates/commands/release.md +19 -114
- package/templates/commands/retrofit.md +21 -303
- package/templates/commands/setup.md +20 -292
- package/templates/commands/ship.md +17 -162
- package/templates/commands/start.md +17 -269
- package/templates/commands/sync.md +16 -164
|
@@ -2,307 +2,25 @@
|
|
|
2
2
|
name: /speclife-retrofit
|
|
3
3
|
id: speclife-retrofit
|
|
4
4
|
category: SpecLife
|
|
5
|
-
description: Formalize ad-hoc changes on main into a
|
|
5
|
+
description: Formalize ad-hoc changes on main into a spec-tracked change for review.
|
|
6
6
|
---
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
## Goal
|
|
29
|
-
|
|
30
|
-
Convert ad-hoc changes on main into a proper spec-tracked workflow:
|
|
31
|
-
1. Document the change with a spec (proposal + tasks)
|
|
32
|
-
2. Move changes to a spec branch for review
|
|
33
|
-
3. Archive the spec
|
|
34
|
-
4. Create PR for approval before merging back
|
|
35
|
-
|
|
36
|
-
This bridges quick ad-hoc work with the spec-driven process.
|
|
37
|
-
|
|
38
|
-
## When to Use
|
|
39
|
-
|
|
40
|
-
- Made changes on main without going through `/speclife start`
|
|
41
|
-
- Want to properly document and review ad-hoc changes
|
|
42
|
-
- Need to create a release-worthy PR from untracked work
|
|
43
|
-
|
|
44
|
-
## Prerequisites
|
|
45
|
-
|
|
46
|
-
Must be on `main` branch with one of:
|
|
47
|
-
- Uncommitted changes (modified/staged files)
|
|
48
|
-
- Recent commits not yet pushed
|
|
49
|
-
|
|
50
|
-
```bash
|
|
51
|
-
# Validation
|
|
52
|
-
BRANCH=$(git branch --show-current)
|
|
53
|
-
[[ "$BRANCH" != "main" ]] && error "Must be on main branch"
|
|
54
|
-
|
|
55
|
-
# Check for changes
|
|
56
|
-
UNCOMMITTED=$(git status --porcelain)
|
|
57
|
-
UNPUSHED=$(git log origin/main..HEAD --oneline 2>/dev/null)
|
|
58
|
-
|
|
59
|
-
[[ -z "$UNCOMMITTED" && -z "$UNPUSHED" ]] && error "No changes to retrofit"
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
## Core Steps
|
|
63
|
-
|
|
64
|
-
### 1. Detect Changes
|
|
65
|
-
|
|
66
|
-
```bash
|
|
67
|
-
# Show what will be retrofitted
|
|
68
|
-
echo "Changes to retrofit:"
|
|
69
|
-
git status --short # Uncommitted changes
|
|
70
|
-
git log origin/main..HEAD --oneline # Unpushed commits (if any)
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### 2. Derive change-id
|
|
74
|
-
|
|
75
|
-
Convert description to kebab-case:
|
|
76
|
-
- "Update ship command to use two commits" → `update-ship-two-commits`
|
|
77
|
-
- Prefix with verb: add-, fix-, update-, remove-, refactor-
|
|
78
|
-
- Keep it short (3-5 words max)
|
|
79
|
-
|
|
80
|
-
```bash
|
|
81
|
-
CHANGE_ID=<derived-from-description>
|
|
82
|
-
SPEC_DIR="openspec/changes/${CHANGE_ID}"
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
### 3. Create Spec
|
|
86
|
-
|
|
87
|
-
Invoke `/openspec-proposal` with the description:
|
|
88
|
-
- Creates `openspec/changes/<change-id>/proposal.md`
|
|
89
|
-
- Creates `openspec/changes/<change-id>/tasks.md`
|
|
90
|
-
- Tasks should reflect what was ALREADY DONE (mark completed)
|
|
91
|
-
|
|
92
|
-
**Important:** The proposal documents what was implemented, not what needs to be done.
|
|
93
|
-
|
|
94
|
-
### 4. Validate Spec
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
openspec validate <change-id>
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
Fix any validation errors before proceeding.
|
|
101
|
-
|
|
102
|
-
### 5. Create Spec Branch
|
|
103
|
-
|
|
104
|
-
```bash
|
|
105
|
-
# Create and switch to spec branch (carries uncommitted changes)
|
|
106
|
-
git checkout -b spec/<change-id>
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
Note: Uncommitted changes automatically move to the new branch.
|
|
110
|
-
|
|
111
|
-
### 6. Commit Implementation + Spec
|
|
112
|
-
|
|
113
|
-
Read proposal.md for commit message, then:
|
|
114
|
-
|
|
115
|
-
```bash
|
|
116
|
-
git add -A
|
|
117
|
-
git commit -m "<type>: <description>"
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
This commit includes:
|
|
121
|
-
- The ad-hoc implementation changes
|
|
122
|
-
- The spec files (proposal.md, tasks.md)
|
|
123
|
-
|
|
124
|
-
### 7. Archive Spec
|
|
125
|
-
|
|
126
|
-
Run `/openspec-archive`:
|
|
127
|
-
- Moves spec to `openspec/changes/archive/<date>-<change-id>/`
|
|
128
|
-
- May require updating `project.md` (follow archive prompts)
|
|
129
|
-
|
|
130
|
-
### 8. Commit Archive
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
git add -A
|
|
134
|
-
git commit -m "chore: archive <change-id> spec"
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
### 9. Push and Create PR
|
|
138
|
-
|
|
139
|
-
```bash
|
|
140
|
-
git push -u origin spec/<change-id>
|
|
141
|
-
gh pr create --fill --base main
|
|
142
|
-
```
|
|
143
|
-
|
|
144
|
-
### 10. Reset Main (Safety)
|
|
145
|
-
|
|
146
|
-
After successful PR creation, main should be clean:
|
|
147
|
-
|
|
148
|
-
```bash
|
|
149
|
-
# Main is already clean because:
|
|
150
|
-
# - Uncommitted changes moved to spec branch
|
|
151
|
-
# - We're now on spec branch, not main
|
|
152
|
-
```
|
|
153
|
-
|
|
154
|
-
### 11. Report and STOP
|
|
155
|
-
|
|
156
|
-
```
|
|
157
|
-
✓ Detected changes in: <list of changed files>
|
|
158
|
-
✓ Created spec at openspec/changes/<change-id>/
|
|
159
|
-
✓ Validated spec
|
|
160
|
-
✓ Created branch spec/<change-id>
|
|
161
|
-
✓ Committed: "<type>: <description>"
|
|
162
|
-
✓ Archived spec
|
|
163
|
-
✓ Committed: "chore: archive <change-id> spec"
|
|
164
|
-
✓ Pushed to origin/spec/<change-id>
|
|
165
|
-
✓ Created PR #XX: <url>
|
|
166
|
-
|
|
167
|
-
Your changes are now on spec/<change-id> (main is unchanged).
|
|
168
|
-
|
|
169
|
-
Next: After approval, run /speclife land
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**⛔ STOP HERE.** Do NOT proceed to merge. Wait for:
|
|
173
|
-
1. PR review and approval
|
|
174
|
-
2. User to invoke `/speclife land`
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
<!-- REFERENCE SECTIONS - Read only when needed -->
|
|
179
|
-
|
|
180
|
-
## Appendix: Examples
|
|
181
|
-
|
|
182
|
-
**Basic retrofit:**
|
|
183
|
-
```
|
|
184
|
-
User: /speclife retrofit "update ship command workflow"
|
|
185
|
-
|
|
186
|
-
Agent:
|
|
187
|
-
ℹ️ On main branch
|
|
188
|
-
✓ Detected changes:
|
|
189
|
-
- openspec/commands/speclife/ship.md (modified)
|
|
190
|
-
✓ Derived change-id: update-ship-workflow
|
|
191
|
-
✓ Created spec at openspec/changes/update-ship-workflow/
|
|
192
|
-
✓ Validated spec
|
|
193
|
-
✓ Created branch spec/update-ship-workflow
|
|
194
|
-
✓ Committed: "docs: update ship command workflow"
|
|
195
|
-
✓ Archived spec
|
|
196
|
-
✓ Committed: "chore: archive update-ship-workflow spec"
|
|
197
|
-
✓ Pushed to origin/spec/update-ship-workflow
|
|
198
|
-
✓ Created PR #47
|
|
199
|
-
|
|
200
|
-
Next: After approval, run /speclife land
|
|
201
|
-
```
|
|
202
|
-
|
|
203
|
-
**With unpushed commits:**
|
|
204
|
-
```
|
|
205
|
-
User: /speclife retrofit "add retrofit command"
|
|
206
|
-
|
|
207
|
-
Agent:
|
|
208
|
-
ℹ️ On main branch
|
|
209
|
-
✓ Detected changes:
|
|
210
|
-
- 2 unpushed commits
|
|
211
|
-
- openspec/commands/speclife/retrofit.md (new file)
|
|
212
|
-
✓ Derived change-id: add-retrofit-command
|
|
213
|
-
✓ Created spec at openspec/changes/add-retrofit-command/
|
|
214
|
-
...
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
**Interactive:**
|
|
218
|
-
```
|
|
219
|
-
User: /speclife retrofit
|
|
220
|
-
|
|
221
|
-
Agent:
|
|
222
|
-
ℹ️ Detected uncommitted changes:
|
|
223
|
-
- src/api.ts (modified)
|
|
224
|
-
- src/utils.ts (modified)
|
|
225
|
-
|
|
226
|
-
What do these changes do? (describe for the spec)
|
|
227
|
-
|
|
228
|
-
User: Add rate limiting to API endpoints
|
|
229
|
-
|
|
230
|
-
Agent:
|
|
231
|
-
✓ Derived change-id: add-rate-limiting
|
|
232
|
-
...
|
|
233
|
-
```
|
|
234
|
-
|
|
235
|
-
## Appendix: Error Handling
|
|
236
|
-
|
|
237
|
-
**Not on main:**
|
|
238
|
-
```
|
|
239
|
-
❌ Must be on main branch to retrofit.
|
|
240
|
-
Current branch: feature/something
|
|
241
|
-
|
|
242
|
-
Either:
|
|
243
|
-
1. Switch to main: git checkout main
|
|
244
|
-
2. Use /speclife ship for non-main branches
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
**No changes to retrofit:**
|
|
248
|
-
```
|
|
249
|
-
❌ No changes to retrofit.
|
|
250
|
-
|
|
251
|
-
Working directory is clean and no unpushed commits.
|
|
252
|
-
|
|
253
|
-
Make some changes first, then run /speclife retrofit
|
|
254
|
-
```
|
|
255
|
-
|
|
256
|
-
**Spec already exists:**
|
|
257
|
-
```
|
|
258
|
-
❌ Spec 'update-ship-workflow' already exists.
|
|
259
|
-
|
|
260
|
-
Either:
|
|
261
|
-
1. Choose a different description
|
|
262
|
-
2. Remove existing: rm -rf openspec/changes/update-ship-workflow/
|
|
263
|
-
3. Use /speclife start "resume update-ship-workflow" to continue existing
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
**Validation failed:**
|
|
267
|
-
```
|
|
268
|
-
❌ Spec validation failed:
|
|
269
|
-
- proposal.md: Missing "What" section
|
|
270
|
-
|
|
271
|
-
Fix issues and retry.
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
## Appendix: Comparison with Other Commands
|
|
275
|
-
|
|
276
|
-
| Command | Starting Point | Creates Spec? | Flow |
|
|
277
|
-
|---------|---------------|---------------|------|
|
|
278
|
-
| `/speclife start` | Clean main | Yes (before implementation) | Spec → Implement → Ship |
|
|
279
|
-
| `/speclife retrofit` | Main with changes | Yes (after implementation) | Implement → Spec → Ship |
|
|
280
|
-
| `/speclife ship` | Spec branch | No (uses existing) | Ship existing work |
|
|
281
|
-
|
|
282
|
-
## Appendix: What Gets Committed
|
|
283
|
-
|
|
284
|
-
**First commit** (implementation + spec):
|
|
285
|
-
```
|
|
286
|
-
<type>: <description>
|
|
287
|
-
|
|
288
|
-
- Implementation changes (the ad-hoc work)
|
|
289
|
-
- openspec/changes/<change-id>/proposal.md
|
|
290
|
-
- openspec/changes/<change-id>/tasks.md
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
**Second commit** (archive):
|
|
294
|
-
```
|
|
295
|
-
chore: archive <change-id> spec
|
|
296
|
-
|
|
297
|
-
- Move spec to archive/
|
|
298
|
-
- Update project.md (if applicable)
|
|
299
|
-
```
|
|
300
|
-
|
|
301
|
-
## Notes
|
|
302
|
-
|
|
303
|
-
- Retrofit is for MAIN branch only (ad-hoc changes)
|
|
304
|
-
- For changes on feature branches, use `/speclife ship` instead
|
|
305
|
-
- The spec documents what WAS done, not what NEEDS to be done
|
|
306
|
-
- Tasks in tasks.md should be marked as completed
|
|
307
|
-
- Main branch stays clean (changes move to spec branch)
|
|
308
|
-
|
|
7
|
+
**Guardrails**
|
|
8
|
+
- Execute immediately—must be on `main` with uncommitted changes or unpushed commits
|
|
9
|
+
- Generate spec from actual changes (retrospective), not speculation
|
|
10
|
+
- STOP after PR created—do NOT auto-invoke `/speclife land`
|
|
11
|
+
|
|
12
|
+
**Steps**
|
|
13
|
+
1. Detect changes: `git status --short` and `git log origin/main..HEAD --oneline`; error if no changes.
|
|
14
|
+
2. Analyze diffs to understand what was done; infer change type (feat, fix, refactor, docs).
|
|
15
|
+
3. Derive change-id: kebab-case with verb prefix (add-, fix-, update-, remove-, refactor-).
|
|
16
|
+
4. Review context: `openspec list --specs`, `cat openspec/project.md`.
|
|
17
|
+
5. Create retrospective spec: `proposal.md` (past tense), `tasks.md` (all `[x]` completed), spec deltas if applicable.
|
|
18
|
+
6. Validate and branch: `openspec validate <id>`, `git checkout -b spec/<id>`.
|
|
19
|
+
7. Commit, archive, push, PR: commit changes, run `openspec archive <id> --yes`, commit archive, push, create PR with `gh pr create --title "<type>: <description>" --body "<body>"`.
|
|
20
|
+
8. Report: change-id, spec created, PR URL. Next: `/speclife land` after approval.
|
|
21
|
+
|
|
22
|
+
**Reference**
|
|
23
|
+
- Proposal documents what was done (reality), not aspirations
|
|
24
|
+
- Uncommitted changes move to the new branch automatically
|
|
25
|
+
- PR title: use conventional commit format (`<type>: <meaningful description>`)
|
|
26
|
+
- PR body: if `.github/pull_request_template.md` exists, read it and fill in each section based on the change context
|
|
@@ -4,295 +4,23 @@ id: speclife-setup
|
|
|
4
4
|
category: SpecLife
|
|
5
5
|
description: Discover project configuration and populate openspec/speclife.md.
|
|
6
6
|
---
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
2. **Detect build system**: Look for project configuration files:
|
|
29
|
-
- `package.json` → Node.js (npm/yarn/pnpm)
|
|
30
|
-
- `Cargo.toml` → Rust (cargo)
|
|
31
|
-
- `go.mod` → Go
|
|
32
|
-
- `Makefile` → Make-based
|
|
33
|
-
- `pyproject.toml` or `setup.py` → Python
|
|
34
|
-
- `build.gradle` or `pom.xml` → Java
|
|
35
|
-
|
|
36
|
-
3. **Extract commands**: From the detected build system, find:
|
|
37
|
-
- **Test command**: e.g., `npm test`, `cargo test`, `make test`
|
|
38
|
-
- **Build command**: e.g., `npm run build`, `cargo build`, `make build`
|
|
39
|
-
- **Lint command**: e.g., `npm run lint`, `cargo clippy`, `make lint`
|
|
40
|
-
|
|
41
|
-
4. **Detect publish configuration**: Based on project type:
|
|
42
|
-
|
|
43
|
-
| Project Type | Detection | Registry | Secret Required |
|
|
44
|
-
|--------------|-----------|----------|-----------------|
|
|
45
|
-
| Node.js | `package.json` with `name` (not private) | npm | `NPM_TOKEN` |
|
|
46
|
-
| Node.js monorepo | `workspaces` in package.json | npm | `NPM_TOKEN` |
|
|
47
|
-
| Rust | `Cargo.toml` with `[package]` | crates.io | `CARGO_REGISTRY_TOKEN` |
|
|
48
|
-
| Python | `pyproject.toml` with `[project]` | PyPI | `PYPI_TOKEN` |
|
|
49
|
-
| Go | `go.mod` | N/A (no central registry) | None |
|
|
50
|
-
| Internal/private | `"private": true` in package.json | N/A | None |
|
|
51
|
-
|
|
52
|
-
5. **Check for existing workflows**: Look in `.github/workflows/` for:
|
|
53
|
-
- `publish.yml` or similar publish workflow
|
|
54
|
-
- `release.yml` - release workflow
|
|
55
|
-
|
|
56
|
-
6. **Identify context files**: Look for common documentation:
|
|
57
|
-
- `openspec/project.md` - project context
|
|
58
|
-
- `openspec/AGENTS.md` - agent guidelines
|
|
59
|
-
- `README.md` - project overview
|
|
60
|
-
- `CONTRIBUTING.md` - contribution guidelines
|
|
61
|
-
|
|
62
|
-
7. **Update speclife.md**: Write discovered values to `openspec/speclife.md`
|
|
63
|
-
|
|
64
|
-
8. **Offer to create publish workflow** (if missing):
|
|
65
|
-
- If no publish workflow exists AND project is publishable (not private, not Go):
|
|
66
|
-
- Ask: "No publish workflow found. Would you like me to create `.github/workflows/publish.yml`?"
|
|
67
|
-
- If user agrees, create the appropriate workflow from the templates below
|
|
68
|
-
- Remind user to add the required secret in repo settings
|
|
69
|
-
- If project is private (`"private": true`) or Go (no central registry):
|
|
70
|
-
- Skip this step (no publish workflow needed)
|
|
71
|
-
|
|
72
|
-
9. **Report**: Tell the user what was configured and any next steps
|
|
73
|
-
|
|
74
|
-
## Publish Workflow Templates
|
|
75
|
-
|
|
76
|
-
Use these templates when creating publish workflows:
|
|
77
|
-
|
|
78
|
-
### Node.js (single package)
|
|
79
|
-
```yaml
|
|
80
|
-
# .github/workflows/publish.yml
|
|
81
|
-
name: Publish to npm
|
|
82
|
-
on:
|
|
83
|
-
release:
|
|
84
|
-
types: [published]
|
|
85
|
-
|
|
86
|
-
jobs:
|
|
87
|
-
publish:
|
|
88
|
-
runs-on: ubuntu-latest
|
|
89
|
-
steps:
|
|
90
|
-
- uses: actions/checkout@v4
|
|
91
|
-
- uses: actions/setup-node@v4
|
|
92
|
-
with:
|
|
93
|
-
node-version: '20'
|
|
94
|
-
registry-url: 'https://registry.npmjs.org'
|
|
95
|
-
- run: npm ci
|
|
96
|
-
- run: npm test
|
|
97
|
-
- run: npm publish --access public
|
|
98
|
-
env:
|
|
99
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
### Node.js (monorepo with workspaces)
|
|
103
|
-
```yaml
|
|
104
|
-
# .github/workflows/publish.yml
|
|
105
|
-
name: Publish to npm
|
|
106
|
-
on:
|
|
107
|
-
release:
|
|
108
|
-
types: [published]
|
|
109
|
-
|
|
110
|
-
jobs:
|
|
111
|
-
publish:
|
|
112
|
-
runs-on: ubuntu-latest
|
|
113
|
-
steps:
|
|
114
|
-
- uses: actions/checkout@v4
|
|
115
|
-
- uses: actions/setup-node@v4
|
|
116
|
-
with:
|
|
117
|
-
node-version: '20'
|
|
118
|
-
registry-url: 'https://registry.npmjs.org'
|
|
119
|
-
- run: npm ci
|
|
120
|
-
- run: npm run build
|
|
121
|
-
- run: npm test
|
|
122
|
-
# Publish each workspace package
|
|
123
|
-
- run: npm publish -w packages/<package-name> --access public
|
|
124
|
-
env:
|
|
125
|
-
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Rust
|
|
129
|
-
```yaml
|
|
130
|
-
# .github/workflows/publish.yml
|
|
131
|
-
name: Publish to crates.io
|
|
132
|
-
on:
|
|
133
|
-
release:
|
|
134
|
-
types: [published]
|
|
135
|
-
|
|
136
|
-
jobs:
|
|
137
|
-
publish:
|
|
138
|
-
runs-on: ubuntu-latest
|
|
139
|
-
steps:
|
|
140
|
-
- uses: actions/checkout@v4
|
|
141
|
-
- uses: dtolnay/rust-toolchain@stable
|
|
142
|
-
- run: cargo test
|
|
143
|
-
- run: cargo publish
|
|
144
|
-
env:
|
|
145
|
-
CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
|
|
146
|
-
```
|
|
147
|
-
|
|
148
|
-
### Python
|
|
149
|
-
```yaml
|
|
150
|
-
# .github/workflows/publish.yml
|
|
151
|
-
name: Publish to PyPI
|
|
152
|
-
on:
|
|
153
|
-
release:
|
|
154
|
-
types: [published]
|
|
155
|
-
|
|
156
|
-
jobs:
|
|
157
|
-
publish:
|
|
158
|
-
runs-on: ubuntu-latest
|
|
159
|
-
steps:
|
|
160
|
-
- uses: actions/checkout@v4
|
|
161
|
-
- uses: actions/setup-python@v5
|
|
162
|
-
with:
|
|
163
|
-
python-version: '3.11'
|
|
164
|
-
- run: pip install build twine
|
|
165
|
-
- run: python -m build
|
|
166
|
-
- run: twine upload dist/*
|
|
167
|
-
env:
|
|
168
|
-
TWINE_USERNAME: __token__
|
|
169
|
-
TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
## Output
|
|
173
|
-
|
|
174
|
-
Update `openspec/speclife.md` with discovered configuration:
|
|
175
|
-
|
|
176
|
-
```markdown
|
|
177
|
-
# SpecLife Configuration
|
|
178
|
-
|
|
179
|
-
## Commands
|
|
180
|
-
|
|
181
|
-
- **Test:** `<detected-test-command>`
|
|
182
|
-
- **Build:** `<detected-build-command>`
|
|
183
|
-
- **Lint:** `<detected-lint-command>`
|
|
184
|
-
|
|
185
|
-
## Release Policy
|
|
186
|
-
|
|
187
|
-
- **Auto-release:** patch and minor versions
|
|
188
|
-
- **Manual release:** major versions (breaking changes)
|
|
189
|
-
|
|
190
|
-
## Publish
|
|
191
|
-
|
|
192
|
-
- **Registry:** npm / PyPI / crates.io / None
|
|
193
|
-
- **Workflow:** .github/workflows/publish.yml (exists / TODO)
|
|
194
|
-
- **Secret:** NPM_TOKEN / PYPI_TOKEN / CARGO_REGISTRY_TOKEN
|
|
195
|
-
|
|
196
|
-
## Context Files
|
|
197
|
-
|
|
198
|
-
When implementing changes, always read:
|
|
199
|
-
- `openspec/project.md` - project context and conventions
|
|
200
|
-
- `openspec/AGENTS.md` - agent guidelines
|
|
201
|
-
- `README.md` - project overview
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
## Example Output
|
|
205
|
-
|
|
206
|
-
### When publish workflow exists:
|
|
207
|
-
```
|
|
208
|
-
User: /speclife setup
|
|
209
|
-
|
|
210
|
-
Agent:
|
|
211
|
-
Detecting project configuration...
|
|
212
|
-
|
|
213
|
-
✓ Project type: Node.js monorepo (npm workspaces)
|
|
214
|
-
✓ Packages: @speclife/core, @speclife/cli, @speclife/mcp-server
|
|
215
|
-
|
|
216
|
-
Commands detected:
|
|
217
|
-
✓ Test: npm test
|
|
218
|
-
✓ Build: npm run build
|
|
219
|
-
✓ Lint: npm run lint
|
|
220
|
-
|
|
221
|
-
Workflows:
|
|
222
|
-
✓ Release: .github/workflows/release.yml
|
|
223
|
-
✓ Publish: .github/workflows/publish.yml
|
|
224
|
-
|
|
225
|
-
Context files:
|
|
226
|
-
✓ openspec/project.md
|
|
227
|
-
✓ openspec/AGENTS.md
|
|
228
|
-
✓ README.md
|
|
229
|
-
|
|
230
|
-
✓ Updated openspec/speclife.md
|
|
231
|
-
```
|
|
232
|
-
|
|
233
|
-
### When publish workflow is missing:
|
|
234
|
-
```
|
|
235
|
-
User: /speclife setup
|
|
236
|
-
|
|
237
|
-
Agent:
|
|
238
|
-
Detecting project configuration...
|
|
239
|
-
|
|
240
|
-
✓ Project type: Node.js (single package)
|
|
241
|
-
✓ Package: my-awesome-lib
|
|
242
|
-
|
|
243
|
-
Commands detected:
|
|
244
|
-
✓ Test: npm test
|
|
245
|
-
✓ Build: npm run build
|
|
246
|
-
✓ Lint: npm run lint
|
|
247
|
-
|
|
248
|
-
Workflows:
|
|
249
|
-
✓ Release: .github/workflows/release.yml
|
|
250
|
-
⚠ Publish: Not found
|
|
251
|
-
|
|
252
|
-
This package appears to be publishable to npm. Would you like me to create
|
|
253
|
-
`.github/workflows/publish.yml`?
|
|
254
|
-
|
|
255
|
-
User: yes
|
|
256
|
-
|
|
257
|
-
Agent:
|
|
258
|
-
✓ Created .github/workflows/publish.yml
|
|
259
|
-
|
|
260
|
-
⚠️ Remember to add NPM_TOKEN to your repository secrets:
|
|
261
|
-
GitHub → Settings → Secrets and variables → Actions → New repository secret
|
|
262
|
-
|
|
263
|
-
Get your token from: https://www.npmjs.com/settings/~/tokens
|
|
264
|
-
|
|
265
|
-
✓ Updated openspec/speclife.md
|
|
266
|
-
|
|
267
|
-
Done! Your project is configured for automated releases and publishing.
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
### When project is private:
|
|
271
|
-
```
|
|
272
|
-
User: /speclife setup
|
|
273
|
-
|
|
274
|
-
Agent:
|
|
275
|
-
Detecting project configuration...
|
|
276
|
-
|
|
277
|
-
✓ Project type: Node.js (private package)
|
|
278
|
-
|
|
279
|
-
Commands detected:
|
|
280
|
-
✓ Test: npm test
|
|
281
|
-
✓ Build: npm run build
|
|
282
|
-
|
|
283
|
-
Workflows:
|
|
284
|
-
✓ Release: .github/workflows/release.yml
|
|
285
|
-
ℹ Publish: Not needed (private package)
|
|
286
|
-
|
|
287
|
-
✓ Updated openspec/speclife.md
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
## Notes
|
|
291
|
-
|
|
292
|
-
- If a command can't be detected, leave it as a TODO for the user
|
|
293
|
-
- Don't overwrite user customizations if speclife.md already exists
|
|
294
|
-
- This command is idempotent - safe to run multiple times
|
|
295
|
-
- Always ask before creating publish workflow (don't auto-create)
|
|
296
|
-
- Remind about secrets after creating publish workflow
|
|
297
|
-
|
|
298
|
-
|
|
7
|
+
**Guardrails**
|
|
8
|
+
- Execute immediately—scan project to auto-detect configuration
|
|
9
|
+
- Don't overwrite existing user customizations in speclife.md
|
|
10
|
+
- Ask before creating publish workflow (don't auto-create)
|
|
11
|
+
|
|
12
|
+
**Steps**
|
|
13
|
+
1. Read existing `openspec/speclife.md` if present.
|
|
14
|
+
2. Detect build system: package.json (Node), Cargo.toml (Rust), go.mod (Go), pyproject.toml (Python), etc.
|
|
15
|
+
3. Extract commands: test, build, lint from detected system (e.g., `npm test`, `cargo test`).
|
|
16
|
+
4. Detect publish config: registry (npm/crates.io/PyPI), required secret, private flag.
|
|
17
|
+
5. Check `.github/workflows/` for existing release/publish workflows.
|
|
18
|
+
6. Identify context files: `openspec/project.md`, `openspec/AGENTS.md`, `README.md`.
|
|
19
|
+
7. Update `openspec/speclife.md` with discovered values.
|
|
20
|
+
8. If publishable and no publish workflow exists: ask user, create if agreed, remind about secrets.
|
|
21
|
+
9. Report: project type, detected commands, workflow status, what was configured.
|
|
22
|
+
|
|
23
|
+
**Reference**
|
|
24
|
+
- Publish workflow templates: Node.js, Rust, Python (standard patterns)
|
|
25
|
+
- Private packages (`"private": true`) skip publish workflow
|
|
26
|
+
- Go has no central registry—skip publish step
|