@pieerry/harness-kit 3.3.0 → 4.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 (87) hide show
  1. package/.claude/{plugins → agents}/product-manager/README.md +32 -30
  2. package/.claude/{plugins → agents}/product-manager/guides/examples/good-prp-example.md +2 -2
  3. package/.claude/{plugins → agents}/product-manager/guides/pipeline.md +7 -7
  4. package/.claude/{plugins → agents}/product-manager/sensors/prp-links.md +1 -1
  5. package/.claude/{plugins → agents}/product-manager/skills/prd/SKILL.md +2 -2
  6. package/.claude/{plugins → agents}/product-manager/skills/prp/SKILL.md +4 -4
  7. package/.claude/agents/product-manager.md +2 -2
  8. package/.claude/agents/staff-software-engineer/README.md +87 -0
  9. package/.claude/{plugins → agents}/staff-software-engineer/guides/conventions-override.md +3 -3
  10. package/.claude/{plugins → agents}/staff-software-engineer/guides/pipeline.md +11 -7
  11. package/.claude/{plugins → agents}/staff-software-engineer/sensors/dev-structure.md +2 -2
  12. package/.claude/{plugins → agents}/staff-software-engineer/sensors/pr-structure.md +3 -3
  13. package/.claude/{plugins → agents}/staff-software-engineer/sensors/test-structure.md +2 -2
  14. package/.claude/agents/staff-software-engineer.md +4 -4
  15. package/.claude/commands/pipeline/reset.md +1 -1
  16. package/.claude/commands/product-manager/prd.md +11 -11
  17. package/.claude/commands/product-manager/prp.md +12 -12
  18. package/.claude/commands/product-manager/run.md +8 -4
  19. package/.claude/commands/sse/dev.md +11 -11
  20. package/.claude/commands/sse/plan.md +11 -12
  21. package/.claude/commands/sse/pr.md +6 -7
  22. package/.claude/commands/sse/run.md +12 -5
  23. package/.claude/commands/sse/test.md +5 -5
  24. package/.claude/conventions/README.md +1 -1
  25. package/.claude/hooks/activity-pre-read.sh +4 -4
  26. package/.claude/hooks/status-line.sh +11 -11
  27. package/.claude/{plugins/product-manager/hooks → runtime/hooks/product-manager}/post-eval-prd.sh +11 -9
  28. package/.claude/{plugins/product-manager/hooks → runtime/hooks/product-manager}/post-eval-prp.sh +11 -9
  29. package/.claude/{plugins/product-manager/hooks → runtime/hooks/product-manager}/post-write-prd.sh +7 -5
  30. package/.claude/{plugins/product-manager/hooks → runtime/hooks/product-manager}/post-write-prp.sh +8 -6
  31. package/.claude/{plugins/product-manager/hooks → runtime/hooks/product-manager}/pre-prp-check.sh +5 -3
  32. package/.claude/{plugins/staff-software-engineer/hooks → runtime/hooks/staff-software-engineer}/post-eval-sse.sh +13 -11
  33. package/.claude/{plugins/staff-software-engineer/hooks → runtime/hooks/staff-software-engineer}/post-write-sse.sh +11 -9
  34. package/.claude/runtime/scripts/product-manager/__pycache__/confluence-publish.cpython-314.pyc +0 -0
  35. package/.claude/runtime/scripts/product-manager/__pycache__/link-validator.cpython-314.pyc +0 -0
  36. package/.claude/runtime/scripts/product-manager/__pycache__/sensor-runner.cpython-314.pyc +0 -0
  37. package/.claude/runtime/scripts/product-manager/__pycache__/token-phase.cpython-314.pyc +0 -0
  38. package/.claude/runtime/scripts/product-manager/confluence-publish.py +206 -0
  39. package/.claude/{plugins/product-manager/scripts → runtime/scripts/product-manager}/link-validator.py +1 -1
  40. package/.claude/{plugins/product-manager/scripts → runtime/scripts/product-manager}/token-phase.py +2 -2
  41. package/.claude/scripts/__pycache__/activity.cpython-314.pyc +0 -0
  42. package/.claude/scripts/__pycache__/pipeline.cpython-314.pyc +0 -0
  43. package/.claude/scripts/__pycache__/pr-monitor.cpython-314.pyc +0 -0
  44. package/.claude/scripts/pipeline.py +6 -6
  45. package/.claude/settings.json +7 -7
  46. package/.claude/settings.local.json +11 -3
  47. package/AGENTS.md +141 -0
  48. package/CLAUDE.md +9 -7
  49. package/README.md +88 -290
  50. package/VERSION +1 -1
  51. package/bin/hk.js +16 -8
  52. package/package.json +5 -3
  53. package/setup/install.sh +59 -40
  54. package/setup/update.sh +5 -0
  55. package/.claude/plugins/product-manager/scripts/confluence-publish.py +0 -205
  56. package/.claude/plugins/staff-software-engineer/README.md +0 -90
  57. /package/.claude/{plugins → agents}/product-manager/evals/prd-quality.md +0 -0
  58. /package/.claude/{plugins → agents}/product-manager/evals/prd-readiness.md +0 -0
  59. /package/.claude/{plugins → agents}/product-manager/evals/prp-context-readiness.md +0 -0
  60. /package/.claude/{plugins → agents}/product-manager/evals/prp-quality.md +0 -0
  61. /package/.claude/{plugins → agents}/product-manager/guides/examples/good-prd-example.md +0 -0
  62. /package/.claude/{plugins → agents}/product-manager/guides/prd-guidelines.md +0 -0
  63. /package/.claude/{plugins → agents}/product-manager/guides/product-guidelines.md +0 -0
  64. /package/.claude/{plugins → agents}/product-manager/guides/prp-guidelines.md +0 -0
  65. /package/.claude/{plugins → agents}/product-manager/guides/templates/prd.md +0 -0
  66. /package/.claude/{plugins → agents}/product-manager/guides/templates/prp.md +0 -0
  67. /package/.claude/{plugins → agents}/product-manager/guides/writing-style.md +0 -0
  68. /package/.claude/{plugins → agents}/product-manager/sensors/prd-acceptance-criteria.md +0 -0
  69. /package/.claude/{plugins → agents}/product-manager/sensors/prd-structure.md +0 -0
  70. /package/.claude/{plugins → agents}/product-manager/sensors/prp-context-quality.md +0 -0
  71. /package/.claude/{plugins → agents}/product-manager/sensors/prp-structure.md +0 -0
  72. /package/.claude/{plugins → agents}/staff-software-engineer/evals/dev-quality.md +0 -0
  73. /package/.claude/{plugins → agents}/staff-software-engineer/evals/plan-quality.md +0 -0
  74. /package/.claude/{plugins → agents}/staff-software-engineer/evals/pr-quality.md +0 -0
  75. /package/.claude/{plugins → agents}/staff-software-engineer/evals/test-quality.md +0 -0
  76. /package/.claude/{plugins → agents}/staff-software-engineer/guides/coding-style.md +0 -0
  77. /package/.claude/{plugins → agents}/staff-software-engineer/guides/commit-style.md +0 -0
  78. /package/.claude/{plugins → agents}/staff-software-engineer/sensors/code-conventions.md +0 -0
  79. /package/.claude/{plugins → agents}/staff-software-engineer/sensors/plan-structure.md +0 -0
  80. /package/.claude/{plugins → agents}/staff-software-engineer/sensors/test-coverage.md +0 -0
  81. /package/.claude/{plugins → agents}/staff-software-engineer/skills/backend/SKILL.md +0 -0
  82. /package/.claude/{plugins → agents}/staff-software-engineer/skills/devops/SKILL.md +0 -0
  83. /package/.claude/{plugins → agents}/staff-software-engineer/skills/mobile/SKILL.md +0 -0
  84. /package/.claude/{plugins → agents}/staff-software-engineer/skills/web/SKILL.md +0 -0
  85. /package/.claude/{plugins/product-manager/outputs → runtime/outputs/pm}/.markers/.gitkeep +0 -0
  86. /package/.claude/{plugins/staff-software-engineer/outputs → runtime/outputs/sse}/.markers/.gitkeep +0 -0
  87. /package/.claude/{plugins/product-manager/scripts → runtime/scripts/product-manager}/sensor-runner.py +0 -0
