@speclife/cli 0.5.0 → 0.6.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.
@@ -0,0 +1,292 @@
1
+ # /speclife setup
2
+
3
+ Discover project configuration and populate `openspec/speclife.md`.
4
+
5
+ ## ⚡ Execution
6
+
7
+ **When this command is invoked, IMMEDIATELY execute the workflow below.**
8
+
9
+ - Scan project files to detect build system and commands
10
+ - Check for existing workflows and context files
11
+ - Update `openspec/speclife.md` with discovered configuration
12
+ - Offer to create publish workflow if missing (ask first)
13
+
14
+ ## Goal
15
+
16
+ Auto-detect project commands (test, build, lint), publishing configuration, and context files to configure speclife for this project.
17
+
18
+ ## Steps
19
+
20
+ 1. **Read current config**: Check if `openspec/speclife.md` exists and what's already configured
21
+
22
+ 2. **Detect build system**: Look for project configuration files:
23
+ - `package.json` → Node.js (npm/yarn/pnpm)
24
+ - `Cargo.toml` → Rust (cargo)
25
+ - `go.mod` → Go
26
+ - `Makefile` → Make-based
27
+ - `pyproject.toml` or `setup.py` → Python
28
+ - `build.gradle` or `pom.xml` → Java
29
+
30
+ 3. **Extract commands**: From the detected build system, find:
31
+ - **Test command**: e.g., `npm test`, `cargo test`, `make test`
32
+ - **Build command**: e.g., `npm run build`, `cargo build`, `make build`
33
+ - **Lint command**: e.g., `npm run lint`, `cargo clippy`, `make lint`
34
+
35
+ 4. **Detect publish configuration**: Based on project type:
36
+
37
+ | Project Type | Detection | Registry | Secret Required |
38
+ |--------------|-----------|----------|-----------------|
39
+ | Node.js | `package.json` with `name` (not private) | npm | `NPM_TOKEN` |
40
+ | Node.js monorepo | `workspaces` in package.json | npm | `NPM_TOKEN` |
41
+ | Rust | `Cargo.toml` with `[package]` | crates.io | `CARGO_REGISTRY_TOKEN` |
42
+ | Python | `pyproject.toml` with `[project]` | PyPI | `PYPI_TOKEN` |
43
+ | Go | `go.mod` | N/A (no central registry) | None |
44
+ | Internal/private | `"private": true` in package.json | N/A | None |
45
+
46
+ 5. **Check for existing workflows**: Look in `.github/workflows/` for:
47
+ - `publish.yml` or similar publish workflow
48
+ - `release.yml` - release workflow
49
+
50
+ 6. **Identify context files**: Look for common documentation:
51
+ - `openspec/project.md` - project context
52
+ - `openspec/AGENTS.md` - agent guidelines
53
+ - `README.md` - project overview
54
+ - `CONTRIBUTING.md` - contribution guidelines
55
+
56
+ 7. **Update speclife.md**: Write discovered values to `openspec/speclife.md`
57
+
58
+ 8. **Offer to create publish workflow** (if missing):
59
+ - If no publish workflow exists AND project is publishable (not private, not Go):
60
+ - Ask: "No publish workflow found. Would you like me to create `.github/workflows/publish.yml`?"
61
+ - If user agrees, create the appropriate workflow from the templates below
62
+ - Remind user to add the required secret in repo settings
63
+ - If project is private (`"private": true`) or Go (no central registry):
64
+ - Skip this step (no publish workflow needed)
65
+
66
+ 9. **Report**: Tell the user what was configured and any next steps
67
+
68
+ ## Publish Workflow Templates
69
+
70
+ Use these templates when creating publish workflows:
71
+
72
+ ### Node.js (single package)
73
+ ```yaml
74
+ # .github/workflows/publish.yml
75
+ name: Publish to npm
76
+ on:
77
+ release:
78
+ types: [published]
79
+
80
+ jobs:
81
+ publish:
82
+ runs-on: ubuntu-latest
83
+ steps:
84
+ - uses: actions/checkout@v4
85
+ - uses: actions/setup-node@v4
86
+ with:
87
+ node-version: '20'
88
+ registry-url: 'https://registry.npmjs.org'
89
+ - run: npm ci
90
+ - run: npm test
91
+ - run: npm publish --access public
92
+ env:
93
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
94
+ ```
95
+
96
+ ### Node.js (monorepo with workspaces)
97
+ ```yaml
98
+ # .github/workflows/publish.yml
99
+ name: Publish to npm
100
+ on:
101
+ release:
102
+ types: [published]
103
+
104
+ jobs:
105
+ publish:
106
+ runs-on: ubuntu-latest
107
+ steps:
108
+ - uses: actions/checkout@v4
109
+ - uses: actions/setup-node@v4
110
+ with:
111
+ node-version: '20'
112
+ registry-url: 'https://registry.npmjs.org'
113
+ - run: npm ci
114
+ - run: npm run build
115
+ - run: npm test
116
+ # Publish each workspace package
117
+ - run: npm publish -w packages/<package-name> --access public
118
+ env:
119
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
120
+ ```
121
+
122
+ ### Rust
123
+ ```yaml
124
+ # .github/workflows/publish.yml
125
+ name: Publish to crates.io
126
+ on:
127
+ release:
128
+ types: [published]
129
+
130
+ jobs:
131
+ publish:
132
+ runs-on: ubuntu-latest
133
+ steps:
134
+ - uses: actions/checkout@v4
135
+ - uses: dtolnay/rust-toolchain@stable
136
+ - run: cargo test
137
+ - run: cargo publish
138
+ env:
139
+ CARGO_REGISTRY_TOKEN: ${{ secrets.CARGO_REGISTRY_TOKEN }}
140
+ ```
141
+
142
+ ### Python
143
+ ```yaml
144
+ # .github/workflows/publish.yml
145
+ name: Publish to PyPI
146
+ on:
147
+ release:
148
+ types: [published]
149
+
150
+ jobs:
151
+ publish:
152
+ runs-on: ubuntu-latest
153
+ steps:
154
+ - uses: actions/checkout@v4
155
+ - uses: actions/setup-python@v5
156
+ with:
157
+ python-version: '3.11'
158
+ - run: pip install build twine
159
+ - run: python -m build
160
+ - run: twine upload dist/*
161
+ env:
162
+ TWINE_USERNAME: __token__
163
+ TWINE_PASSWORD: ${{ secrets.PYPI_TOKEN }}
164
+ ```
165
+
166
+ ## Output
167
+
168
+ Update `openspec/speclife.md` with discovered configuration:
169
+
170
+ ```markdown
171
+ # SpecLife Configuration
172
+
173
+ ## Commands
174
+
175
+ - **Test:** `<detected-test-command>`
176
+ - **Build:** `<detected-build-command>`
177
+ - **Lint:** `<detected-lint-command>`
178
+
179
+ ## Release Policy
180
+
181
+ - **Auto-release:** patch and minor versions
182
+ - **Manual release:** major versions (breaking changes)
183
+
184
+ ## Publish
185
+
186
+ - **Registry:** npm / PyPI / crates.io / None
187
+ - **Workflow:** .github/workflows/publish.yml (exists / TODO)
188
+ - **Secret:** NPM_TOKEN / PYPI_TOKEN / CARGO_REGISTRY_TOKEN
189
+
190
+ ## Context Files
191
+
192
+ When implementing changes, always read:
193
+ - `openspec/project.md` - project context and conventions
194
+ - `openspec/AGENTS.md` - agent guidelines
195
+ - `README.md` - project overview
196
+ ```
197
+
198
+ ## Example Output
199
+
200
+ ### When publish workflow exists:
201
+ ```
202
+ User: /speclife setup
203
+
204
+ Agent:
205
+ Detecting project configuration...
206
+
207
+ ✓ Project type: Node.js monorepo (npm workspaces)
208
+ ✓ Packages: @speclife/core, @speclife/cli, @speclife/mcp-server
209
+
210
+ Commands detected:
211
+ ✓ Test: npm test
212
+ ✓ Build: npm run build
213
+ ✓ Lint: npm run lint
214
+
215
+ Workflows:
216
+ ✓ Release: .github/workflows/release.yml
217
+ ✓ Publish: .github/workflows/publish.yml
218
+
219
+ Context files:
220
+ ✓ openspec/project.md
221
+ ✓ openspec/AGENTS.md
222
+ ✓ README.md
223
+
224
+ ✓ Updated openspec/speclife.md
225
+ ```
226
+
227
+ ### When publish workflow is missing:
228
+ ```
229
+ User: /speclife setup
230
+
231
+ Agent:
232
+ Detecting project configuration...
233
+
234
+ ✓ Project type: Node.js (single package)
235
+ ✓ Package: my-awesome-lib
236
+
237
+ Commands detected:
238
+ ✓ Test: npm test
239
+ ✓ Build: npm run build
240
+ ✓ Lint: npm run lint
241
+
242
+ Workflows:
243
+ ✓ Release: .github/workflows/release.yml
244
+ ⚠ Publish: Not found
245
+
246
+ This package appears to be publishable to npm. Would you like me to create
247
+ `.github/workflows/publish.yml`?
248
+
249
+ User: yes
250
+
251
+ Agent:
252
+ ✓ Created .github/workflows/publish.yml
253
+
254
+ ⚠️ Remember to add NPM_TOKEN to your repository secrets:
255
+ GitHub → Settings → Secrets and variables → Actions → New repository secret
256
+
257
+ Get your token from: https://www.npmjs.com/settings/~/tokens
258
+
259
+ ✓ Updated openspec/speclife.md
260
+
261
+ Done! Your project is configured for automated releases and publishing.
262
+ ```
263
+
264
+ ### When project is private:
265
+ ```
266
+ User: /speclife setup
267
+
268
+ Agent:
269
+ Detecting project configuration...
270
+
271
+ ✓ Project type: Node.js (private package)
272
+
273
+ Commands detected:
274
+ ✓ Test: npm test
275
+ ✓ Build: npm run build
276
+
277
+ Workflows:
278
+ ✓ Release: .github/workflows/release.yml
279
+ ℹ Publish: Not needed (private package)
280
+
281
+ ✓ Updated openspec/speclife.md
282
+ ```
283
+
284
+ ## Notes
285
+
286
+ - If a command can't be detected, leave it as a TODO for the user
287
+ - Don't overwrite user customizations if speclife.md already exists
288
+ - This command is idempotent - safe to run multiple times
289
+ - Always ask before creating publish workflow (don't auto-create)
290
+ - Remind about secrets after creating publish workflow
291
+
292
+
@@ -0,0 +1,154 @@
1
+ ---
2
+ name: /speclife/ship
3
+ id: speclife-ship
4
+ category: SpecLife
5
+ description: Commit changes, push to remote, and create a PR for review.
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 + archive spec
31
+ 3. Stage, commit, push
32
+ 4. 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
+ - **⚡ Required:** Invoke `/openspec-archive <change-id>` command
54
+ - Do NOT manually `mv` files—the command updates project.md and specs
55
+ - Wait for archive confirmation before proceeding
56
+ - Read proposal.md for commit message
57
+
58
+ ### 2. Ad-hoc Branch Only
59
+ - Infer commit type from branch name (`fix/*` → `fix:`, `feat/*` → `feat:`)
60
+ - Ask user for commit message if needed
61
+
62
+ ### 3. All Branches
63
+ ```bash
64
+ git add -A
65
+ git commit -m "<type>: <description>" # if uncommitted changes
66
+ git push -u origin <branch>
67
+ ```
68
+
69
+ ### 4. Create PR
70
+ ```bash
71
+ # Check if PR exists
72
+ gh pr view --json url 2>/dev/null
73
+
74
+ # If not, create
75
+ gh pr create --fill --base main
76
+ # Or: gh pr create --fill --base main --draft
77
+ ```
78
+
79
+ ### 5. Report and STOP
80
+ ```
81
+ ✓ Committed: "feat: description"
82
+ ✓ Pushed to origin/<branch>
83
+ ✓ Created PR #42: <url>
84
+
85
+ Next: After approval, run /speclife land
86
+ ```
87
+
88
+ **⛔ STOP HERE.** Do NOT proceed to merge. Wait for:
89
+ 1. PR review and approval
90
+ 2. User to invoke `/speclife land`
91
+
92
+ ---
93
+
94
+ <!-- REFERENCE SECTIONS - Read only when needed -->
95
+
96
+ ## Appendix: Commit Type Inference
97
+
98
+ | Branch Pattern | Commit Type |
99
+ |----------------|-------------|
100
+ | `fix/*`, `bugfix/*`, `hotfix/*` | `fix:` |
101
+ | `feat/*`, `feature/*` | `feat:` |
102
+ | `docs/*` | `docs:` |
103
+ | `refactor/*` | `refactor:` |
104
+ | `chore/*` | `chore:` |
105
+ | Other | Ask user |
106
+
107
+ ## Appendix: Error Handling
108
+
109
+ **Cannot ship from main:**
110
+ ```
111
+ ❌ Cannot ship from main. Create a branch first.
112
+ ```
113
+
114
+ **No changes:**
115
+ ```
116
+ ❌ No changes to ship. Working directory clean.
117
+ ```
118
+
119
+ **Spec validation failed:**
120
+ ```
121
+ ❌ Spec validation failed:
122
+ - proposal.md: Missing "What" section
123
+ Fix issues and retry, or use --skip-validation
124
+ ```
125
+
126
+ **PR already exists:**
127
+ ```
128
+ ℹ️ PR #43 already exists. Pushing updates...
129
+ ✓ Updated PR #43
130
+ ```
131
+
132
+ ## Appendix: Examples
133
+
134
+ **Spec branch:**
135
+ ```
136
+ User: /speclife ship
137
+
138
+ Agent:
139
+ ℹ️ Spec branch: spec/add-oauth-login
140
+ ✓ Validated spec
141
+ ✓ Archived to openspec/changes/archive/
142
+ ✓ Committed: "feat: add OAuth login"
143
+ ✓ Created PR #42
144
+ ```
145
+
146
+ **Ad-hoc branch:**
147
+ ```
148
+ User: /speclife ship
149
+
150
+ Agent:
151
+ ℹ️ Ad-hoc branch: fix/login-bug
152
+ ✓ Committed: "fix: resolve login redirect"
153
+ ✓ Created PR #43
154
+ ```
@@ -0,0 +1,145 @@
1
+ ---
2
+ name: /speclife/start
3
+ id: speclife-start
4
+ category: SpecLife
5
+ description: Create a new branch for a change, optionally in a worktree for parallel work.
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> # Worktree (default)
25
+ /speclife start <description> in a branch # Branch-only
26
+ /speclife start # Interactive
27
+ ```
28
+
29
+ ## Goal
30
+
31
+ Set up a workspace for a new change with proper git branch.
32
+
33
+ ## Mode Detection
34
+
35
+ Parse the input for workflow hints:
36
+
37
+ | Phrase in input | Mode |
38
+ |-----------------|------|
39
+ | "in a branch", "branch only", "no worktree", "simple" | **Branch-only** |
40
+ | "in a worktree", "with worktree", "parallel" | **Worktree** |
41
+ | Neither | **Worktree** (default) |
42
+
43
+ Strip workflow hints from the description before deriving change-id.
44
+
45
+ ## Steps
46
+
47
+ ### 1. Derive change-id
48
+
49
+ Convert description to kebab-case:
50
+ - "Add user authentication" → `add-user-auth`
51
+ - Prefix with verb: add-, fix-, update-, remove-, refactor-
52
+ - Keep it short (3-5 words max)
53
+
54
+ ### 2. Create branch/worktree
55
+
56
+ **Branch-only mode:**
57
+ ```bash
58
+ git checkout -b spec/<change-id>
59
+ ```
60
+ - Works in current directory
61
+ - One change at a time (switch branches to context-switch)
62
+
63
+ **Worktree mode (default):**
64
+ ```bash
65
+ speclife worktree create <change-id>
66
+ ```
67
+ - Creates `worktrees/<change-id>/`
68
+ - Creates branch `spec/<change-id>`
69
+ - Parallel changes possible
70
+
71
+ ### 3. Scaffold proposal
72
+
73
+ Invoke `/openspec-proposal` with the description (minus workflow hints)
74
+ - Creates `openspec/changes/<change-id>/proposal.md`
75
+ - Creates `openspec/changes/<change-id>/tasks.md`
76
+
77
+ ### 4. Report and STOP
78
+
79
+ **Branch-only:**
80
+ ```
81
+ ✓ Derived change-id: add-oauth-login
82
+ ✓ Created branch spec/add-oauth-login
83
+ ✓ Scaffolded proposal at openspec/changes/add-oauth-login/
84
+
85
+ Next: Review the proposal, then run `/openspec-apply` to implement.
86
+ ```
87
+
88
+ **Worktree:**
89
+ ```
90
+ ✓ Derived change-id: add-oauth-login
91
+ ✓ Created worktree at worktrees/add-oauth-login/
92
+ ✓ Created branch spec/add-oauth-login
93
+ ✓ Scaffolded proposal at openspec/changes/add-oauth-login/
94
+
95
+ Next: cd worktrees/add-oauth-login/ then run `/openspec-apply`.
96
+ ```
97
+
98
+ **⛔ STOP HERE.** Do NOT proceed to implementation. Wait for user to:
99
+ 1. Review the proposal
100
+ 2. Invoke `/openspec-apply` or `/speclife implement`
101
+
102
+ ## Examples
103
+
104
+ ```
105
+ User: /speclife start "Add OAuth login support"
106
+ → Creates worktree (default)
107
+
108
+ User: /speclife start "Add OAuth login" in a branch
109
+ → Creates branch only, no worktree
110
+
111
+ User: /speclife start "fix login bug" branch only
112
+ → Creates branch only
113
+
114
+ User: /speclife start
115
+ → Prompts: "Describe your change" then "Worktree (default) or branch-only?"
116
+ ```
117
+
118
+ ## Tradeoffs
119
+
120
+ | Aspect | Worktree | Branch-only |
121
+ |--------|----------|-------------|
122
+ | Parallel changes | ✓ Multiple worktrees | One at a time |
123
+ | IDE support | May need reload | Seamless |
124
+ | Setup complexity | More dirs | Simpler |
125
+ | Context switching | cd to worktree | git checkout |
126
+
127
+ ## Naming Conventions
128
+
129
+ - Use kebab-case for change-id
130
+ - Prefix with action verb: `add-`, `fix-`, `update-`, `remove-`, `refactor-`
131
+ - Keep it descriptive but concise
132
+ - Examples:
133
+ - `add-user-auth`
134
+ - `fix-login-redirect`
135
+ - `update-api-docs`
136
+ - `remove-deprecated-endpoint`
137
+ - `refactor-database-layer`
138
+
139
+ ## Notes
140
+
141
+ - Branch name is always `spec/<change-id>` regardless of mode
142
+ - If branch exists, error and suggest using existing
143
+ - Branch-only: uncommitted changes carry over (stash if needed)
144
+ - Worktree: clean checkout from main
145
+ - To switch modes later, use `/speclife convert`