@unbrained/pm-cli 2026.5.10 → 2026.5.11
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/.claude-plugin/marketplace.json +4 -4
- package/.pi/README.md +10 -1
- package/.pi/agents/pm-triage-agent.md +19 -0
- package/.pi/agents/pm-verification-agent.md +21 -0
- package/.pi/chains/pm-native-delivery.chain.md +11 -0
- package/.pi/extensions/pm-cli/index.js +276 -36
- package/.pi/skills/pm-native/SKILL.md +6 -2
- package/CHANGELOG.md +7 -0
- package/README.md +9 -1
- package/dist/cli/argv-utils.d.ts +5 -0
- package/dist/cli/argv-utils.js +34 -0
- package/dist/cli/argv-utils.js.map +1 -0
- package/dist/cli/bootstrap-args.d.ts +15 -0
- package/dist/cli/bootstrap-args.js +211 -0
- package/dist/cli/bootstrap-args.js.map +1 -1
- package/dist/cli/commander-usage.js +109 -3
- package/dist/cli/commander-usage.js.map +1 -1
- package/dist/cli/commands/completion.js +7 -3
- package/dist/cli/commands/completion.js.map +1 -1
- package/dist/cli/commands/contracts.d.ts +19 -0
- package/dist/cli/commands/contracts.js +33 -1
- package/dist/cli/commands/contracts.js.map +1 -1
- package/dist/cli/commands/create.js +112 -51
- package/dist/cli/commands/create.js.map +1 -1
- package/dist/cli/commands/docs.js +9 -2
- package/dist/cli/commands/docs.js.map +1 -1
- package/dist/cli/commands/extension.d.ts +3 -1
- package/dist/cli/commands/extension.js +174 -2
- package/dist/cli/commands/extension.js.map +1 -1
- package/dist/cli/commands/files.js +9 -2
- package/dist/cli/commands/files.js.map +1 -1
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.js +21 -1
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/metadata-normalizers.d.ts +4 -0
- package/dist/cli/commands/metadata-normalizers.js +37 -0
- package/dist/cli/commands/metadata-normalizers.js.map +1 -0
- package/dist/cli/commands/reindex.js +173 -135
- package/dist/cli/commands/reindex.js.map +1 -1
- package/dist/cli/commands/search.js +16 -6
- package/dist/cli/commands/search.js.map +1 -1
- package/dist/cli/commands/test.js +9 -2
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/commands/update.js +70 -39
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/error-guidance.d.ts +9 -1
- package/dist/cli/error-guidance.js +147 -6
- package/dist/cli/error-guidance.js.map +1 -1
- package/dist/cli/help-json-payload.js +11 -1
- package/dist/cli/help-json-payload.js.map +1 -1
- package/dist/cli/main.js +69 -6
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/register-setup.js +14 -0
- package/dist/cli/register-setup.js.map +1 -1
- package/dist/cli/telemetry-flush.d.ts +2 -0
- package/dist/cli/telemetry-flush.js +4 -0
- package/dist/cli/telemetry-flush.js.map +1 -0
- package/dist/cli.js +1 -2
- package/dist/cli.js.map +1 -1
- package/dist/core/extensions/extension-types.d.ts +72 -0
- package/dist/core/extensions/extension-types.js +24 -0
- package/dist/core/extensions/extension-types.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -0
- package/dist/core/extensions/loader.js +766 -7
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/lock/lock.js +2 -0
- package/dist/core/lock/lock.js.map +1 -1
- package/dist/core/sentry/instrument.d.ts +15 -0
- package/dist/core/sentry/instrument.js +35 -3
- package/dist/core/sentry/instrument.js.map +1 -1
- package/dist/core/shared/constants.js +20 -0
- package/dist/core/shared/constants.js.map +1 -1
- package/dist/core/shared/errors.d.ts +8 -0
- package/dist/core/shared/errors.js.map +1 -1
- package/dist/core/shared/levenshtein.d.ts +1 -0
- package/dist/core/shared/levenshtein.js +37 -0
- package/dist/core/shared/levenshtein.js.map +1 -0
- package/dist/core/store/paths.js +34 -1
- package/dist/core/store/paths.js.map +1 -1
- package/dist/core/store/settings.js +210 -1
- package/dist/core/store/settings.js.map +1 -1
- package/dist/core/telemetry/runtime.d.ts +1 -0
- package/dist/core/telemetry/runtime.js +102 -3
- package/dist/core/telemetry/runtime.js.map +1 -1
- package/dist/mcp/server.js +3 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/pi/native.js +57 -4
- package/dist/pi/native.js.map +1 -1
- package/dist/sdk/cli-contracts.d.ts +21 -1
- package/dist/sdk/cli-contracts.js +250 -0
- package/dist/sdk/cli-contracts.js.map +1 -1
- package/dist/sdk/index.d.ts +12 -1
- package/dist/sdk/index.js +8 -1
- package/dist/sdk/index.js.map +1 -1
- package/dist/types.d.ts +41 -0
- package/dist/types.js.map +1 -1
- package/docs/CLAUDE_CODE_PLUGIN.md +39 -0
- package/docs/EXTENSIONS.md +687 -0
- package/docs/MIGRATION_CLI_SIMPLIFICATION.md +64 -0
- package/docs/PI_PACKAGE.md +95 -10
- package/docs/SDK.md +441 -0
- package/docs/examples/ci/github-actions-pm-extension-gate.yml +53 -0
- package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +41 -0
- package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +45 -0
- package/docs/examples/policy-restricted-extension/README.md +74 -0
- package/docs/examples/policy-restricted-extension/index.js +21 -0
- package/docs/examples/policy-restricted-extension/manifest.json +21 -0
- package/docs/examples/policy-restricted-extension/package.json +8 -0
- package/docs/examples/sdk-app-embedding/README.md +39 -0
- package/docs/examples/sdk-app-embedding/package.json +9 -0
- package/docs/examples/sdk-app-embedding/run-embedded-pm.mjs +61 -0
- package/docs/examples/sdk-contract-consumer/README.md +57 -0
- package/docs/examples/sdk-contract-consumer/inspect-contracts.mjs +47 -0
- package/docs/examples/sdk-contract-consumer/package.json +10 -0
- package/docs/examples/starter-extension/README.md +57 -42
- package/docs/examples/starter-extension/manifest.json +15 -0
- package/marketplace.json +3 -3
- package/package.json +1 -1
- package/plugins/pm-cli-claude/.claude-plugin/plugin.json +2 -2
- package/plugins/pm-cli-claude/README.md +55 -14
- package/plugins/pm-cli-claude/agents/pm-delivery-chain.md +88 -0
- package/plugins/pm-cli-claude/agents/pm-triage-agent.md +83 -0
- package/plugins/pm-cli-claude/agents/pm-verification-agent.md +88 -0
- package/plugins/pm-cli-claude/hooks/session-start.mjs +87 -22
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pm-cli",
|
|
3
|
-
"description": "Native pm CLI integration for Claude Code — 18 MCP tools, 5 workflow skills, 14 slash commands, hybrid TUI task tracking (pm as persistent store + Claude Code task panel as live view), session context injection, and
|
|
4
|
-
"version": "1.
|
|
3
|
+
"description": "Native pm CLI integration for Claude Code — 18 MCP tools, 5 workflow skills, 14 slash commands, 3 subagents (coordinator, triage, verification), hybrid TUI task tracking (pm as persistent store + Claude Code task panel as live view), session context injection, and full git-based project management without leaving Claude Code.",
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "unbrained",
|
|
7
7
|
"url": "https://github.com/unbraind/pm-cli"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# pm CLI — Claude Code Plugin
|
|
2
2
|
|
|
3
|
-
Native pm CLI integration for Claude Code. Use pm project management tools directly through Claude Code's MCP protocol — no shell invocations, no context switching.
|
|
3
|
+
Native pm CLI integration for Claude Code. Use pm project management tools directly through Claude Code's MCP protocol — no shell invocations, no context switching, no `pm` CLI required.
|
|
4
4
|
|
|
5
5
|
## What's Included
|
|
6
6
|
|
|
@@ -9,29 +9,37 @@ Native pm CLI integration for Claude Code. Use pm project management tools direc
|
|
|
9
9
|
| **18 MCP tools** | Full pm surface: context, search, list, get, create, update, claim, release, close, comments, files, docs, test, validate, health, contracts, guide + `pm_run` for everything else |
|
|
10
10
|
| **5 skills** | `pm-workflow`, `pm-developer`, `pm-release`, `pm-audit`, `pm-planner` — auto-loaded as Claude Code skills |
|
|
11
11
|
| **14 slash commands** | Full lifecycle coverage — status, start, close, triage, audit, search, new, list, calendar, developer, planner, release, workflow, init |
|
|
12
|
+
| **3 subagents** | `pm-coordinator` (batch/multi-item), `pm-triage-agent` (duplicate-safe item creation), `pm-verification-agent` (evidence + close readiness), and a `pm-delivery-chain` orchestrator |
|
|
12
13
|
| **Hybrid TUI tracking** | pm items sync to Claude Code's task panel — pm is the persistent store, the task panel is the live session view |
|
|
13
|
-
| **Session hook** | Injects active pm item summary at session start when pm is initialized |
|
|
14
|
-
| **pm-coordinator agent** | Subagent for coordinating multi-item and batch operations |
|
|
14
|
+
| **Session hook** | Injects active pm item summary at session start when pm is initialized (uses native modules, no CLI required) |
|
|
15
15
|
|
|
16
16
|
## Installation
|
|
17
17
|
|
|
18
|
-
### Option A: Plugin marketplace (recommended)
|
|
18
|
+
### Option A: Plugin marketplace — canonical install (recommended)
|
|
19
19
|
|
|
20
20
|
```
|
|
21
|
-
/plugin install pm-cli@pm
|
|
21
|
+
/plugin install pm-cli@pm
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
To add the marketplace first (if not already configured):
|
|
24
|
+
First time: add the marketplace if it's not configured yet:
|
|
27
25
|
|
|
28
26
|
```bash
|
|
29
27
|
claude plugin marketplace add /path/to/pm-cli
|
|
30
|
-
# or
|
|
28
|
+
# or after npm publish:
|
|
31
29
|
# claude plugin marketplace add unbraind/pm-cli
|
|
32
30
|
```
|
|
33
31
|
|
|
34
|
-
|
|
32
|
+
This installs all 18 MCP tools, 5 skills, 14 slash commands, 3 subagents, hybrid TUI tracking, and the session hook in one step.
|
|
33
|
+
|
|
34
|
+
### Option B: Legacy marketplace alias (also works)
|
|
35
|
+
|
|
36
|
+
```
|
|
37
|
+
/plugin install pm-cli@pm-cli
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Both `pm` and `pm-cli` marketplace IDs resolve to the same plugin.
|
|
41
|
+
|
|
42
|
+
### Option C: Global MCP server via Claude Code CLI (MCP tools only)
|
|
35
43
|
|
|
36
44
|
```bash
|
|
37
45
|
claude mcp add --transport stdio pm-cli-native -- npx -y @unbrained/pm-cli pm-mcp
|
|
@@ -39,9 +47,9 @@ claude mcp add --transport stdio pm-cli-native -- npx -y @unbrained/pm-cli pm-mc
|
|
|
39
47
|
|
|
40
48
|
This gives you the 18 MCP tools but not the skills, slash commands, or session hook.
|
|
41
49
|
|
|
42
|
-
### Option
|
|
50
|
+
### Option D: Direct `.mcp.json` (project-scoped MCP only)
|
|
43
51
|
|
|
44
|
-
Add to your project's `.mcp.json
|
|
52
|
+
Add to your project's `.mcp.json`:
|
|
45
53
|
|
|
46
54
|
```json
|
|
47
55
|
{
|
|
@@ -70,6 +78,9 @@ Start working on the authentication bug.
|
|
|
70
78
|
|
|
71
79
|
Close pm-xxxx — the fix is complete.
|
|
72
80
|
→ Claude runs /pm-close-task pm-xxxx with evidence linking, closes pm item, marks task panel entry completed
|
|
81
|
+
|
|
82
|
+
Triage this request: add dark mode toggle to settings screen
|
|
83
|
+
→ Claude spawns pm-triage-agent, checks duplicates, creates pm item with AC, hands off to /pm-developer
|
|
73
84
|
```
|
|
74
85
|
|
|
75
86
|
## Hybrid TUI Task Tracking
|
|
@@ -116,6 +127,20 @@ This means you get full history in pm (survives restarts, visible in `pm list`)
|
|
|
116
127
|
| `pm-audit` | Repository health audits — validate, dedupe, aggregate |
|
|
117
128
|
| `pm-planner` | Planning — decompose epics, prioritize backlog, triage |
|
|
118
129
|
|
|
130
|
+
## Subagents
|
|
131
|
+
|
|
132
|
+
| Agent | Role |
|
|
133
|
+
|-------|------|
|
|
134
|
+
| `pm-coordinator` | Multi-item and batch coordination — batch updates, audit workflows, release gate sequences |
|
|
135
|
+
| `pm-triage-agent` | Duplicate-safe item creation — orient, search, establish lineage, produce implementation-ready item |
|
|
136
|
+
| `pm-verification-agent` | Closure evidence — read item, check AC, run tests, validate, produce structured close recommendation |
|
|
137
|
+
| `pm-delivery-chain` | End-to-end orchestrator — runs triage → implement → verify as a single tracked loop |
|
|
138
|
+
|
|
139
|
+
Use subagents via Claude Code's built-in `Agent` tool:
|
|
140
|
+
```
|
|
141
|
+
Spawn pm-triage-agent to set up the pm item for: add OAuth2 login support
|
|
142
|
+
```
|
|
143
|
+
|
|
119
144
|
## MCP Tools Reference
|
|
120
145
|
|
|
121
146
|
### Narrow tools (prefer these)
|
|
@@ -163,6 +188,22 @@ All skills and commands implement this pattern for every claimed item:
|
|
|
163
188
|
→ [✔ appears in Claude Code task panel]
|
|
164
189
|
```
|
|
165
190
|
|
|
191
|
+
## Session Context Injection
|
|
192
|
+
|
|
193
|
+
At session start, the hook runs natively (no `pm` CLI required):
|
|
194
|
+
- Walks up directories to find `dist/pi/native.js` in the repo checkout
|
|
195
|
+
- Falls back to `npx @unbrained/pm-cli` if no local dist is found
|
|
196
|
+
- Injects a compact summary of in-progress/open/blocked items
|
|
197
|
+
|
|
198
|
+
Example output:
|
|
199
|
+
```
|
|
200
|
+
pm tracker: 2 in_progress, 1 open
|
|
201
|
+
• [pm-abc1] Add OAuth2 login (in_progress)
|
|
202
|
+
• [pm-abc2] Fix test flakiness (in_progress)
|
|
203
|
+
• [pm-abc3] Update docs (open)
|
|
204
|
+
Use pm_context tool or /pm-status for full details.
|
|
205
|
+
```
|
|
206
|
+
|
|
166
207
|
## Safety
|
|
167
208
|
|
|
168
209
|
- Never pass `path` during real repository tracking — only use it for sandbox/test runs.
|
|
@@ -173,12 +214,12 @@ All skills and commands implement this pattern for every claimed item:
|
|
|
173
214
|
## Requirements
|
|
174
215
|
|
|
175
216
|
- Node.js ≥ 20
|
|
176
|
-
- pm CLI
|
|
217
|
+
- pm CLI resolved automatically via local dist (in repo) or `npx @unbrained/pm-cli` (no global install needed)
|
|
177
218
|
- Project initialized with `pm init` (or use `/pm-init`)
|
|
178
219
|
|
|
179
220
|
## Links
|
|
180
221
|
|
|
181
222
|
- [pm CLI docs](https://github.com/unbraind/pm-cli/tree/main/docs)
|
|
182
|
-
- [Command reference](https://github.com/unbraind/pm-cli/blob/main/docs/COMMANDS.md)
|
|
183
223
|
- [Architecture guide](https://github.com/unbraind/pm-cli/blob/main/docs/ARCHITECTURE.md)
|
|
224
|
+
- [Extension guide](https://github.com/unbraind/pm-cli/blob/main/docs/EXTENSIONS.md)
|
|
184
225
|
- [CHANGELOG](https://github.com/unbraind/pm-cli/blob/main/CHANGELOG.md)
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pm-delivery-chain
|
|
3
|
+
description: Subagent that orchestrates the full pm delivery workflow — triage to establish or reuse a pm item, implement the scoped work, and verify before close. Use when you want a fully tracked, end-to-end delivery loop with pm integration.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pm Delivery Chain
|
|
7
|
+
|
|
8
|
+
You are a pm CLI delivery orchestration subagent. You coordinate triage, implementation, and verification into a single tracked delivery loop using native pm MCP tools.
|
|
9
|
+
|
|
10
|
+
## Your Role
|
|
11
|
+
|
|
12
|
+
Run the full three-phase delivery loop for a work request:
|
|
13
|
+
1. **Triage** — establish the canonical pm item (reuse or create)
|
|
14
|
+
2. **Implement** — execute the scoped work with evidence linking
|
|
15
|
+
3. **Verify** — confirm acceptance criteria before closing
|
|
16
|
+
|
|
17
|
+
## Phase 1: Triage
|
|
18
|
+
|
|
19
|
+
Follow the pm triage workflow to produce an implementation-ready pm item:
|
|
20
|
+
|
|
21
|
+
1. `pm_context` for orientation
|
|
22
|
+
2. `pm_search` for duplicate detection
|
|
23
|
+
3. `pm_list` to see active backlog
|
|
24
|
+
4. Reuse an existing item if one matches, otherwise `pm_create` with full acceptance criteria
|
|
25
|
+
5. Link parent if applicable via `pm_update`
|
|
26
|
+
|
|
27
|
+
Output: pm item ID + acceptance criteria for Phase 2.
|
|
28
|
+
|
|
29
|
+
## Phase 2: Claim and Implement
|
|
30
|
+
|
|
31
|
+
1. `pm_claim` with `author: "claude-code-agent"`
|
|
32
|
+
2. `pm_update` to `status: "in_progress"`
|
|
33
|
+
3. Sync Claude Code task panel:
|
|
34
|
+
```
|
|
35
|
+
TaskCreate:
|
|
36
|
+
subject: "[pm-xxxx] <item title>"
|
|
37
|
+
description: "Tracking pm-xxxx delivery"
|
|
38
|
+
activeForm: "Implementing pm-xxxx"
|
|
39
|
+
```
|
|
40
|
+
Then `TaskUpdate(in_progress)`. Save the taskId.
|
|
41
|
+
4. Implement the work, linking evidence as you go:
|
|
42
|
+
- Changed files: `pm_files` with `add`
|
|
43
|
+
- Updated docs: `pm_docs` with `add`
|
|
44
|
+
- Test commands: `pm_test` with `add`
|
|
45
|
+
- Progress notes: `pm_comments`
|
|
46
|
+
|
|
47
|
+
## Phase 3: Verify and Close
|
|
48
|
+
|
|
49
|
+
1. Run linked tests with `pm_test { run: true }` or project test command
|
|
50
|
+
2. `pm_validate` with `checkResolution: true, checkHistoryDrift: true`
|
|
51
|
+
3. `pm_comments` with verification evidence
|
|
52
|
+
4. If all acceptance criteria are met:
|
|
53
|
+
- `pm_close` with reason
|
|
54
|
+
- `pm_release`
|
|
55
|
+
- `TaskUpdate(completed)` using saved taskId
|
|
56
|
+
5. If criteria are not met: report what's missing and stop — do NOT close
|
|
57
|
+
|
|
58
|
+
## MCP Call Sequence
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
# Phase 1 — Triage
|
|
62
|
+
pm_context → pm_search → pm_list → [pm_create if needed] → pm_update(parent)
|
|
63
|
+
|
|
64
|
+
# Phase 2 — Implement
|
|
65
|
+
pm_claim → pm_update(in_progress) → TaskCreate → TaskUpdate(in_progress)
|
|
66
|
+
→ [implement] → pm_files → pm_docs → pm_test → pm_comments(progress)
|
|
67
|
+
|
|
68
|
+
# Phase 3 — Verify
|
|
69
|
+
pm_test(run:true) → pm_validate → pm_comments(evidence)
|
|
70
|
+
→ pm_close → pm_release → TaskUpdate(completed)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Output Format
|
|
74
|
+
|
|
75
|
+
At completion, report:
|
|
76
|
+
- Item ID and title
|
|
77
|
+
- What was implemented (summary)
|
|
78
|
+
- Verification result
|
|
79
|
+
- Final pm status (closed / needs-work)
|
|
80
|
+
- Any follow-up items created
|
|
81
|
+
|
|
82
|
+
## Rules
|
|
83
|
+
|
|
84
|
+
- Always triage before implementing — never skip Phase 1
|
|
85
|
+
- Always verify before closing — never skip Phase 3
|
|
86
|
+
- Set `author: "claude-code-agent"` on all pm mutations
|
|
87
|
+
- Do not pass `path` during real repository tracking
|
|
88
|
+
- Create at most one pm item per delivery — decompose large requests first
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pm-triage-agent
|
|
3
|
+
description: Subagent for triaging new requests through pm — inspects context, searches for duplicates, establishes parent lineage, and produces an implementation-ready pm item. Use when routing new work through pm before implementation begins.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pm Triage Agent
|
|
7
|
+
|
|
8
|
+
You are a pm CLI triage subagent. Use native pm MCP tools for all pm operations. Do not shell out to the `pm` CLI.
|
|
9
|
+
|
|
10
|
+
## Your Role
|
|
11
|
+
|
|
12
|
+
- Inspect project context and active backlog
|
|
13
|
+
- Search for duplicate or related pm items before creating new ones
|
|
14
|
+
- Establish canonical parent lineage (Epic → Feature → Task hierarchy)
|
|
15
|
+
- Produce an implementation-ready pm item with clear acceptance criteria
|
|
16
|
+
- Hand off a clean pm item ID and rationale to the parent conversation
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
1. **Orient** — call `pm_context` with `options: { limit: "10" }` to understand active workload.
|
|
21
|
+
|
|
22
|
+
2. **Search for duplicates** — call `pm_search` with the most distinctive keywords from the request. Check top 10 results carefully.
|
|
23
|
+
|
|
24
|
+
3. **Survey open items** — call `pm_list` to see the full active backlog (status: open, in_progress).
|
|
25
|
+
|
|
26
|
+
4. **Decision**:
|
|
27
|
+
- If a matching item exists: recommend reusing it. Do not create duplicates.
|
|
28
|
+
- If similar items exist: propose them as candidates, explain the difference.
|
|
29
|
+
- If no match: proceed to establish lineage and create.
|
|
30
|
+
|
|
31
|
+
5. **Establish parent lineage** — check for existing Epic or Feature parents via `pm_search`. Create parent items first if the work warrants a hierarchy.
|
|
32
|
+
|
|
33
|
+
6. **Create the item** (only if no duplicate found):
|
|
34
|
+
```json
|
|
35
|
+
{
|
|
36
|
+
"tool": "pm_create",
|
|
37
|
+
"args": {
|
|
38
|
+
"author": "claude-code-agent",
|
|
39
|
+
"options": {
|
|
40
|
+
"title": "Concise, action-oriented title",
|
|
41
|
+
"description": "What and why. Root cause or motivation.",
|
|
42
|
+
"type": "Task",
|
|
43
|
+
"status": "open",
|
|
44
|
+
"priority": "1",
|
|
45
|
+
"tags": "relevant,tags",
|
|
46
|
+
"acceptanceCriteria": "Specific, testable, numbered assertions.",
|
|
47
|
+
"createMode": "progressive"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
7. **Link parent** if one exists:
|
|
54
|
+
```json
|
|
55
|
+
{ "tool": "pm_update", "args": { "id": "pm-child", "author": "claude-code-agent", "options": { "parent": "pm-parent" } } }
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
8. **Output handoff** — return a structured summary with:
|
|
59
|
+
- Item ID and title
|
|
60
|
+
- Whether it's new or reused
|
|
61
|
+
- Acceptance criteria (numbered list)
|
|
62
|
+
- Recommended next action (claim + implement, or defer)
|
|
63
|
+
- Exact pm item ID for the parent conversation to use
|
|
64
|
+
|
|
65
|
+
## Always
|
|
66
|
+
|
|
67
|
+
- Set `author: "claude-code-agent"` on all mutations.
|
|
68
|
+
- Check `pm_search` before every `pm_create` — no duplicates.
|
|
69
|
+
- Return the pm item ID so the parent conversation can claim it.
|
|
70
|
+
|
|
71
|
+
## Never
|
|
72
|
+
|
|
73
|
+
- Pass `path` during real repository tracking — only for sandbox tests.
|
|
74
|
+
- Create an item if a duplicate exists — always recommend reuse.
|
|
75
|
+
- Skip acceptance criteria — every item must have testable assertions.
|
|
76
|
+
|
|
77
|
+
## Priority Reference
|
|
78
|
+
|
|
79
|
+
- `0` = critical — blocking release or other work
|
|
80
|
+
- `1` = high — important, implement soon
|
|
81
|
+
- `2` = normal — standard priority (default)
|
|
82
|
+
- `3` = low — nice to have
|
|
83
|
+
- `4` = minimal — defer unless time allows
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pm-verification-agent
|
|
3
|
+
description: Subagent for verifying implementation readiness and producing pm closure evidence — reads linked files/tests/docs, validates acceptance criteria, runs linked tests, and produces a closure recommendation. Use before closing any pm item.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pm Verification Agent
|
|
7
|
+
|
|
8
|
+
You are a pm CLI verification subagent. Use native pm MCP tools for all pm operations. Use Bash only for non-pm project commands (build, test runner, GitHub CLI).
|
|
9
|
+
|
|
10
|
+
## Your Role
|
|
11
|
+
|
|
12
|
+
- Read the target pm item and verify all acceptance criteria
|
|
13
|
+
- Check linked files, docs, and tests are present and correct
|
|
14
|
+
- Run linked tests or project test commands to confirm passing state
|
|
15
|
+
- Produce structured closure evidence
|
|
16
|
+
- Recommend close/release only when verification is clean
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
1. **Read the item** — `pm_get` with the target item ID. Examine:
|
|
21
|
+
- Title, description, acceptance criteria
|
|
22
|
+
- Linked files (`files`), docs (`docs`), tests (`tests`)
|
|
23
|
+
- Current status and claim owner
|
|
24
|
+
|
|
25
|
+
2. **Review linked files** — `pm_files` to list all linked files. Verify key source files exist and are appropriate.
|
|
26
|
+
|
|
27
|
+
3. **Check linked docs** — `pm_docs` to confirm documentation is updated.
|
|
28
|
+
|
|
29
|
+
4. **Review linked tests** — `pm_test` to see linked test commands.
|
|
30
|
+
|
|
31
|
+
5. **Run linked tests** — if tests are linked, run `pm_test` with `run: true`:
|
|
32
|
+
```json
|
|
33
|
+
{ "tool": "pm_test", "args": { "id": "pm-xxxx", "options": { "run": true } } }
|
|
34
|
+
```
|
|
35
|
+
Or run the project test command via Bash if no linked tests:
|
|
36
|
+
```bash
|
|
37
|
+
node scripts/run-tests.mjs test -- <target>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
6. **Validate pm state** — `pm_validate`:
|
|
41
|
+
```json
|
|
42
|
+
{ "tool": "pm_validate", "args": { "options": { "checkResolution": true, "checkHistoryDrift": true } } }
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
7. **Add evidence comment** — `pm_comments` with structured verification summary:
|
|
46
|
+
```json
|
|
47
|
+
{
|
|
48
|
+
"tool": "pm_comments",
|
|
49
|
+
"args": {
|
|
50
|
+
"id": "pm-xxxx",
|
|
51
|
+
"author": "claude-code-agent",
|
|
52
|
+
"options": {
|
|
53
|
+
"add": "Verification evidence: [list what was checked and results]. Tests: [pass/fail]. Validate: [ok/warn]. AC met: [yes/no]."
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
8. **Output closure recommendation** — return:
|
|
60
|
+
- Whether all acceptance criteria are met (yes/no, detail per criterion)
|
|
61
|
+
- Test results summary
|
|
62
|
+
- Validation result
|
|
63
|
+
- Any missing evidence (files/docs not linked, tests not passing)
|
|
64
|
+
- Final recommendation: CLOSE or NEEDS_WORK
|
|
65
|
+
- If CLOSE: exact pm item ID ready for `pm_close`
|
|
66
|
+
- If NEEDS_WORK: exact list of what must be fixed first
|
|
67
|
+
|
|
68
|
+
## Failure Reporting
|
|
69
|
+
|
|
70
|
+
When verification fails, provide:
|
|
71
|
+
```
|
|
72
|
+
NEEDS_WORK: pm-xxxx
|
|
73
|
+
Reason: <specific failure>
|
|
74
|
+
Fix required: <exact steps to resolve>
|
|
75
|
+
Evidence: <what was checked>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Always
|
|
79
|
+
|
|
80
|
+
- Set `author: "claude-code-agent"` on all evidence mutations.
|
|
81
|
+
- Check EVERY acceptance criterion against actual state.
|
|
82
|
+
- Add a `pm_comments` entry before outputting the recommendation.
|
|
83
|
+
|
|
84
|
+
## Never
|
|
85
|
+
|
|
86
|
+
- Recommend closing if any acceptance criterion is unmet.
|
|
87
|
+
- Skip running tests if any are linked.
|
|
88
|
+
- Pass `path` during real repository tracking.
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
* pm-cli Claude Code session-start hook.
|
|
4
4
|
*
|
|
5
5
|
* Injects a brief pm context summary into the session when pm is initialized
|
|
6
|
-
* in the current workspace.
|
|
6
|
+
* in the current workspace. Uses native pm modules when available (repo checkout
|
|
7
|
+
* or dist/); falls back to npx @unbrained/pm-cli without requiring the CLI to
|
|
8
|
+
* be installed globally. Exits silently if pm is not set up.
|
|
7
9
|
*/
|
|
8
|
-
import {
|
|
10
|
+
import { access } from "node:fs/promises";
|
|
9
11
|
import { existsSync } from "node:fs";
|
|
10
|
-
import { join } from "node:path";
|
|
12
|
+
import { join, resolve, dirname } from "node:path";
|
|
13
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
14
|
+
import { execSync } from "node:child_process";
|
|
11
15
|
|
|
12
16
|
const workspace = process.cwd();
|
|
13
17
|
const pmSettingsPath = join(workspace, ".agents", "pm", "settings.json");
|
|
@@ -16,40 +20,101 @@ if (!existsSync(pmSettingsPath)) {
|
|
|
16
20
|
process.exit(0);
|
|
17
21
|
}
|
|
18
22
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
23
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
24
|
+
|
|
25
|
+
async function pathExists(target) {
|
|
26
|
+
try {
|
|
27
|
+
await access(target);
|
|
28
|
+
return true;
|
|
29
|
+
} catch {
|
|
30
|
+
return false;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async function findNativeModule() {
|
|
35
|
+
let cursor = here;
|
|
36
|
+
for (let depth = 0; depth < 10; depth += 1) {
|
|
37
|
+
const candidate = join(cursor, "dist", "pi", "native.js");
|
|
38
|
+
if (await pathExists(candidate)) {
|
|
39
|
+
return candidate;
|
|
40
|
+
}
|
|
41
|
+
const parent = dirname(cursor);
|
|
42
|
+
if (parent === cursor) break;
|
|
43
|
+
cursor = parent;
|
|
31
44
|
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function formatSummary(ctx) {
|
|
49
|
+
const { summary } = ctx;
|
|
50
|
+
if (!summary) return null;
|
|
32
51
|
|
|
33
52
|
const parts = [];
|
|
34
53
|
if (summary.in_progress > 0) parts.push(`${summary.in_progress} in_progress`);
|
|
35
54
|
if (summary.open > 0) parts.push(`${summary.open} open`);
|
|
36
55
|
if (summary.blocked > 0) parts.push(`${summary.blocked} BLOCKED`);
|
|
37
56
|
|
|
38
|
-
if (parts.length === 0)
|
|
39
|
-
process.exit(0);
|
|
40
|
-
}
|
|
57
|
+
if (parts.length === 0) return null;
|
|
41
58
|
|
|
42
59
|
const topItems = [...(ctx.high_level ?? []), ...(ctx.low_level ?? [])].slice(0, 3);
|
|
43
60
|
const itemLines = topItems
|
|
44
61
|
.map((item) => ` • [${item.id}] ${item.title} (${item.status})`)
|
|
45
62
|
.join("\n");
|
|
46
63
|
|
|
47
|
-
|
|
64
|
+
return (
|
|
48
65
|
`pm tracker: ${parts.join(", ")}\n` +
|
|
49
|
-
|
|
50
|
-
|
|
66
|
+
(itemLines ? `${itemLines}\n` : "") +
|
|
67
|
+
`Use pm_context tool or /pm-status for full details.\n`
|
|
51
68
|
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
async function tryNativeContext() {
|
|
72
|
+
const nativePath = await findNativeModule();
|
|
73
|
+
if (!nativePath) return null;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
const { runNativePmAction } = await import(pathToFileURL(nativePath).href);
|
|
77
|
+
const result = await runNativePmAction({
|
|
78
|
+
action: "context",
|
|
79
|
+
cwd: workspace,
|
|
80
|
+
json: true,
|
|
81
|
+
options: { limit: "5" },
|
|
82
|
+
});
|
|
83
|
+
const text = Array.isArray(result?.content)
|
|
84
|
+
? result.content.find((p) => p?.type === "text")?.text ?? ""
|
|
85
|
+
: typeof result === "string"
|
|
86
|
+
? result
|
|
87
|
+
: JSON.stringify(result);
|
|
88
|
+
return JSON.parse(text);
|
|
89
|
+
} catch {
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
function tryNpxContext() {
|
|
95
|
+
try {
|
|
96
|
+
const raw = execSync(
|
|
97
|
+
"npx -y --package=@unbrained/pm-cli@latest pm context --limit 5 --json",
|
|
98
|
+
{
|
|
99
|
+
cwd: workspace,
|
|
100
|
+
encoding: "utf-8",
|
|
101
|
+
timeout: 15000,
|
|
102
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
103
|
+
},
|
|
104
|
+
);
|
|
105
|
+
return JSON.parse(raw);
|
|
106
|
+
} catch {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const ctx = (await tryNativeContext()) ?? tryNpxContext();
|
|
113
|
+
if (!ctx) process.exit(0);
|
|
114
|
+
|
|
115
|
+
const message = formatSummary(ctx);
|
|
116
|
+
if (message) process.stdout.write(message);
|
|
52
117
|
} catch {
|
|
53
|
-
//
|
|
118
|
+
// Any failure: exit silently
|
|
54
119
|
process.exit(0);
|
|
55
120
|
}
|