@speclife/cli 0.9.0 → 0.9.2
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/dist/index.d.ts +0 -7
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -0
- package/dist/index.js.map +1 -1
- 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 +22 -303
- package/templates/commands/setup.md +20 -292
- package/templates/commands/ship.md +18 -162
- package/templates/commands/start.md +17 -269
- package/templates/commands/sync.md +16 -164
|
@@ -4,272 +4,20 @@ id: speclife-start
|
|
|
4
4
|
category: SpecLife
|
|
5
5
|
description: Create a new branch for a change, optionally in a worktree for parallel work.
|
|
6
6
|
---
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
**
|
|
14
|
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
/speclife start <description> # New proposal, worktree (default)
|
|
25
|
-
/speclife start <description> in a branch # New proposal, branch-only
|
|
26
|
-
/speclife start "resume <change-id>" # Resume existing proposal, worktree
|
|
27
|
-
/speclife start "implement <change-id>" # Resume if exists, create if not
|
|
28
|
-
/speclife start # Interactive
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
## Goal
|
|
32
|
-
|
|
33
|
-
Set up a workspace for a new change with proper git branch.
|
|
34
|
-
|
|
35
|
-
## Mode Detection
|
|
36
|
-
|
|
37
|
-
Parse the input for workflow hints in this order:
|
|
38
|
-
|
|
39
|
-
### 1. Resume Intent Detection
|
|
40
|
-
|
|
41
|
-
| Phrase in input | Meaning |
|
|
42
|
-
|-----------------|---------|
|
|
43
|
-
| "resume <change-id>", "continue <change-id>", "pick up <change-id>" | **Resume existing proposal** (error if not found) |
|
|
44
|
-
| "implement <change-id>" | **Resume if exists**, create new if not |
|
|
45
|
-
|
|
46
|
-
Examples:
|
|
47
|
-
- `"resume fix-release-and-init"` → resume mode, change-id = `fix-release-and-init`
|
|
48
|
-
- `"continue working on add-oauth-login"` → resume mode, change-id = `add-oauth-login`
|
|
49
|
-
- `"implement fix-email-validation"` → try resume, fallback to new
|
|
50
|
-
|
|
51
|
-
### 2. Worktree Mode Detection
|
|
52
|
-
|
|
53
|
-
| Phrase in input | Mode |
|
|
54
|
-
|-----------------|------|
|
|
55
|
-
| "in a branch", "branch only", "no worktree", "simple" | **Branch-only** |
|
|
56
|
-
| "in a worktree", "with worktree", "parallel" | **Worktree** |
|
|
57
|
-
| Neither | **Worktree** (default) |
|
|
58
|
-
|
|
59
|
-
### 3. Parsing Order
|
|
60
|
-
|
|
61
|
-
1. Check for resume keywords → extract change-id
|
|
62
|
-
2. Check for mode keywords → determine worktree/branch
|
|
63
|
-
3. Strip workflow hints → derive description (new proposals only)
|
|
64
|
-
|
|
65
|
-
Examples:
|
|
66
|
-
- `"resume fix-bug in a branch"` → resume mode, branch-only
|
|
67
|
-
- `"implement oauth with worktree"` → resume/new mode, worktree
|
|
68
|
-
|
|
69
|
-
## Steps
|
|
70
|
-
|
|
71
|
-
### 1. Check for Resume Intent
|
|
72
|
-
|
|
73
|
-
Parse input for resume keywords (`resume`, `continue`, `pick up`, `implement`):
|
|
74
|
-
|
|
75
|
-
**If resume intent detected:**
|
|
76
|
-
```bash
|
|
77
|
-
CHANGE_ID=<extracted-from-input> # e.g., "fix-release-and-init"
|
|
78
|
-
PROPOSAL_DIR="openspec/changes/${CHANGE_ID}"
|
|
79
|
-
|
|
80
|
-
if [[ ! -d "$PROPOSAL_DIR" ]]; then
|
|
81
|
-
echo "❌ Proposal '${CHANGE_ID}' not found"
|
|
82
|
-
echo ""
|
|
83
|
-
echo "Available proposals:"
|
|
84
|
-
ls -1 openspec/changes/ | grep -v archive
|
|
85
|
-
exit 1
|
|
86
|
-
fi
|
|
87
|
-
|
|
88
|
-
echo "✓ Found existing proposal at ${PROPOSAL_DIR}/"
|
|
89
|
-
# Skip to step 3 (create branch/worktree)
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
**If "implement" keyword and proposal doesn't exist:**
|
|
93
|
-
- Continue as new proposal (steps 2-5)
|
|
94
|
-
|
|
95
|
-
**If no resume intent:**
|
|
96
|
-
- Continue to step 2
|
|
97
|
-
|
|
98
|
-
### 2. Derive change-id (New Proposals Only)
|
|
99
|
-
|
|
100
|
-
Convert description to kebab-case:
|
|
101
|
-
- "Add user authentication" → `add-user-auth`
|
|
102
|
-
- Prefix with verb: add-, fix-, update-, remove-, refactor-
|
|
103
|
-
- Keep it short (3-5 words max)
|
|
104
|
-
|
|
105
|
-
### 3. Create branch/worktree
|
|
106
|
-
|
|
107
|
-
**Branch-only mode:**
|
|
108
|
-
```bash
|
|
109
|
-
git checkout -b spec/<change-id>
|
|
110
|
-
```
|
|
111
|
-
- Works in current directory
|
|
112
|
-
- One change at a time (switch branches to context-switch)
|
|
113
|
-
|
|
114
|
-
**Worktree mode (default):**
|
|
115
|
-
```bash
|
|
116
|
-
speclife worktree create <change-id>
|
|
117
|
-
```
|
|
118
|
-
- Creates `worktrees/<change-id>/`
|
|
119
|
-
- Creates branch `spec/<change-id>`
|
|
120
|
-
- Parallel changes possible
|
|
121
|
-
|
|
122
|
-
### 4. Scaffold proposal (New Proposals Only)
|
|
123
|
-
|
|
124
|
-
**Skip this step if resuming an existing proposal.**
|
|
125
|
-
|
|
126
|
-
Invoke `/openspec-proposal` with the description (minus workflow hints)
|
|
127
|
-
- Creates `openspec/changes/<change-id>/proposal.md`
|
|
128
|
-
- Creates `openspec/changes/<change-id>/tasks.md`
|
|
129
|
-
|
|
130
|
-
### 5. Report and STOP
|
|
131
|
-
|
|
132
|
-
**New Proposal - Branch-only:**
|
|
133
|
-
```
|
|
134
|
-
✓ Derived change-id: add-oauth-login
|
|
135
|
-
✓ Created branch spec/add-oauth-login
|
|
136
|
-
✓ Scaffolded proposal at openspec/changes/add-oauth-login/
|
|
137
|
-
|
|
138
|
-
Next: Review the proposal, then run `/openspec-apply` to implement.
|
|
139
|
-
```
|
|
140
|
-
|
|
141
|
-
**New Proposal - Worktree:**
|
|
142
|
-
```
|
|
143
|
-
✓ Derived change-id: add-oauth-login
|
|
144
|
-
✓ Created worktree at worktrees/add-oauth-login/
|
|
145
|
-
✓ Created branch spec/add-oauth-login
|
|
146
|
-
✓ Scaffolded proposal at openspec/changes/add-oauth-login/
|
|
147
|
-
|
|
148
|
-
⚠️ IMPORTANT: You must work from the worktree directory!
|
|
149
|
-
|
|
150
|
-
Next steps:
|
|
151
|
-
1. Switch to worktree: cd worktrees/add-oauth-login/
|
|
152
|
-
2. Invoke /openspec-apply from there
|
|
153
|
-
|
|
154
|
-
🚨 CRITICAL: All file edits MUST happen in:
|
|
155
|
-
worktrees/add-oauth-login/openspec/...
|
|
156
|
-
worktrees/add-oauth-login/packages/...
|
|
157
|
-
|
|
158
|
-
NOT in the main repo paths!
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
**Resume Proposal - Branch-only:**
|
|
162
|
-
```
|
|
163
|
-
✓ Found existing proposal at openspec/changes/fix-release-and-init/
|
|
164
|
-
✓ Created branch spec/fix-release-and-init
|
|
165
|
-
ℹ️ Proposal already defined - ready to implement
|
|
166
|
-
|
|
167
|
-
Next: Run `/openspec-apply` to implement tasks.
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
**Resume Proposal - Worktree:**
|
|
171
|
-
```
|
|
172
|
-
✓ Found existing proposal at openspec/changes/fix-release-and-init/
|
|
173
|
-
✓ Created worktree at worktrees/fix-release-and-init/
|
|
174
|
-
✓ Created branch spec/fix-release-and-init
|
|
175
|
-
ℹ️ Proposal already defined - ready to implement
|
|
176
|
-
|
|
177
|
-
Next: cd worktrees/fix-release-and-init/ then run `/openspec-apply`.
|
|
178
|
-
```
|
|
179
|
-
|
|
180
|
-
**⛔ STOP HERE.** Do NOT proceed to implementation. Wait for user to:
|
|
181
|
-
1. Review the proposal (if new)
|
|
182
|
-
2. Switch to worktree directory (if worktree mode)
|
|
183
|
-
3. Invoke `/openspec-apply` or `/speclife implement`
|
|
184
|
-
|
|
185
|
-
## Examples
|
|
186
|
-
|
|
187
|
-
**New proposals:**
|
|
188
|
-
```
|
|
189
|
-
User: /speclife start "Add OAuth login support"
|
|
190
|
-
→ Creates worktree (default), scaffolds new proposal
|
|
191
|
-
|
|
192
|
-
User: /speclife start "Add OAuth login" in a branch
|
|
193
|
-
→ Creates branch only, scaffolds new proposal
|
|
194
|
-
|
|
195
|
-
User: /speclife start "fix login bug" branch only
|
|
196
|
-
→ Creates branch only, scaffolds new proposal
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
**Resume existing proposals:**
|
|
200
|
-
```
|
|
201
|
-
User: /speclife start "resume fix-release-and-init"
|
|
202
|
-
→ Creates worktree, uses existing proposal
|
|
203
|
-
|
|
204
|
-
User: /speclife start "continue working on add-oauth-login"
|
|
205
|
-
→ Creates worktree, uses existing proposal
|
|
206
|
-
|
|
207
|
-
User: /speclife start "pick up fix-email-validation in a branch"
|
|
208
|
-
→ Creates branch only, uses existing proposal
|
|
209
|
-
|
|
210
|
-
User: /speclife start "implement add-user-auth"
|
|
211
|
-
→ If proposal exists: resumes it
|
|
212
|
-
→ If not: creates new proposal
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**Error case:**
|
|
216
|
-
```
|
|
217
|
-
User: /speclife start "resume nonexistent-change"
|
|
218
|
-
|
|
219
|
-
Agent:
|
|
220
|
-
❌ Proposal 'nonexistent-change' not found
|
|
221
|
-
|
|
222
|
-
Available proposals:
|
|
223
|
-
fix-release-and-init
|
|
224
|
-
add-oauth-login
|
|
225
|
-
fix-email-validation
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Interactive:**
|
|
229
|
-
```
|
|
230
|
-
User: /speclife start
|
|
231
|
-
→ Prompts: "Describe your change" then "Worktree (default) or branch-only?"
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
## Tradeoffs
|
|
235
|
-
|
|
236
|
-
| Aspect | Worktree | Branch-only |
|
|
237
|
-
|--------|----------|-------------|
|
|
238
|
-
| Parallel changes | ✓ Multiple worktrees | One at a time |
|
|
239
|
-
| IDE support | May need reload | Seamless |
|
|
240
|
-
| Setup complexity | More dirs | Simpler |
|
|
241
|
-
| Context switching | cd to worktree | git checkout |
|
|
242
|
-
|
|
243
|
-
## Naming Conventions
|
|
244
|
-
|
|
245
|
-
- Use kebab-case for change-id
|
|
246
|
-
- Prefix with action verb: `add-`, `fix-`, `update-`, `remove-`, `refactor-`
|
|
247
|
-
- Keep it descriptive but concise
|
|
248
|
-
- Examples:
|
|
249
|
-
- `add-user-auth`
|
|
250
|
-
- `fix-login-redirect`
|
|
251
|
-
- `update-api-docs`
|
|
252
|
-
- `remove-deprecated-endpoint`
|
|
253
|
-
- `refactor-database-layer`
|
|
254
|
-
|
|
255
|
-
## Notes
|
|
256
|
-
|
|
257
|
-
### General
|
|
258
|
-
- Branch name is always `spec/<change-id>` regardless of mode
|
|
259
|
-
- If branch exists, error and suggest using existing
|
|
260
|
-
- Branch-only: uncommitted changes carry over (stash if needed)
|
|
261
|
-
- Worktree: clean checkout from main
|
|
262
|
-
- To switch modes later, use `/speclife convert`
|
|
263
|
-
|
|
264
|
-
### Resume Behavior
|
|
265
|
-
- Resume keywords: `resume`, `continue`, `pick up`, `implement`
|
|
266
|
-
- Proposals must exist in `openspec/changes/<change-id>/`
|
|
267
|
-
- Archived proposals are not searched (move from archive first if needed)
|
|
268
|
-
- Resume skips `/openspec-proposal` scaffolding
|
|
269
|
-
- "implement" keyword tries resume first, creates new if not found
|
|
270
|
-
- Combine with mode: "resume X in a branch" or "resume X with worktree"
|
|
271
|
-
|
|
272
|
-
### Next Steps
|
|
273
|
-
- After creating new proposal: Review, refine, then `/openspec-apply`
|
|
274
|
-
- After resuming proposal: Directly run `/openspec-apply` to implement tasks
|
|
275
|
-
- Both workflows converge at implementation phase
|
|
7
|
+
**Guardrails**
|
|
8
|
+
- Execute immediately when invoked
|
|
9
|
+
- Parse input for resume keywords (`resume`, `continue`, `pick up`, `implement <id>`)
|
|
10
|
+
- Parse for mode keywords: "in a branch" → branch-only, otherwise → worktree (default)
|
|
11
|
+
- STOP after scaffolding—do NOT auto-invoke `/openspec-apply`
|
|
12
|
+
|
|
13
|
+
**Steps**
|
|
14
|
+
1. If resume intent detected, verify `openspec/changes/<id>/` exists; error with available proposals if not found.
|
|
15
|
+
2. For new proposals: derive kebab-case change-id from description (prefix: add-, fix-, update-, remove-, refactor-).
|
|
16
|
+
3. Create workspace: branch-only → `git checkout -b spec/<id>`, worktree → `speclife worktree create <id>`.
|
|
17
|
+
4. For new proposals only: scaffold `proposal.md` and `tasks.md` under `openspec/changes/<id>/` (follow `/openspec-proposal` for format), then run `openspec validate <id> --strict`.
|
|
18
|
+
5. Report: change-id, branch/worktree created, path to work directory. If worktree, emphasize: "All edits must happen in worktrees/<id>/".
|
|
19
|
+
|
|
20
|
+
**Reference**
|
|
21
|
+
- Branch name always `spec/<change-id>` regardless of mode
|
|
22
|
+
- Resume skips proposal scaffolding; proceed directly to `/openspec-apply`
|
|
23
|
+
- Use `/speclife convert` to switch modes later
|
|
@@ -4,167 +4,19 @@ id: speclife-sync
|
|
|
4
4
|
category: SpecLife
|
|
5
5
|
description: Update current branch with latest changes from main.
|
|
6
6
|
---
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
/speclife sync # Rebase onto main (default)
|
|
24
|
-
/speclife sync --merge # Merge main into branch
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
**Quick flow:**
|
|
28
|
-
1. Check prerequisites (not on main, clean working dir)
|
|
29
|
-
2. Fetch latest
|
|
30
|
-
3. Rebase or merge
|
|
31
|
-
4. Handle conflicts if any
|
|
32
|
-
5. Force push (if rebased)
|
|
33
|
-
|
|
34
|
-
## Prerequisites
|
|
35
|
-
|
|
36
|
-
- Not on main branch
|
|
37
|
-
- Working directory clean (commit or stash first)
|
|
38
|
-
|
|
39
|
-
## Core Steps
|
|
40
|
-
|
|
41
|
-
### 1. Check State
|
|
42
|
-
```bash
|
|
43
|
-
BRANCH=$(git branch --show-current)
|
|
44
|
-
[[ "$BRANCH" == "main" ]] && echo "Already on main" && exit
|
|
45
|
-
|
|
46
|
-
# Check for uncommitted changes
|
|
47
|
-
[[ -n $(git status --porcelain) ]] && echo "Commit or stash changes first"
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
### 2. Fetch & Check
|
|
51
|
-
```bash
|
|
52
|
-
git fetch origin main
|
|
53
|
-
BEHIND=$(git rev-list --count HEAD..origin/main)
|
|
54
|
-
[[ "$BEHIND" == "0" ]] && echo "Already up to date" && exit
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
### 3. Rebase (default) or Merge
|
|
58
|
-
```bash
|
|
59
|
-
# Rebase (cleaner history)
|
|
60
|
-
git rebase origin/main
|
|
61
|
-
|
|
62
|
-
# Or merge (preserves history)
|
|
63
|
-
git merge origin/main
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
### 4. Handle Conflicts
|
|
67
|
-
If conflicts:
|
|
68
|
-
```bash
|
|
69
|
-
# List conflicts
|
|
70
|
-
git diff --name-only --diff-filter=U
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
Tell user:
|
|
74
|
-
```
|
|
75
|
-
⚠️ Conflicts in 3 files:
|
|
76
|
-
- src/auth/login.ts
|
|
77
|
-
- package.json
|
|
78
|
-
|
|
79
|
-
To resolve:
|
|
80
|
-
1. Edit files, remove <<<<<<< ======= >>>>>>> markers
|
|
81
|
-
2. git add <resolved-files>
|
|
82
|
-
3. git rebase --continue
|
|
83
|
-
|
|
84
|
-
Or abort: git rebase --abort
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
### 5. Push
|
|
88
|
-
```bash
|
|
89
|
-
# After rebase (force required)
|
|
90
|
-
git push --force-with-lease origin <branch>
|
|
91
|
-
|
|
92
|
-
# After merge (normal push)
|
|
93
|
-
git push origin <branch>
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
### 6. Report
|
|
97
|
-
```
|
|
98
|
-
✓ Rebased onto main (5 commits)
|
|
99
|
-
✓ No conflicts
|
|
100
|
-
✓ Pushed
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
---
|
|
104
|
-
|
|
105
|
-
<!-- REFERENCE SECTIONS - Read only when needed -->
|
|
106
|
-
|
|
107
|
-
## Appendix: Conflict Resolution
|
|
108
|
-
|
|
109
|
-
**Conflict markers:**
|
|
110
|
-
```
|
|
111
|
-
<<<<<<< HEAD (yours)
|
|
112
|
-
const timeout = 5000;
|
|
113
|
-
=======
|
|
114
|
-
const timeout = 10000;
|
|
115
|
-
>>>>>>> origin/main (theirs)
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
**Resolution strategies:**
|
|
119
|
-
- Keep yours: delete their section + markers
|
|
120
|
-
- Keep theirs: delete your section + markers
|
|
121
|
-
- Combine: merge logic, delete markers
|
|
122
|
-
|
|
123
|
-
**Common conflicts:**
|
|
124
|
-
- `package.json` version → keep higher (main)
|
|
125
|
-
- Import conflicts → combine imports
|
|
126
|
-
|
|
127
|
-
## Appendix: Error Handling
|
|
128
|
-
|
|
129
|
-
**On main:**
|
|
130
|
-
```
|
|
131
|
-
ℹ️ Already on main - nothing to sync.
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
**Uncommitted changes:**
|
|
135
|
-
```
|
|
136
|
-
⚠️ Uncommitted changes detected.
|
|
137
|
-
Commit or stash, then retry.
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**Rebase in progress:**
|
|
141
|
-
```
|
|
142
|
-
⚠️ Rebase already in progress.
|
|
143
|
-
Continue: git rebase --continue
|
|
144
|
-
Abort: git rebase --abort
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Appendix: Examples
|
|
148
|
-
|
|
149
|
-
**Clean sync:**
|
|
150
|
-
```
|
|
151
|
-
User: /speclife sync
|
|
152
|
-
|
|
153
|
-
Agent:
|
|
154
|
-
✓ Fetched latest
|
|
155
|
-
ℹ️ 3 commits behind main
|
|
156
|
-
✓ Rebased - no conflicts
|
|
157
|
-
✓ Force pushed
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
**With conflicts:**
|
|
161
|
-
```
|
|
162
|
-
User: /speclife sync
|
|
163
|
-
|
|
164
|
-
Agent:
|
|
165
|
-
⚠️ Conflicts in 2 files:
|
|
166
|
-
- src/auth.ts
|
|
167
|
-
- package.json
|
|
168
|
-
|
|
169
|
-
[Offers to help resolve]
|
|
170
|
-
```
|
|
7
|
+
**Guardrails**
|
|
8
|
+
- Execute immediately—default to rebase unless `--merge` specified
|
|
9
|
+
- Require: not on main, working directory clean
|
|
10
|
+
- Guide user through conflict resolution if any
|
|
11
|
+
|
|
12
|
+
**Steps**
|
|
13
|
+
1. Check state: error if on main or uncommitted changes exist.
|
|
14
|
+
2. Fetch and check: `git fetch origin main`; if already up to date, report and exit.
|
|
15
|
+
3. Rebase (default) or merge: `git rebase origin/main` or `git merge origin/main`.
|
|
16
|
+
4. If conflicts: list conflicting files, explain resolution (edit files, `git add`, `git rebase --continue`), offer to help resolve.
|
|
17
|
+
5. Push: `git push --force-with-lease` (rebase) or `git push` (merge).
|
|
18
|
+
6. Report: commits synced, conflicts resolved (if any), pushed.
|
|
19
|
+
|
|
20
|
+
**Reference**
|
|
21
|
+
- Conflict markers: `<<<<<<< HEAD`, `=======`, `>>>>>>> origin/main`
|
|
22
|
+
- Abort rebase: `git rebase --abort`
|