package/setup/install.sh CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env bash
2
- # harness-kit installer. Copies plugins, status-line hook, and
3
- # settings.json into a target repo. Reads VERSION at the repo root and records
4
- # it in the target.
2
+ # harness-kit installer (v4). Copies agents, runtime hooks/scripts,
3
+ # root hooks/scripts, slash commands, AGENTS.md/CLAUDE.md, and writes
4
+ # the wiring settings.json into a target repo. Reads VERSION at the
5
+ # repo root and records it in the target.
5
6
  #
6
7
  # Usage:
7
8
  # bash /path/to/harness-kit/setup/install.sh [target-dir]
@@ -14,8 +15,8 @@ TARGET="${1:-${TARGET:-$(pwd)}}"
14
15
 
15
16
  VERSION="$(cat "$SOURCE_ROOT/VERSION" 2>/dev/null || echo "0.0.0")"
16
17
 
17
- if [ ! -d "$SOURCE_ROOT/.claude/plugins/product-manager" ]; then
18
- echo "missing plugins at $SOURCE_ROOT/.claude/plugins/"
18
+ if [ ! -d "$SOURCE_ROOT/.claude/agents/product-manager" ]; then
19
+ echo "missing agents at $SOURCE_ROOT/.claude/agents/"
19
20
  echo "clone the repo first, then re-run: git clone https://github.com/Pierry/harness-kit ~/.harness-kit"
