sddflow 2.7.0__tar.gz
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.
- sddflow-2.7.0/.gitignore +9 -0
- sddflow-2.7.0/PKG-INFO +639 -0
- sddflow-2.7.0/README.md +607 -0
- sddflow-2.7.0/pyproject.toml +59 -0
- sddflow-2.7.0/sdd/__init__.py +1 -0
- sddflow-2.7.0/sdd/__main__.py +30 -0
- sddflow-2.7.0/sdd/commands/__init__.py +0 -0
- sddflow-2.7.0/sdd/commands/config.py +268 -0
- sddflow-2.7.0/sdd/commands/confluence.py +376 -0
- sddflow-2.7.0/sdd/commands/cr.py +257 -0
- sddflow-2.7.0/sdd/commands/init.py +279 -0
- sddflow-2.7.0/sdd/commands/jira.py +262 -0
- sddflow-2.7.0/sdd/commands/pr.py +308 -0
- sddflow-2.7.0/sdd/commands/review.py +608 -0
- sddflow-2.7.0/sdd/commands/upgrade.py +100 -0
- sddflow-2.7.0/sdd/utils/__init__.py +0 -0
- sddflow-2.7.0/sdd/utils/atlassian_auth.py +108 -0
- sddflow-2.7.0/sdd/utils/cf_to_md.py +81 -0
- sddflow-2.7.0/sdd/utils/confluence_client.py +170 -0
- sddflow-2.7.0/sdd/utils/detect.py +97 -0
- sddflow-2.7.0/sdd/utils/git_host.py +657 -0
- sddflow-2.7.0/sdd/utils/integrations.py +165 -0
- sddflow-2.7.0/sdd/utils/jira_client.py +86 -0
- sddflow-2.7.0/sdd/utils/manifest.py +44 -0
- sddflow-2.7.0/sdd/utils/md_to_cf.py +139 -0
- sddflow-2.7.0/sdd/utils/scaffold.py +85 -0
- sddflow-2.7.0/sdd/utils/sdd_parser.py +194 -0
- sddflow-2.7.0/sdd/utils/validate.py +37 -0
sddflow-2.7.0/.gitignore
ADDED
sddflow-2.7.0/PKG-INFO
ADDED
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: sddflow
|
|
3
|
+
Version: 2.7.0
|
|
4
|
+
Summary: SDD Framework CLI — initialize and upgrade Spec-Driven Development packs
|
|
5
|
+
Project-URL: Homepage, https://github.com/sunil1983us/universalguide
|
|
6
|
+
Project-URL: Repository, https://github.com/sunil1983us/universalguide
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/sunil1983us/universalguide/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/sunil1983us/universalguide/blob/main/CHANGELOG.md
|
|
9
|
+
Author-email: Sunil Kumar <sunil1983.us@gmail.com>
|
|
10
|
+
License: MIT
|
|
11
|
+
Keywords: ai,claude,llm,sdd,sdlc,spec-driven-development,specification
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Software Development
|
|
23
|
+
Classifier: Topic :: Software Development :: Documentation
|
|
24
|
+
Classifier: Topic :: Utilities
|
|
25
|
+
Requires-Python: >=3.9
|
|
26
|
+
Requires-Dist: click>=8.0
|
|
27
|
+
Requires-Dist: pyyaml>=6.0
|
|
28
|
+
Requires-Dist: questionary>=2.0
|
|
29
|
+
Requires-Dist: requests>=2.28
|
|
30
|
+
Requires-Dist: rich>=13.0
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# sddflow (Python) — SDD Framework CLI
|
|
34
|
+
|
|
35
|
+
Python CLI for the SDD (Spec-Driven Development) Framework.
|
|
36
|
+
Mirrors the Node.js CLI exactly and adds Jira + Confluence integration.
|
|
37
|
+
|
|
38
|
+
## Install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
pip install sddflow
|
|
42
|
+
sdd init
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Requirements:** Python ≥ 3.9
|
|
46
|
+
|
|
47
|
+
For development / contributors:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
git clone https://github.com/sunil1983us/universalguide.git
|
|
51
|
+
pip install -e ./universalguide/cli-python
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Commands
|
|
57
|
+
|
|
58
|
+
### `sdd init`
|
|
59
|
+
|
|
60
|
+
Initialize an SDD pack in the current project directory.
|
|
61
|
+
Replaces `bash setup.sh` / `.\setup.ps1`.
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
# Interactive (recommended)
|
|
65
|
+
sdd init
|
|
66
|
+
|
|
67
|
+
# Non-interactive
|
|
68
|
+
sdd init --project "my-payments-api" \
|
|
69
|
+
--feature "user-authentication" \
|
|
70
|
+
--scope pilot \
|
|
71
|
+
--type backend-service
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
| Flag | Description | Default |
|
|
75
|
+
|---|---|---|
|
|
76
|
+
| `-p, --project <name>` | Project name | prompted |
|
|
77
|
+
| `-f, --feature <name>` | First feature name | prompted |
|
|
78
|
+
| `-s, --scope <scope>` | `pilot` \| `mvp` \| `full` | prompted |
|
|
79
|
+
| `-t, --type <type>` | Project type (auto-detected if omitted) | auto |
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
### `sdd upgrade`
|
|
84
|
+
|
|
85
|
+
Migrate an existing project's `manifest.yml` to the current pack version.
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
sdd upgrade
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
---
|
|
92
|
+
|
|
93
|
+
### `sdd config init`
|
|
94
|
+
|
|
95
|
+
Interactive setup wizard — creates `~/.sdd/config.yml` (auth profile) and
|
|
96
|
+
`.specify/integrations.yml` (project field mappings).
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
sdd config init
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Walks through:
|
|
103
|
+
1. Profile name (e.g. `work-cloud`, `on-prem`)
|
|
104
|
+
2. Atlassian base URL
|
|
105
|
+
3. Auth mode — see [Auth Modes](#auth-modes) below
|
|
106
|
+
4. Credential env var names (never the values themselves)
|
|
107
|
+
5. Optionally scaffolds `.specify/integrations.yml`
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
### `sdd config test`
|
|
112
|
+
|
|
113
|
+
Ping Jira and Confluence to verify credentials are working.
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
sdd config test
|
|
117
|
+
sdd config test --profile on-prem
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Output:
|
|
121
|
+
```
|
|
122
|
+
✓ Jira — connected as Jane Smith
|
|
123
|
+
✓ Confluence — connected as Jane Smith
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
### `sdd config fields`
|
|
129
|
+
|
|
130
|
+
List all Jira custom field IDs for your instance.
|
|
131
|
+
Use this to find the right IDs for `integrations.yml → custom_fields`.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
sdd config fields
|
|
135
|
+
sdd config fields --project MYPROJ
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Output:
|
|
139
|
+
```
|
|
140
|
+
ID Name Type
|
|
141
|
+
───────────────────────────── ─────────────────────────────────────── ────────────
|
|
142
|
+
customfield_10016 Story Points number
|
|
143
|
+
customfield_10021 Acceptance Criteria string
|
|
144
|
+
customfield_10100 Team string
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
### `sdd jira push`
|
|
150
|
+
|
|
151
|
+
Create or update Jira issues from `stories.md` and `tasks.md`.
|
|
152
|
+
Hierarchy: **Feature → Story → Task** (configurable issue type names).
|
|
153
|
+
|
|
154
|
+
> Need Epic and Stories created earlier — before tasks even exist, right after
|
|
155
|
+
> BRD/Use Case/SRD approval? Use the agent's `/jira-push` slash command instead
|
|
156
|
+
> (per-pack `.specify/scripts/jira-push.py`, config in `.specify/jira-config.yml`).
|
|
157
|
+
> It pushes progressively at each SDLC gate (Epic → Story → Task → CHG) rather
|
|
158
|
+
> than all at once. See each pack's `HOW-TO-USE.md → Jira & Confluence
|
|
159
|
+
> Integration` for a side-by-side comparison.
|
|
160
|
+
|
|
161
|
+
```bash
|
|
162
|
+
sdd jira push
|
|
163
|
+
sdd jira push --dry-run # print plan, no API calls
|
|
164
|
+
sdd jira push --feature auth # override feature name
|
|
165
|
+
sdd jira push --profile on-prem # use a specific auth profile
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
**Dry-run output:**
|
|
169
|
+
```
|
|
170
|
+
Would create:
|
|
171
|
+
┌── [Feature] user-authentication
|
|
172
|
+
│ ├── [Story] STORY-001 — Login with email (must-have 3sp)
|
|
173
|
+
│ │ └── [Task] TASK-001 — JWT validation
|
|
174
|
+
│ │ └── [Task] TASK-002 — POST /auth/login endpoint
|
|
175
|
+
│ ├── [Story] STORY-002 — Password reset (should-have 2sp)
|
|
176
|
+
│ │ └── [Task] TASK-003 — Email service integration
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
**Idempotency:** Re-running never creates duplicates. Each issue is tagged
|
|
180
|
+
`sdd:STORY-001` / `sdd:TASK-001` as a unique label. On re-run, push searches
|
|
181
|
+
by that label — updates if found, creates if not.
|
|
182
|
+
|
|
183
|
+
**MoSCoW → Jira priority mapping** (configurable in `integrations.yml`):
|
|
184
|
+
|
|
185
|
+
| SDD MoSCoW | Default Jira priority |
|
|
186
|
+
|---|---|
|
|
187
|
+
| Must Have | High |
|
|
188
|
+
| Should Have | Medium |
|
|
189
|
+
| Could Have | Low |
|
|
190
|
+
| Won't Have | Lowest |
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### `sdd jira sync`
|
|
195
|
+
|
|
196
|
+
Pull Jira issue statuses back and display alongside task IDs.
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
sdd jira sync
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
Output:
|
|
203
|
+
```
|
|
204
|
+
TASK ID Jira Key Status
|
|
205
|
+
──────────── ────────────── ────────────────────
|
|
206
|
+
TASK-001 MYPROJ-42 In Progress
|
|
207
|
+
TASK-002 MYPROJ-43 To Do
|
|
208
|
+
TASK-003 — not pushed
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
### `sdd confluence push`
|
|
214
|
+
|
|
215
|
+
Publish SDD documents to Confluence pages (create or update).
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
sdd confluence push # push all docs found
|
|
219
|
+
sdd confluence push --doc hld # push one doc only
|
|
220
|
+
sdd confluence push --dry-run # print page titles, no API calls
|
|
221
|
+
sdd confluence push --feature auth # override feature name
|
|
222
|
+
sdd confluence push --profile on-prem # use a specific auth profile
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
**Which docs get pushed:**
|
|
226
|
+
Any `.md` file in `.specify/features/{feature}/` that has a matching key in
|
|
227
|
+
`integrations.yml → confluence.page_map`. Missing docs are skipped with a
|
|
228
|
+
message.
|
|
229
|
+
|
|
230
|
+
**Dry-run output:**
|
|
231
|
+
```
|
|
232
|
+
would push Todo API — High-Level Design ← .specify/features/task-management/hld.md
|
|
233
|
+
would push Todo API — Architecture Overview ← .specify/features/task-management/arch.md
|
|
234
|
+
· lld.md not found — skipped
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
**Idempotency:** Pages are matched by title in the Confluence space. If a page
|
|
238
|
+
with that title already exists, it is updated (version incremented). If not,
|
|
239
|
+
it is created under the configured parent page.
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
### `sdd review submit`
|
|
244
|
+
|
|
245
|
+
Push a document to Confluence and create a Jira review task assigned to the
|
|
246
|
+
configured reviewer.
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
sdd review submit --doc brd
|
|
250
|
+
sdd review submit --doc hld
|
|
251
|
+
sdd review submit --doc adr --feature auth
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
What it does:
|
|
255
|
+
1. Reads `.specify/features/{feature}/{doc}.md`
|
|
256
|
+
2. Converts Markdown → Confluence Storage Format, creates or updates the page
|
|
257
|
+
3. Creates (or updates) a Jira task with the label `sdd-doc:{doc}`, assigned to
|
|
258
|
+
the configured reviewer
|
|
259
|
+
|
|
260
|
+
**Sequence enforcement:** Within each phase, a document cannot be submitted
|
|
261
|
+
until its predecessor is approved (e.g. BRD must be approved before SRD can be
|
|
262
|
+
submitted). The CLI refuses with a clear message if the predecessor is not yet
|
|
263
|
+
approved.
|
|
264
|
+
|
|
265
|
+
---
|
|
266
|
+
|
|
267
|
+
### `sdd review check`
|
|
268
|
+
|
|
269
|
+
Check the review status of a submitted document. Exits with a code the agent
|
|
270
|
+
uses to decide the next step.
|
|
271
|
+
|
|
272
|
+
```bash
|
|
273
|
+
sdd review check --doc brd
|
|
274
|
+
sdd review check --doc srd --profile on-prem
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
**Exit codes:**
|
|
278
|
+
|
|
279
|
+
| Code | Meaning | Agent action |
|
|
280
|
+
|---|---|---|
|
|
281
|
+
| `0` | Approved | Advance to next document / phase |
|
|
282
|
+
| `1` | Needs revision | Print comments; agent edits doc, then calls `sdd review apply` |
|
|
283
|
+
| `2` | Pending | Waiting for reviewer — do not advance |
|
|
284
|
+
| `3` | Not submitted | Run `sdd review submit` first |
|
|
285
|
+
|
|
286
|
+
**Approval detection:** A document is approved when the Jira task status is in
|
|
287
|
+
`approved_statuses` (default: `Done`, `Approved`) **or** any comment contains
|
|
288
|
+
a keyword from `approved_keywords` (default: `approved`, `lgtm`, `looks good`,
|
|
289
|
+
`go ahead`, `confirmed`).
|
|
290
|
+
|
|
291
|
+
---
|
|
292
|
+
|
|
293
|
+
### `sdd review apply`
|
|
294
|
+
|
|
295
|
+
After the agent addresses reviewer comments, re-push the updated document to
|
|
296
|
+
Confluence and notify the reviewer in Jira with a comment.
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
sdd review apply --doc brd
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Typical agent workflow:
|
|
303
|
+
```
|
|
304
|
+
sdd review check --doc brd # exit 1: NEEDS_REVISION
|
|
305
|
+
# (agent edits .specify/features/{feature}/brd.md)
|
|
306
|
+
sdd review apply --doc brd # re-push + notify reviewer
|
|
307
|
+
sdd review check --doc brd # poll again after reviewer re-reviews
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
---
|
|
311
|
+
|
|
312
|
+
### `sdd review approve` (no-Jira / chat approvals)
|
|
313
|
+
|
|
314
|
+
Record an approval locally when Jira is not configured — the agent runs this
|
|
315
|
+
automatically after the user says "approved" in chat.
|
|
316
|
+
|
|
317
|
+
```bash
|
|
318
|
+
sdd review approve --doc brd --local --by "Product Owner" --note "approved in chat"
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
What it does:
|
|
322
|
+
1. Writes an audit record to `.specify/.local-approvals.yml`
|
|
323
|
+
(`sdd review check` then returns exit 0 for this document)
|
|
324
|
+
2. Flips the document header `Status: Draft` → `Status: Approved` if the agent
|
|
325
|
+
has not already done so
|
|
326
|
+
3. If a `confluence:` section exists in `.specify/integrations.yml`, updates the
|
|
327
|
+
document's existing Confluence page so it matches the approved `.md`
|
|
328
|
+
(skip with `--no-confluence`; a Confluence failure never blocks the approval —
|
|
329
|
+
re-try with `sdd confluence push --doc {name}`)
|
|
330
|
+
|
|
331
|
+
The `Status: Approved` header in the `.md` is the authoritative gate in every
|
|
332
|
+
mode — Jira and Confluence are integrations on top of it, never a prerequisite.
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### `sdd review status`
|
|
337
|
+
|
|
338
|
+
Show the review state of every document in all phases at a glance.
|
|
339
|
+
|
|
340
|
+
```bash
|
|
341
|
+
sdd review status
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
Output:
|
|
345
|
+
```
|
|
346
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
347
|
+
Review Status
|
|
348
|
+
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
|
349
|
+
|
|
350
|
+
SPECIFY phase
|
|
351
|
+
✓ BRD Approved Product Owner
|
|
352
|
+
✓ SRD Approved Business Analyst
|
|
353
|
+
⏳ ARCH Pending Architect
|
|
354
|
+
🔒 HLD Blocked Architect
|
|
355
|
+
|
|
356
|
+
PLANNING phase
|
|
357
|
+
· LLD Not Submitted Tech Lead
|
|
358
|
+
· ADR Not Submitted Architect
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
Blocked = predecessor in the same phase is not yet approved.
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### `sdd pr create`
|
|
366
|
+
|
|
367
|
+
Create a git branch and a PR for a task, linked back to its Jira issue — on
|
|
368
|
+
**GitHub, GitLab, Bitbucket, or Azure DevOps**. The host is auto-detected from
|
|
369
|
+
`git remote get-url origin`; nothing to configure to pick one.
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
sdd pr create --task TASK-001
|
|
373
|
+
sdd pr create --task TASK-002 --base develop
|
|
374
|
+
sdd pr create --task TASK-003 --feature auth
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
What it does:
|
|
378
|
+
1. Looks up `TASK-001` in `.specify/features/{feature}/tasks.md`
|
|
379
|
+
2. Searches Jira for the issue with label `sdd:TASK-001` (if Jira is configured)
|
|
380
|
+
3. Creates and pushes a git branch using `branch_pattern` from `integrations.yml`
|
|
381
|
+
4. Detects the git host and creates a PR there with the task description and
|
|
382
|
+
acceptance criteria in the body, linked to the Jira issue:
|
|
383
|
+
- **GitHub** — via the `gh` CLI
|
|
384
|
+
- **GitLab** — via the `glab` CLI, or the REST API if you set `GITLAB_TOKEN`
|
|
385
|
+
instead of installing glab
|
|
386
|
+
- **Bitbucket** — via the REST API, using `BITBUCKET_USERNAME` +
|
|
387
|
+
`BITBUCKET_APP_PASSWORD` (Bitbucket has no CLI as ubiquitous as gh/glab)
|
|
388
|
+
- **Azure DevOps** — via the `az` CLI (`azure-devops` extension)
|
|
389
|
+
5. Posts the PR URL as a comment on the Jira task
|
|
390
|
+
|
|
391
|
+
**Branch / PR title patterns** (configurable in `integrations.yml`, apply to
|
|
392
|
+
every host the same way):
|
|
393
|
+
|
|
394
|
+
| Config key | Default | Example output |
|
|
395
|
+
|---|---|---|
|
|
396
|
+
| `branch_pattern` | `feature/{task_id}-{slug}` | `feature/task-001-jwt-validation` |
|
|
397
|
+
| `pr_title_pattern` | `feat({task_id}): {title}` | `feat(TASK-001): JWT validation` |
|
|
398
|
+
|
|
399
|
+
**Fallback:** If the detected host's CLI/token isn't set up (or the host isn't
|
|
400
|
+
recognized — e.g. self-hosted git), the branch is still created and pushed;
|
|
401
|
+
the PR title + body are printed so you can paste them in manually.
|
|
402
|
+
|
|
403
|
+
**CI on other hosts:** `.github/workflows/quality-gate.yml` (GitHub Actions)
|
|
404
|
+
is the reference implementation of the PR-size / TASK-NNN-reference /
|
|
405
|
+
build-test-coverage / secret-scan / SCA rules. Each pack also ships
|
|
406
|
+
`bitbucket-pipelines.yml`, `.gitlab-ci.yml`, and `azure-pipelines.yml` at the
|
|
407
|
+
repo root, mirroring the same rules in that host's native syntax — only the
|
|
408
|
+
file matching your actual host is ever read; the others are inert. These are
|
|
409
|
+
starter templates like the GitHub one: adjust build/test commands for your
|
|
410
|
+
Tech Stack, and verify once against your real pipeline before relying on it.
|
|
411
|
+
|
|
412
|
+
---
|
|
413
|
+
|
|
414
|
+
### `/pre-review` (agent command)
|
|
415
|
+
|
|
416
|
+
Run a one-time code pre-review on the current task before the PR is created.
|
|
417
|
+
Controlled by `code_review.pre_review` in `integrations.yml`.
|
|
418
|
+
|
|
419
|
+
```
|
|
420
|
+
/pre-review # infer task from current branch
|
|
421
|
+
/pre-review TASK-001 # explicit task ID
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**What it does:**
|
|
425
|
+
1. Checks `code_review.pre_review` — if `false`, skips and calls `sdd pr create` directly
|
|
426
|
+
2. Reads the diff (`git diff main...HEAD`)
|
|
427
|
+
3. Analyses for: correctness bugs, removed behaviour, security issues, cross-file impact, quality, performance
|
|
428
|
+
4. Presents a numbered checklist to the developer
|
|
429
|
+
5. Developer picks which items to fix (`all`, `none`, or `1,3`)
|
|
430
|
+
6. Agent applies selected fixes and commits
|
|
431
|
+
7. Saves pre-review summary to `.specify/features/{feature}/.pre-review-{task}.md`
|
|
432
|
+
8. Calls `sdd pr create --task {task}` — summary is included in the PR body automatically
|
|
433
|
+
|
|
434
|
+
**Runs once per task** — do not re-run after fixes are applied.
|
|
435
|
+
|
|
436
|
+
---
|
|
437
|
+
|
|
438
|
+
### `/address-review` (agent command)
|
|
439
|
+
|
|
440
|
+
Read unresolved human review comments from a PR, apply developer-selected fixes,
|
|
441
|
+
reply to threads, and request re-review. Repeatable — run once per review round.
|
|
442
|
+
Works on **GitHub, GitLab, Bitbucket, and Azure DevOps** — same host
|
|
443
|
+
auto-detection as `sdd pr create`.
|
|
444
|
+
|
|
445
|
+
```
|
|
446
|
+
/address-review # infer PR from current branch
|
|
447
|
+
/address-review 42 # explicit PR number
|
|
448
|
+
```
|
|
449
|
+
|
|
450
|
+
**What it does:**
|
|
451
|
+
1. `sdd pr comments` fetches all unresolved comment threads from the PR
|
|
452
|
+
2. Presents them as a numbered checklist
|
|
453
|
+
3. Developer picks which to fix
|
|
454
|
+
4. Agent applies fixes, commits, pushes to the same branch (PR auto-updates)
|
|
455
|
+
5. `sdd pr reply` posts a reply on each thread: "Fixed in {commit}" or "Acknowledged"
|
|
456
|
+
6. `sdd pr resolve` resolves fixed threads so reviewer sees a clean diff
|
|
457
|
+
7. `sdd pr request-review` requests re-review from the original reviewer
|
|
458
|
+
|
|
459
|
+
**Run again** after the reviewer adds a new round of comments.
|
|
460
|
+
When there are no unresolved comments: "PR is ready to approve."
|
|
461
|
+
|
|
462
|
+
**Per-host notes:**
|
|
463
|
+
- **GitHub** — uses `gh`/GraphQL; unchanged from the original GitHub-only implementation
|
|
464
|
+
- **GitLab** — REST API via `GITLAB_TOKEN` (Discussions API)
|
|
465
|
+
- **Bitbucket** — REST API via `BITBUCKET_USERNAME`/`BITBUCKET_APP_PASSWORD`.
|
|
466
|
+
Bitbucket has no API-level thread resolution — `sdd pr resolve` posts the
|
|
467
|
+
reply and prints a warning asking the reviewer to resolve it manually in
|
|
468
|
+
the UI; this is expected, not a failure
|
|
469
|
+
- **Azure DevOps** — `az` CLI + `az rest` (Threads API)
|
|
470
|
+
- **Unrecognized/self-hosted host** — no automated comment handling; address
|
|
471
|
+
review comments directly in the host's web UI
|
|
472
|
+
|
|
473
|
+
**Underlying commands** (what the prompt calls — usable standalone too):
|
|
474
|
+
```bash
|
|
475
|
+
sdd pr comments [--pr-id N]
|
|
476
|
+
sdd pr reply --comment-id ID --body "..." [--pr-id N]
|
|
477
|
+
sdd pr resolve --comment-id ID [--pr-id N]
|
|
478
|
+
sdd pr request-review --reviewer LOGIN [--pr-id N]
|
|
479
|
+
```
|
|
480
|
+
|
|
481
|
+
---
|
|
482
|
+
|
|
483
|
+
## Code Review Configuration
|
|
484
|
+
|
|
485
|
+
```yaml
|
|
486
|
+
# .specify/integrations.yml
|
|
487
|
+
code_review:
|
|
488
|
+
enabled: true
|
|
489
|
+
pre_review: true # false = skip pre-review, go straight to human review
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
| Setting | Behaviour |
|
|
493
|
+
|---|---|
|
|
494
|
+
| `pre_review: true` | Agent runs `/pre-review` before creating the PR. PR body includes pre-review summary. |
|
|
495
|
+
| `pre_review: false` | PR created immediately. Human reviewer is the first reviewer of the code. |
|
|
496
|
+
|
|
497
|
+
`/address-review` is always available regardless of `pre_review` setting.
|
|
498
|
+
|
|
499
|
+
---
|
|
500
|
+
|
|
501
|
+
## Auth Modes
|
|
502
|
+
|
|
503
|
+
Credentials are **never stored in config files** — only the name of the
|
|
504
|
+
environment variable that holds them.
|
|
505
|
+
|
|
506
|
+
### `basic` — Atlassian Cloud (email + API token)
|
|
507
|
+
|
|
508
|
+
```bash
|
|
509
|
+
export JIRA_API_TOKEN="your-api-token-here"
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
`~/.sdd/config.yml`:
|
|
513
|
+
```yaml
|
|
514
|
+
profiles:
|
|
515
|
+
work-cloud:
|
|
516
|
+
auth_mode: basic
|
|
517
|
+
base_url: https://myco.atlassian.net
|
|
518
|
+
email: user@myco.com
|
|
519
|
+
api_token_env: JIRA_API_TOKEN
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
Get your API token: <https://id.atlassian.com/manage-profile/security/api-tokens>
|
|
523
|
+
|
|
524
|
+
---
|
|
525
|
+
|
|
526
|
+
### `pat` — Jira/Confluence Server 8.14+ or Data Centre
|
|
527
|
+
|
|
528
|
+
```bash
|
|
529
|
+
export JIRA_PAT="your-personal-access-token"
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
`~/.sdd/config.yml`:
|
|
533
|
+
```yaml
|
|
534
|
+
profiles:
|
|
535
|
+
on-prem:
|
|
536
|
+
auth_mode: pat
|
|
537
|
+
base_url: https://jira.internal.myco.com
|
|
538
|
+
pat_env: JIRA_PAT
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
---
|
|
542
|
+
|
|
543
|
+
### `oauth2` — Cloud CI/CD pipelines
|
|
544
|
+
|
|
545
|
+
```bash
|
|
546
|
+
export JIRA_ACCESS_TOKEN="your-oauth2-bearer-token"
|
|
547
|
+
```
|
|
548
|
+
|
|
549
|
+
`~/.sdd/config.yml`:
|
|
550
|
+
```yaml
|
|
551
|
+
profiles:
|
|
552
|
+
ci:
|
|
553
|
+
auth_mode: oauth2
|
|
554
|
+
base_url: https://myco.atlassian.net
|
|
555
|
+
access_token_env: JIRA_ACCESS_TOKEN
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
---
|
|
559
|
+
|
|
560
|
+
## Configuration Files
|
|
561
|
+
|
|
562
|
+
### `~/.sdd/config.yml` — global, machine-level, never commit
|
|
563
|
+
|
|
564
|
+
Holds named auth profiles. Multiple profiles supported (e.g. one per Atlassian instance).
|
|
565
|
+
|
|
566
|
+
```yaml
|
|
567
|
+
version: "1"
|
|
568
|
+
default_profile: work-cloud
|
|
569
|
+
profiles:
|
|
570
|
+
work-cloud:
|
|
571
|
+
auth_mode: basic
|
|
572
|
+
base_url: https://myco.atlassian.net
|
|
573
|
+
email: user@myco.com
|
|
574
|
+
api_token_env: JIRA_API_TOKEN
|
|
575
|
+
on-prem:
|
|
576
|
+
auth_mode: pat
|
|
577
|
+
base_url: https://jira.internal.myco.com
|
|
578
|
+
pat_env: JIRA_PAT
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
---
|
|
582
|
+
|
|
583
|
+
### `.specify/integrations.yml` — project-level, safe to commit
|
|
584
|
+
|
|
585
|
+
Wires SDD fields to your Jira project and Confluence space.
|
|
586
|
+
Copy from `.specify/integrations.yml.example` and fill in your values.
|
|
587
|
+
|
|
588
|
+
```yaml
|
|
589
|
+
profile: work-cloud # references a profile in ~/.sdd/config.yml
|
|
590
|
+
|
|
591
|
+
jira:
|
|
592
|
+
project_key: MYPROJ
|
|
593
|
+
issue_hierarchy:
|
|
594
|
+
feature: Feature # or "Epic" if your project has no Feature type
|
|
595
|
+
story: Story
|
|
596
|
+
task: Task
|
|
597
|
+
parent_field: parent # "parent" for next-gen; "customfield_10014" for classic
|
|
598
|
+
base_fields:
|
|
599
|
+
priority_map:
|
|
600
|
+
must-have: High
|
|
601
|
+
should-have: Medium
|
|
602
|
+
could-have: Low
|
|
603
|
+
wont-have: Lowest
|
|
604
|
+
labels: [sdd-generated]
|
|
605
|
+
custom_fields:
|
|
606
|
+
story_points: customfield_10016 # run "sdd config fields" to find yours
|
|
607
|
+
|
|
608
|
+
confluence:
|
|
609
|
+
space_key: ENG
|
|
610
|
+
parent_page_id: "123456"
|
|
611
|
+
page_map:
|
|
612
|
+
brd: "My Project — Business Requirements"
|
|
613
|
+
hld: "My Project — High-Level Design"
|
|
614
|
+
runbook: "My Project — Runbook"
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
Full reference: see `.specify/integrations.yml.example`.
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## Supported Project Types
|
|
622
|
+
|
|
623
|
+
Auto-detected by `sdd init` from files in the current directory.
|
|
624
|
+
|
|
625
|
+
| Type | Detected from |
|
|
626
|
+
|---|---|
|
|
627
|
+
| `backend-service` | `pom.xml`, `build.gradle`, `go.mod`, Python files |
|
|
628
|
+
| `frontend-spa` | `package.json` + react/vue/svelte/angular/next/nuxt |
|
|
629
|
+
| `mobile` | `pubspec.yaml`, or `package.json` + react-native/expo |
|
|
630
|
+
| `fullstack` | `package.json` + `pom.xml`/`build.gradle`/`go.mod` |
|
|
631
|
+
| `cli` | `Cargo.toml` with `[[bin]]`, or `go.mod` + `cmd/` dir |
|
|
632
|
+
| `data-ml` | `requirements.txt` with pandas/torch/sklearn/keras/jax |
|
|
633
|
+
| `serverless` | `serverless.yml`, or `template.yaml` with AWSTemplateFormatVersion |
|
|
634
|
+
| `library` | `Cargo.toml` without `[[bin]]`, or Python lib structure |
|
|
635
|
+
| `iac` | `*.tf` files, `Pulumi.yaml`, `cdk.json` |
|
|
636
|
+
| `desktop` | `package.json` + electron, or `tauri.conf.json` |
|
|
637
|
+
|
|
638
|
+
Detection order matches `setup.sh` and `specify.prompt.md` Step 0 — mobile
|
|
639
|
+
is always checked before fullstack.
|