@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.
@@ -4,165 +4,20 @@ id: speclife-ship
4
4
  category: SpecLife
5
5
  description: Commit changes, push to remote, and create a PR for review.
6
6
  ---
7
- # /speclife ship
8
-
9
- Create a PR from your current branch. Works with spec branches and ad-hoc branches.
10
-
11
- ## ⚡ Execution
12
-
13
- **When this command is invoked, IMMEDIATELY execute the workflow below.**
14
-
15
- - Do NOT skip steps or ask for confirmation before starting
16
- - Detect branch type first, then follow the appropriate flow
17
- - If there are uncommitted changes, proceed to stage and commit them
18
- - Create or update PR as the final step
19
- - **STOP after PR created—do NOT auto-invoke `/speclife land`**
20
-
21
- ## TL;DR
22
-
23
- ```
24
- /speclife ship # Ship current branch
25
- /speclife ship --draft # Create as draft PR
26
- ```
27
-
28
- **Quick flow:**
29
- 1. Detect branch type (spec vs ad-hoc)
30
- 2. For spec branches: validate → commit changes → archive → commit archive
31
- 3. For ad-hoc branches: stage, commit
32
- 4. Push, create/update PR
33
-
34
- ## Mode Detection
35
-
36
- ```bash
37
- BRANCH=$(git branch --show-current)
38
- ```
39
-
40
- | Branch | Type | Behavior |
41
- |--------|------|----------|
42
- | `spec/*` | **Spec** | Full workflow with OpenSpec (validate, archive) |
43
- | Any other non-main | **Ad-hoc** | Simplified (skip spec steps) |
44
- | `main` | **Error** | Cannot ship from main |
45
-
46
- Note: Spec mode is determined by branch name prefix (`spec/`), not worktree existence. Works identically whether you're in a worktree or the main repo.
47
-
48
- ## Core Steps
49
-
50
- ### 1. Spec Branch Only
51
- If spec branch detected:
52
- - Run `openspec validate <change-id>`
53
- - Read proposal.md for commit message
54
- - Commit the implementation changes:
55
- ```bash
56
- git add -A
57
- git commit -m "<type>: <description>"
58
- ```
59
- - Run `/openspec-archive` (may require updating project.md)
60
- - Commit the archive changes:
61
- ```bash
62
- git add -A
63
- git commit -m "chore: archive <change-id> spec"
64
- ```
65
- - Skip to step 3 (push only, no additional commit needed)
66
-
67
- ### 2. Ad-hoc Branch Only
68
- - Infer commit type from branch name (`fix/*` → `fix:`, `feat/*` → `feat:`)
69
- - Ask user for commit message if needed
70
-
71
- ### 3. All Branches
72
- ```bash
73
- # For ad-hoc branches only (spec branches already committed above):
74
- git add -A
75
- git commit -m "<type>: <description>" # if uncommitted changes
76
-
77
- # All branches:
78
- git push -u origin <branch>
79
- ```
80
-
81
- ### 4. Create PR
82
- ```bash
83
- # Check if PR exists
84
- gh pr view --json url 2>/dev/null
85
-
86
- # If not, create
87
- gh pr create --fill --base main
88
- # Or: gh pr create --fill --base main --draft
89
- ```
90
-
91
- ### 5. Report and STOP
92
- ```
93
- ✓ Committed: "feat: description"
94
- ✓ Pushed to origin/<branch>
95
- ✓ Created PR #42: <url>
96
-
97
- Next: After approval, run /speclife land
98
- ```
99
-
100
- **⛔ STOP HERE.** Do NOT proceed to merge. Wait for:
101
- 1. PR review and approval
102
- 2. User to invoke `/speclife land`
103
-
104
- ---
105
-
106
- <!-- REFERENCE SECTIONS - Read only when needed -->
107
-
108
- ## Appendix: Commit Type Inference
109
-
110
- | Branch Pattern | Commit Type |
111
- |----------------|-------------|
112
- | `fix/*`, `bugfix/*`, `hotfix/*` | `fix:` |
113
- | `feat/*`, `feature/*` | `feat:` |
114
- | `docs/*` | `docs:` |
115
- | `refactor/*` | `refactor:` |
116
- | `chore/*` | `chore:` |
117
- | Other | Ask user |
118
-
119
- ## Appendix: Error Handling
120
-
121
- **Cannot ship from main:**
122
- ```
123
- ❌ Cannot ship from main. Create a branch first.
124
- ```
125
-
126
- **No changes:**
127
- ```
128
- ❌ No changes to ship. Working directory clean.
129
- ```
130
-
131
- **Spec validation failed:**
132
- ```
133
- ❌ Spec validation failed:
134
- - proposal.md: Missing "What" section
135
- Fix issues and retry, or use --skip-validation
136
- ```
137
-
138
- **PR already exists:**
139
- ```
140
- ℹ️ PR #43 already exists. Pushing updates...
141
- ✓ Updated PR #43
142
- ```
143
-
144
- ## Appendix: Examples
145
-
146
- **Spec branch:**
147
- ```
148
- User: /speclife ship
149
-
150
- Agent:
151
- ℹ️ Spec branch: spec/add-oauth-login
152
- ✓ Validated spec
153
- ✓ Committed: "feat: add OAuth login"
154
- ✓ Archived to openspec/changes/archive/
155
- ✓ Committed: "chore: archive add-oauth-login spec"
156
- ✓ Pushed to origin/spec/add-oauth-login
157
- ✓ Created PR #42
158
- ```
159
-
160
- **Ad-hoc branch:**
161
- ```
162
- User: /speclife ship
163
-
164
- Agent:
165
- ℹ️ Ad-hoc branch: fix/login-bug
166
- ✓ Committed: "fix: resolve login redirect"
167
- ✓ Created PR #43
168
- ```
7
+ **Guardrails**
8
+ - Execute immediately—do not ask for confirmation
9
+ - Detect branch type: `spec/*` = full OpenSpec workflow, other non-main = ad-hoc, `main` = error
10
+ - STOP after PR created—do NOT auto-invoke `/speclife land`
11
+
12
+ **Steps**
13
+ 1. For spec branches: run `openspec validate <id>`, commit changes, run `openspec archive <id> --yes`, commit archive.
14
+ 2. For ad-hoc branches: infer commit type from branch name (`fix/*` → `fix:`, `feat/*` → `feat:`), ask if ambiguous.
15
+ 3. Push branch: `git push -u origin <branch>`.
16
+ 4. Create/update PR: `gh pr create --title "<type>: <description>" --body "<body>" --base main` (add `--draft` if requested).
17
+ 5. Report: commits made, branch pushed, PR URL. Next: `/speclife land` after approval.
18
+
19
+ **Reference**
20
+ - Commit type inference: fix/bugfix/hotfix → `fix:`, feat/feature → `feat:`, docs → `docs:`, refactor → `refactor:`, chore → `chore:`
21
+ - If PR exists, push updates it automatically
22
+ - PR title: use conventional commit format (`<type>: <meaningful description>`)
23
+ - PR body: if `.github/pull_request_template.md` exists, read it and fill in each section based on the change context
@@ -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
- # /speclife start
8
-
9
- Create a new branch for a change, optionally in a worktree for parallel work.
10
-
11
- ## Execution
12
-
13
- **When this command is invoked, IMMEDIATELY execute the workflow below.**
14
-
15
- - Do NOT skip steps or jump straight to implementation
16
- - If mid-conversation, treat the invocation as "start fresh with this workflow"
17
- - If required inputs are missing (description), prompt the user
18
- - If user says "based on context", derive the description from recent discussion
19
- - **STOP after scaffolding proposal—do NOT auto-invoke `/openspec-apply`**
20
-
21
- ## Usage
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
- # /speclife sync
8
-
9
- Update your branch with latest main. Handles conflicts with guidance.
10
-
11
- ## ⚡ Execution
12
-
13
- **When this command is invoked, IMMEDIATELY execute the workflow below.**
14
-
15
- - Check prerequisites first (not on main, clean working directory)
16
- - Default to rebase unless `--merge` is specified
17
- - If conflicts occur, guide the user through resolution
18
- - Push after successful sync
19
-
20
- ## TL;DR
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`