20
21
  exit 1
21
22
  fi
@@ -33,47 +34,61 @@ else
33
34
  echo "harness-kit v$VERSION installing at $TARGET"
34
35
  fi
35
36
 
36
- # Copy plugin support code (hooks, scripts, guides, sensors, evals, skills, outputs)
37
- mkdir -p "$TARGET/.claude/plugins"
38
- for plugin in product-manager staff-software-engineer; do
39
- rm -rf "$TARGET/.claude/plugins/$plugin"
40
- cp -R "$SOURCE_ROOT/.claude/plugins/$plugin" "$TARGET/.claude/plugins/$plugin"
37
+ # Migrate legacy v3.x layout if detected. Backs up to .claude/.legacy-v3-backup/.
38
+ if [ -d "$TARGET/.claude/plugins" ]; then
39
+ echo " detected legacy v3.x plugins/ — backing up to .claude/.legacy-v3-backup/"
40
+ STAMP="$(date +%Y%m%d-%H%M%S)"
41
+ mkdir -p "$TARGET/.claude/.legacy-v3-backup"
42
+ mv "$TARGET/.claude/plugins" "$TARGET/.claude/.legacy-v3-backup/plugins.$STAMP"
43
+ fi
44
+
45
+ # 1) AGENTS.md + CLAUDE.md at the repo root.
46
+ cp "$SOURCE_ROOT/AGENTS.md" "$TARGET/AGENTS.md"
47
+ if [ ! -f "$TARGET/CLAUDE.md" ]; then
48
+ cp "$SOURCE_ROOT/CLAUDE.md" "$TARGET/CLAUDE.md"
49
+ fi
50
+
51
+ # 2) Agent definitions (sensors, evals, guides, skills, README + orchestrator .md)
52
+ mkdir -p "$TARGET/.claude/agents"
53
+ for agent in product-manager staff-software-engineer; do
54
+ rm -rf "$TARGET/.claude/agents/$agent"
55
+ cp -R "$SOURCE_ROOT/.claude/agents/$agent" "$TARGET/.claude/agents/$agent"
56
+ cp "$SOURCE_ROOT/.claude/agents/$agent.md" "$TARGET/.claude/agents/$agent.md"
57
+ done
58
+
59
+ # 3) Per-agent runtime hooks + scripts (NOT outputs — that's target-side state)
60
+ mkdir -p "$TARGET/.claude/runtime/hooks" "$TARGET/.claude/runtime/scripts" "$TARGET/.claude/runtime/outputs/pm/.markers" "$TARGET/.claude/runtime/outputs/sse/.markers"
61
+ for agent in product-manager staff-software-engineer; do
62
+ rm -rf "$TARGET/.claude/runtime/hooks/$agent"
63
+ cp -R "$SOURCE_ROOT/.claude/runtime/hooks/$agent" "$TARGET/.claude/runtime/hooks/$agent"
64
+ rm -rf "$TARGET/.claude/runtime/scripts/$agent"
65
+ cp -R "$SOURCE_ROOT/.claude/runtime/scripts/$agent" "$TARGET/.claude/runtime/scripts/$agent"
41
66
  done
42
67
 
