@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.
Files changed (77) hide show
  1. package/.claude/agents/product-manager.md +20 -0
  2. package/.claude/agents/staff-software-engineer.md +25 -0
  3. package/.claude/commands/product-manager/prd.md +31 -0
  4. package/.claude/commands/product-manager/prp.md +35 -0
  5. package/.claude/commands/product-manager/run.md +31 -0
  6. package/.claude/commands/sse/dev.md +47 -0
  7. package/.claude/commands/sse/plan.md +33 -0
  8. package/.claude/commands/sse/pr.md +43 -0
  9. package/.claude/commands/sse/run.md +39 -0
  10. package/.claude/commands/sse/test.md +38 -0
  11. package/.claude/hooks/status-line.sh +103 -0
  12. package/.claude/plugins/product-manager/README.md +120 -0
  13. package/.claude/plugins/product-manager/evals/prd-quality.md +88 -0
  14. package/.claude/plugins/product-manager/evals/prd-readiness.md +66 -0
  15. package/.claude/plugins/product-manager/evals/prp-context-readiness.md +51 -0
  16. package/.claude/plugins/product-manager/evals/prp-quality.md +88 -0
  17. package/.claude/plugins/product-manager/guides/examples/good-prd-example.md +121 -0
  18. package/.claude/plugins/product-manager/guides/examples/good-prp-example.md +128 -0
  19. package/.claude/plugins/product-manager/guides/pipeline.md +84 -0
  20. package/.claude/plugins/product-manager/guides/prd-guidelines.md +27 -0
  21. package/.claude/plugins/product-manager/guides/product-guidelines.md +75 -0
  22. package/.claude/plugins/product-manager/guides/prp-guidelines.md +64 -0
  23. package/.claude/plugins/product-manager/guides/templates/prd.md +89 -0
  24. package/.claude/plugins/product-manager/guides/templates/prp.md +98 -0
  25. package/.claude/plugins/product-manager/guides/writing-style.md +71 -0
  26. package/.claude/plugins/product-manager/hooks/post-eval-prd.sh +77 -0
  27. package/.claude/plugins/product-manager/hooks/post-eval-prp.sh +70 -0
  28. package/.claude/plugins/product-manager/hooks/post-write-prd.sh +56 -0
  29. package/.claude/plugins/product-manager/hooks/post-write-prp.sh +61 -0
  30. package/.claude/plugins/product-manager/hooks/pre-prp-check.sh +48 -0
  31. package/.claude/plugins/product-manager/outputs/.markers/.gitkeep +0 -0
  32. package/.claude/plugins/product-manager/scripts/confluence-publish.py +205 -0
  33. package/.claude/plugins/product-manager/scripts/link-validator.py +87 -0
  34. package/.claude/plugins/product-manager/scripts/sensor-runner.py +140 -0
  35. package/.claude/plugins/product-manager/scripts/token-phase.py +208 -0
  36. package/.claude/plugins/product-manager/sensors/prd-acceptance-criteria.md +39 -0
  37. package/.claude/plugins/product-manager/sensors/prd-structure.md +39 -0
  38. package/.claude/plugins/product-manager/sensors/prp-context-quality.md +42 -0
  39. package/.claude/plugins/product-manager/sensors/prp-links.md +24 -0
  40. package/.claude/plugins/product-manager/sensors/prp-structure.md +52 -0
  41. package/.claude/plugins/product-manager/skills/prd/SKILL.md +33 -0
  42. package/.claude/plugins/product-manager/skills/prp/SKILL.md +37 -0
  43. package/.claude/plugins/staff-software-engineer/README.md +90 -0
  44. package/.claude/plugins/staff-software-engineer/evals/plan-quality.md +48 -0
  45. package/.claude/plugins/staff-software-engineer/guides/coding-style.md +51 -0
  46. package/.claude/plugins/staff-software-engineer/guides/commit-style.md +44 -0
  47. package/.claude/plugins/staff-software-engineer/guides/conventions-override.md +79 -0
  48. package/.claude/plugins/staff-software-engineer/guides/pipeline.md +69 -0
  49. package/.claude/plugins/staff-software-engineer/hooks/post-eval-plan.sh +43 -0
  50. package/.claude/plugins/staff-software-engineer/hooks/post-write-plan.sh +49 -0
  51. package/.claude/plugins/staff-software-engineer/outputs/.markers/.gitkeep +0 -0
  52. package/.claude/plugins/staff-software-engineer/sensors/code-conventions.md +37 -0
  53. package/.claude/plugins/staff-software-engineer/sensors/plan-structure.md +37 -0
  54. package/.claude/plugins/staff-software-engineer/sensors/test-coverage.md +28 -0
  55. package/.claude/plugins/staff-software-engineer/skills/backend/SKILL.md +80 -0
  56. package/.claude/plugins/staff-software-engineer/skills/devops/SKILL.md +58 -0
  57. package/.claude/plugins/staff-software-engineer/skills/mobile/SKILL.md +52 -0
  58. package/.claude/plugins/staff-software-engineer/skills/web/SKILL.md +64 -0
  59. package/.claude/settings.local.json +61 -0
  60. package/CLAUDE.md +90 -0
  61. package/LICENSE +21 -0
  62. package/README.md +192 -0
  63. package/VERSION +1 -0
  64. package/bin/hk.js +141 -0
  65. package/context-library/README.md +38 -0
  66. package/context-library/business-info-template.md +39 -0
  67. package/context-library/decisions/README.md +3 -0
  68. package/context-library/example-prds/README.md +3 -0
  69. package/context-library/meetings/.gitkeep +0 -0
  70. package/context-library/metrics/.gitkeep +0 -0
  71. package/context-library/personal-context-template.md +31 -0
  72. package/context-library/research/.gitkeep +0 -0
  73. package/context-library/squads/README.md +32 -0
  74. package/context-library/strategy/README.md +3 -0
  75. package/package.json +43 -0
  76. package/setup/install.sh +154 -0
  77. 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