@webpresso/claude-plugin 3.1.10 → 3.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/package.json +2 -1
- package/plugin-skill-ownership.json +77 -0
- package/skills/claude/SKILL.md +51 -99
- package/skills/codex/SKILL.md +27 -1
- package/skills/opencode-go/SKILL.md +54 -55
- package/skills/verify/SKILL.md +4 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Webpresso agent-kit Claude Code plugin: blueprints, skills, hooks, MCP server",
|
|
9
|
-
"version": "3.1.
|
|
9
|
+
"version": "3.1.12"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
@@ -34,5 +34,5 @@
|
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
36
|
],
|
|
37
|
-
"version": "3.1.
|
|
37
|
+
"version": "3.1.12"
|
|
38
38
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpresso/claude-plugin",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.12",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Claude Code plugin adapter for Webpresso agent-kit skills, commands, and MCP runtime.",
|
|
6
6
|
"homepage": "https://github.com/webpresso/agent-kit#readme",
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"files": [
|
|
17
17
|
".claude-plugin",
|
|
18
|
+
"plugin-skill-ownership.json",
|
|
18
19
|
"skills",
|
|
19
20
|
"commands",
|
|
20
21
|
"bin/wp",
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"host": "claude",
|
|
4
|
+
"packageName": "@webpresso/claude-plugin",
|
|
5
|
+
"packageVersion": "3.1.12",
|
|
6
|
+
"runtimeDirs": [
|
|
7
|
+
".claude/skills"
|
|
8
|
+
],
|
|
9
|
+
"skills": {
|
|
10
|
+
"autopilot": {
|
|
11
|
+
"digest": "sha256:7fc1fe9f5fb5b8a3e755f8e3ac4b807e4f140288544ffcf39e4cbfdea984014d"
|
|
12
|
+
},
|
|
13
|
+
"best-practice-research": {
|
|
14
|
+
"digest": "sha256:b0d355c7f4afe9c38be83e293788bf582bea068c1db2fa5c45400441e315735d"
|
|
15
|
+
},
|
|
16
|
+
"browse": {
|
|
17
|
+
"digest": "sha256:21fd24862e7f7c8a1feadea6bc376492b136b99fc381cf1b8927c9db80615431"
|
|
18
|
+
},
|
|
19
|
+
"claude": {
|
|
20
|
+
"digest": "sha256:b75a472594d78bd9452c07fd791a426864848a2c9c726454dc72daf3813ae22b"
|
|
21
|
+
},
|
|
22
|
+
"codex": {
|
|
23
|
+
"digest": "sha256:803cea9c1b37406d7bdc8e44e9d5e9f3988218277500d8d6cb0d955c933c3302"
|
|
24
|
+
},
|
|
25
|
+
"deep-research": {
|
|
26
|
+
"digest": "sha256:01dafd194066a2936db0b437fd5c3beef6d7ff82478d0d995393093d89496f18"
|
|
27
|
+
},
|
|
28
|
+
"design-review": {
|
|
29
|
+
"digest": "sha256:5b213735e2842568774572f36b198bccf03c03a54b2732484aadd023f04acb23"
|
|
30
|
+
},
|
|
31
|
+
"devex-review": {
|
|
32
|
+
"digest": "sha256:306355888da0827e3523022077f731845726bbaaf595ca12515cc91d8605b5e6"
|
|
33
|
+
},
|
|
34
|
+
"fix": {
|
|
35
|
+
"digest": "sha256:e43dfad198f7279ebc2dca9e62f43fd960c783ca0ab25f133668fca13aed96b2"
|
|
36
|
+
},
|
|
37
|
+
"goal": {
|
|
38
|
+
"digest": "sha256:85380b633cfaaff8ec1639dd3a88412a41920aae3e8531de95e2b79411926a18"
|
|
39
|
+
},
|
|
40
|
+
"hooks-doctor": {
|
|
41
|
+
"digest": "sha256:3bfb0af64ff6796c56d51e4cd2bede7fb24c869f89b292546ea13ad2f5d3bb73"
|
|
42
|
+
},
|
|
43
|
+
"lore-protocol": {
|
|
44
|
+
"digest": "sha256:a80fbacc765e8b886437b9fdf7dd71e1ceb1b98b939078ec90fc88d06a8b4c69"
|
|
45
|
+
},
|
|
46
|
+
"opencode-go": {
|
|
47
|
+
"digest": "sha256:ccb2bcf09cc1c5c0d54027b84f580e688f5f5cf624e6cdc19870bd3ce99940fc"
|
|
48
|
+
},
|
|
49
|
+
"plan-ceo-review": {
|
|
50
|
+
"digest": "sha256:4d426158518dd71f8998770e8d4037bcbfa3c65d7265a93a4a78a9b015ba881e"
|
|
51
|
+
},
|
|
52
|
+
"plan-design-review": {
|
|
53
|
+
"digest": "sha256:a8a33efe67844d0602ff595c0b7e8f5529e52f51a781112952636c91963ce19e"
|
|
54
|
+
},
|
|
55
|
+
"plan-devex-review": {
|
|
56
|
+
"digest": "sha256:a49b4f61f1c54a7d89111c270616684dcbf2a7236bc817fafb5919366a7cda31"
|
|
57
|
+
},
|
|
58
|
+
"plan-eng-review": {
|
|
59
|
+
"digest": "sha256:b728dad90254d4c9f81b3818321d34ab53519b79ce20ff3bfe08bfacb2aa3e86"
|
|
60
|
+
},
|
|
61
|
+
"plan-refine": {
|
|
62
|
+
"digest": "sha256:891e84ff8592b8489b59e8642f6a602c9558fd57edd171af98499c94e2f62f13"
|
|
63
|
+
},
|
|
64
|
+
"tech-debt": {
|
|
65
|
+
"digest": "sha256:8b1f30e55ec6e5ab185ff19ecf15384438dbd619f675c2c65f2e53cedecbae5c"
|
|
66
|
+
},
|
|
67
|
+
"testing-philosophy": {
|
|
68
|
+
"digest": "sha256:43fa05bcb7eaf8efd4a8dcc0f9fb9c30ae9f80079d9b3dbfdc926734a64a2973"
|
|
69
|
+
},
|
|
70
|
+
"tph": {
|
|
71
|
+
"digest": "sha256:bed3684a850651534f315d355cdeae50d951c429817df0f105cccdb7f4e1561b"
|
|
72
|
+
},
|
|
73
|
+
"verify": {
|
|
74
|
+
"digest": "sha256:b088b138a985f94e29970edac1bcae70b29b15b5b3573787652ad590b789c9c7"
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
package/skills/claude/SKILL.md
CHANGED
|
@@ -38,6 +38,19 @@ PROMPT_FILE=$(mktemp -t wp-claude-review.XXXXXX)
|
|
|
38
38
|
trap 'rm -f "$PROMPT_FILE"' EXIT
|
|
39
39
|
```
|
|
40
40
|
|
|
41
|
+
## Dashboard helper relation
|
|
42
|
+
|
|
43
|
+
When this skill is invoked from `wp dash`, create explicit lifecycle records around the outside-voice call. The shared `wp dash-helper-*` service owns the event JSON and report shape; do not duplicate it in a skill. Outside the dashboard the block is a no-op, preserving standalone calls.
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
DASH_HELPER_RUN_ID=""
|
|
47
|
+
if [ "${WP_DASH:-}" = "1" ] && [ -n "${WP_DASH_RUN_ID:-}" ]; then
|
|
48
|
+
DASH_HELPER_RUN_ID=$(wp dash-helper-start --provider claude --role reviewer)
|
|
49
|
+
fi
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Claude's managed native subagent lifecycle does not provide a reliable parent-linked completion event. It remains explicitly unsupported rather than being inferred from transcript text or timing.
|
|
53
|
+
|
|
41
54
|
## Modes
|
|
42
55
|
|
|
43
56
|
### Review
|
|
@@ -77,116 +90,55 @@ TARGET_FILE=${TARGET_FILE:?set TARGET_FILE to one changed file}
|
|
|
77
90
|
} >"$PROMPT_FILE"
|
|
78
91
|
```
|
|
79
92
|
|
|
80
|
-
####
|
|
93
|
+
#### Progress-aware review runtime
|
|
81
94
|
|
|
82
|
-
Run
|
|
83
|
-
|
|
84
|
-
- it defaults to `CLAUDE_REVIEW_MODEL=sonnet` and allows only `opus` or `sonnet`
|
|
85
|
-
- it never passes `--tools ""`, because Claude's variadic `--tools` option can swallow the prompt
|
|
86
|
-
- it captures stdout and stderr for preflight and the full review
|
|
87
|
-
- it writes the artifact on success, non-zero exit, or timeout
|
|
88
|
-
- it runs one full review attempt only; retry only if you change the command shape for a specific diagnosed reason
|
|
89
|
-
|
|
90
|
-
Preflight must be only the tiny `claude-ok` prompt with the selected model. Do not use the real review prompt for preflight.
|
|
95
|
+
Run both the availability probe and the full review through the typed `wp review run` owner. Skills must not embed subprocess supervision. The runtime consumes Claude's streaming JSON events, advances its idle clock only on monotonic semantic progress, and has no total wall-clock cutoff.
|
|
91
96
|
|
|
92
97
|
```bash
|
|
93
98
|
CLAUDE_REVIEW_MODEL=${CLAUDE_REVIEW_MODEL:-sonnet}
|
|
94
99
|
CLAUDE_REVIEW_EFFORT=${CLAUDE_REVIEW_EFFORT:-medium}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
def write_artifact(status: str, exit_code: int) -> None:
|
|
124
|
-
artifact.update({"finishedAt": utc_now(), "status": status, "exitCode": exit_code})
|
|
125
|
-
artifact_path.parent.mkdir(parents=True, exist_ok=True)
|
|
126
|
-
artifact_path.write_text(json.dumps(artifact, indent=2) + "\n", encoding="utf-8")
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
def as_text(value: str | bytes | None) -> str:
|
|
130
|
-
return value.decode(errors="replace") if isinstance(value, bytes) else (value or "")
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
def run_claude(stage: str, prompt: str, timeout_seconds: float, timeout_kind: str) -> int:
|
|
134
|
-
command = ["claude", "--print", "--model", model, "--effort", effort, prompt]
|
|
135
|
-
started = last_progress = time.monotonic()
|
|
136
|
-
last_progress_at = utc_now()
|
|
137
|
-
out = err = ""
|
|
138
|
-
record: dict[str, object] = {"stage": stage, "command": [*command[:-1], "<prompt>"], "timeoutKind": timeout_kind, "timeoutSeconds": timeout_seconds, "idleTimeoutSeconds": timeout_seconds if timeout_kind == "idle" else None, "startedAt": last_progress_at}
|
|
139
|
-
try:
|
|
140
|
-
process = subprocess.Popen(command, text=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
|
141
|
-
while True:
|
|
142
|
-
try:
|
|
143
|
-
new_out, new_err = process.communicate(timeout=0.5)
|
|
144
|
-
out, err = as_text(new_out), as_text(new_err)
|
|
145
|
-
code = int(process.returncode)
|
|
146
|
-
timed_out = False
|
|
147
|
-
break
|
|
148
|
-
except subprocess.TimeoutExpired as exc:
|
|
149
|
-
new_out, new_err = as_text(exc.stdout), as_text(exc.stderr)
|
|
150
|
-
if new_out != out or new_err != err:
|
|
151
|
-
out, err, last_progress, last_progress_at = new_out, new_err, time.monotonic(), utc_now()
|
|
152
|
-
reference = last_progress if timeout_kind == "idle" else started
|
|
153
|
-
if time.monotonic() - reference > timeout_seconds:
|
|
154
|
-
process.kill()
|
|
155
|
-
final_out, final_err = process.communicate()
|
|
156
|
-
out += as_text(final_out)[len(out):]
|
|
157
|
-
err += as_text(final_err)[len(err):]
|
|
158
|
-
code, timed_out = 124, True
|
|
159
|
-
break
|
|
160
|
-
except OSError as exc:
|
|
161
|
-
out, err, code, timed_out = "", str(exc), 1, False
|
|
162
|
-
record.update({"exitCode": code, "timedOut": timed_out, "stdout": out, "stderr": err, "finishedAt": utc_now(), "lastProgressAt": last_progress_at, "elapsedSeconds": round(time.monotonic() - started, 3)})
|
|
163
|
-
artifact["runs"].append(record)
|
|
164
|
-
return code
|
|
165
|
-
|
|
166
|
-
preflight_code = run_claude("preflight", "claude-ok", preflight_timeout, "wall-clock")
|
|
167
|
-
if preflight_code != 0:
|
|
168
|
-
write_artifact("preflight-timeout" if preflight_code == 124 else "preflight-failed", preflight_code)
|
|
169
|
-
print(f"CLAUDE_REVIEW_PREFLIGHT_EXIT={preflight_code}", file=sys.stderr)
|
|
170
|
-
print(f"CLAUDE_REVIEW_ARTIFACT={artifact_path}", file=sys.stderr)
|
|
171
|
-
raise SystemExit(preflight_code)
|
|
172
|
-
review_code = run_claude("review", prompt_path.read_text(encoding="utf-8"), review_idle_timeout, "idle")
|
|
173
|
-
write_artifact("idle-timeout" if review_code == 124 else ("success" if review_code == 0 else "failed"), review_code)
|
|
174
|
-
print(f"CLAUDE_REVIEW_EXIT={review_code}", file=sys.stderr)
|
|
175
|
-
print(f"CLAUDE_REVIEW_ARTIFACT={artifact_path}", file=sys.stderr)
|
|
176
|
-
raise SystemExit(review_code)
|
|
177
|
-
PY
|
|
100
|
+
CLAUDE_REVIEW_PROBE_IDLE_SECONDS=${CLAUDE_REVIEW_PROBE_IDLE_SECONDS:-180}
|
|
101
|
+
CLAUDE_REVIEW_IDLE_SECONDS=${CLAUDE_REVIEW_IDLE_SECONDS:-180}
|
|
102
|
+
CLAUDE_REVIEW_ARTIFACT_ROOT=${CLAUDE_REVIEW_ARTIFACT_ROOT:-"$(pwd)/.webpresso/reviews"}
|
|
103
|
+
PROBE_FILE=$(mktemp -t wp-claude-probe.XXXXXX)
|
|
104
|
+
trap 'rm -f "$PROMPT_FILE" "$PROBE_FILE"' EXIT
|
|
105
|
+
printf 'Reply exactly CLAUDE_OK.\n' >"$PROBE_FILE"
|
|
106
|
+
|
|
107
|
+
wp review run \
|
|
108
|
+
--provider claude \
|
|
109
|
+
--prompt-file "$PROBE_FILE" \
|
|
110
|
+
--model "$CLAUDE_REVIEW_MODEL" \
|
|
111
|
+
--effort "$CLAUDE_REVIEW_EFFORT" \
|
|
112
|
+
--stage probe \
|
|
113
|
+
--expected-marker CLAUDE_OK \
|
|
114
|
+
--artifact-root "$CLAUDE_REVIEW_ARTIFACT_ROOT" \
|
|
115
|
+
--idle-seconds "$CLAUDE_REVIEW_PROBE_IDLE_SECONDS"
|
|
116
|
+
|
|
117
|
+
wp review run \
|
|
118
|
+
--provider claude \
|
|
119
|
+
--prompt-file "$PROMPT_FILE" \
|
|
120
|
+
--model "$CLAUDE_REVIEW_MODEL" \
|
|
121
|
+
--effort "$CLAUDE_REVIEW_EFFORT" \
|
|
122
|
+
--stage review \
|
|
123
|
+
--artifact-root "$CLAUDE_REVIEW_ARTIFACT_ROOT" \
|
|
124
|
+
--idle-seconds "$CLAUDE_REVIEW_IDLE_SECONDS"
|
|
125
|
+
CLAUDE_REVIEW_CODE=$?
|
|
178
126
|
```
|
|
179
127
|
|
|
180
|
-
After the
|
|
128
|
+
After the review runtime exits, emit its terminal state using the same artifact path:
|
|
181
129
|
|
|
182
130
|
```bash
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
131
|
+
if [ -n "$DASH_HELPER_RUN_ID" ]; then
|
|
132
|
+
if [ "$CLAUDE_REVIEW_CODE" -eq 0 ]; then
|
|
133
|
+
wp dash-helper-complete --provider claude --run-id "$DASH_HELPER_RUN_ID" --role reviewer --outcome completed --artifact "${CLAUDE_REVIEW_ARTIFACT:-}"
|
|
134
|
+
else
|
|
135
|
+
wp dash-helper-complete --provider claude --run-id "$DASH_HELPER_RUN_ID" --role reviewer --outcome failed --artifact "${CLAUDE_REVIEW_ARTIFACT:-}"
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
188
138
|
```
|
|
189
139
|
|
|
140
|
+
Treat `true-idle`, `protocol-unsupported`, provider failure, abort, spawn failure, or artifact failure as unavailable review evidence. Never replace them with a static timeout, arbitrary byte-growth heartbeat, or buffered-output fallback.
|
|
141
|
+
|
|
190
142
|
#### Retry policy
|
|
191
143
|
|
|
192
144
|
Do not perform blind retries. Run the full review once. Retry only after diagnosing and changing a command-shape problem; record the reason and artifact path. Do not fall back to an unbounded whole-PR prompt.
|
package/skills/codex/SKILL.md
CHANGED
|
@@ -25,6 +25,31 @@ PROMPT_FILE=$(mktemp -t wp-codex-review.XXXXXX)
|
|
|
25
25
|
trap 'rm -f "$PROMPT_FILE"' EXIT
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
+
## Dashboard helper relation
|
|
29
|
+
|
|
30
|
+
When called by `wp dash`, register the outside-voice helper through the shared service rather than writing relationship JSON in this skill. This is intentionally a no-op for standalone use.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
DASH_HELPER_RUN_ID=""
|
|
34
|
+
if [ "${WP_DASH:-}" = "1" ] && [ -n "${WP_DASH_RUN_ID:-}" ]; then
|
|
35
|
+
DASH_HELPER_RUN_ID=$(wp dash-helper-start --provider codex --role reviewer)
|
|
36
|
+
fi
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
After the review command completes, report the exact terminal outcome. Supply an artifact path when the caller created one.
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
if [ -n "$DASH_HELPER_RUN_ID" ]; then
|
|
43
|
+
if [ "${CODEX_REVIEW_CODE:-0}" -eq 0 ]; then
|
|
44
|
+
wp dash-helper-complete --provider codex --run-id "$DASH_HELPER_RUN_ID" --role reviewer --outcome completed --artifact "${CODEX_REVIEW_ARTIFACT:-}"
|
|
45
|
+
else
|
|
46
|
+
wp dash-helper-complete --provider codex --run-id "$DASH_HELPER_RUN_ID" --role reviewer --outcome failed --artifact "${CODEX_REVIEW_ARTIFACT:-}"
|
|
47
|
+
fi
|
|
48
|
+
fi
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Codex native subagent events are not currently parent-linked in the managed lifecycle. They are shown as unsupported, never inferred from text, PIDs, or timestamps.
|
|
52
|
+
|
|
28
53
|
## Modes
|
|
29
54
|
|
|
30
55
|
### Review
|
|
@@ -39,7 +64,8 @@ case "$CODEX_REVIEW_EFFORT" in
|
|
|
39
64
|
medium|high) ;;
|
|
40
65
|
*) echo "CODEX_REVIEW_EFFORT must be one of: medium, high" >&2; exit 2 ;;
|
|
41
66
|
esac
|
|
42
|
-
|
|
67
|
+
CODEX_REVIEW_CODE=0
|
|
68
|
+
codex exec -c model_reasoning_effort="\"$CODEX_REVIEW_EFFORT\"" --sandbox read-only --cd "$PWD" - <"$PROMPT_FILE" || CODEX_REVIEW_CODE=$?
|
|
43
69
|
```
|
|
44
70
|
|
|
45
71
|
4. Summarize findings with severity, evidence, and whether you independently verified them.
|
|
@@ -28,6 +28,32 @@ PROMPT_FILE=$(mktemp -t wp-opencode-go-review.XXXXXX)
|
|
|
28
28
|
trap 'rm -f "$PROMPT_FILE"' EXIT
|
|
29
29
|
```
|
|
30
30
|
|
|
31
|
+
## Dashboard helper relation
|
|
32
|
+
|
|
33
|
+
When `wp dash` provides dashboard context, use the shared helper emitter around this outside-voice review. The commands leave standalone OpenCode Go reviews unchanged.
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
DASH_HELPER_RUN_ID=""
|
|
37
|
+
if [ "${WP_DASH:-}" = "1" ] && [ -n "${WP_DASH_RUN_ID:-}" ]; then
|
|
38
|
+
DASH_HELPER_RUN_ID=$(wp dash-helper-start --provider opencode-go --role reviewer --artifact "${OPENCODE_GO_REVIEW_ARTIFACT:-}")
|
|
39
|
+
fi
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
After the review runtime exits, record its actual result and optional artifact:
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
OPENCODE_GO_REVIEW_CODE=$?
|
|
46
|
+
if [ -n "$DASH_HELPER_RUN_ID" ]; then
|
|
47
|
+
if [ "$OPENCODE_GO_REVIEW_CODE" -eq 0 ]; then
|
|
48
|
+
wp dash-helper-complete --provider opencode-go --run-id "$DASH_HELPER_RUN_ID" --role reviewer --outcome completed --artifact "${OPENCODE_GO_REVIEW_ARTIFACT:-}"
|
|
49
|
+
else
|
|
50
|
+
wp dash-helper-complete --provider opencode-go --run-id "$DASH_HELPER_RUN_ID" --role reviewer --outcome failed --artifact "${OPENCODE_GO_REVIEW_ARTIFACT:-}"
|
|
51
|
+
fi
|
|
52
|
+
fi
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The managed OpenCode plugin currently has no parent-linked native subagent completion lifecycle. This capability is explicit unsupported coverage, not an inferred dashboard relation.
|
|
56
|
+
|
|
31
57
|
## Review command
|
|
32
58
|
|
|
33
59
|
Use read-only prompts. Run from the repo directory; do NOT pass `--dir "$PWD"` because opencode already uses the current directory and the extra index can stall reviews.
|
|
@@ -44,64 +70,37 @@ MODEL=$(echo "$CATALOG" | grep '^opencode-go/kimi' | grep -- '-code$' | sort -V
|
|
|
44
70
|
[ -z "$MODEL" ] && MODEL=$(echo "$CATALOG" | grep '^opencode-go/mimo' | grep -- '-pro$' | sort -V | tail -1)
|
|
45
71
|
[ -z "$MODEL" ] && MODEL=$(echo "$CATALOG" | sort -V | tail -1)
|
|
46
72
|
|
|
47
|
-
# Fail fast on blocked quota before launching a long review. The
|
|
48
|
-
#
|
|
49
|
-
# The probe succeeds as soon as it observes the expected success marker instead of
|
|
50
|
-
# waiting for the CLI to finish teardown after the reply has already arrived.
|
|
73
|
+
# Fail fast on blocked quota before launching a long review. The typed runtime
|
|
74
|
+
# consumes provider JSON events and resets its idle clock only on semantic progress.
|
|
51
75
|
[ -n "$MODEL" ] || { echo "No OpenCode Go model resolved for this reviewer." >&2; exit 2; }
|
|
52
76
|
OPENCODE_GO_REVIEW_EFFORT=${OPENCODE_GO_REVIEW_EFFORT:-medium}
|
|
53
77
|
[ "$OPENCODE_GO_REVIEW_EFFORT" = medium ] || [ "$OPENCODE_GO_REVIEW_EFFORT" = high ] || { echo "OPENCODE_GO_REVIEW_EFFORT must be one of: medium, high" >&2; exit 2; }
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
kill -KILL "$PROBE_PID" 2>/dev/null || true
|
|
80
|
-
wait "$PROBE_PID" 2>/dev/null || true
|
|
81
|
-
PROBE_RC=124
|
|
82
|
-
break
|
|
83
|
-
fi
|
|
84
|
-
sleep 1
|
|
85
|
-
done
|
|
86
|
-
if [ -z "${PROBE_RC+x}" ]; then
|
|
87
|
-
if grep -q "OPENCODE_GO_OK" "$PROBE_LOG"; then
|
|
88
|
-
PROBE_RC=0
|
|
89
|
-
else
|
|
90
|
-
wait "$PROBE_PID" || PROBE_RC=$?
|
|
91
|
-
fi
|
|
92
|
-
fi
|
|
93
|
-
if [ "$PROBE_RC" -eq 0 ] && ! grep -q "OPENCODE_GO_OK" "$PROBE_LOG"; then
|
|
94
|
-
echo "OpenCode Go probe finished without the expected success marker." >>"$PROBE_LOG"
|
|
95
|
-
PROBE_RC=1
|
|
96
|
-
fi
|
|
97
|
-
if [ "$PROBE_RC" -ne 0 ]; then
|
|
98
|
-
echo "OpenCode Go probe failed or timed out for $MODEL after ${OPENCODE_GO_PROBE_TIMEOUT}s; skipping this reviewer instead of starting the full review." >&2
|
|
99
|
-
sed -n '1,80p' "$PROBE_LOG" >&2
|
|
100
|
-
rm -f "$PROBE_LOG"
|
|
101
|
-
exit "$PROBE_RC"
|
|
102
|
-
fi
|
|
103
|
-
rm -f "$PROBE_LOG"
|
|
104
|
-
opencode run --variant "$OPENCODE_GO_REVIEW_EFFORT" --model "$MODEL" "$(cat "$PROMPT_FILE")"
|
|
78
|
+
OPENCODE_GO_PROBE_IDLE_SECONDS=${OPENCODE_GO_PROBE_IDLE_SECONDS:-180}
|
|
79
|
+
OPENCODE_GO_REVIEW_IDLE_SECONDS=${OPENCODE_GO_REVIEW_IDLE_SECONDS:-180}
|
|
80
|
+
OPENCODE_GO_REVIEW_ARTIFACT_ROOT=${OPENCODE_GO_REVIEW_ARTIFACT_ROOT:-"$(pwd)/.webpresso/reviews"}
|
|
81
|
+
PROBE_FILE=$(mktemp -t wp-opencode-go-probe.XXXXXX)
|
|
82
|
+
trap 'rm -f "$PROMPT_FILE" "$PROBE_FILE"' EXIT
|
|
83
|
+
printf 'Reply exactly OPENCODE_GO_OK.\n' >"$PROBE_FILE"
|
|
84
|
+
|
|
85
|
+
wp review run \
|
|
86
|
+
--provider opencode \
|
|
87
|
+
--prompt-file "$PROBE_FILE" \
|
|
88
|
+
--model "$MODEL" \
|
|
89
|
+
--effort "$OPENCODE_GO_REVIEW_EFFORT" \
|
|
90
|
+
--stage probe \
|
|
91
|
+
--expected-marker OPENCODE_GO_OK \
|
|
92
|
+
--artifact-root "$OPENCODE_GO_REVIEW_ARTIFACT_ROOT" \
|
|
93
|
+
--idle-seconds "$OPENCODE_GO_PROBE_IDLE_SECONDS"
|
|
94
|
+
|
|
95
|
+
wp review run \
|
|
96
|
+
--provider opencode \
|
|
97
|
+
--prompt-file "$PROMPT_FILE" \
|
|
98
|
+
--model "$MODEL" \
|
|
99
|
+
--effort "$OPENCODE_GO_REVIEW_EFFORT" \
|
|
100
|
+
--stage review \
|
|
101
|
+
--artifact-root "$OPENCODE_GO_REVIEW_ARTIFACT_ROOT" \
|
|
102
|
+
--idle-seconds "$OPENCODE_GO_REVIEW_IDLE_SECONDS"
|
|
105
103
|
```
|
|
106
104
|
|
|
107
105
|
If `$MODEL` is empty, run `opencode models opencode-go` and choose a present reviewer.
|
|
106
|
+
Treat `true-idle`, `protocol-unsupported`, provider failure, abort, spawn failure, or artifact failure as unavailable review evidence. Never replace them with a static timeout, arbitrary byte-growth heartbeat, or buffered-output fallback.
|
package/skills/verify/SKILL.md
CHANGED
|
@@ -182,6 +182,10 @@ Reviewer preference:
|
|
|
182
182
|
|
|
183
183
|
Approval evidence requirements:
|
|
184
184
|
|
|
185
|
+
- For blueprint lifecycle approval workflows, run `wp review gate <blueprint-slug> --target HEAD --json`
|
|
186
|
+
first so exact-SHA reusable evidence and approval frontmatter are handled
|
|
187
|
+
transactionally. Use `wp review log` / `wp review read` for focused ledger
|
|
188
|
+
inspection or manual evidence recording.
|
|
185
189
|
- Each outside reviewer must return a clear `APPROVED`/`BLOCKED` (or equivalent)
|
|
186
190
|
verdict with enough evidence to identify what it reviewed.
|
|
187
191
|
- Record outside approval evidence as PR comments when a PR exists.
|