prizmkit 1.1.127 → 1.1.129
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/bundled/VERSION.json +3 -3
- package/bundled/adapters/claude/command-adapter.js +2 -75
- package/bundled/dev-pipeline/assets/skill-subagent-integration.md +14 -11
- package/bundled/dev-pipeline/prizmkit_runtime/gitops.py +88 -58
- package/bundled/dev-pipeline/prizmkit_runtime/reset.py +4 -3
- package/bundled/dev-pipeline/prizmkit_runtime/runner_bookkeeping.py +53 -1
- package/bundled/dev-pipeline/prizmkit_runtime/runners.py +33 -17
- package/bundled/dev-pipeline/prizmkit_runtime/runtime_helper.py +0 -1
- package/bundled/dev-pipeline/scripts/generate-bootstrap-prompt.py +28 -26
- package/bundled/dev-pipeline/scripts/generate-bugfix-prompt.py +1 -1
- package/bundled/dev-pipeline/scripts/generate-recovery-prompt.py +4 -3
- package/bundled/dev-pipeline/scripts/generate-refactor-prompt.py +1 -1
- package/bundled/dev-pipeline/scripts/parse-stream-progress.py +3 -3
- package/bundled/dev-pipeline/templates/bootstrap-prompt.md +2 -2
- package/bundled/dev-pipeline/templates/bootstrap-tier3.md +22 -21
- package/bundled/dev-pipeline/templates/bugfix-bootstrap-prompt.md +4 -4
- package/bundled/dev-pipeline/templates/refactor-bootstrap-prompt.md +5 -5
- package/bundled/dev-pipeline/templates/sections/bugfix-mission.md +1 -1
- package/bundled/dev-pipeline/templates/sections/bugfix-phase-review.md +11 -4
- package/bundled/dev-pipeline/templates/sections/context-budget-rules.md +1 -1
- package/bundled/dev-pipeline/templates/sections/directory-convention-agent.md +3 -2
- package/bundled/dev-pipeline/templates/sections/directory-convention-full.md +3 -2
- package/bundled/dev-pipeline/templates/sections/phase-commit-full.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-commit.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-agent.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-implement-full.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase-review-agent.md +12 -5
- package/bundled/dev-pipeline/templates/sections/phase-review-full.md +12 -5
- package/bundled/dev-pipeline/templates/sections/phase-specify-plan-full.md +1 -1
- package/bundled/dev-pipeline/templates/sections/phase0-init.md +1 -1
- package/bundled/dev-pipeline/templates/sections/refactor-mission.md +1 -1
- package/bundled/dev-pipeline/templates/sections/refactor-phase-review.md +13 -6
- package/bundled/dev-pipeline/templates/sections/refactor-reminders.md +1 -1
- package/bundled/dev-pipeline/templates/sections/subagent-timeout-recovery.md +6 -4
- package/bundled/dev-pipeline/templates/sections/test-failure-recovery-agent.md +1 -1
- package/bundled/dev-pipeline/tests/test_generate_bootstrap_prompt.py +106 -7
- package/bundled/dev-pipeline/tests/test_python_runner_parity.py +139 -11
- package/bundled/dev-pipeline/tests/test_runtime_helper.py +9 -3
- package/bundled/dev-pipeline/tests/test_unified_cli.py +225 -24
- package/bundled/skills/_metadata.json +3 -3
- package/bundled/skills/feature-planner/SKILL.md +2 -2
- package/bundled/skills/prizmkit/SKILL.md +1 -1
- package/bundled/skills/prizmkit-code-review/SKILL.md +63 -122
- package/bundled/skills/prizmkit-code-review/references/review-report-template.md +9 -36
- package/bundled/skills/prizmkit-code-review/scripts/render_review_report.py +21 -111
- package/package.json +1 -1
- package/src/manifest.js +8 -3
- package/src/scaffold.js +5 -16
- package/bundled/skills/prizmkit-code-review/assets/reviewer-role.json +0 -19
- package/bundled/skills/prizmkit-code-review/references/reviewer-agent-prompt.md +0 -120
|
@@ -16,17 +16,6 @@ Within that execution, append sections only. Never edit or replace an earlier pr
|
|
|
16
16
|
|
|
17
17
|
## Progress Sections
|
|
18
18
|
|
|
19
|
-
### Risk Assessment
|
|
20
|
-
|
|
21
|
-
```markdown
|
|
22
|
-
## Risk Assessment
|
|
23
|
-
|
|
24
|
-
- Risk: <low|medium|high>
|
|
25
|
-
- Independent Reviewer Limit: <0|1|2>
|
|
26
|
-
- Reasons:
|
|
27
|
-
- <concrete behavioral reason>
|
|
28
|
-
```
|
|
29
|
-
|
|
30
19
|
### Main-Agent Review Round
|
|
31
20
|
|
|
32
21
|
```markdown
|
|
@@ -36,6 +25,7 @@ Within that execution, append sections only. Never edit or replace an earlier pr
|
|
|
36
25
|
- Findings: <count>
|
|
37
26
|
- Accepted: <count>
|
|
38
27
|
- Rejected: <count>
|
|
28
|
+
- Unresolved: <count>
|
|
39
29
|
- Next: <next action>
|
|
40
30
|
```
|
|
41
31
|
|
|
@@ -44,34 +34,18 @@ Within that execution, append sections only. Never edit or replace an earlier pr
|
|
|
44
34
|
```markdown
|
|
45
35
|
## Repair Verification
|
|
46
36
|
|
|
47
|
-
- Source: <main|reviewer-1|reviewer-2>
|
|
48
37
|
- Fixed Findings: <count>
|
|
49
38
|
- Verification: <evidence summary>
|
|
50
39
|
- Next: <next action>
|
|
51
40
|
```
|
|
52
41
|
|
|
53
|
-
###
|
|
54
|
-
|
|
55
|
-
```markdown
|
|
56
|
-
## Independent Reviewer <N>
|
|
57
|
-
|
|
58
|
-
- Status: RUNNING
|
|
59
|
-
- Risk Trigger: <medium|high>
|
|
60
|
-
- Attempt: <1|2>
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
### Independent Reviewer Result
|
|
42
|
+
### Final Verification
|
|
64
43
|
|
|
65
44
|
```markdown
|
|
66
|
-
##
|
|
45
|
+
## Final Verification
|
|
67
46
|
|
|
68
|
-
- Status: <COMPLETED|
|
|
69
|
-
-
|
|
70
|
-
- Findings: <count>
|
|
71
|
-
- Accepted: <count>
|
|
72
|
-
- Rejected: <count>
|
|
73
|
-
- Accepted High: <count>
|
|
74
|
-
- Next: <next action>
|
|
47
|
+
- Status: <COMPLETED|FAILED>
|
|
48
|
+
- Evidence: <evidence summary>
|
|
75
49
|
```
|
|
76
50
|
|
|
77
51
|
## Final Result
|
|
@@ -81,10 +55,8 @@ Exactly one Final Result terminates a completed execution:
|
|
|
81
55
|
```markdown
|
|
82
56
|
## Final Result
|
|
83
57
|
|
|
84
|
-
- Verdict: <PASS|NEEDS_FIXES
|
|
85
|
-
- Risk: <low|medium|high>
|
|
58
|
+
- Verdict: <PASS | NEEDS_FIXES>
|
|
86
59
|
- Main Review Rounds: <count>
|
|
87
|
-
- Independent Reviewers Started: <count>
|
|
88
60
|
- Accepted Findings: <count>
|
|
89
61
|
- Fixed Findings: <count>
|
|
90
62
|
- Rejected Findings: <count>
|
|
@@ -96,8 +68,9 @@ Exactly one Final Result terminates a completed execution:
|
|
|
96
68
|
|
|
97
69
|
- Start of a new execution removes stale progress and terminal results from prior executions.
|
|
98
70
|
- A phase appends its result before the next phase starts.
|
|
99
|
-
-
|
|
100
|
-
-
|
|
71
|
+
- Finding counts satisfy `accepted + rejected + unresolved = findings`.
|
|
72
|
+
- `PASS` requires every accepted finding fixed and zero unresolved findings.
|
|
73
|
+
- `NEEDS_FIXES` requires at least one unfixed accepted or unresolved finding.
|
|
101
74
|
- An IN_PROGRESS report without Final Result is incomplete.
|
|
102
75
|
- Generic or incidental verdict text outside the last Final Result does not prove completion.
|
|
103
76
|
- Do not append any section after Final Result.
|
|
@@ -9,15 +9,10 @@ import sys
|
|
|
9
9
|
from pathlib import Path
|
|
10
10
|
from typing import Any
|
|
11
11
|
|
|
12
|
-
VERDICTS = {"PASS", "NEEDS_FIXES"
|
|
13
|
-
RISKS = {"low", "medium", "high"}
|
|
12
|
+
VERDICTS = {"PASS", "NEEDS_FIXES"}
|
|
14
13
|
EVENTS = {
|
|
15
|
-
"risk-assessment",
|
|
16
14
|
"main-review-round",
|
|
17
15
|
"repair-verification",
|
|
18
|
-
"reviewer-running",
|
|
19
|
-
"reviewer-result",
|
|
20
|
-
"infrastructure-failure",
|
|
21
16
|
"final-verification",
|
|
22
17
|
}
|
|
23
18
|
FINAL_HEADING = "## Final Result"
|
|
@@ -49,13 +44,6 @@ def _require_count(data: dict[str, Any], name: str, *, maximum: int | None = Non
|
|
|
49
44
|
return value
|
|
50
45
|
|
|
51
46
|
|
|
52
|
-
def _require_risk(data: dict[str, Any]) -> str:
|
|
53
|
-
risk = data.get("risk")
|
|
54
|
-
if risk not in RISKS:
|
|
55
|
-
raise ReportStateError(f"risk has invalid value: {risk!r}")
|
|
56
|
-
return risk
|
|
57
|
-
|
|
58
|
-
|
|
59
47
|
def _report_text(path: Path) -> str:
|
|
60
48
|
try:
|
|
61
49
|
return path.read_text(encoding="utf-8")
|
|
@@ -87,24 +75,6 @@ def _render_event(data: dict[str, Any]) -> str:
|
|
|
87
75
|
if event not in EVENTS:
|
|
88
76
|
raise ReportStateError(f"event has invalid value: {event!r}")
|
|
89
77
|
|
|
90
|
-
if event == "risk-assessment":
|
|
91
|
-
risk = _require_risk(data)
|
|
92
|
-
reasons = data.get("reasons")
|
|
93
|
-
if not isinstance(reasons, list) or not reasons or not all(
|
|
94
|
-
isinstance(reason, str) and reason.strip() for reason in reasons
|
|
95
|
-
):
|
|
96
|
-
raise ReportStateError("reasons must be a non-empty string array")
|
|
97
|
-
limit = {"low": 0, "medium": 1, "high": 2}[risk]
|
|
98
|
-
lines = [
|
|
99
|
-
"## Risk Assessment",
|
|
100
|
-
"",
|
|
101
|
-
f"- Risk: {risk}",
|
|
102
|
-
f"- Independent Reviewer Limit: {limit}",
|
|
103
|
-
"- Reasons:",
|
|
104
|
-
]
|
|
105
|
-
lines.extend(f" - {reason.strip()}" for reason in reasons)
|
|
106
|
-
return "\n".join(lines)
|
|
107
|
-
|
|
108
78
|
if event == "main-review-round":
|
|
109
79
|
round_number = _require_count(data, "round", maximum=10)
|
|
110
80
|
if round_number < 1:
|
|
@@ -112,8 +82,11 @@ def _render_event(data: dict[str, Any]) -> str:
|
|
|
112
82
|
findings = _require_count(data, "findings")
|
|
113
83
|
accepted = _require_count(data, "accepted")
|
|
114
84
|
rejected = _require_count(data, "rejected")
|
|
115
|
-
|
|
116
|
-
|
|
85
|
+
unresolved = _require_count(data, "unresolved")
|
|
86
|
+
if accepted + rejected + unresolved != findings:
|
|
87
|
+
raise ReportStateError(
|
|
88
|
+
"accepted + rejected + unresolved must equal findings"
|
|
89
|
+
)
|
|
117
90
|
return "\n".join(
|
|
118
91
|
[
|
|
119
92
|
f"## Main Review Round {round_number}",
|
|
@@ -122,93 +95,30 @@ def _render_event(data: dict[str, Any]) -> str:
|
|
|
122
95
|
f"- Findings: {findings}",
|
|
123
96
|
f"- Accepted: {accepted}",
|
|
124
97
|
f"- Rejected: {rejected}",
|
|
98
|
+
f"- Unresolved: {unresolved}",
|
|
125
99
|
f"- Next: {_require_text(data, 'next')}",
|
|
126
100
|
]
|
|
127
101
|
)
|
|
128
102
|
|
|
129
103
|
if event == "repair-verification":
|
|
130
|
-
source = _require_text(data, "source")
|
|
131
|
-
if source not in {"main", "reviewer-1", "reviewer-2"}:
|
|
132
|
-
raise ReportStateError(f"source has invalid value: {source!r}")
|
|
133
104
|
return "\n".join(
|
|
134
105
|
[
|
|
135
106
|
"## Repair Verification",
|
|
136
107
|
"",
|
|
137
|
-
f"- Source: {source}",
|
|
138
108
|
f"- Fixed Findings: {_require_count(data, 'fixed_findings')}",
|
|
139
109
|
f"- Verification: {_require_text(data, 'verification')}",
|
|
140
110
|
f"- Next: {_require_text(data, 'next')}",
|
|
141
111
|
]
|
|
142
112
|
)
|
|
143
113
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
raise ReportStateError("reviewer must be 1 or 2")
|
|
148
|
-
risk = _require_risk(data)
|
|
149
|
-
if risk == "low" or (risk == "medium" and reviewer == 2):
|
|
150
|
-
raise ReportStateError("reviewer exceeds the semantic risk limit")
|
|
151
|
-
attempt = data.get("attempt", 1)
|
|
152
|
-
if attempt not in {1, 2}:
|
|
153
|
-
raise ReportStateError("attempt must be 1 or 2")
|
|
154
|
-
return "\n".join(
|
|
155
|
-
[
|
|
156
|
-
f"## Independent Reviewer {reviewer}",
|
|
157
|
-
"",
|
|
158
|
-
"- Status: RUNNING",
|
|
159
|
-
f"- Risk Trigger: {risk}",
|
|
160
|
-
f"- Attempt: {attempt}",
|
|
161
|
-
]
|
|
162
|
-
)
|
|
163
|
-
|
|
164
|
-
if event == "reviewer-result":
|
|
165
|
-
reviewer = _require_count(data, "reviewer", maximum=2)
|
|
166
|
-
if reviewer < 1:
|
|
167
|
-
raise ReportStateError("reviewer must be 1 or 2")
|
|
168
|
-
result = data.get("result")
|
|
169
|
-
if result not in {"PASS", "FINDINGS", "BLOCKED"}:
|
|
170
|
-
raise ReportStateError(f"result has invalid value: {result!r}")
|
|
171
|
-
findings = _require_count(data, "findings")
|
|
172
|
-
accepted = _require_count(data, "accepted")
|
|
173
|
-
rejected = _require_count(data, "rejected")
|
|
174
|
-
accepted_high = _require_count(data, "accepted_high")
|
|
175
|
-
if accepted + rejected != findings or accepted_high > accepted:
|
|
176
|
-
raise ReportStateError("reviewer finding counts are inconsistent")
|
|
177
|
-
status = "BLOCKED" if result == "BLOCKED" else "COMPLETED"
|
|
178
|
-
return "\n".join(
|
|
179
|
-
[
|
|
180
|
-
f"## Independent Reviewer {reviewer} Result",
|
|
181
|
-
"",
|
|
182
|
-
f"- Status: {status}",
|
|
183
|
-
f"- Result: {result}",
|
|
184
|
-
f"- Findings: {findings}",
|
|
185
|
-
f"- Accepted: {accepted}",
|
|
186
|
-
f"- Rejected: {rejected}",
|
|
187
|
-
f"- Accepted High: {accepted_high}",
|
|
188
|
-
f"- Next: {_require_text(data, 'next')}",
|
|
189
|
-
]
|
|
190
|
-
)
|
|
191
|
-
|
|
192
|
-
if event == "infrastructure-failure":
|
|
193
|
-
reviewer = _require_count(data, "reviewer", maximum=2)
|
|
194
|
-
attempt = _require_count(data, "attempt", maximum=2)
|
|
195
|
-
if reviewer < 1 or attempt < 1:
|
|
196
|
-
raise ReportStateError("reviewer and attempt must be at least 1")
|
|
197
|
-
return "\n".join(
|
|
198
|
-
[
|
|
199
|
-
f"## Independent Reviewer {reviewer} Infrastructure Failure",
|
|
200
|
-
"",
|
|
201
|
-
f"- Attempt: {attempt}",
|
|
202
|
-
f"- Evidence: {_require_text(data, 'evidence')}",
|
|
203
|
-
f"- Next: {_require_text(data, 'next')}",
|
|
204
|
-
]
|
|
205
|
-
)
|
|
206
|
-
|
|
114
|
+
status = _require_text(data, "status")
|
|
115
|
+
if status not in {"COMPLETED", "FAILED"}:
|
|
116
|
+
raise ReportStateError(f"status has invalid value: {status!r}")
|
|
207
117
|
return "\n".join(
|
|
208
118
|
[
|
|
209
119
|
"## Final Verification",
|
|
210
120
|
"",
|
|
211
|
-
f"- Status: {
|
|
121
|
+
f"- Status: {status}",
|
|
212
122
|
f"- Evidence: {_require_text(data, 'evidence')}",
|
|
213
123
|
]
|
|
214
124
|
)
|
|
@@ -227,28 +137,28 @@ def append_final_result(path: Path, data: Any) -> None:
|
|
|
227
137
|
verdict = valid.get("verdict")
|
|
228
138
|
if verdict not in VERDICTS:
|
|
229
139
|
raise ReportStateError(f"verdict has invalid value: {verdict!r}")
|
|
230
|
-
risk = _require_risk(valid)
|
|
231
140
|
main_rounds = _require_count(valid, "main_review_rounds", maximum=10)
|
|
232
|
-
reviewers = _require_count(valid, "independent_reviewers_started", maximum=2)
|
|
233
|
-
if reviewers > {"low": 0, "medium": 1, "high": 2}[risk]:
|
|
234
|
-
raise ReportStateError("independent_reviewers_started exceeds risk limit")
|
|
235
141
|
accepted = _require_count(valid, "accepted_findings")
|
|
236
142
|
fixed = _require_count(valid, "fixed_findings")
|
|
237
143
|
rejected = _require_count(valid, "rejected_findings")
|
|
238
144
|
unresolved = _require_count(valid, "unresolved_findings")
|
|
239
|
-
if
|
|
240
|
-
raise ReportStateError("
|
|
241
|
-
if verdict == "
|
|
242
|
-
raise ReportStateError(
|
|
145
|
+
if fixed > accepted:
|
|
146
|
+
raise ReportStateError("fixed_findings cannot exceed accepted_findings")
|
|
147
|
+
if verdict == "PASS" and (unresolved or fixed != accepted):
|
|
148
|
+
raise ReportStateError(
|
|
149
|
+
"PASS requires every accepted finding fixed and no unresolved findings"
|
|
150
|
+
)
|
|
151
|
+
if verdict == "NEEDS_FIXES" and not unresolved and fixed == accepted:
|
|
152
|
+
raise ReportStateError(
|
|
153
|
+
"NEEDS_FIXES requires an unfixed accepted or unresolved finding"
|
|
154
|
+
)
|
|
243
155
|
|
|
244
156
|
section = "\n".join(
|
|
245
157
|
[
|
|
246
158
|
FINAL_HEADING,
|
|
247
159
|
"",
|
|
248
160
|
f"- Verdict: {verdict}",
|
|
249
|
-
f"- Risk: {risk}",
|
|
250
161
|
f"- Main Review Rounds: {main_rounds}",
|
|
251
|
-
f"- Independent Reviewers Started: {reviewers}",
|
|
252
162
|
f"- Accepted Findings: {accepted}",
|
|
253
163
|
f"- Fixed Findings: {fixed}",
|
|
254
164
|
f"- Rejected Findings: {rejected}",
|
package/package.json
CHANGED
package/src/manifest.js
CHANGED
|
@@ -19,6 +19,7 @@ const MANIFEST_DIR = '.prizmkit';
|
|
|
19
19
|
* Read the manifest from a project directory.
|
|
20
20
|
* @param {string} projectRoot
|
|
21
21
|
* @returns {Promise<Object|null>} parsed manifest or null if not found
|
|
22
|
+
* @throws {Error} when a present manifest cannot be read or parsed
|
|
22
23
|
*/
|
|
23
24
|
export async function readManifest(projectRoot) {
|
|
24
25
|
const manifestPath = path.join(projectRoot, MANIFEST_DIR, MANIFEST_FILE);
|
|
@@ -26,9 +27,13 @@ export async function readManifest(projectRoot) {
|
|
|
26
27
|
return null;
|
|
27
28
|
}
|
|
28
29
|
try {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
30
|
+
const manifest = await fs.readJSON(manifestPath);
|
|
31
|
+
if (manifest === null || Array.isArray(manifest) || typeof manifest !== 'object') {
|
|
32
|
+
throw new TypeError('manifest root must be a JSON object');
|
|
33
|
+
}
|
|
34
|
+
return manifest;
|
|
35
|
+
} catch (error) {
|
|
36
|
+
throw new Error(`Failed to read PrizmKit manifest at ${manifestPath}: ${error.message}`, { cause: error });
|
|
32
37
|
}
|
|
33
38
|
}
|
|
34
39
|
|
package/src/scaffold.js
CHANGED
|
@@ -81,6 +81,7 @@ const RETIRED_POWERSHELL_RUNTIME_FILES = new Set([
|
|
|
81
81
|
'lib/heartbeat.ps1',
|
|
82
82
|
]);
|
|
83
83
|
const LEGACY_TEAM_NAME = ['prizm', 'dev', 'team'].join('-');
|
|
84
|
+
const RETIRED_CODE_REVIEW_AGENT_BASENAME = 'prizmkit-code-reviewer';
|
|
84
85
|
const LEGACY_AGENT_BASENAMES = [
|
|
85
86
|
`${LEGACY_TEAM_NAME}-dev`,
|
|
86
87
|
`${LEGACY_TEAM_NAME}-reviewer`,
|
|
@@ -102,7 +103,10 @@ export async function removeRetiredAgentTeamArtifacts(platform, projectRoot, dry
|
|
|
102
103
|
: path.join(projectRoot, '.codebuddy', 'agents');
|
|
103
104
|
const agentExtensions = platform === 'codex' ? ['.toml', '.md'] : ['.md'];
|
|
104
105
|
|
|
105
|
-
|
|
106
|
+
const retiredBasenames = platform === 'claude'
|
|
107
|
+
? [...LEGACY_AGENT_BASENAMES, RETIRED_CODE_REVIEW_AGENT_BASENAME]
|
|
108
|
+
: LEGACY_AGENT_BASENAMES;
|
|
109
|
+
for (const basename of retiredBasenames) {
|
|
106
110
|
for (const extension of agentExtensions) {
|
|
107
111
|
const filePath = path.join(agentDir, `${basename}${extension}`);
|
|
108
112
|
if (!await fs.pathExists(filePath)) continue;
|
|
@@ -226,12 +230,10 @@ export async function installSkills(platform, skills, projectRoot, dryRun, runti
|
|
|
226
230
|
|
|
227
231
|
// Load Claude command adapter for skill conversion
|
|
228
232
|
let convertSkillToCommand;
|
|
229
|
-
let getClaudeSkillAgentDefinitions;
|
|
230
233
|
let convertSkillToCodex;
|
|
231
234
|
if (platform === 'claude') {
|
|
232
235
|
const commandAdapter = await loadAdapter('claude', 'command-adapter.js');
|
|
233
236
|
convertSkillToCommand = commandAdapter.convertSkillToCommand;
|
|
234
|
-
getClaudeSkillAgentDefinitions = commandAdapter.getClaudeSkillAgentDefinitions;
|
|
235
237
|
} else if (platform === 'codex') {
|
|
236
238
|
const codexSkillAdapter = await loadAdapter('codex', 'skill-adapter.js');
|
|
237
239
|
convertSkillToCodex = codexSkillAdapter.convertSkill;
|
|
@@ -323,19 +325,6 @@ export async function installSkills(platform, skills, projectRoot, dryRun, runti
|
|
|
323
325
|
await fs.copy(path.join(corePath, subdir), path.join(assetTargetDir, subdir));
|
|
324
326
|
}
|
|
325
327
|
}
|
|
326
|
-
|
|
327
|
-
const roleManifestPath = path.join(corePath, 'assets', 'reviewer-role.json');
|
|
328
|
-
const roleManifest = await fs.pathExists(roleManifestPath)
|
|
329
|
-
? await fs.readJson(roleManifestPath)
|
|
330
|
-
: null;
|
|
331
|
-
const agentDefinitions = getClaudeSkillAgentDefinitions(skillName, roleManifest);
|
|
332
|
-
if (agentDefinitions.length > 0) {
|
|
333
|
-
const agentsDir = path.join(projectRoot, '.claude', 'agents');
|
|
334
|
-
await fs.ensureDir(agentsDir);
|
|
335
|
-
for (const definition of agentDefinitions) {
|
|
336
|
-
await fs.writeFile(path.join(agentsDir, definition.fileName), definition.content);
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
328
|
console.log(chalk.green(` ✓ .claude/commands/${skillName}.md`));
|
|
340
329
|
} else if (platform === 'codex') {
|
|
341
330
|
const content = await fs.readFile(skillMdPath, 'utf8');
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"protocol_version": 2,
|
|
3
|
-
"role_name": "prizmkit-code-reviewer",
|
|
4
|
-
"description": "Use only as the one fresh independent read-only Reviewer for a completed /prizmkit-code-review round.",
|
|
5
|
-
"observational_capabilities": [
|
|
6
|
-
"read-files",
|
|
7
|
-
"search-content",
|
|
8
|
-
"search-paths"
|
|
9
|
-
],
|
|
10
|
-
"unavailable_capabilities": [
|
|
11
|
-
"workspace-mutation",
|
|
12
|
-
"shell-execution",
|
|
13
|
-
"downstream-execution-creation",
|
|
14
|
-
"delegation-equivalent-behavior",
|
|
15
|
-
"orchestration-reentry",
|
|
16
|
-
"skill-invocation"
|
|
17
|
-
],
|
|
18
|
-
"execution_mode": "foreground-independent-review"
|
|
19
|
-
}
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
# Reviewer Prompt Contract
|
|
2
|
-
|
|
3
|
-
Use this complete template for every Reviewer execution. Fill the documented placeholders with current-round context. Do not include previous-round findings, verdicts, filtering decisions, rejection reasons, or repair explanations.
|
|
4
|
-
|
|
5
|
-
```text
|
|
6
|
-
You are the sole independent read-only Reviewer for this round of `/prizmkit-code-review`.
|
|
7
|
-
|
|
8
|
-
## Execution Boundary
|
|
9
|
-
|
|
10
|
-
Perform the complete review yourself.
|
|
11
|
-
|
|
12
|
-
Do not create, schedule, resume, continue, request, or coordinate any separate downstream execution unit. Do not re-enter orchestration, invoke a skill, delegate review work, or ask the Main Agent to create a helper.
|
|
13
|
-
|
|
14
|
-
Do not modify, create, delete, rename, stage, or commit workspace files. Use only read-only inspection capabilities.
|
|
15
|
-
|
|
16
|
-
If you cannot complete the review in this execution context, return `BLOCKED` with the missing capability or context. Do not delegate and do not return a partial `PASS`.
|
|
17
|
-
|
|
18
|
-
## Independent Input Boundary
|
|
19
|
-
|
|
20
|
-
Review only the current state supplied below. No previous-round findings, verdicts, filtering decisions, rejection reasons, repair descriptions, or Reviewer reasoning are part of your input.
|
|
21
|
-
|
|
22
|
-
## Goals and Acceptance Criteria
|
|
23
|
-
|
|
24
|
-
{goals and acceptance criteria from spec.md, or "No spec artifact found; infer the requested behavior from the user goal and current change."}
|
|
25
|
-
|
|
26
|
-
## Plan and Intended Change
|
|
27
|
-
|
|
28
|
-
{relevant architecture decisions and completed tasks from plan.md, or a concise current task description}
|
|
29
|
-
|
|
30
|
-
## Applicable Rules and Contracts
|
|
31
|
-
|
|
32
|
-
{relevant Prizm docs, project rules, public and internal contracts, or "No additional project rules identified."}
|
|
33
|
-
|
|
34
|
-
## Test Evidence
|
|
35
|
-
|
|
36
|
-
{current scoped test evidence, or "No scoped test report found."}
|
|
37
|
-
|
|
38
|
-
## Current Change
|
|
39
|
-
|
|
40
|
-
- Repository and Reviewer-visible checkout: {path or platform-visible location}
|
|
41
|
-
- Base revision: {base revision when known}
|
|
42
|
-
- Changed paths and states: {staged, unstaged, untracked, deleted, and renamed inventory}
|
|
43
|
-
- Review access: {active checkout, or forced worktree used only for baseline and surrounding context}
|
|
44
|
-
|
|
45
|
-
## Supplied Git Diff
|
|
46
|
-
|
|
47
|
-
### Staged
|
|
48
|
-
|
|
49
|
-
{complete staged diff, or "No staged changes."}
|
|
50
|
-
|
|
51
|
-
### Unstaged
|
|
52
|
-
|
|
53
|
-
{complete unstaged diff, or "No unstaged tracked changes."}
|
|
54
|
-
|
|
55
|
-
## Supplied Untracked Files
|
|
56
|
-
|
|
57
|
-
{path and full content of every untracked file, or "No untracked files."}
|
|
58
|
-
|
|
59
|
-
Treat the supplied diffs, path states, and untracked file contents as the authoritative current change. Use read-only file inspection for targeted surrounding context, callers, dependents, contracts, and tests. Do not depend on shell or Git execution being available.
|
|
60
|
-
|
|
61
|
-
If a platform-forced worktree does not contain the active checkout's dirty or untracked changes, use the worktree only for baseline and surrounding-context reads. You are not required to calculate hashes or prove equivalence between physical checkouts. If an essential changed file or diff is missing from the supplied input, return `BLOCKED` and identify exactly what is missing.
|
|
62
|
-
|
|
63
|
-
## Complete Current-Change Review
|
|
64
|
-
|
|
65
|
-
Review the complete current change independently. Do not limit inspection to one file or one suspected issue.
|
|
66
|
-
|
|
67
|
-
Evaluate applicable dimensions:
|
|
68
|
-
|
|
69
|
-
1. Requirement and acceptance-criteria alignment
|
|
70
|
-
2. Implementation completeness
|
|
71
|
-
3. Correctness and concrete failure scenarios
|
|
72
|
-
4. Error handling
|
|
73
|
-
5. Security and authorization
|
|
74
|
-
6. Data integrity
|
|
75
|
-
7. Transaction and concurrency behavior
|
|
76
|
-
8. Public and internal contracts
|
|
77
|
-
9. Backward compatibility and regression risks
|
|
78
|
-
10. Test adequacy and evidence compatibility
|
|
79
|
-
11. Project-rule compliance
|
|
80
|
-
|
|
81
|
-
Use both directions in this review:
|
|
82
|
-
|
|
83
|
-
- Code-forward: changed code → affected symbols → callers and dependents → concrete failure scenarios
|
|
84
|
-
- Requirement-backward: requirements and contracts → required behavior → implementation path → side effects → test evidence
|
|
85
|
-
|
|
86
|
-
Read unchanged callers, dependents, shared patterns, or tests when needed. Prefer targeted read-only inspection. Do not perform a broad repository scan without a concrete cross-cutting reason.
|
|
87
|
-
|
|
88
|
-
## Finding Standard
|
|
89
|
-
|
|
90
|
-
Report every concrete defect you find, including low-severity issues. Exclude pure style preferences and speculative concerns that lack a concrete wrong behavior, contract violation, regression path, security weakness, data-integrity risk, or misleading test result.
|
|
91
|
-
|
|
92
|
-
## Output Contract
|
|
93
|
-
|
|
94
|
-
Respond with exactly this structure:
|
|
95
|
-
|
|
96
|
-
### Result: PASS | FINDINGS | BLOCKED
|
|
97
|
-
|
|
98
|
-
### Findings
|
|
99
|
-
|
|
100
|
-
If the result is `PASS`, write:
|
|
101
|
-
|
|
102
|
-
No issues found.
|
|
103
|
-
|
|
104
|
-
If the result is `BLOCKED`, write only the missing capability or essential context and the required action.
|
|
105
|
-
|
|
106
|
-
If the result is `FINDINGS`, repeat this block for every concrete issue:
|
|
107
|
-
|
|
108
|
-
#### Finding N: <short title>
|
|
109
|
-
- Severity: high | medium | low
|
|
110
|
-
- Location: filepath:line (or "project-level")
|
|
111
|
-
- Problem: concrete wrong behavior and why it matters
|
|
112
|
-
- Failure scenario: inputs or state that produce the wrong result
|
|
113
|
-
- Reasoning: concise evidence connecting the current code to the failure
|
|
114
|
-
- Suggested repair: smallest safe repair approach
|
|
115
|
-
- Verification: how to prove the repair
|
|
116
|
-
|
|
117
|
-
### Summary
|
|
118
|
-
|
|
119
|
-
One or two sentences describing the current change and result. Do not expose private reasoning traces.
|
|
120
|
-
```
|