openspecpm 0.1.0-alpha.0 → 1.0.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.
package/README.md CHANGED
@@ -1,352 +1,388 @@
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, Jira, Linear, or GitLab.
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 · Linear · GitLab"]
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 five differences:
34
+
35
+ 1. **OpenSpec drives spec authoring + BDD scenarios become enforceable.** Every feature gets `proposal.md`, `design.md`, `tasks.md`, and a `specs/` folder of Given/When/Then scenarios. A heuristic linter blocks vague Thens at `sync` time. An optional [LLM judge](#architecture-highlights) (Claude Haiku 4.5, opt-in via `--llm`) catches cross-spec contradictions and missing-coverage gaps the regex linter can't see.
36
+ 2. **Five pluggable PM backends** — an interactive wizard at `init` time picks GitHub Issues/Projects, Azure DevOps Boards, Jira, Linear, or GitLab. New backends register without forking via `registerAdapter()`.
37
+ 3. **Built for non-engineers too** — PMs/BAs/PgMs can drive the flow. A `doctor` command owns auth-setup pain (with `--install` and `--setup-auth` flags for OS-specific install hints and PAT-creation URLs). Worktrees are hidden by default.
38
+ 4. **Audit-logged by default.** Every command appends a JSONL entry (secrets scrubbed) to `.openspecpm/audit.log`. Useful for regulated industries that need a paper trail; useful for the rest of us when something looks weird.
39
+ 5. **Cross-feature task graphs.** `depends_on:` can reach across changes (`<feature>/<task-title>` or `<feature>/<external-id>`), so `next` and `blocked` reflect the whole project rather than one feature in isolation.
40
+
41
+ ## Architecture
42
+
43
+ ```mermaid
44
+ flowchart TD
45
+ PM([👤 Project Manager / BA])
46
+ Dev([👤 Developer])
47
+ Agent([🤖 AI Agent · Claude Code])
48
+
49
+ Skill["**Agent Skill**<br/>skill/openspecpm/SKILL.md<br/><br/>Routes natural-language intent"]
50
+ CLI["**Node CLI**<br/>cli/bin/openspecpm.js<br/><br/>Commander dispatch + audit"]
51
+
52
+ subgraph CMDS["📋 Commands · cli/src/commands/"]
53
+ direction LR
54
+ Setup["**① Setup**<br/>init • doctor"]
55
+ Plan["**② Plan**<br/>propose • decompose"]
56
+ SyncCmd["**③ Sync**<br/>sync • comment • reconcile<br/>assign • bug-report"]
57
+ Track["**④ Track**<br/>status • standup • next<br/>blocked • validate • search • watch"]
58
+ Exec["**⑤ Execute / Ship**<br/>fan-out ship help-table"]
59
+ end
60
+
61
+ subgraph CORE["⚙️ Core services · cli/src/"]
62
+ direction LR
63
+ Bridge["**OpenSpec Bridge + BDD**<br/>openspec-bridge.js<br/>bdd/linter.js"]
64
+ TrackingS["**Tracking + Audit**<br/>tracking.js<br/>audit.js"]
65
+ HTTP["**HTTP + Rate-limit**<br/>http.js<br/>ratelimit.js"]
66
+ IO["**Config + Notify + Telemetry**<br/>config.js • notify.js<br/>telemetry.js"]
67
+ end
68
+
69
+ subgraph ADAPTERS["🔌 Adapter contract · cli/src/adapters/ · 9 methods + capabilities()"]
70
+ direction LR
71
+ GHA["**GitHub**<br/>depth 2"]
72
+ AzA["**Azure DevOps**<br/>depth 4"]
73
+ JiA["**Jira**<br/>depth 3"]
74
+ LiA["**Linear**<br/>depth 2"]
75
+ GlA["**GitLab**<br/>depth 2"]
76
+ end
77
+
78
+ subgraph EXT["☁️ External PM systems"]
79
+ direction LR
80
+ GHE[("GitHub<br/>Issues / Projects")]
81
+ AzE[("Azure DevOps<br/>Boards")]
82
+ JiE[("Jira<br/>Cloud / Server")]
83
+ LiE[("Linear")]
84
+ GlE[("GitLab<br/>Issues")]
85
+ end
86
+
87
+ subgraph PERSIST["💾 Persistence & sinks"]
88
+ direction LR
89
+ FS1["📁 **openspec/**<br/>changes/&lt;feature&gt;/<br/>• proposal.md<br/>• specs/*.md (BDD)<br/>• tasks.md<br/>• updates/progress.md"]
90
+ FS2["📁 **.openspecpm/**<br/>• config.json<br/>• audit.log (JSONL)<br/>• state.json"]
91
+ Sinks["🔔 **Webhooks**<br/>• Slack<br/>• Teams<br/>• Generic JSON"]
92
+ end
93
+
94
+ PM --> Skill
95
+ Dev --> CLI
96
+ Agent --> Skill
97
+ Skill -- invokes --> CLI
98
+ CLI --> CMDS
99
+ CMDS --> CORE
100
+ CORE --> ADAPTERS
101
+
102
+ GHA --> GHE
103
+ AzA --> AzE
104
+ JiA --> JiE
105
+ LiA --> LiE
106
+ GlA --> GlE
107
+
108
+ Bridge -. writes .-> FS1
109
+ TrackingS -. writes .-> FS1
110
+ IO -. writes .-> FS2
111
+ IO -. broadcast .-> Sinks
112
+
113
+ classDef user fill:#DAE8FC,stroke:#6C8EBF,color:#000
114
+ classDef agent fill:#FFE0B2,stroke:#D97757,color:#000
115
+ classDef entry fill:#C5E1A5,stroke:#558B2F,color:#000
116
+ classDef skill fill:#FFE0B2,stroke:#D97757,color:#000
117
+ classDef github fill:#222,stroke:#000,color:#fff
118
+ classDef azure fill:#0078D7,stroke:#005A9E,color:#fff
119
+ classDef jira fill:#0052CC,stroke:#003580,color:#fff
120
+ classDef linear fill:#5E6AD2,stroke:#3F47A0,color:#fff
121
+ classDef gitlab fill:#FC6D26,stroke:#C44A19,color:#fff
122
+ classDef ext fill:#fff,stroke:#333,stroke-width:3px,color:#000
123
+ classDef fs fill:#fff,stroke:#444,stroke-width:2px,color:#000
124
+
125
+ class PM,Dev user
126
+ class Agent agent
127
+ class CLI entry
128
+ class Skill skill
129
+ class GHA github
130
+ class AzA azure
131
+ class JiA jira
132
+ class LiA linear
133
+ class GlA gitlab
134
+ class GHE,AzE,JiE,LiE,GlE ext
135
+ class FS1,FS2,Sinks fs
136
+ ```
137
+
138
+ ## Lifecycle
139
+
140
+ ```mermaid
141
+ flowchart LR
142
+ Idea["💡 **Idea**<br/>stakeholder feature,<br/>bug, or refactor"]
143
+
144
+ subgraph P1[" PLAN"]
145
+ direction TB
146
+ Propose["**openspecpm propose**<br/>Shells out to OpenSpec<br/>Soft BDD lint"]
147
+ Decompose["**openspecpm decompose**<br/>Extract tasks from<br/>proposal + BDD"]
148
+ Propose --> Decompose
149
+ end
150
+
151
+ subgraph P2[" REVIEW + SYNC"]
152
+ direction TB
153
+ Review["👀 **Human review**<br/>Sign off on BDD"]
154
+ Validate["**openspecpm validate**<br/>Schema + BDD sweep"]
155
+ SyncCmd["**openspecpm sync**<br/>Hard BDD lint<br/>Idempotent"]
156
+ Review --> Validate --> SyncCmd
157
+ end
158
+
159
+ subgraph P3[" EXECUTE"]
160
+ direction TB
161
+ Next["**openspecpm next**"]
162
+ FanOut["**openspecpm fan-out**<br/>Parallel agent prompts"]
163
+ Build["🤖 **Implement**<br/>BDD = acceptance criteria"]
164
+ Comment["**openspecpm comment**<br/>Broadcast progress"]
165
+ Reconcile["**openspecpm reconcile**<br/>Pull remote state"]
166
+ Next --> FanOut --> Build --> Comment --> Reconcile
167
+ end
168
+
169
+ subgraph P4[" TRACK"]
170
+ direction TB
171
+ Status["**Track commands**<br/>status • standup<br/>blocked • search<br/>watch • bug-report"]
172
+ end
173
+
174
+ subgraph P5[" SHIP"]
175
+ direction TB
176
+ Ship["**openspecpm ship**<br/>Close tasks + epic<br/>Archive change"]
177
+ Shipped["🚀 **Shipped**"]
178
+ Ship --> Shipped
179
+ end
180
+
181
+ Idea --> P1
182
+ P1 --> P2
183
+ P2 --> P3
184
+ P3 --> P4
185
+ P4 --> P5
186
+ Shipped -. next feature .-> Idea
187
+
188
+ classDef ideaC fill:#FFF9C4,stroke:#F9A825,color:#000
189
+ classDef cmdC fill:#D5E8D4,stroke:#82B366,color:#000
190
+ classDef humanC fill:#FFF9C4,stroke:#F9A825,color:#000
191
+ classDef agentC fill:#FFE0B2,stroke:#D97757,color:#000
192
+ classDef shipC fill:#FFCDD2,stroke:#D32F2F,color:#000
193
+ classDef doneC fill:#C8E6C9,stroke:#2E7D32,color:#000
194
+
195
+ class Idea ideaC
196
+ class Propose,Decompose,Validate,SyncCmd,Next,FanOut,Comment,Reconcile,Status cmdC
197
+ class Review humanC
198
+ class Build agentC
199
+ class Ship shipC
200
+ class Shipped doneC
201
+ ```
202
+
203
+ > 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 · optional Slack / Teams / generic-webhook broadcasts on `standup --broadcast`.
204
+
205
+ ## Install
206
+
207
+ ```bash
208
+ # Standalone CLI (any harness)
209
+ npx openspecpm@latest init
210
+
211
+ # Claude Code Agent Skill
212
+ # Copy skill/openspecpm/ into your Claude Code skills directory.
213
+ # SKILL.md handles routing — just talk to Claude.
214
+ ```
215
+
216
+ OpenSpecPM shells out to [OpenSpec](https://github.com/Fission-AI/OpenSpec); install it first:
217
+
218
+ ```bash
219
+ npm install -g @fission-ai/openspec
220
+ ```
221
+
222
+ ## In action
223
+
224
+ > 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.
225
+
226
+ **1 · Phase-grouped command reference** — `help-table` shows every command grouped by workflow phase (Setup → Plan → Sync → Track → Execute/Ship):
227
+
228
+ ![openspecpm help-table](docs/screenshots/help-table.png)
229
+
230
+ **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:
231
+
232
+ ![openspecpm doctor](docs/screenshots/doctor.png)
233
+
234
+ **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:
235
+
236
+ ![openspecpm propose](docs/screenshots/propose.png)
237
+
238
+ **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`:*
239
+
240
+ ![openspecpm propose --llm](docs/screenshots/judge.png)
241
+
242
+ **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:
243
+
244
+ ![openspecpm decompose](docs/screenshots/decompose.png)
245
+
246
+ **6 · Multi-feature status** — `status` shows the configured adapter and per-change task counts (`synced / pending / failed / done`) at a glance:
247
+
248
+ ![openspecpm status](docs/screenshots/status.png)
249
+
250
+ **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:
251
+
252
+ ![openspecpm next](docs/screenshots/next.png)
253
+
254
+ **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:
255
+
256
+ ![openspecpm blocked](docs/screenshots/blocked.png)
257
+
258
+ **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:
259
+
260
+ ![openspecpm fan-out](docs/screenshots/fan-out.png)
261
+
262
+ **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:
263
+
264
+ ![openspecpm search](docs/screenshots/search.png)
265
+
266
+ **11 · Project-wide validation** — `validate` runs the schema check and BDD linter across every change and reports per-feature error + warning counts:
267
+
268
+ ![openspecpm validate](docs/screenshots/validate.png)
269
+
270
+ ## Quick start
271
+
272
+ ```bash
273
+ # 1. One-time setup. The wizard asks which PM tool your team uses.
274
+ npx openspecpm init
275
+
276
+ # 2. Verify auth before doing anything remote.
277
+ npx openspecpm doctor
278
+
279
+ # 3. Author a proposal. OpenSpec generates proposal.md, design.md, tasks.md,
280
+ # and BDD scenarios in specs/. Soft BDD-lint runs after authoring.
281
+ npx openspecpm propose dark-mode --prompt "Per-user dark theme with persistence."
282
+
283
+ # 4. Review the generated files. Refine BDD scenarios until lint is clean.
284
+
285
+ # 5. Sync to the PM tool. Hard BDD lint runs first; pass --force to override.
286
+ npx openspecpm sync dark-mode
287
+
288
+ # 6. Pick up where you left off.
289
+ npx openspecpm next # tasks ready to start
290
+ npx openspecpm blocked # tasks waiting on dependencies
291
+ npx openspecpm standup # progress updates in the last 24h
292
+
293
+ # 7. When the feature is verified, close + archive.
294
+ npx openspecpm ship dark-mode
295
+ ```
296
+
297
+ ## Command reference
298
+
299
+ | Command | What it does |
300
+ |---|---|
301
+ | `init` | Interactive wizard. Picks the PM tool. Writes `.openspecpm/config.json`. |
302
+ | `doctor [adapter]` | Auth/tooling health check. English remediation hints on every failure. |
303
+ | `propose <feature> [--llm]` | Shell out to OpenSpec; create `openspec/changes/<feature>/`. Soft-lint BDD scenarios; `--llm` adds the LLM judge. |
304
+ | `decompose <feature>` | Extract tasks from proposal headings/checklists + BDD scenarios into `tasks.md`. |
305
+ | `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. |
306
+ | `comment <feature> <task>` | Broadcast local `progress.md` (or `-m`) to the PM tool with `<!-- SYNCED -->` marker. |
307
+ | `reconcile <feature>` | Pull remote work-item state into local frontmatter. Detects out-of-band closes. |
308
+ | `bug-report <feature> <task> --title "…"` | File a linked regression against a shipped task. |
309
+ | `status` | Per-change task counts: pending / created / failed / done. |
310
+ | `standup [--since 24h]` | Recent `progress.md` updates, newest first. |
311
+ | `next [-l 5]` | Tasks with no unmet dependencies. |
312
+ | `blocked` | Tasks waiting on unmet dependencies (with reasons). |
313
+ | `validate [--llm]` | Schema + dependency + BDD-lint sweep across every change; `--llm` adds the LLM judge per change. |
314
+ | `search <query>` | Grep across proposals, specs, tasks, progress notes. |
315
+ | `fan-out <feature>` | Emit ready-to-paste agent prompts for `parallel: true` tasks. |
316
+ | `ship <feature> [-y]` | Close all task work items + close the epic + archive the OpenSpec change. |
317
+ | `help-table [topic]` | Context-aware command reference grouped by workflow phase. |
318
+
319
+ Every command appends a JSONL entry (secrets scrubbed) to `.openspecpm/audit.log`.
320
+
321
+ ## Workflow phases
322
+
323
+ OpenSpecPM is organized into five phases, each with a reference doc under [`skill/openspecpm/references/`](skill/openspecpm/references/):
324
+
325
+ 1. **Plan** ([`plan.md`](skill/openspecpm/references/plan.md)) — Capture requirements through an OpenSpec proposal + BDD scenarios.
326
+ 2. **Structure** ([`structure.md`](skill/openspecpm/references/structure.md)) — Decompose into tasks with explicit dependencies and parallelism hints.
327
+ 3. **Sync** ([`sync.md`](skill/openspecpm/references/sync.md)) — Push to the PM tool. Capabilities-driven hierarchy collapse for flatter backends.
328
+ 4. **Execute** ([`execute.md`](skill/openspecpm/references/execute.md)) — Start work on a tracked item. Optional worktrees, parallel-agent dispatch.
329
+ 5. **Track** ([`track.md`](skill/openspecpm/references/track.md)) — Status, standup, next, blocked, ship.
330
+
331
+ ## Architecture highlights
332
+
333
+ - **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.
334
+ - **OpenSpec anti-corruption layer.** Version-pinned probe on every CLI invocation. One constant absorbs upstream path moves.
335
+ - **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.
336
+ - **Token-bucket rate-limiting.** Per-adapter presets tuned for each backend's published limits.
337
+ - **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.
338
+ - **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.
339
+
340
+ ## Roadmap
341
+
342
+ Active v2 work is tracked as OpenSpec changes under [`openspec/changes/`](openspec/changes/README.md). The first scaffolded feature — **`bdd-llm-reviewer`** — shipped in v1.0.0. Five remain: dependency-graph visualization, 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.
343
+
344
+ OpenSpecPM dogfoods itself: anyone can `openspecpm next` to see what's ready to start, or `openspecpm sync <change>` to push any of the five into a tracked PM tool.
345
+
346
+ ## Project structure
347
+
348
+ ```
349
+ openspecpm/
350
+ ├── README.md this file
351
+ ├── LICENSE MIT
352
+ ├── CHANGELOG.md
353
+ ├── CONTRIBUTING.md
354
+ ├── SECURITY.md
355
+ ├── package.json
356
+ ├── .github/
357
+ │ ├── workflows/ test.yml · auto-approve.yml · release.yml · publish.yml
358
+ │ ├── ISSUE_TEMPLATE/
359
+ │ └── PULL_REQUEST_TEMPLATE.md
360
+ ├── docs/screenshots/ README captures + render.ps1 renderer
361
+ ├── openspec/changes/ v2 roadmap (each subdir is a tracked change)
362
+ ├── skill/openspecpm/ Claude Code Agent Skill
363
+ │ ├── SKILL.md
364
+ │ └── references/ conventions · plan · structure · sync · execute · track
365
+ └── cli/
366
+ ├── bin/openspecpm.js Commander entrypoint
367
+ ├── src/
368
+ │ ├── commands/ init · doctor · propose · decompose · sync · comment · reconcile ·
369
+ │ │ status · standup · next · blocked · validate · search · fan-out ·
370
+ │ │ bug-report · ship · assign · watch · help · bulk
371
+ │ ├── adapters/ base · github · azure · jira · linear · gitlab · index
372
+ │ ├── bdd/ linter · judge · templates
373
+ │ ├── audit.js JSONL audit log + secret scrubber
374
+ │ ├── http.js REST helper for ADO / Jira / Linear / GitLab
375
+ │ ├── tracking.js listChanges · findNext · findBlocked · findRecent
376
+ │ ├── notify.js Slack / Teams / generic-webhook envelopes
377
+ │ ├── telemetry.js opt-in, audit-log-only at alpha
378
+ │ ├── install-hints.js
379
+ │ ├── openspec-bridge.js
380
+ │ ├── config.js
381
+ │ ├── frontmatter.js
382
+ │ └── ratelimit.js
383
+ └── tests/ unit + contract tests (count badge is auto-updated by CI)
384
+ ```
385
+
386
+ ## License
387
+
388
+ [MIT](LICENSE)