43
- # Re-resolve symlinks in SSE scripts
44
- for f in "$TARGET/.claude/plugins/staff-software-engineer/scripts/"*; do
68
+ # Re-resolve symlinks in SSE scripts (point at PM's shared utilities)
69
+ for f in "$TARGET/.claude/runtime/scripts/staff-software-engineer/"*; do
45
70
  if [ -L "$f" ]; then
46
71
  name="$(basename "$f")"
47
72
  rm "$f"
48
- ln -sf "../../product-manager/scripts/$name" "$f"
73
+ ln -sf "../product-manager/$name" "$f"
49
74
  fi
50
75
  done
51
76
 
52
- # Copy slash commands and Task-invokable agents
53
- mkdir -p "$TARGET/.claude/commands" "$TARGET/.claude/agents"
77
+ # 4) Slash commands
78
+ mkdir -p "$TARGET/.claude/commands"
54
79
  for ns in product-manager sse pipeline; do
55
80
  rm -rf "$TARGET/.claude/commands/$ns"
56
81
  cp -R "$SOURCE_ROOT/.claude/commands/$ns" "$TARGET/.claude/commands/$ns"
57
82
  done
58
- for agent in product-manager staff-software-engineer; do
59
- cp "$SOURCE_ROOT/.claude/agents/$agent.md" "$TARGET/.claude/agents/$agent.md"
60
- done
61
-
62
- # Clean up legacy plugin layout from older installs
63
- for plugin in product-manager staff-software-engineer; do
64
- rm -rf "$TARGET/.claude/plugins/$plugin/commands" \
65
- "$TARGET/.claude/plugins/$plugin/agents" \
66
- "$TARGET/.claude/plugins/$plugin/.claude-plugin"
67
- done
68
83
 
69
- # Copy harness-kit hooks (status-line + pipeline tracking + live activity)
84
+ # 5) Root harness hooks (status-line + pipeline tracking + live activity)
70
85
  mkdir -p "$TARGET/.claude/hooks"
71
86
  for h in status-line.sh pipeline-prompt.sh pipeline-postwrite.sh pipeline-postedit.sh pipeline-session-start.sh activity-pre-read.sh; do
72
87
  cp "$SOURCE_ROOT/.claude/hooks/$h" "$TARGET/.claude/hooks/$h"
73
88
  chmod +x "$TARGET/.claude/hooks/$h"
74
89
  done
75
90
 
76
- # Copy harness-kit scripts (pipeline state, activity tracker, PR monitor, stage-card)
91
+ # 6) Root harness scripts (pipeline state, activity, PR monitor, stage-card)
77
92
  mkdir -p "$TARGET/.claude/scripts"
78
93
  for s in pipeline.py activity.py pr-monitor.py; do
79
94
  cp "$SOURCE_ROOT/.claude/scripts/$s" "$TARGET/.claude/scripts/$s"
@@ -81,7 +96,11 @@ for s in pipeline.py activity.py pr-monitor.py; do
81
96
  done
82
97
  cp "$SOURCE_ROOT/.claude/scripts/stage-card.md" "$TARGET/.claude/scripts/stage-card.md"
83
98
 
84
- # Settings.json (back up existing if content differs)
99
+ # 6.5) Strip any __pycache__/.pyc that hitched a ride from the source repo
100
+ find "$TARGET/.claude" -name __pycache__ -type d -prune -exec rm -rf {} + 2>/dev/null || true
101
+ find "$TARGET/.claude" -name "*.pyc" -type f -delete 2>/dev/null || true
102
+
103
+ # 7) settings.json (back up existing if content differs)
85
104
  if [ -f "$TARGET/.claude/settings.json" ]; then
86
105
  STAMP="$(date +%Y%m%d-%H%M%S)"
87
106
  BACKUP="$TARGET/.claude/settings.json.bak.$STAMP"
@@ -99,8 +118,8 @@ cat > "$TARGET/.claude/settings.json" <<'EOF'
99
118
  "Bash(npm:*)",
100
119
  "Bash(gh:*)",
101
120
  "Bash(jq:*)",
102
- "Read(outputs/**)",
103
- "Write(outputs/**)"
121
+ "Read(.claude/runtime/outputs/**)",
122
+ "Write(.claude/runtime/outputs/**)"
104
123
  ],
