openspecpm 0.1.0-alpha.0 → 1.0.0

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/README.md CHANGED
@@ -1,352 +1,373 @@
1
- # OpenSpecPM — Spec-driven PM for any backend
2
-
3
- [![test](https://github.com/aks-builds/openspecpm/actions/workflows/test.yml/badge.svg?event=push)](https://github.com/aks-builds/openspecpm/actions/workflows/test.yml)
4
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
- [![tests](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Faks-builds%2F03ce34dc5c6486c004dd8cf4c27ea87c%2Fraw%2Ftests.json)](cli/tests)
6
-
7
- > Spec-driven, BDD-shaped project management for AI agents — author once in [OpenSpec](https://github.com/Fission-AI/OpenSpec), sync to GitHub Issues, Azure DevOps Boards, or Jira.
8
-
9
- OpenSpecPM turns natural-language intent ("plan X", "sync the X epic", "what's blocked", "ship X") into a disciplined flow:
10
-
11
- ```mermaid
12
- flowchart LR
13
- Idea["💡 **Idea**"]
14
- Proposal["📝 **proposal.md**<br/>(OpenSpec)"]
15
- BDD["📋 **BDD specs**<br/>Given / When / Then"]
16
- Tasks["✅ **tasks**"]
17
- Tracked["🎯 **Tracked work items**<br/>GitHub · ADO · Jira"]
18
- Shipped["🚀 **Shipped code**"]
19
-
20
- Idea --> Proposal --> BDD --> Tasks --> Tracked --> Shipped
21
-
22
- classDef ideaC fill:#FFF9C4,stroke:#F9A825,color:#000
23
- classDef artifactC fill:#D5E8D4,stroke:#82B366,color:#000
24
- classDef extC fill:#DAE8FC,stroke:#6C8EBF,color:#000
25
- classDef doneC fill:#C8E6C9,stroke:#2E7D32,color:#000
26
-
27
- class Idea ideaC
28
- class Proposal,BDD,Tasks artifactC
29
- class Tracked extC
30
- class Shipped doneC
31
- ```
32
-
33
- It is a sibling of [CCPM](https://github.com/automazeio/ccpm), with three differences:
34
-
35
- 1. **OpenSpec drives spec authoring** — every feature gets `proposal.md`, `design.md`, `tasks.md`, and a `specs/` folder of BDD scenarios.
36
- 2. **The PM tool is pluggable** — an interactive wizard at `init` time picks GitHub Issues/Projects, Azure DevOps Boards, or Jira.
37
- 3. **Built for non-engineers too** — PMs/BAs/PgMs can drive the flow. A `doctor` command owns auth-setup pain. Worktrees are hidden by default.
38
-
39
- ## Install
40
-
41
- ```bash
42
- # Standalone CLI (any harness)
43
- npx openspecpm@latest init
44
-
45
- # Claude Code Agent Skill
46
- # Copy skill/openspecpm/ into your Claude Code skills directory.
47
- # SKILL.md handles routing — just talk to Claude.
48
- ```
49
-
50
- OpenSpecPM shells out to [OpenSpec](https://github.com/Fission-AI/OpenSpec); install it first:
51
-
52
- ```bash
53
- npm install -g @fission-ai/openspec
54
- ```
55
-
56
- ## In action
57
-
58
- > A walkthrough of OpenSpecPM running against two sample features (`dark-mode`, `auth-rate-limit`). Source images live in [`docs/screenshots/`](docs/screenshots/); regenerate with `pwsh docs/screenshots/render.ps1` after CLI output changes — the renderer sets up its own sample data and cleans up after itself.
59
-
60
- **1 · Phase-grouped command reference** — `help-table` shows every command grouped by workflow phase (Setup → Plan → Sync → Track → Execute/Ship):
61
-
62
- ![openspecpm help-table](docs/screenshots/help-table.png)
63
-
64
- **2 · Health check across every adapter** — `doctor` diagnoses auth + tooling for all five backends (GitHub, Azure DevOps, Jira, Linear, GitLab) with an English remediation hint on every failure:
65
-
66
- ![openspecpm doctor](docs/screenshots/doctor.png)
67
-
68
- **3 · Multi-feature status** — `status` shows the configured adapter and per-change task counts (`synced / pending / failed / done`) at a glance:
69
-
70
- ![openspecpm status](docs/screenshots/status.png)
71
-
72
- **4 · "What can I work on right now?"** `next` lists tasks with no unmet dependencies, marking parallel-safe ones so multiple agents can pick them up:
73
-
74
- ![openspecpm next](docs/screenshots/next.png)
75
-
76
- **5 · "What's waiting on what?"** — `blocked` lists every task held up by a dependency and names the blocker, so the path to unblocking is one read away:
77
-
78
- ![openspecpm blocked](docs/screenshots/blocked.png)
79
-
80
- **6 · Project-wide validation** — `validate` runs the schema check and BDD linter across every change and reports per-feature error + warning counts:
81
-
82
- ![openspecpm validate](docs/screenshots/validate.png)
83
-
84
- ## Quick start
85
-
86
- ```bash
87
- # 1. One-time setup. The wizard asks which PM tool your team uses.
88
- npx openspecpm init
89
-
90
- # 2. Verify auth before doing anything remote.
91
- npx openspecpm doctor
92
-
93
- # 3. Author a proposal. OpenSpec generates proposal.md, design.md, tasks.md,
94
- # and BDD scenarios in specs/. Soft BDD-lint runs after authoring.
95
- npx openspecpm propose dark-mode --prompt "Per-user dark theme with persistence."
96
-
97
- # 4. Review the generated files. Refine BDD scenarios until lint is clean.
98
-
99
- # 5. Sync to the PM tool. Hard BDD lint runs first; pass --force to override.
100
- npx openspecpm sync dark-mode
101
-
102
- # 6. Pick up where you left off.
103
- npx openspecpm next # tasks ready to start
104
- npx openspecpm blocked # tasks waiting on dependencies
105
- npx openspecpm standup # progress updates in the last 24h
106
-
107
- # 7. When the feature is verified, close + archive.
108
- npx openspecpm ship dark-mode
109
- ```
110
-
111
- ## Command reference
112
-
113
- | Command | What it does |
114
- |---|---|
115
- | `init` | Interactive wizard. Picks the PM tool. Writes `.openspecpm/config.json`. |
116
- | `doctor [adapter]` | Auth/tooling health check. English remediation hints on every failure. |
117
- | `propose <feature>` | Shell out to OpenSpec; create `openspec/changes/<feature>/`. Soft-lint BDD scenarios. |
118
- | `decompose <feature>` | Extract tasks from proposal headings/checklists + BDD scenarios into `tasks.md`. |
119
- | `sync <feature>` | Hard-lint BDD, then create/update work items in the PM tool. Idempotent. |
120
- | `comment <feature> <task>` | Broadcast local `progress.md` (or `-m`) to the PM tool with `<!-- SYNCED -->` marker. |
121
- | `reconcile <feature>` | Pull remote work-item state into local frontmatter. Detects out-of-band closes. |
122
- | `bug-report <feature> <task> --title "…"` | File a linked regression against a shipped task. |
123
- | `status` | Per-change task counts: pending / created / failed / done. |
124
- | `standup [--since 24h]` | Recent `progress.md` updates, newest first. |
125
- | `next [-l 5]` | Tasks with no unmet dependencies. |
126
- | `blocked` | Tasks waiting on unmet dependencies (with reasons). |
127
- | `validate` | Schema + dependency + BDD-lint sweep across every change. |
128
- | `search <query>` | Grep across proposals, specs, tasks, progress notes. |
129
- | `fan-out <feature>` | Emit ready-to-paste agent prompts for `parallel: true` tasks. |
130
- | `ship <feature> [-y]` | Close all task work items + close the epic + archive the OpenSpec change. |
131
- | `help-table [topic]` | Context-aware command reference grouped by workflow phase. |
132
-
133
- Every command appends a JSONL entry (secrets scrubbed) to `.openspecpm/audit.log`.
134
-
135
- ## Architecture
136
-
137
- ```mermaid
138
- flowchart TD
139
- PM([👤 Project Manager / BA])
140
- Dev([👤 Developer])
141
- Agent([🤖 AI Agent · Claude Code])
142
-
143
- Skill["**Agent Skill**<br/>skill/openspecpm/SKILL.md<br/><br/>Routes natural-language intent"]
144
- CLI["**Node CLI**<br/>cli/bin/openspecpm.js<br/><br/>Commander dispatch + audit"]
145
-
146
- subgraph CMDS["📋 Commands · cli/src/commands/"]
147
- direction LR
148
- Setup["**① Setup**<br/>init doctor"]
149
- Plan["**② Plan**<br/>propose decompose"]
150
- SyncCmd["**③ Sync**<br/>sync comment reconcile<br/>assign bug-report"]
151
- Track["**④ Track**<br/>status standup next<br/>blocked validate search watch"]
152
- Exec["**⑤ Execute / Ship**<br/>fan-out • ship • help-table"]
153
- end
154
-
155
- subgraph CORE["⚙️ Core services · cli/src/"]
156
- direction LR
157
- Bridge["**OpenSpec Bridge + BDD**<br/>openspec-bridge.js<br/>bdd/linter.js"]
158
- TrackingS["**Tracking + Audit**<br/>tracking.js<br/>audit.js"]
159
- HTTP["**HTTP + Rate-limit**<br/>http.js<br/>ratelimit.js"]
160
- IO["**Config + Notify + Telemetry**<br/>config.js • notify.js<br/>telemetry.js"]
161
- end
162
-
163
- subgraph ADAPTERS["🔌 Adapter contract · cli/src/adapters/ · 9 methods + capabilities()"]
164
- direction LR
165
- GHA["**GitHub**<br/>depth 2"]
166
- AzA["**Azure DevOps**<br/>depth 4"]
167
- JiA["**Jira**<br/>depth 3"]
168
- LiA["**Linear**<br/>depth 2"]
169
- GlA["**GitLab**<br/>depth 2"]
170
- end
171
-
172
- subgraph EXT["☁️ External PM systems"]
173
- direction LR
174
- GHE[("GitHub<br/>Issues / Projects")]
175
- AzE[("Azure DevOps<br/>Boards")]
176
- JiE[("Jira<br/>Cloud / Server")]
177
- LiE[("Linear")]
178
- GlE[("GitLab<br/>Issues")]
179
- end
180
-
181
- subgraph PERSIST["💾 Persistence & sinks"]
182
- direction LR
183
- FS1["📁 **openspec/**<br/>changes/&lt;feature&gt;/<br/>• proposal.md<br/>• specs/*.md (BDD)<br/>• tasks.md<br/>• updates/progress.md"]
184
- FS2["📁 **.openspecpm/**<br/>• config.json<br/>• audit.log (JSONL)<br/>• state.json"]
185
- Sinks["🔔 **Webhooks**<br/>• Slack<br/>• Teams<br/>• Generic JSON"]
186
- end
187
-
188
- PM --> Skill
189
- Dev --> CLI
190
- Agent --> Skill
191
- Skill -- invokes --> CLI
192
- CLI --> CMDS
193
- CMDS --> CORE
194
- CORE --> ADAPTERS
195
-
196
- GHA --> GHE
197
- AzA --> AzE
198
- JiA --> JiE
199
- LiA --> LiE
200
- GlA --> GlE
201
-
202
- Bridge -. writes .-> FS1
203
- TrackingS -. writes .-> FS1
204
- IO -. writes .-> FS2
205
- IO -. broadcast .-> Sinks
206
-
207
- classDef user fill:#DAE8FC,stroke:#6C8EBF,color:#000
208
- classDef agent fill:#FFE0B2,stroke:#D97757,color:#000
209
- classDef entry fill:#C5E1A5,stroke:#558B2F,color:#000
210
- classDef skill fill:#FFE0B2,stroke:#D97757,color:#000
211
- classDef github fill:#222,stroke:#000,color:#fff
212
- classDef azure fill:#0078D7,stroke:#005A9E,color:#fff
213
- classDef jira fill:#0052CC,stroke:#003580,color:#fff
214
- classDef linear fill:#5E6AD2,stroke:#3F47A0,color:#fff
215
- classDef gitlab fill:#FC6D26,stroke:#C44A19,color:#fff
216
- classDef ext fill:#fff,stroke:#333,stroke-width:3px,color:#000
217
- classDef fs fill:#fff,stroke:#444,stroke-width:2px,color:#000
218
-
219
- class PM,Dev user
220
- class Agent agent
221
- class CLI entry
222
- class Skill skill
223
- class GHA github
224
- class AzA azure
225
- class JiA jira
226
- class LiA linear
227
- class GlA gitlab
228
- class GHE,AzE,JiE,LiE,GlE ext
229
- class FS1,FS2,Sinks fs
230
- ```
231
-
232
- ## Lifecycle
233
-
234
- ```mermaid
235
- flowchart LR
236
- Idea["💡 **Idea**<br/>stakeholder feature,<br/>bug, or refactor"]
237
-
238
- subgraph P1["① PLAN"]
239
- direction TB
240
- Propose["**openspecpm propose**<br/>Shells out to OpenSpec<br/>Soft BDD lint"]
241
- Decompose["**openspecpm decompose**<br/>Extract tasks from<br/>proposal + BDD"]
242
- Propose --> Decompose
243
- end
244
-
245
- subgraph P2["② REVIEW + SYNC"]
246
- direction TB
247
- Review["👀 **Human review**<br/>Sign off on BDD"]
248
- Validate["**openspecpm validate**<br/>Schema + BDD sweep"]
249
- SyncCmd["**openspecpm sync**<br/>Hard BDD lint<br/>Idempotent"]
250
- Review --> Validate --> SyncCmd
251
- end
252
-
253
- subgraph P3["③ EXECUTE"]
254
- direction TB
255
- Next["**openspecpm next**"]
256
- FanOut["**openspecpm fan-out**<br/>Parallel agent prompts"]
257
- Build["🤖 **Implement**<br/>BDD = acceptance criteria"]
258
- Comment["**openspecpm comment**<br/>Broadcast progress"]
259
- Reconcile["**openspecpm reconcile**<br/>Pull remote state"]
260
- Next --> FanOut --> Build --> Comment --> Reconcile
261
- end
262
-
263
- subgraph P4["④ TRACK"]
264
- direction TB
265
- Status["**Track commands**<br/>status standup<br/>blocked • search<br/>watch • bug-report"]
266
- end
267
-
268
- subgraph P5[" SHIP"]
269
- direction TB
270
- Ship["**openspecpm ship**<br/>Close tasks + epic<br/>Archive change"]
271
- Shipped["🚀 **Shipped**"]
272
- Ship --> Shipped
273
- end
274
-
275
- Idea --> P1
276
- P1 --> P2
277
- P2 --> P3
278
- P3 --> P4
279
- P4 --> P5
280
- Shipped -. next feature .-> Idea
281
-
282
- classDef ideaC fill:#FFF9C4,stroke:#F9A825,color:#000
283
- classDef cmdC fill:#D5E8D4,stroke:#82B366,color:#000
284
- classDef humanC fill:#FFF9C4,stroke:#F9A825,color:#000
285
- classDef agentC fill:#FFE0B2,stroke:#D97757,color:#000
286
- classDef shipC fill:#FFCDD2,stroke:#D32F2F,color:#000
287
- classDef doneC fill:#C8E6C9,stroke:#2E7D32,color:#000
288
-
289
- class Idea ideaC
290
- class Propose,Decompose,Validate,SyncCmd,Next,FanOut,Comment,Reconcile,Status cmdC
291
- class Review humanC
292
- class Build agentC
293
- class Ship shipC
294
- class Shipped doneC
295
- ```
296
-
297
- > Cross-cutting on every command: audit log (`.openspecpm/audit.log`, secrets scrubbed) · token-bucket rate-limiting per adapter · OpenSpec version probe · optional opt-in telemetry.
298
-
299
- ## Workflow phases
300
-
301
- OpenSpecPM is organized into five phases, each with a reference doc under [`skill/openspecpm/references/`](skill/openspecpm/references/):
302
-
303
- 1. **Plan** ([`plan.md`](skill/openspecpm/references/plan.md)) — Capture requirements through an OpenSpec proposal + BDD scenarios.
304
- 2. **Structure** ([`structure.md`](skill/openspecpm/references/structure.md)) — Decompose into tasks with explicit dependencies and parallelism hints.
305
- 3. **Sync** ([`sync.md`](skill/openspecpm/references/sync.md)) — Push to the PM tool. Capabilities-driven hierarchy collapse for flatter backends.
306
- 4. **Execute** ([`execute.md`](skill/openspecpm/references/execute.md)) — Start work on a tracked item. Optional worktrees, parallel-agent dispatch.
307
- 5. **Track** ([`track.md`](skill/openspecpm/references/track.md)) — Status, standup, next, blocked, ship.
308
-
309
- ## Architecture highlights
310
-
311
- - **Adapter contract.** Every backend implements the same 9-method interface plus `capabilities()` reporting hierarchy depth (GitHub=2, Linear=2, GitLab=2, Jira=3, ADO=4). The sync layer collapses levels gracefully.
312
- - **OpenSpec anti-corruption layer.** Version-pinned probe on every CLI invocation. One constant absorbs upstream path moves.
313
- - **Idempotent sync.** Each task carries `sync_state` + `external_id` in frontmatter. Re-running `sync` skips created items and retries failures. Comments use `<!-- SYNCED: <ts> -->` markers to prevent duplication.
314
- - **Token-bucket rate-limiting.** Per-adapter presets tuned for each backend's published limits.
315
- - **BDD linter.** Heuristic checks: one Given/When/Then per scenario, observable verbs in Then, deny-list for vague phrases ("should work"), tautology detection via word-bigram similarity.
316
-
317
- ## Roadmap
318
-
319
- Active v2 work is tracked as OpenSpec changes under [`openspec/changes/`](openspec/changes/README.md). Six features are scaffolded with full proposals, dependency-aware task lists, and BDD scenarios: dependency-graph visualization, LLM-backed BDD reviewer, spec → test scaffolding, compliance traceability export, three new adapters (Notion / ClickUp / Asana), and a real agent orchestrator that graduates `fan-out` from prompt-emitter to dispatcher.
320
-
321
- OpenSpecPM dogfoods itself: anyone can `openspecpm next` to see what's ready to start, or `openspecpm sync <change>` to push any of the six into a tracked PM tool.
322
-
323
- ## Project structure
324
-
325
- ```
326
- openspecpm/
327
- ├── README.md this file
328
- ├── LICENSE MIT
329
- ├── CHANGELOG.md
330
- ├── package.json
331
- ├── .github/workflows/test.yml
332
- ├── skill/openspecpm/ Claude Code Agent Skill
333
- │ ├── SKILL.md
334
- │ └── references/ conventions, plan, structure, sync, execute, track
335
- └── cli/
336
- ├── bin/openspecpm.js Commander entrypoint
337
- ├── src/
338
- │ ├── commands/ init, doctor, propose, sync, status, standup, next, blocked, ship
339
- │ ├── adapters/ base, github, azure, jira, index
340
- │ ├── bdd/ linter, templates
341
- │ ├── http.js REST helper for ADO + Jira
342
- │ ├── tracking.js listChanges, findNext, findBlocked, findRecent
343
- │ ├── openspec-bridge.js
344
- │ ├── config.js
345
- │ ├── frontmatter.js
346
- │ └── ratelimit.js
347
- └── tests/ unit + contract tests (count badge is auto-updated by CI)
348
- ```
349
-
350
- ## License
351
-
352
- [MIT](LICENSE)
1
+ # OpenSpecPM — Spec-driven PM for any backend
2
+
3
+ [![test](https://github.com/aks-builds/openspecpm/actions/workflows/test.yml/badge.svg?event=push)](https://github.com/aks-builds/openspecpm/actions/workflows/test.yml)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+ [![tests](https://img.shields.io/endpoint?url=https%3A%2F%2Fgist.githubusercontent.com%2Faks-builds%2F03ce34dc5c6486c004dd8cf4c27ea87c%2Fraw%2Ftests.json)](cli/tests)
6
+
7
+ > Spec-driven, BDD-shaped project management for AI agents — author once in [OpenSpec](https://github.com/Fission-AI/OpenSpec), sync to GitHub Issues, Azure DevOps Boards, or Jira.
8
+
9
+ OpenSpecPM turns natural-language intent ("plan X", "sync the X epic", "what's blocked", "ship X") into a disciplined flow:
10
+
11
+ ```mermaid
12
+ flowchart LR
13
+ Idea["💡 **Idea**"]
14
+ Proposal["📝 **proposal.md**<br/>(OpenSpec)"]
15
+ BDD["📋 **BDD specs**<br/>Given / When / Then"]
16
+ Tasks["✅ **tasks**"]
17
+ Tracked["🎯 **Tracked work items**<br/>GitHub · ADO · Jira"]
18
+ Shipped["🚀 **Shipped code**"]
19
+
20
+ Idea --> Proposal --> BDD --> Tasks --> Tracked --> Shipped
21
+
22
+ classDef ideaC fill:#FFF9C4,stroke:#F9A825,color:#000
23
+ classDef artifactC fill:#D5E8D4,stroke:#82B366,color:#000
24
+ classDef extC fill:#DAE8FC,stroke:#6C8EBF,color:#000
25
+ classDef doneC fill:#C8E6C9,stroke:#2E7D32,color:#000
26
+
27
+ class Idea ideaC
28
+ class Proposal,BDD,Tasks artifactC
29
+ class Tracked extC
30
+ class Shipped doneC
31
+ ```
32
+
33
+ It is a sibling of [CCPM](https://github.com/automazeio/ccpm), with three differences:
34
+
35
+ 1. **OpenSpec drives spec authoring** — every feature gets `proposal.md`, `design.md`, `tasks.md`, and a `specs/` folder of BDD scenarios.
36
+ 2. **The PM tool is pluggable** — an interactive wizard at `init` time picks GitHub Issues/Projects, Azure DevOps Boards, or Jira.
37
+ 3. **Built for non-engineers too** — PMs/BAs/PgMs can drive the flow. A `doctor` command owns auth-setup pain. Worktrees are hidden by default.
38
+
39
+ ## Install
40
+
41
+ ```bash
42
+ # Standalone CLI (any harness)
43
+ npx openspecpm@latest init
44
+
45
+ # Claude Code Agent Skill
46
+ # Copy skill/openspecpm/ into your Claude Code skills directory.
47
+ # SKILL.md handles routing — just talk to Claude.
48
+ ```
49
+
50
+ OpenSpecPM shells out to [OpenSpec](https://github.com/Fission-AI/OpenSpec); install it first:
51
+
52
+ ```bash
53
+ npm install -g @fission-ai/openspec
54
+ ```
55
+
56
+ ## In action
57
+
58
+ > A walkthrough of OpenSpecPM running against two sample features (`dark-mode`, `auth-rate-limit`). Source images live in [`docs/screenshots/`](docs/screenshots/); regenerate with `pwsh docs/screenshots/render.ps1` after CLI output changes — the renderer sets up its own sample data and cleans up after itself.
59
+
60
+ **1 · Phase-grouped command reference** — `help-table` shows every command grouped by workflow phase (Setup → Plan → Sync → Track → Execute/Ship):
61
+
62
+ ![openspecpm help-table](docs/screenshots/help-table.png)
63
+
64
+ **2 · Health check across every adapter** — `doctor` diagnoses auth + tooling for all five backends (GitHub, Azure DevOps, Jira, Linear, GitLab) with an English remediation hint on every failure. The `[judge]` section reports `ANTHROPIC_API_KEY` for the optional LLM BDD judge:
65
+
66
+ ![openspecpm doctor](docs/screenshots/doctor.png)
67
+
68
+ **3 · Author a proposal** — `propose --offline` scaffolds `proposal.md`, `tasks.md`, and `specs/main.md` from templates without calling the OpenSpec CLI. Soft BDD lint runs immediately so placeholder Then-clauses are flagged before you keep editing:
69
+
70
+ ![openspecpm propose](docs/screenshots/propose.png)
71
+
72
+ **4 · Optional LLM BDD judge** pass `--llm` (or set `judge.enabled: true` in `.openspecpm/config.json`) to augment the heuristic linter with Claude Haiku 4.5. The judge catches what regex can't: cross-spec contradictions (`bdd/llm-contradiction`), success criteria with no scenario (`bdd/llm-missing-coverage`), and Then-clauses that pass the verb check but state no observable outcome (`bdd/llm-vague-then`). Findings merge into the same lint stream and respect `--force` the same way. Prompt-cached on the proposal so re-runs across multiple specs stay cheap. *Sample output below — real findings vary per scenario set; the judge can't be regenerated by `render.ps1` because it requires a live `ANTHROPIC_API_KEY`:*
73
+
74
+ ![openspecpm propose --llm](docs/screenshots/judge.png)
75
+
76
+ **5 · Decompose into tasks** — `decompose` walks proposal headings, GitHub-style checklists, a `Tasks` section, and BDD scenarios under `specs/` and writes a structured `tasks.md` with `sync_state` frontmatter:
77
+
78
+ ![openspecpm decompose](docs/screenshots/decompose.png)
79
+
80
+ **6 · Multi-feature status** — `status` shows the configured adapter and per-change task counts (`synced / pending / failed / done`) at a glance:
81
+
82
+ ![openspecpm status](docs/screenshots/status.png)
83
+
84
+ **7 · "What can I work on right now?"** — `next` lists tasks with no unmet dependencies, marking parallel-safe ones so multiple agents can pick them up:
85
+
86
+ ![openspecpm next](docs/screenshots/next.png)
87
+
88
+ **8 · "What's waiting on what?"** — `blocked` lists every task held up by a dependency and names the blocker, so the path to unblocking is one read away:
89
+
90
+ ![openspecpm blocked](docs/screenshots/blocked.png)
91
+
92
+ **9 · Parallel-agent dispatch** — `fan-out` emits ready-to-paste prompts for `parallel: true` tasks with no unmet deps. Each prompt embeds the proposal summary, design notes, and BDD spec as acceptance criteria so subagents can work in isolation:
93
+
94
+ ![openspecpm fan-out](docs/screenshots/fan-out.png)
95
+
96
+ **10 · Cross-file search** — `search` is a case-insensitive grep across every proposal, spec, tasks file, and progress note. Useful for tracing back from a keyword to the change that owns it:
97
+
98
+ ![openspecpm search](docs/screenshots/search.png)
99
+
100
+ **11 · Project-wide validation** — `validate` runs the schema check and BDD linter across every change and reports per-feature error + warning counts:
101
+
102
+ ![openspecpm validate](docs/screenshots/validate.png)
103
+
104
+ ## Quick start
105
+
106
+ ```bash
107
+ # 1. One-time setup. The wizard asks which PM tool your team uses.
108
+ npx openspecpm init
109
+
110
+ # 2. Verify auth before doing anything remote.
111
+ npx openspecpm doctor
112
+
113
+ # 3. Author a proposal. OpenSpec generates proposal.md, design.md, tasks.md,
114
+ # and BDD scenarios in specs/. Soft BDD-lint runs after authoring.
115
+ npx openspecpm propose dark-mode --prompt "Per-user dark theme with persistence."
116
+
117
+ # 4. Review the generated files. Refine BDD scenarios until lint is clean.
118
+
119
+ # 5. Sync to the PM tool. Hard BDD lint runs first; pass --force to override.
120
+ npx openspecpm sync dark-mode
121
+
122
+ # 6. Pick up where you left off.
123
+ npx openspecpm next # tasks ready to start
124
+ npx openspecpm blocked # tasks waiting on dependencies
125
+ npx openspecpm standup # progress updates in the last 24h
126
+
127
+ # 7. When the feature is verified, close + archive.
128
+ npx openspecpm ship dark-mode
129
+ ```
130
+
131
+ ## Command reference
132
+
133
+ | Command | What it does |
134
+ |---|---|
135
+ | `init` | Interactive wizard. Picks the PM tool. Writes `.openspecpm/config.json`. |
136
+ | `doctor [adapter]` | Auth/tooling health check. English remediation hints on every failure. |
137
+ | `propose <feature> [--llm]` | Shell out to OpenSpec; create `openspec/changes/<feature>/`. Soft-lint BDD scenarios; `--llm` adds the LLM judge. |
138
+ | `decompose <feature>` | Extract tasks from proposal headings/checklists + BDD scenarios into `tasks.md`. |
139
+ | `sync <feature> [--llm]` | Hard-lint BDD, then create/update work items in the PM tool. Idempotent; `--llm` adds the LLM judge as a hard gate. |
140
+ | `comment <feature> <task>` | Broadcast local `progress.md` (or `-m`) to the PM tool with `<!-- SYNCED -->` marker. |
141
+ | `reconcile <feature>` | Pull remote work-item state into local frontmatter. Detects out-of-band closes. |
142
+ | `bug-report <feature> <task> --title "…"` | File a linked regression against a shipped task. |
143
+ | `status` | Per-change task counts: pending / created / failed / done. |
144
+ | `standup [--since 24h]` | Recent `progress.md` updates, newest first. |
145
+ | `next [-l 5]` | Tasks with no unmet dependencies. |
146
+ | `blocked` | Tasks waiting on unmet dependencies (with reasons). |
147
+ | `validate [--llm]` | Schema + dependency + BDD-lint sweep across every change; `--llm` adds the LLM judge per change. |
148
+ | `search <query>` | Grep across proposals, specs, tasks, progress notes. |
149
+ | `fan-out <feature>` | Emit ready-to-paste agent prompts for `parallel: true` tasks. |
150
+ | `ship <feature> [-y]` | Close all task work items + close the epic + archive the OpenSpec change. |
151
+ | `help-table [topic]` | Context-aware command reference grouped by workflow phase. |
152
+
153
+ Every command appends a JSONL entry (secrets scrubbed) to `.openspecpm/audit.log`.
154
+
155
+ ## Architecture
156
+
157
+ ```mermaid
158
+ flowchart TD
159
+ PM([👤 Project Manager / BA])
160
+ Dev([👤 Developer])
161
+ Agent([🤖 AI Agent · Claude Code])
162
+
163
+ Skill["**Agent Skill**<br/>skill/openspecpm/SKILL.md<br/><br/>Routes natural-language intent"]
164
+ CLI["**Node CLI**<br/>cli/bin/openspecpm.js<br/><br/>Commander dispatch + audit"]
165
+
166
+ subgraph CMDS["📋 Commands · cli/src/commands/"]
167
+ direction LR
168
+ Setup["**① Setup**<br/>init • doctor"]
169
+ Plan["**② Plan**<br/>propose • decompose"]
170
+ SyncCmd["**③ Sync**<br/>sync • comment • reconcile<br/>assign • bug-report"]
171
+ Track["**④ Track**<br/>status • standup • next<br/>blocked • validate • search • watch"]
172
+ Exec["**⑤ Execute / Ship**<br/>fan-out • ship • help-table"]
173
+ end
174
+
175
+ subgraph CORE["⚙️ Core services · cli/src/"]
176
+ direction LR
177
+ Bridge["**OpenSpec Bridge + BDD**<br/>openspec-bridge.js<br/>bdd/linter.js"]
178
+ TrackingS["**Tracking + Audit**<br/>tracking.js<br/>audit.js"]
179
+ HTTP["**HTTP + Rate-limit**<br/>http.js<br/>ratelimit.js"]
180
+ IO["**Config + Notify + Telemetry**<br/>config.js • notify.js<br/>telemetry.js"]
181
+ end
182
+
183
+ subgraph ADAPTERS["🔌 Adapter contract · cli/src/adapters/ · 9 methods + capabilities()"]
184
+ direction LR
185
+ GHA["**GitHub**<br/>depth 2"]
186
+ AzA["**Azure DevOps**<br/>depth 4"]
187
+ JiA["**Jira**<br/>depth 3"]
188
+ LiA["**Linear**<br/>depth 2"]
189
+ GlA["**GitLab**<br/>depth 2"]
190
+ end
191
+
192
+ subgraph EXT["☁️ External PM systems"]
193
+ direction LR
194
+ GHE[("GitHub<br/>Issues / Projects")]
195
+ AzE[("Azure DevOps<br/>Boards")]
196
+ JiE[("Jira<br/>Cloud / Server")]
197
+ LiE[("Linear")]
198
+ GlE[("GitLab<br/>Issues")]
199
+ end
200
+
201
+ subgraph PERSIST["💾 Persistence & sinks"]
202
+ direction LR
203
+ FS1["📁 **openspec/**<br/>changes/&lt;feature&gt;/<br/>• proposal.md<br/>• specs/*.md (BDD)<br/>• tasks.md<br/>• updates/progress.md"]
204
+ FS2["📁 **.openspecpm/**<br/>• config.json<br/>• audit.log (JSONL)<br/>• state.json"]
205
+ Sinks["🔔 **Webhooks**<br/>• Slack<br/>• Teams<br/>• Generic JSON"]
206
+ end
207
+
208
+ PM --> Skill
209
+ Dev --> CLI
210
+ Agent --> Skill
211
+ Skill -- invokes --> CLI
212
+ CLI --> CMDS
213
+ CMDS --> CORE
214
+ CORE --> ADAPTERS
215
+
216
+ GHA --> GHE
217
+ AzA --> AzE
218
+ JiA --> JiE
219
+ LiA --> LiE
220
+ GlA --> GlE
221
+
222
+ Bridge -. writes .-> FS1
223
+ TrackingS -. writes .-> FS1
224
+ IO -. writes .-> FS2
225
+ IO -. broadcast .-> Sinks
226
+
227
+ classDef user fill:#DAE8FC,stroke:#6C8EBF,color:#000
228
+ classDef agent fill:#FFE0B2,stroke:#D97757,color:#000
229
+ classDef entry fill:#C5E1A5,stroke:#558B2F,color:#000
230
+ classDef skill fill:#FFE0B2,stroke:#D97757,color:#000
231
+ classDef github fill:#222,stroke:#000,color:#fff
232
+ classDef azure fill:#0078D7,stroke:#005A9E,color:#fff
233
+ classDef jira fill:#0052CC,stroke:#003580,color:#fff
234
+ classDef linear fill:#5E6AD2,stroke:#3F47A0,color:#fff
235
+ classDef gitlab fill:#FC6D26,stroke:#C44A19,color:#fff
236
+ classDef ext fill:#fff,stroke:#333,stroke-width:3px,color:#000
237
+ classDef fs fill:#fff,stroke:#444,stroke-width:2px,color:#000
238
+
239
+ class PM,Dev user
240
+ class Agent agent
241
+ class CLI entry
242
+ class Skill skill
243
+ class GHA github
244
+ class AzA azure
245
+ class JiA jira
246
+ class LiA linear
247
+ class GlA gitlab
248
+ class GHE,AzE,JiE,LiE,GlE ext
249
+ class FS1,FS2,Sinks fs
250
+ ```
251
+
252
+ ## Lifecycle
253
+
254
+ ```mermaid
255
+ flowchart LR
256
+ Idea["💡 **Idea**<br/>stakeholder feature,<br/>bug, or refactor"]
257
+
258
+ subgraph P1[" PLAN"]
259
+ direction TB
260
+ Propose["**openspecpm propose**<br/>Shells out to OpenSpec<br/>Soft BDD lint"]
261
+ Decompose["**openspecpm decompose**<br/>Extract tasks from<br/>proposal + BDD"]
262
+ Propose --> Decompose
263
+ end
264
+
265
+ subgraph P2[" REVIEW + SYNC"]
266
+ direction TB
267
+ Review["👀 **Human review**<br/>Sign off on BDD"]
268
+ Validate["**openspecpm validate**<br/>Schema + BDD sweep"]
269
+ SyncCmd["**openspecpm sync**<br/>Hard BDD lint<br/>Idempotent"]
270
+ Review --> Validate --> SyncCmd
271
+ end
272
+
273
+ subgraph P3["③ EXECUTE"]
274
+ direction TB
275
+ Next["**openspecpm next**"]
276
+ FanOut["**openspecpm fan-out**<br/>Parallel agent prompts"]
277
+ Build["🤖 **Implement**<br/>BDD = acceptance criteria"]
278
+ Comment["**openspecpm comment**<br/>Broadcast progress"]
279
+ Reconcile["**openspecpm reconcile**<br/>Pull remote state"]
280
+ Next --> FanOut --> Build --> Comment --> Reconcile
281
+ end
282
+
283
+ subgraph P4["④ TRACK"]
284
+ direction TB
285
+ Status["**Track commands**<br/>status • standup<br/>blocked • search<br/>watch • bug-report"]
286
+ end
287
+
288
+ subgraph P5["⑤ SHIP"]
289
+ direction TB
290
+ Ship["**openspecpm ship**<br/>Close tasks + epic<br/>Archive change"]
291
+ Shipped["🚀 **Shipped**"]
292
+ Ship --> Shipped
293
+ end
294
+
295
+ Idea --> P1
296
+ P1 --> P2
297
+ P2 --> P3
298
+ P3 --> P4
299
+ P4 --> P5
300
+ Shipped -. next feature .-> Idea
301
+
302
+ classDef ideaC fill:#FFF9C4,stroke:#F9A825,color:#000
303
+ classDef cmdC fill:#D5E8D4,stroke:#82B366,color:#000
304
+ classDef humanC fill:#FFF9C4,stroke:#F9A825,color:#000
305
+ classDef agentC fill:#FFE0B2,stroke:#D97757,color:#000
306
+ classDef shipC fill:#FFCDD2,stroke:#D32F2F,color:#000
307
+ classDef doneC fill:#C8E6C9,stroke:#2E7D32,color:#000
308
+
309
+ class Idea ideaC
310
+ class Propose,Decompose,Validate,SyncCmd,Next,FanOut,Comment,Reconcile,Status cmdC
311
+ class Review humanC
312
+ class Build agentC
313
+ class Ship shipC
314
+ class Shipped doneC
315
+ ```
316
+
317
+ > Cross-cutting on every command: audit log (`.openspecpm/audit.log`, secrets scrubbed) · token-bucket rate-limiting per adapter · OpenSpec version probe · optional opt-in telemetry.
318
+
319
+ ## Workflow phases
320
+
321
+ OpenSpecPM is organized into five phases, each with a reference doc under [`skill/openspecpm/references/`](skill/openspecpm/references/):
322
+
323
+ 1. **Plan** ([`plan.md`](skill/openspecpm/references/plan.md)) — Capture requirements through an OpenSpec proposal + BDD scenarios.
324
+ 2. **Structure** ([`structure.md`](skill/openspecpm/references/structure.md)) — Decompose into tasks with explicit dependencies and parallelism hints.
325
+ 3. **Sync** ([`sync.md`](skill/openspecpm/references/sync.md)) — Push to the PM tool. Capabilities-driven hierarchy collapse for flatter backends.
326
+ 4. **Execute** ([`execute.md`](skill/openspecpm/references/execute.md)) — Start work on a tracked item. Optional worktrees, parallel-agent dispatch.
327
+ 5. **Track** ([`track.md`](skill/openspecpm/references/track.md)) — Status, standup, next, blocked, ship.
328
+
329
+ ## Architecture highlights
330
+
331
+ - **Adapter contract.** Every backend implements the same 9-method interface plus `capabilities()` reporting hierarchy depth (GitHub=2, Linear=2, GitLab=2, Jira=3, ADO=4). The sync layer collapses levels gracefully.
332
+ - **OpenSpec anti-corruption layer.** Version-pinned probe on every CLI invocation. One constant absorbs upstream path moves.
333
+ - **Idempotent sync.** Each task carries `sync_state` + `external_id` in frontmatter. Re-running `sync` skips created items and retries failures. Comments use `<!-- SYNCED: <ts> -->` markers to prevent duplication.
334
+ - **Token-bucket rate-limiting.** Per-adapter presets tuned for each backend's published limits.
335
+ - **BDD linter.** Heuristic checks: one Given/When/Then per scenario, observable verbs in Then, deny-list for vague phrases ("should work"), tautology detection via word-bigram similarity.
336
+ - **Optional LLM judge.** `--llm` (or `judge.enabled: true` in `.openspecpm/config.json`) augments the heuristic linter with Claude Haiku 4.5 to catch cross-spec contradictions, missing success-criteria coverage, and vague Then predicates the regex linter misses. Uses prompt caching on the proposal so re-runs across multiple specs stay cheap. Requires `ANTHROPIC_API_KEY` — `openspecpm doctor` reports its presence.
337
+
338
+ ## Roadmap
339
+
340
+ Active v2 work is tracked as OpenSpec changes under [`openspec/changes/`](openspec/changes/README.md). Six features are scaffolded with full proposals, dependency-aware task lists, and BDD scenarios: dependency-graph visualization, LLM-backed BDD reviewer, spec → test scaffolding, compliance traceability export, three new adapters (Notion / ClickUp / Asana), and a real agent orchestrator that graduates `fan-out` from prompt-emitter to dispatcher.
341
+
342
+ OpenSpecPM dogfoods itself: anyone can `openspecpm next` to see what's ready to start, or `openspecpm sync <change>` to push any of the six into a tracked PM tool.
343
+
344
+ ## Project structure
345
+
346
+ ```
347
+ openspecpm/
348
+ ├── README.md this file
349
+ ├── LICENSE MIT
350
+ ├── CHANGELOG.md
351
+ ├── package.json
352
+ ├── .github/workflows/test.yml
353
+ ├── skill/openspecpm/ Claude Code Agent Skill
354
+ │ ├── SKILL.md
355
+ │ └── references/ conventions, plan, structure, sync, execute, track
356
+ └── cli/
357
+ ├── bin/openspecpm.js Commander entrypoint
358
+ ├── src/
359
+ │ ├── commands/ init, doctor, propose, sync, status, standup, next, blocked, ship
360
+ │ ├── adapters/ base, github, azure, jira, index
361
+ │ ├── bdd/ linter, templates
362
+ │ ├── http.js REST helper for ADO + Jira
363
+ │ ├── tracking.js listChanges, findNext, findBlocked, findRecent
364
+ │ ├── openspec-bridge.js
365
+ │ ├── config.js
366
+ │ ├── frontmatter.js
367
+ │ └── ratelimit.js
368
+ └── tests/ unit + contract tests (count badge is auto-updated by CI)
369
+ ```
370
+
371
+ ## License
372
+
373
+ [MIT](LICENSE)