@pieerry/harness-kit 3.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/.claude/agents/product-manager.md +20 -0
- package/.claude/agents/staff-software-engineer.md +25 -0
- package/.claude/commands/product-manager/prd.md +31 -0
- package/.claude/commands/product-manager/prp.md +35 -0
- package/.claude/commands/product-manager/run.md +31 -0
- package/.claude/commands/sse/dev.md +47 -0
- package/.claude/commands/sse/plan.md +33 -0
- package/.claude/commands/sse/pr.md +43 -0
- package/.claude/commands/sse/run.md +39 -0
- package/.claude/commands/sse/test.md +38 -0
- package/.claude/hooks/status-line.sh +103 -0
- package/.claude/plugins/product-manager/README.md +120 -0
- package/.claude/plugins/product-manager/evals/prd-quality.md +88 -0
- package/.claude/plugins/product-manager/evals/prd-readiness.md +66 -0
- package/.claude/plugins/product-manager/evals/prp-context-readiness.md +51 -0
- package/.claude/plugins/product-manager/evals/prp-quality.md +88 -0
- package/.claude/plugins/product-manager/guides/examples/good-prd-example.md +121 -0
- package/.claude/plugins/product-manager/guides/examples/good-prp-example.md +128 -0
- package/.claude/plugins/product-manager/guides/pipeline.md +84 -0
- package/.claude/plugins/product-manager/guides/prd-guidelines.md +27 -0
- package/.claude/plugins/product-manager/guides/product-guidelines.md +75 -0
- package/.claude/plugins/product-manager/guides/prp-guidelines.md +64 -0
- package/.claude/plugins/product-manager/guides/templates/prd.md +89 -0
- package/.claude/plugins/product-manager/guides/templates/prp.md +98 -0
- package/.claude/plugins/product-manager/guides/writing-style.md +71 -0
- package/.claude/plugins/product-manager/hooks/post-eval-prd.sh +77 -0
- package/.claude/plugins/product-manager/hooks/post-eval-prp.sh +70 -0
- package/.claude/plugins/product-manager/hooks/post-write-prd.sh +56 -0
- package/.claude/plugins/product-manager/hooks/post-write-prp.sh +61 -0
- package/.claude/plugins/product-manager/hooks/pre-prp-check.sh +48 -0
- package/.claude/plugins/product-manager/outputs/.markers/.gitkeep +0 -0
- package/.claude/plugins/product-manager/scripts/confluence-publish.py +205 -0
- package/.claude/plugins/product-manager/scripts/link-validator.py +87 -0
- package/.claude/plugins/product-manager/scripts/sensor-runner.py +140 -0
- package/.claude/plugins/product-manager/scripts/token-phase.py +208 -0
- package/.claude/plugins/product-manager/sensors/prd-acceptance-criteria.md +39 -0
- package/.claude/plugins/product-manager/sensors/prd-structure.md +39 -0
- package/.claude/plugins/product-manager/sensors/prp-context-quality.md +42 -0
- package/.claude/plugins/product-manager/sensors/prp-links.md +24 -0
- package/.claude/plugins/product-manager/sensors/prp-structure.md +52 -0
- package/.claude/plugins/product-manager/skills/prd/SKILL.md +33 -0
- package/.claude/plugins/product-manager/skills/prp/SKILL.md +37 -0
- package/.claude/plugins/staff-software-engineer/README.md +90 -0
- package/.claude/plugins/staff-software-engineer/evals/plan-quality.md +48 -0
- package/.claude/plugins/staff-software-engineer/guides/coding-style.md +51 -0
- package/.claude/plugins/staff-software-engineer/guides/commit-style.md +44 -0
- package/.claude/plugins/staff-software-engineer/guides/conventions-override.md +79 -0
- package/.claude/plugins/staff-software-engineer/guides/pipeline.md +69 -0
- package/.claude/plugins/staff-software-engineer/hooks/post-eval-plan.sh +43 -0
- package/.claude/plugins/staff-software-engineer/hooks/post-write-plan.sh +49 -0
- package/.claude/plugins/staff-software-engineer/outputs/.markers/.gitkeep +0 -0
- package/.claude/plugins/staff-software-engineer/sensors/code-conventions.md +37 -0
- package/.claude/plugins/staff-software-engineer/sensors/plan-structure.md +37 -0
- package/.claude/plugins/staff-software-engineer/sensors/test-coverage.md +28 -0
- package/.claude/plugins/staff-software-engineer/skills/backend/SKILL.md +80 -0
- package/.claude/plugins/staff-software-engineer/skills/devops/SKILL.md +58 -0
- package/.claude/plugins/staff-software-engineer/skills/mobile/SKILL.md +52 -0
- package/.claude/plugins/staff-software-engineer/skills/web/SKILL.md +64 -0
- package/.claude/settings.local.json +61 -0
- package/CLAUDE.md +90 -0
- package/LICENSE +21 -0
- package/README.md +192 -0
- package/VERSION +1 -0
- package/bin/hk.js +141 -0
- package/context-library/README.md +38 -0
- package/context-library/business-info-template.md +39 -0
- package/context-library/decisions/README.md +3 -0
- package/context-library/example-prds/README.md +3 -0
- package/context-library/meetings/.gitkeep +0 -0
- package/context-library/metrics/.gitkeep +0 -0
- package/context-library/personal-context-template.md +31 -0
- package/context-library/research/.gitkeep +0 -0
- package/context-library/squads/README.md +32 -0
- package/context-library/strategy/README.md +3 -0
- package/package.json +43 -0
- package/setup/install.sh +154 -0
- package/setup/update.sh +17 -0
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# PRP Guidelines
|
|
2
|
+
|
|
3
|
+
A PRP is a PRD plus curated codebase intelligence plus an agent runbook. If the executor has to leave the document to figure out what to do, the PRP is incomplete.
|
|
4
|
+
|
|
5
|
+
## Three pillars
|
|
6
|
+
|
|
7
|
+
### Context
|
|
8
|
+
|
|
9
|
+
Everything the executor needs, included or linked. Specific:
|
|
10
|
+
- file paths with line numbers when localized
|
|
11
|
+
- existing patterns to mimic, one concrete example each
|
|
12
|
+
- external docs scoped to the relevant section
|
|
13
|
+
- known gotchas (concurrency, idempotency, retries, timezones)
|
|
14
|
+
|
|
15
|
+
If the codebase has a similar feature already, point to it. Coding agents do their best work by analogy.
|
|
16
|
+
|
|
17
|
+
### Implementation detail
|
|
18
|
+
|
|
19
|
+
Pseudocode or numbered steps concrete enough to translate one-to-one. Include:
|
|
20
|
+
- class names, method signatures, return types where decided
|
|
21
|
+
- schema changes with the actual migration file or DDL
|
|
22
|
+
- endpoint definitions: method, path, request/response shape
|
|
23
|
+
- logging, metrics, alert hooks
|
|
24
|
+
|
|
25
|
+
You do not write the code. You remove every "what should I name this" decision.
|
|
26
|
+
|
|
27
|
+
### Validation gates
|
|
28
|
+
|
|
29
|
+
Real commands the executor runs and passes. Vague checks fail.
|
|
30
|
+
|
|
31
|
+
Bad:
|
|
32
|
+
- "Make sure tests pass"
|
|
33
|
+
|
|
34
|
+
Good:
|
|
35
|
+
- `./gradlew :billing-service:test --tests "InvoiceValidator*"`
|
|
36
|
+
- `npm --prefix web run typecheck`
|
|
37
|
+
- `./gradlew :billing-service:detekt`
|
|
38
|
+
|
|
39
|
+
Manual gates count, but must be specific:
|
|
40
|
+
- [ ] Open `https://staging.example.com/invoices/new` and verify the deadline badge renders for region `EU-WEST`.
|
|
41
|
+
|
|
42
|
+
## A good PRP
|
|
43
|
+
|
|
44
|
+
1. Executor reads top-to-bottom, never tabs out except to view linked files.
|
|
45
|
+
2. No decisions left for the executor that change scope.
|
|
46
|
+
3. Every TODO has an owner.
|
|
47
|
+
4. Validation block is copy-pasteable.
|
|
48
|
+
|
|
49
|
+
## Anti-patterns
|
|
50
|
+
|
|
51
|
+
- Prose mush where bullets would do
|
|
52
|
+
- Restating the PRD instead of linking
|
|
53
|
+
- Hidden scope ("also we should refactor X")
|
|
54
|
+
- Optimism about state ("there is probably a helper for this already")
|
|
55
|
+
- Fabricated file paths or class names
|
|
56
|
+
|
|
57
|
+
## When to split a PRP
|
|
58
|
+
|
|
59
|
+
Split if:
|
|
60
|
+
- scope crosses two repos with independent deploy cycles
|
|
61
|
+
- one PR would exceed ~600 lines
|
|
62
|
+
- independent validation gates pass or fail separately
|
|
63
|
+
|
|
64
|
+
Otherwise keep it one. Context fragmentation costs more than a slightly longer doc.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# PRD Template
|
|
2
|
+
|
|
3
|
+
Fill this template when drafting a Product Requirements Document. Keep section numbering. Replace placeholders. Delete sections that do not apply at the current stage.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PRD: {Title}
|
|
8
|
+
|
|
9
|
+
**Squad:** {squad} | **DRI (PM):** {name} | **Date:** {YYYY-MM-DD}
|
|
10
|
+
**Stage:** Team Kickoff | Planning Review | Solution Review | Launch Readiness
|
|
11
|
+
**Bet:** {link or N/A}
|
|
12
|
+
**Status:** Draft | In Review | Approved | Shipped
|
|
13
|
+
|
|
14
|
+
## 1) Problem and Hypothesis
|
|
15
|
+
|
|
16
|
+
**Problem** (2 sentences max): Who suffers, how often, what it costs.
|
|
17
|
+
|
|
18
|
+
**Hypothesis:** If we {build X}, then {Y metric} will {change by Z}, because {assumption}.
|
|
19
|
+
|
|
20
|
+
**Strategy fit:** This supports {pillar} because {why now}.
|
|
21
|
+
|
|
22
|
+
**Evidence:**
|
|
23
|
+
- {user quote / data point / ticket id}
|
|
24
|
+
|
|
25
|
+
## 2) Customers
|
|
26
|
+
|
|
27
|
+
| Customer | Why it matters |
|
|
28
|
+
|----------|----------------|
|
|
29
|
+
| {name} | {context} |
|
|
30
|
+
|
|
31
|
+
## 3) Scope and Non-Goals
|
|
32
|
+
|
|
33
|
+
**In scope:**
|
|
34
|
+
- {bullet}
|
|
35
|
+
|
|
36
|
+
**Non-goals (max 3):**
|
|
37
|
+
- {what we are NOT doing and why}
|
|
38
|
+
|
|
39
|
+
**Trade-offs accepted:**
|
|
40
|
+
- {bullet}
|
|
41
|
+
|
|
42
|
+
## 4) Solution Overview
|
|
43
|
+
|
|
44
|
+
**Summary:** 2-3 paragraphs.
|
|
45
|
+
|
|
46
|
+
**User flow:** numbered steps or Mermaid.
|
|
47
|
+
|
|
48
|
+
**User stories:**
|
|
49
|
+
- As a {persona}, I want {action}, so that {benefit}.
|
|
50
|
+
|
|
51
|
+
**UX reference:** {Figma or experience expected}.
|
|
52
|
+
|
|
53
|
+
## 5) Success Metrics
|
|
54
|
+
|
|
55
|
+
| Metric | Baseline | Target | Horizon |
|
|
56
|
+
|--------|----------|--------|---------|
|
|
57
|
+
| {name} | {value} | {value}| {N days}|
|
|
58
|
+
|
|
59
|
+
**Guardrails (must not harm):**
|
|
60
|
+
- {metric}: {range}
|
|
61
|
+
|
|
62
|
+
**Kill criteria:** If {condition with numeric threshold}, we will {rollback / pause / iterate}.
|
|
63
|
+
|
|
64
|
+
## 6) Rollout
|
|
65
|
+
|
|
66
|
+
| Phase | Audience | Duration | Pass criteria |
|
|
67
|
+
|-------|----------|----------|---------------|
|
|
68
|
+
| 1 | | | |
|
|
69
|
+
|
|
70
|
+
## 7) Risks
|
|
71
|
+
|
|
72
|
+
| Risk | Likelihood | Impact | Mitigation |
|
|
73
|
+
|------|-----------|--------|------------|
|
|
74
|
+
|
|
75
|
+
## 8) Owners and Open Questions
|
|
76
|
+
|
|
77
|
+
**DRI:** {name}
|
|
78
|
+
**Reviewers:** {eng, design, legal, support}
|
|
79
|
+
|
|
80
|
+
**Open questions:**
|
|
81
|
+
- [ ] {question}, owner @{name}
|
|
82
|
+
|
|
83
|
+
## 9) Appendix
|
|
84
|
+
|
|
85
|
+
**Alternatives considered:**
|
|
86
|
+
- {bullet with reason for rejection}
|
|
87
|
+
|
|
88
|
+
**Research quotes:**
|
|
89
|
+
- {direct quote with source}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# PRP Template
|
|
2
|
+
|
|
3
|
+
Fill this template when drafting a Product Requirements Prompt. Keep section numbering. Replace placeholders. Pin every reference to a real file or URL.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# PRP: {Title}
|
|
8
|
+
|
|
9
|
+
**Source PRD:** {path}
|
|
10
|
+
**Target executor:** coding-agent | engineer | mixed
|
|
11
|
+
**Squad:** {squad} | **Tech lead:** {name} | **Date:** {YYYY-MM-DD}
|
|
12
|
+
|
|
13
|
+
## 1) Goal
|
|
14
|
+
|
|
15
|
+
One paragraph. What the executor must ship. Tied to the PRD's hypothesis.
|
|
16
|
+
|
|
17
|
+
## 2) Why
|
|
18
|
+
|
|
19
|
+
- business value
|
|
20
|
+
- user impact
|
|
21
|
+
- strategic tie
|
|
22
|
+
|
|
23
|
+
## 3) What
|
|
24
|
+
|
|
25
|
+
**User-visible behavior:**
|
|
26
|
+
- {bullet}
|
|
27
|
+
|
|
28
|
+
**Out of scope:**
|
|
29
|
+
- {what NOT to build}
|
|
30
|
+
|
|
31
|
+
**Success criteria (verifiable):**
|
|
32
|
+
- [ ] {Given/When/Then or measurable check}
|
|
33
|
+
|
|
34
|
+
## 4) Context
|
|
35
|
+
|
|
36
|
+
### Repos and files touched
|
|
37
|
+
|
|
38
|
+
| Repo | File | Change type | Reference |
|
|
39
|
+
|------|------|-------------|-----------|
|
|
40
|
+
| {repo} | {file:line} | new \| modify \| delete | {link or PR id} |
|
|
41
|
+
|
|
42
|
+
### Patterns to follow
|
|
43
|
+
|
|
44
|
+
- **Pattern:** {name}
|
|
45
|
+
**Example in codebase:** `{file:line}`
|
|
46
|
+
**Why follow it:** {1 sentence}
|
|
47
|
+
|
|
48
|
+
### External documentation
|
|
49
|
+
|
|
50
|
+
- {URL}: {what to read, which section}
|
|
51
|
+
|
|
52
|
+
### Known gotchas
|
|
53
|
+
|
|
54
|
+
- {gotcha}: {how to handle}
|
|
55
|
+
|
|
56
|
+
## 5) Implementation blueprint
|
|
57
|
+
|
|
58
|
+
```
|
|
59
|
+
1. Add {class} at {path}
|
|
60
|
+
2. Wire into {existing class} at {file:line}
|
|
61
|
+
3. Add migration {script name}
|
|
62
|
+
4. Expose endpoint {METHOD /path}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
**Data:**
|
|
66
|
+
- Schema changes: {DDL or migration file name}
|
|
67
|
+
- Volumes expected: {rows/day, peak rps}
|
|
68
|
+
|
|
69
|
+
**Observability:**
|
|
70
|
+
- Logs: {what to log, level, where}
|
|
71
|
+
- Metrics: {metric name + dashboard link}
|
|
72
|
+
- Alerts: {condition: action}
|
|
73
|
+
|
|
74
|
+
## 6) Validation gates
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
{commands the executor MUST run}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
**Manual verification:**
|
|
81
|
+
- [ ] {step that requires human or browser check}
|
|
82
|
+
|
|
83
|
+
## 7) Rollout
|
|
84
|
+
|
|
85
|
+
- [ ] Feature flag: {flag name or "none"}
|
|
86
|
+
- [ ] Migration required: {yes/no, plan}
|
|
87
|
+
- [ ] Rollback plan: {one-line description}
|
|
88
|
+
|
|
89
|
+
## 8) Open items
|
|
90
|
+
|
|
91
|
+
- [ ] {item}, owner @{name}
|
|
92
|
+
|
|
93
|
+
## 9) References
|
|
94
|
+
|
|
95
|
+
- PRD: {path}
|
|
96
|
+
- ADR: {link}
|
|
97
|
+
- Design doc: {link}
|
|
98
|
+
- Dashboards: {link}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# Writing Style
|
|
2
|
+
|
|
3
|
+
How PRDs and PRPs read .
|
|
4
|
+
|
|
5
|
+
## Voice
|
|
6
|
+
|
|
7
|
+
- Direct. Lead with the point.
|
|
8
|
+
- Specific. Real numbers, real names, real quotes. "47% abandon at step 3" beats "many users struggle".
|
|
9
|
+
- Conversational, professional. Contractions ok. Use "we", not "I".
|
|
10
|
+
- Action-oriented. Every section helps a reader decide or act.
|
|
11
|
+
|
|
12
|
+
## Length
|
|
13
|
+
|
|
14
|
+
- Shorter beats longer.
|
|
15
|
+
- Vary sentence length. Short ones land harder.
|
|
16
|
+
- One idea per bullet.
|
|
17
|
+
|
|
18
|
+
## Audience modes
|
|
19
|
+
|
|
20
|
+
- Internal team: conversational, bullets over paragraphs, "we" framing
|
|
21
|
+
- Executives: lead with so-what, numbers first, decision asked explicitly
|
|
22
|
+
- Engineering (PRP): precise terms, edge cases upfront, constraints visible
|
|
23
|
+
- End users (in product): 8th-grade reading level, benefits before features
|
|
24
|
+
|
|
25
|
+
## Banned words
|
|
26
|
+
|
|
27
|
+
Dead giveaways for AI fluff:
|
|
28
|
+
- delve, leverage, utilize, unlock, harness, streamline, robust, cutting-edge
|
|
29
|
+
- "in today's fast-paced world", "at the end of the day", "best-in-class"
|
|
30
|
+
- "I'd be happy to", "Of course!", "Certainly", "Sure!"
|
|
31
|
+
- "Hope this helps", "Let me know if you need anything else"
|
|
32
|
+
|
|
33
|
+
## Punctuation
|
|
34
|
+
|
|
35
|
+
- No em-dashes. Use commas, periods, parentheses, or a new sentence.
|
|
36
|
+
- Oxford comma: yes.
|
|
37
|
+
- One space after a period.
|
|
38
|
+
|
|
39
|
+
## Negative parallelism
|
|
40
|
+
|
|
41
|
+
Avoid. Lead with the positive:
|
|
42
|
+
- bad: "Don't use X. Use Y."
|
|
43
|
+
- good: "Use Y."
|
|
44
|
+
|
|
45
|
+
## AI-detector test
|
|
46
|
+
|
|
47
|
+
If a paragraph sounds like a LinkedIn post, rewrite it. Real human writing:
|
|
48
|
+
- occasional sentence starting with "And" or "But"
|
|
49
|
+
- specific details a generic writer would not know
|
|
50
|
+
- slightly imperfect rhythm
|
|
51
|
+
- mid-paragraph asides
|
|
52
|
+
|
|
53
|
+
Embed naturally, do not perform.
|
|
54
|
+
|
|
55
|
+
## Quoting users
|
|
56
|
+
|
|
57
|
+
Direct quotes with source:
|
|
58
|
+
|
|
59
|
+
> "By the time I add everything, she remembers 3 more things and I have to edit the cart again." Priya, Mumbai, support ticket #1842
|
|
60
|
+
|
|
61
|
+
Not:
|
|
62
|
+
|
|
63
|
+
> "Users often experience frustration with the cart editing experience."
|
|
64
|
+
|
|
65
|
+
## Tables
|
|
66
|
+
|
|
67
|
+
Use when you have comparison across 3+ items, structured data with same fields per row, or decision matrices. Otherwise use bullets.
|
|
68
|
+
|
|
69
|
+
## Diagrams
|
|
70
|
+
|
|
71
|
+
Mermaid only. Never ASCII art.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Fires after Edit tool appends the approval marker. Detects the marker,
|
|
3
|
+
# closes the validate phase, runs token accounting, and triggers publish.
|
|
4
|
+
#
|
|
5
|
+
# Registered in .claude/settings.json under PostToolUse > Edit.
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
FILE_PATH="${CLAUDE_TOOL_FILE_PATH:-}"
|
|
10
|
+
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
11
|
+
|
|
12
|
+
case "$FILE_PATH" in
|
|
13
|
+
*.claude/plugins/product-manager/outputs/prd/*.md) ;;
|
|
14
|
+
*) exit 0 ;;
|
|
15
|
+
esac
|
|
16
|
+
|
|
17
|
+
if ! grep -q "<!-- approved:" "$FILE_PATH"; then
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
if grep -q "<!-- published:" "$FILE_PATH"; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
echo "[hook] PRD approved, publishing $(basename "$FILE_PATH")" >&2
|
|
26
|
+
|
|
27
|
+
FEATURE_ID="$(basename "$FILE_PATH" .md)"
|
|
28
|
+
MARKERS_DIR="$PLUGIN_DIR/outputs/.markers"
|
|
29
|
+
mkdir -p "$MARKERS_DIR"
|
|
30
|
+
NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
31
|
+
|
|
32
|
+
# Close validate phase
|
|
33
|
+
if [ -f "$MARKERS_DIR/${FEATURE_ID}.prd-validate.start" ]; then
|
|
34
|
+
printf '{"timestamp":"%s"}\n' "$NOW" > "$MARKERS_DIR/${FEATURE_ID}.prd-validate.end"
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Token accounting for both phases
|
|
38
|
+
python3 "$PLUGIN_DIR/scripts/token-phase.py" \
|
|
39
|
+
--feature-id "$FEATURE_ID" \
|
|
40
|
+
--phase "prd-generate" \
|
|
41
|
+
--plugin-dir "$PLUGIN_DIR" \
|
|
42
|
+
--prd-path "$FILE_PATH" >&2 || true
|
|
43
|
+
|
|
44
|
+
python3 "$PLUGIN_DIR/scripts/token-phase.py" \
|
|
45
|
+
--feature-id "$FEATURE_ID" \
|
|
46
|
+
--phase "prd-validate" \
|
|
47
|
+
--plugin-dir "$PLUGIN_DIR" \
|
|
48
|
+
--prd-path "$FILE_PATH" >&2 || true
|
|
49
|
+
|
|
50
|
+
# Confluence (optional)
|
|
51
|
+
if [ -n "${JIRA_USERNAME:-}" ] && [ -n "${JIRA_API_TOKEN:-}" ]; then
|
|
52
|
+
python3 "$PLUGIN_DIR/scripts/confluence-publish.py" \
|
|
53
|
+
--artifact "$FILE_PATH" \
|
|
54
|
+
--kind prd >&2 || {
|
|
55
|
+
echo "[hook] Confluence publish failed but local copy is saved" >&2
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
echo "[hook] Confluence creds not set (JIRA_USERNAME, JIRA_API_TOKEN). Local save only." >&2
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
# Append published marker + inline tokens reference
|
|
62
|
+
TOKENS_FILE="$PLUGIN_DIR/outputs/tokens/${FEATURE_ID}.json"
|
|
63
|
+
if [ -f "$TOKENS_FILE" ]; then
|
|
64
|
+
TOKENS_LINE=$(python3 -c "
|
|
65
|
+
import json,sys
|
|
66
|
+
with open('$TOKENS_FILE') as f:
|
|
67
|
+
d=json.load(f)
|
|
68
|
+
t=d.get('totals',{})
|
|
69
|
+
print(f'<!-- tokens: outputs/tokens/${FEATURE_ID}.json in={t.get(\"input\",0)} out={t.get(\"output\",0)} cache_r={t.get(\"cache_read\",0)} -->')
|
|
70
|
+
")
|
|
71
|
+
printf '\n%s\n' "$TOKENS_LINE" >> "$FILE_PATH"
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
printf '\n<!-- published: %s -->\n' "$NOW" >> "$FILE_PATH"
|
|
75
|
+
|
|
76
|
+
echo "[hook] PRD published" >&2
|
|
77
|
+
exit 0
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Fires after Edit tool appends the approval marker on a PRP.
|
|
3
|
+
# Closes validate phase, runs token accounting, finalizes handoff.
|
|
4
|
+
#
|
|
5
|
+
# Registered in .claude/settings.json under PostToolUse > Edit.
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
FILE_PATH="${CLAUDE_TOOL_FILE_PATH:-}"
|
|
10
|
+
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
11
|
+
|
|
12
|
+
case "$FILE_PATH" in
|
|
13
|
+
*.claude/plugins/product-manager/outputs/prp/*.md) ;;
|
|
14
|
+
*) exit 0 ;;
|
|
15
|
+
esac
|
|
16
|
+
|
|
17
|
+
if ! grep -q "<!-- approved:" "$FILE_PATH"; then
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
if grep -q "<!-- published:" "$FILE_PATH"; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
|
|
25
|
+
echo "[hook] PRP approved, finalizing handoff for $(basename "$FILE_PATH")" >&2
|
|
26
|
+
|
|
27
|
+
FEATURE_ID="$(basename "$FILE_PATH" .md)"
|
|
28
|
+
MARKERS_DIR="$PLUGIN_DIR/outputs/.markers"
|
|
29
|
+
mkdir -p "$MARKERS_DIR"
|
|
30
|
+
NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
31
|
+
|
|
32
|
+
if [ -f "$MARKERS_DIR/${FEATURE_ID}.prp-validate.start" ]; then
|
|
33
|
+
printf '{"timestamp":"%s"}\n' "$NOW" > "$MARKERS_DIR/${FEATURE_ID}.prp-validate.end"
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
python3 "$PLUGIN_DIR/scripts/token-phase.py" \
|
|
37
|
+
--feature-id "$FEATURE_ID" \
|
|
38
|
+
--phase "prp-generate" \
|
|
39
|
+
--plugin-dir "$PLUGIN_DIR" \
|
|
40
|
+
--prp-path "$FILE_PATH" >&2 || true
|
|
41
|
+
|
|
42
|
+
python3 "$PLUGIN_DIR/scripts/token-phase.py" \
|
|
43
|
+
--feature-id "$FEATURE_ID" \
|
|
44
|
+
--phase "prp-validate" \
|
|
45
|
+
--plugin-dir "$PLUGIN_DIR" \
|
|
46
|
+
--prp-path "$FILE_PATH" >&2 || true
|
|
47
|
+
|
|
48
|
+
if [ -n "${JIRA_USERNAME:-}" ] && [ -n "${JIRA_API_TOKEN:-}" ]; then
|
|
49
|
+
python3 "$PLUGIN_DIR/scripts/confluence-publish.py" \
|
|
50
|
+
--artifact "$FILE_PATH" \
|
|
51
|
+
--kind prp >&2 || true
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Inline tokens summary
|
|
55
|
+
TOKENS_FILE="$PLUGIN_DIR/outputs/tokens/${FEATURE_ID}.json"
|
|
56
|
+
if [ -f "$TOKENS_FILE" ]; then
|
|
57
|
+
TOKENS_LINE=$(python3 -c "
|
|
58
|
+
import json,sys
|
|
59
|
+
with open('$TOKENS_FILE') as f:
|
|
60
|
+
d=json.load(f)
|
|
61
|
+
t=d.get('totals',{})
|
|
62
|
+
print(f'<!-- tokens: outputs/tokens/${FEATURE_ID}.json in={t.get(\"input\",0)} out={t.get(\"output\",0)} cache_r={t.get(\"cache_read\",0)} -->')
|
|
63
|
+
")
|
|
64
|
+
printf '\n%s\n' "$TOKENS_LINE" >> "$FILE_PATH"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
printf '\n<!-- published: %s -->\n' "$NOW" >> "$FILE_PATH"
|
|
68
|
+
|
|
69
|
+
echo "[hook] PRP handoff complete" >&2
|
|
70
|
+
exit 0
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Fires after Write tool saves a file. If the file is a PRD draft, runs the
|
|
3
|
+
# deterministic sensor pipeline and writes phase markers for token accounting.
|
|
4
|
+
#
|
|
5
|
+
# Registered in .claude/settings.json under PostToolUse > Write.
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
FILE_PATH="${CLAUDE_TOOL_FILE_PATH:-}"
|
|
10
|
+
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
11
|
+
|
|
12
|
+
case "$FILE_PATH" in
|
|
13
|
+
*.claude/plugins/product-manager/outputs/prd/*.md) ;;
|
|
14
|
+
*) exit 0 ;;
|
|
15
|
+
esac
|
|
16
|
+
|
|
17
|
+
# Skip if file already approved (avoid loops)
|
|
18
|
+
if grep -q "<!-- approved:" "$FILE_PATH" 2>/dev/null; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
echo "[hook] Running PRD sensors on $(basename "$FILE_PATH")" >&2
|
|
23
|
+
|
|
24
|
+
FAILURES=()
|
|
25
|
+
for sensor in "$PLUGIN_DIR"/sensors/prd-*.md; do
|
|
26
|
+
[ -f "$sensor" ] || continue
|
|
27
|
+
if ! python3 "$PLUGIN_DIR/scripts/sensor-runner.py" \
|
|
28
|
+
--sensor "$sensor" \
|
|
29
|
+
--artifact "$FILE_PATH" >&2; then
|
|
30
|
+
FAILURES+=("$(basename "$sensor")")
|
|
31
|
+
fi
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
if [ ${#FAILURES[@]} -gt 0 ]; then
|
|
35
|
+
echo "" >&2
|
|
36
|
+
echo "[hook] PRD sensor failures: ${FAILURES[*]}" >&2
|
|
37
|
+
echo "[hook] Read the messages above and regenerate the failed sections." >&2
|
|
38
|
+
exit 2
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
echo "[hook] PRD sensors passed" >&2
|
|
42
|
+
|
|
43
|
+
# Token phase markers: only on first save (no validate.start yet)
|
|
44
|
+
FEATURE_ID="$(basename "$FILE_PATH" .md)"
|
|
45
|
+
MARKERS_DIR="$PLUGIN_DIR/outputs/.markers"
|
|
46
|
+
mkdir -p "$MARKERS_DIR"
|
|
47
|
+
NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
48
|
+
|
|
49
|
+
if [ ! -f "$MARKERS_DIR/${FEATURE_ID}.prd-validate.start" ]; then
|
|
50
|
+
if [ -f "$MARKERS_DIR/${FEATURE_ID}.prd-generate.start" ]; then
|
|
51
|
+
printf '{"timestamp":"%s"}\n' "$NOW" > "$MARKERS_DIR/${FEATURE_ID}.prd-generate.end"
|
|
52
|
+
printf '{"timestamp":"%s","session_id":"%s"}\n' "$NOW" "${CLAUDE_SESSION_ID:-}" > "$MARKERS_DIR/${FEATURE_ID}.prd-validate.start"
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
exit 0
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Fires after Write tool saves a file. If the file is a PRP draft, runs
|
|
3
|
+
# structural sensors plus link validation and writes phase markers.
|
|
4
|
+
#
|
|
5
|
+
# Registered in .claude/settings.json under PostToolUse > Write.
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
FILE_PATH="${CLAUDE_TOOL_FILE_PATH:-}"
|
|
10
|
+
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
11
|
+
|
|
12
|
+
case "$FILE_PATH" in
|
|
13
|
+
*.claude/plugins/product-manager/outputs/prp/*.md) ;;
|
|
14
|
+
*) exit 0 ;;
|
|
15
|
+
esac
|
|
16
|
+
|
|
17
|
+
if grep -q "<!-- approved:" "$FILE_PATH" 2>/dev/null; then
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
echo "[hook] Running PRP sensors on $(basename "$FILE_PATH")" >&2
|
|
22
|
+
|
|
23
|
+
FAILURES=()
|
|
24
|
+
for sensor in "$PLUGIN_DIR"/sensors/prp-*.md; do
|
|
25
|
+
[ -f "$sensor" ] || continue
|
|
26
|
+
if ! python3 "$PLUGIN_DIR/scripts/sensor-runner.py" \
|
|
27
|
+
--sensor "$sensor" \
|
|
28
|
+
--artifact "$FILE_PATH" >&2; then
|
|
29
|
+
FAILURES+=("$(basename "$sensor")")
|
|
30
|
+
fi
|
|
31
|
+
done
|
|
32
|
+
|
|
33
|
+
if ! python3 "$PLUGIN_DIR/scripts/link-validator.py" \
|
|
34
|
+
--artifact "$FILE_PATH" \
|
|
35
|
+
--repo-root "$(git rev-parse --show-toplevel 2>/dev/null || pwd)" >&2; then
|
|
36
|
+
FAILURES+=("link-validator")
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if [ ${#FAILURES[@]} -gt 0 ]; then
|
|
40
|
+
echo "" >&2
|
|
41
|
+
echo "[hook] PRP sensor failures: ${FAILURES[*]}" >&2
|
|
42
|
+
echo "[hook] Read the messages above and regenerate the failed sections." >&2
|
|
43
|
+
exit 2
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
echo "[hook] PRP sensors passed" >&2
|
|
47
|
+
|
|
48
|
+
# Token phase markers
|
|
49
|
+
FEATURE_ID="$(basename "$FILE_PATH" .md)"
|
|
50
|
+
MARKERS_DIR="$PLUGIN_DIR/outputs/.markers"
|
|
51
|
+
mkdir -p "$MARKERS_DIR"
|
|
52
|
+
NOW="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
|
|
53
|
+
|
|
54
|
+
if [ ! -f "$MARKERS_DIR/${FEATURE_ID}.prp-validate.start" ]; then
|
|
55
|
+
if [ -f "$MARKERS_DIR/${FEATURE_ID}.prp-generate.start" ]; then
|
|
56
|
+
printf '{"timestamp":"%s"}\n' "$NOW" > "$MARKERS_DIR/${FEATURE_ID}.prp-generate.end"
|
|
57
|
+
printf '{"timestamp":"%s","session_id":"%s"}\n' "$NOW" "${CLAUDE_SESSION_ID:-}" > "$MARKERS_DIR/${FEATURE_ID}.prp-validate.start"
|
|
58
|
+
fi
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
exit 0
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Fires before Write tool creates a PRP file. Refuses if there is no approved
|
|
3
|
+
# PRD for the same feature slug.
|
|
4
|
+
#
|
|
5
|
+
# Registered in .claude/settings.json under PreToolUse > Write matcher.
|
|
6
|
+
|
|
7
|
+
set -euo pipefail
|
|
8
|
+
|
|
9
|
+
FILE_PATH="${CLAUDE_TOOL_FILE_PATH:-}"
|
|
10
|
+
PLUGIN_DIR="$(cd "$(dirname "$0")/.." && pwd)"
|
|
11
|
+
|
|
12
|
+
case "$FILE_PATH" in
|
|
13
|
+
*.claude/plugins/product-manager/outputs/prp/*.md) ;;
|
|
14
|
+
*) exit 0 ;;
|
|
15
|
+
esac
|
|
16
|
+
|
|
17
|
+
# Allow rewrites of an existing PRP
|
|
18
|
+
if [ -f "$FILE_PATH" ]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
# Extract slug from PRP filename: YYYY-MM-DD-{slug}.md
|
|
23
|
+
PRP_BASENAME="$(basename "$FILE_PATH" .md)"
|
|
24
|
+
SLUG="$(echo "$PRP_BASENAME" | sed -E 's/^[0-9]{4}-[0-9]{2}-[0-9]{2}-//')"
|
|
25
|
+
|
|
26
|
+
if [ -z "$SLUG" ]; then
|
|
27
|
+
echo "[hook] PRP filename must follow YYYY-MM-DD-{slug}.md. Got: $PRP_BASENAME" >&2
|
|
28
|
+
exit 2
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Look for any approved PRD matching the slug
|
|
32
|
+
MATCHED=""
|
|
33
|
+
for prd in "$PLUGIN_DIR"/outputs/prd/*"-${SLUG}.md"; do
|
|
34
|
+
[ -f "$prd" ] || continue
|
|
35
|
+
if grep -q "<!-- approved:" "$prd"; then
|
|
36
|
+
MATCHED="$prd"
|
|
37
|
+
break
|
|
38
|
+
fi
|
|
39
|
+
done
|
|
40
|
+
|
|
41
|
+
if [ -z "$MATCHED" ]; then
|
|
42
|
+
echo "[hook] No approved PRD found for slug '$SLUG'." >&2
|
|
43
|
+
echo "[hook] Run /product-manager:prd first and ensure the PRD has the <!-- approved: --> marker." >&2
|
|
44
|
+
exit 2
|
|
45
|
+
fi
|
|
46
|
+
|
|
47
|
+
echo "[hook] PRP gate cleared: source PRD: $(basename "$MATCHED")" >&2
|
|
48
|
+
exit 0
|
|
File without changes
|