105
124
  "deny": [
106
125
  "Bash(rm -rf:*)",
@@ -128,7 +147,7 @@ cat > "$TARGET/.claude/settings.json" <<'EOF'
128
147
  {
129
148
  "matcher": "Write",
130
149
  "hooks": [
131
- { "type": "command", "command": "[ -x .claude/plugins/product-manager/hooks/pre-prp-check.sh ] && bash .claude/plugins/product-manager/hooks/pre-prp-check.sh; exit 0" }
150
+ { "type": "command", "command": "[ -x .claude/runtime/hooks/product-manager/pre-prp-check.sh ] && bash .claude/runtime/hooks/product-manager/pre-prp-check.sh; exit 0" }
132
151
  ]
133
152
  },
134
153
  {
@@ -142,18 +161,18 @@ cat > "$TARGET/.claude/settings.json" <<'EOF'
142
161
  {
143
162
  "matcher": "Write",
144
163
  "hooks": [
145
- { "type": "command", "command": "[ -x .claude/plugins/product-manager/hooks/post-write-prd.sh ] && bash .claude/plugins/product-manager/hooks/post-write-prd.sh; exit 0" },
146
- { "type": "command", "command": "[ -x .claude/plugins/product-manager/hooks/post-write-prp.sh ] && bash .claude/plugins/product-manager/hooks/post-write-prp.sh; exit 0" },
147
- { "type": "command", "command": "[ -x .claude/plugins/staff-software-engineer/hooks/post-write-sse.sh ] && bash .claude/plugins/staff-software-engineer/hooks/post-write-sse.sh; exit 0" },
164
+ { "type": "command", "command": "[ -x .claude/runtime/hooks/product-manager/post-write-prd.sh ] && bash .claude/runtime/hooks/product-manager/post-write-prd.sh; exit 0" },
165
+ { "type": "command", "command": "[ -x .claude/runtime/hooks/product-manager/post-write-prp.sh ] && bash .claude/runtime/hooks/product-manager/post-write-prp.sh; exit 0" },
166
+ { "type": "command", "command": "[ -x .claude/runtime/hooks/staff-software-engineer/post-write-sse.sh ] && bash .claude/runtime/hooks/staff-software-engineer/post-write-sse.sh; exit 0" },
148
167
  { "type": "command", "command": "[ -x .claude/hooks/pipeline-postwrite.sh ] && bash .claude/hooks/pipeline-postwrite.sh; exit 0" }
149
168
  ]
150
169
  },
151
170
  {
152
171
  "matcher": "Edit",
153
172
  "hooks": [
154
- { "type": "command", "command": "[ -x .claude/plugins/product-manager/hooks/post-eval-prd.sh ] && bash .claude/plugins/product-manager/hooks/post-eval-prd.sh; exit 0" },
155
- { "type": "command", "command": "[ -x .claude/plugins/product-manager/hooks/post-eval-prp.sh ] && bash .claude/plugins/product-manager/hooks/post-eval-prp.sh; exit 0" },
156
- { "type": "command", "command": "[ -x .claude/plugins/staff-software-engineer/hooks/post-eval-sse.sh ] && bash .claude/plugins/staff-software-engineer/hooks/post-eval-sse.sh; exit 0" },
173
+ { "type": "command", "command": "[ -x .claude/runtime/hooks/product-manager/post-eval-prd.sh ] && bash .claude/runtime/hooks/product-manager/post-eval-prd.sh; exit 0" },
174
+ { "type": "command", "command": "[ -x .claude/runtime/hooks/product-manager/post-eval-prp.sh ] && bash .claude/runtime/hooks/product-manager/post-eval-prp.sh; exit 0" },
175
+ { "type": "command", "command": "[ -x .claude/runtime/hooks/staff-software-engineer/post-eval-sse.sh ] && bash .claude/runtime/hooks/staff-software-engineer/post-eval-sse.sh; exit 0" },
157
176
  { "type": "command", "command": "[ -x .claude/hooks/pipeline-postedit.sh ] && bash .claude/hooks/pipeline-postedit.sh; exit 0" }
158
177
  ]
159
178
  }
@@ -172,16 +191,16 @@ if [ ! -f "$TARGET/.claude/conventions/README.md" ]; then
172
191
  cat > "$TARGET/.claude/conventions/README.md" <<'EOF'
173
192
  # Project Conventions
174
193
 
175
- Override staff-software-engineer plugin defaults for this repo. Create files as needed:
194
+ Override staff-software-engineer defaults for this repo. Create files as needed:
176
195
 
177
196
  - backend.md
178
197
  - web.md
179
198
  - mobile.md
180
199
  - devops.md
181
200
 
182
- When a file exists here, plugin reads it on top of defaults. Rules in this folder win.
201
+ When a file exists here, the agent reads it on top of defaults. Rules in this folder win.
183
202
 
184
- See `.claude/plugins/staff-software-engineer/guides/conventions-override.md` for the full reference.
203
+ See `.claude/agents/staff-software-engineer/guides/conventions-override.md` for the full reference.
185
204
  EOF
186
205
  fi
187
206
 
package/setup/update.sh CHANGED
@@ -3,6 +3,11 @@
3
3
  # the installer. For npm installs, you must upgrade the package first:
4
4
  # npm i -g @pieerry/harness-kit@latest
5
5
  #
6
+ # v3.x → v4.x migration: install.sh detects a legacy .claude/plugins/ tree in
7
+ # the target and backs it up to .claude/.legacy-v3-backup/ before laying down
8
+ # the v4 structure (.claude/agents/, .claude/runtime/, AGENTS.md). Custom
9
+ # edits inside the legacy tree are preserved in the backup for manual merge.
10
+ #
6
11
  # Usage:
7
12
  # bash /path/to/harness-kit/setup/update.sh [target-dir]
8
13
 
@@ -1,205 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Publish a PRD or PRP to Confluence.
4
-
5
- Reads credentials from environment:
6
- - JIRA_USERNAME (email)
7
- - JIRA_API_TOKEN (API token)
8
-
9
- Targets the Confluence at https://YOUR-DOMAIN.atlassian.net.
10
-
11
- Usage:
12
- confluence-publish.py --artifact PATH.md --kind {prd|prp}
13
-
14
- Exit 0 on success, 1 on failure. Stays silent on routine output, prints
15
- errors to stderr.
16
- """
17
-
18
- import argparse
19
- import base64
20
- import html
21
- import json
22
- import os
23
- import re
24
- import sys
25
- import urllib.request
26
- from pathlib import Path
27
-
28
- CONFLUENCE_BASE = "https://YOUR-DOMAIN.atlassian.net/wiki/rest/api/content"
29
- SPACE_KEY = "TET1"
30
-
31
- # Parent page IDs per kind. Override via env if needed.
32
- PARENT_IDS = {
33
- "prd": os.environ.get("CONFLUENCE_PARENT_PRD", "11351457795"),
34
- "prp": os.environ.get("CONFLUENCE_PARENT_PRP", "11351457795"),
35
- }
36
-
37
-
38
- def md_to_storage(md: str) -> str:
39
- """Minimal Markdown to Confluence storage XHTML.
40
- Good enough for headings, paragraphs, fenced code, lists, tables.
41
- For richer rendering, swap for a real converter later.
42
- """
43
- lines = md.splitlines()
44
- out: list[str] = []
45
- in_code = False
46
- in_list: str | None = None # 'ul' or 'ol'
47
- in_table = False
48
-
49
- def close_list():
50
- nonlocal in_list
51
- if in_list:
52
- out.append(f"</{in_list}>")
53
- in_list = None
54
-
55
- def close_table():
56
- nonlocal in_table
57
- if in_table:
58
- out.append("</tbody></table>")
59
- in_table = False
60
-
61
- for line in lines:
62
- if line.startswith("```"):
63
- close_list()
64
- close_table()
65
- if not in_code:
66
- lang = line[3:].strip() or "none"
67
- out.append(
68
- f'<ac:structured-macro ac:name="code">'
69
- f'<ac:parameter ac:name="language">{html.escape(lang)}</ac:parameter>'
70
- f'<ac:plain-text-body><![CDATA['
71
- )
72
- in_code = True
73
- else:
74
- out.append("]]></ac:plain-text-body></ac:structured-macro>")
75
- in_code = False
76
- continue
77
-
78
- if in_code:
79
- out.append(line)
80
- continue
81
-
82
- h = re.match(r"^(#{1,6})\s+(.+)$", line)
83
- if h:
84
- close_list()
85
- close_table()
86
- level = len(h.group(1))
87
- out.append(f"<h{level}>{html.escape(h.group(2))}</h{level}>")
88
- continue
89
-
90
- if re.match(r"^[-*]\s+", line):
91
- close_table()
92
- if in_list != "ul":
93
- close_list()
94
- out.append("<ul>")
95
- in_list = "ul"
96
- item = re.sub(r"^[-*]\s+", "", line)
97
- out.append(f"<li>{html.escape(item)}</li>")
98
- continue
99
-
100
- if re.match(r"^\d+\.\s+", line):
101
- close_table()
102
- if in_list != "ol":
103
- close_list()
104
- out.append("<ol>")
105
- in_list = "ol"
106
- item = re.sub(r"^\d+\.\s+", "", line)
107
- out.append(f"<li>{html.escape(item)}</li>")
108
- continue
109
-
110
- if line.startswith("|") and "|" in line[1:]:
111
- close_list()
112
- cells = [c.strip() for c in line.strip("|").split("|")]
113
- if not in_table:
114
- out.append("<table><tbody>")
115
- in_table = True
116
- out.append(
117
- "<tr>"
118
- + "".join(f"<th>{html.escape(c)}</th>" for c in cells)
119
- + "</tr>"
120
- )
121
- elif all(re.fullmatch(r":?-+:?", c) for c in cells):
122
- # separator row, skip
123
- pass
124
- else:
125
- out.append(
126
- "<tr>"
127
- + "".join(f"<td>{html.escape(c)}</td>" for c in cells)
128
- + "</tr>"
129
- )
130
- continue
131
-
132
- # paragraph or blank
133
- close_list()
134
- close_table()
135
- if line.strip():
136
- out.append(f"<p>{html.escape(line)}</p>")
137
-
138
- close_list()
139
- close_table()
140
- return "\n".join(out)
141
-
142
-
143
- def extract_title(md: str) -> str:
144
- for line in md.splitlines():
145
- m = re.match(r"^#\s+(.+)$", line)
146
- if m:
147
- return m.group(1).strip()
148
- return "Untitled"
149
-
150
-
151
- def main() -> int:
152
- parser = argparse.ArgumentParser()
153
- parser.add_argument("--artifact", required=True, type=Path)
154
- parser.add_argument("--kind", required=True, choices=["prd", "prp"])
155
- args = parser.parse_args()
156
-
157
- username = os.environ.get("JIRA_USERNAME")
158
- token = os.environ.get("JIRA_API_TOKEN")
159
- if not username or not token:
160
- print("[confluence-publish] JIRA_USERNAME/JIRA_API_TOKEN not set", file=sys.stderr)
161
- return 1
162
-
163
- md = args.artifact.read_text(encoding="utf-8")
164
- title = extract_title(md)
165
- storage = md_to_storage(md)
166
-
167
- payload = {
168
- "type": "page",
169
- "title": title,
170
- "ancestors": [{"id": PARENT_IDS[args.kind]}],
171
- "space": {"key": SPACE_KEY},
172
- "body": {"storage": {"value": storage, "representation": "storage"}},
173
- }
174
-
175
- auth = base64.b64encode(f"{username}:{token}".encode()).decode()
176
- req = urllib.request.Request(
177
- CONFLUENCE_BASE,
178
- data=json.dumps(payload).encode("utf-8"),
179
- method="POST",
180
- headers={
181
- "Authorization": f"Basic {auth}",
182
- "Content-Type": "application/json",
183
- "Accept": "application/json",
184
- },
185
- )
186
-
187
- try:
188
- with urllib.request.urlopen(req, timeout=20) as resp:
189
- data = json.loads(resp.read().decode("utf-8"))
190
- page_url = data.get("_links", {}).get("base", "") + data.get(
191
- "_links", {}
192
- ).get("webui", "")
193
- print(f"[confluence-publish] published: {page_url}", file=sys.stderr)
194
- return 0
195
- except urllib.error.HTTPError as e:
196
- body = e.read().decode("utf-8", errors="replace")
197
- print(f"[confluence-publish] HTTP {e.code}: {body[:500]}", file=sys.stderr)
198
- return 1
199
- except Exception as e:
200
- print(f"[confluence-publish] error: {e}", file=sys.stderr)
201
- return 1
202
-
203
-
204
- if __name__ == "__main__":
205
- sys.exit(main())
@@ -1,90 +0,0 @@
1
- # Staff Software Engineer Plugin
2
-
3
- Native Claude Code plugin for the engineering team. Drives plan, dev, test, and pr stages across backend, web, mobile, and devops. Per-project conventions in each repo's `.claude/conventions/` override plugin defaults.
4
-
5
- ## Slash commands
6
-
7
- - `/sse:plan`: generate an implementation plan from an approved PRP
8
- - `/sse:dev`: implement the plan in code, run convention gates
9
- - `/sse:test`: run the project test suite
10
- - `/sse:pr`: open the draft PR
11
- - `/sse:run`: full pipeline, plan to pr
12
-
13
- Also invokable as sub-agent via Task tool with `subagent_type: "staff-software-engineer"`.
14
-
15
- ## Tree
16
-
17
- ```
18
- .claude/plugins/staff-software-engineer/
19
- ├── .claude-plugin/plugin.json
20
- ├── agents/staff-software-engineer.md sub-agent
21
- ├── commands/
22
- │ ├── plan.md /sse:plan
23
- │ ├── dev.md /sse:dev
24
- │ ├── test.md /sse:test
25
- │ ├── pr.md /sse:pr
26
- │ └── run.md /sse:run
27
- ├── skills/
28
- │ ├── backend/SKILL.md Java/Spring defaults
29
- │ ├── web/SKILL.md Vue defaults
30
- │ ├── mobile/SKILL.md iOS/Android defaults
31
- │ └── devops/SKILL.md CI/IaC defaults
32
- ├── hooks/ phase markers, sensor gates
33
- ├── scripts/ symlinks to product-manager scripts
34
- ├── guides/
35
- │ ├── pipeline.md retry, approval, token accounting
36
- │ ├── coding-style.md team code style
37
- │ ├── commit-style.md Conventional Commits with TICKET
38
- │ └── conventions-override.md how project overrides work
39
- ├── sensors/ plan structure, code conventions, test coverage
40
- ├── evals/ plan quality rubric
41
- └── outputs/
42
- ├── plan/ generated plans
43
- ├── dev/ dev summaries
44
- ├── test/ test results
45
- ├── pr/ opened PR records
46
- ├── tokens/ per-feature phase tokens JSON
47
- └── .markers/ phase start/end markers (transient)
48
- ```
49
-
50
- ## How conventions work
51
-
52
- The plugin holds team defaults per area. Each project repo can override by adding:
53
-
54
- ```
55
- {repo-root}/.claude/conventions/{area}.md
56
- ```
57
-
58
- Example for the `recon-service` repo:
59
-
60
- ```
61
- recon-service/.claude/conventions/backend.md
62
- ```
63
-
64
- Plugin skills read both. Project rules win. See `guides/conventions-override.md`.
65
-
66
- ## Where to edit
67
-
68
- | Change | File |
69
- |--------|------|
70
- | Pipeline order | guides/pipeline.md |
71
- | Retry count | guides/pipeline.md (Max attempts) |
72
- | Plan template/rules | skills/backend/SKILL.md (etc per area), commands/plan.md |
73
- | Eval threshold | evals/plan-quality.md (Threshold) |
74
- | Code style | guides/coding-style.md |
75
- | Commit format | guides/commit-style.md |
76
- | Test command detection | commands/test.md |
77
- | PR template | commands/pr.md, hooks/post-eval-pr.sh |
78
- | Sensors | sensors/*.md |
79
-
80
- ## Connects to PM plugin
81
-
82
- `/sse:run` reads the latest approved PRP from `.claude/plugins/product-manager/outputs/prp/`. The feature_id flows through: PM plugin creates `2026-05-12-billing-tz-fix`, SSE plugin reuses the same id and writes its phases to the same `outputs/tokens/{feature_id}.json` file (per `guides/pipeline.md`).
83
-
84
- Full lifecycle in one JSON: PRD generate, PRD validate, PRP generate, PRP validate, plan generate, plan validate, dev, test, pr.
85
-
86
- ## Setup
87
-
88
- Hooks registered in `.claude/settings.json` under PostToolUse. Token script reused from the PM plugin via symlinks in `scripts/`.
89
-
90
- PR opening requires the `gh` CLI authenticated. `pr.md` command details ticket detection and template.