@webpresso/claude-plugin 3.1.30 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +3 -12
- package/.claude-plugin/plugin.json +1 -1
- package/bin/wp +95 -11
- package/commands/blueprint.md +1 -1
- package/package.json +1 -1
- package/plugin-skill-ownership.json +3 -3
- package/skills/codex/SKILL.md +25 -1
- package/skills/verify/SKILL.md +4 -2
|
@@ -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.
|
|
9
|
+
"version": "3.3.0"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
@@ -14,17 +14,8 @@
|
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Webpresso agent-kit: blueprints, skills, lore commit protocol, tech-debt lifecycle",
|
|
16
16
|
"category": "development",
|
|
17
|
-
"keywords": ["agent", "blueprint", "claude-code", "skills", "mcp"]
|
|
18
|
-
"mcpServers": {
|
|
19
|
-
"webpresso": {
|
|
20
|
-
"command": "${CLAUDE_PLUGIN_ROOT}/bin/wp",
|
|
21
|
-
"args": ["mcp"],
|
|
22
|
-
"env": {
|
|
23
|
-
"WP_SKIP_UPDATE_CHECK": "1"
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
}
|
|
17
|
+
"keywords": ["agent", "blueprint", "claude-code", "skills", "mcp"]
|
|
27
18
|
}
|
|
28
19
|
],
|
|
29
|
-
"version": "3.
|
|
20
|
+
"version": "3.3.0"
|
|
30
21
|
}
|
package/bin/wp
CHANGED
|
@@ -1,21 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { spawnSync } from "node:child_process";
|
|
4
|
-
import { accessSync, constants, realpathSync, statSync } from "node:fs";
|
|
4
|
+
import { accessSync, constants, existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
|
-
import { dirname, delimiter, join } from "node:path";
|
|
6
|
+
import { dirname, delimiter, isAbsolute, join, relative, resolve } from "node:path";
|
|
7
|
+
import { homedir } from "node:os";
|
|
7
8
|
import { fileURLToPath } from "node:url";
|
|
8
9
|
|
|
9
10
|
const require = createRequire(import.meta.url);
|
|
10
11
|
const shimPath = fileURLToPath(import.meta.url);
|
|
11
12
|
const shimDir = dirname(shimPath);
|
|
12
13
|
const adapterRoot = dirname(shimDir);
|
|
14
|
+
const pathWpBinNames = process.platform === "win32" ? ["wp.cmd", "wp"] : ["wp"];
|
|
13
15
|
|
|
14
16
|
function isExecutableFile(candidate) {
|
|
15
17
|
try {
|
|
16
18
|
const stat = statSync(candidate);
|
|
17
19
|
if (!stat.isFile()) return false;
|
|
18
|
-
accessSync(candidate, constants.X_OK);
|
|
20
|
+
if (process.platform !== "win32") accessSync(candidate, constants.X_OK);
|
|
19
21
|
return true;
|
|
20
22
|
} catch {
|
|
21
23
|
return false;
|
|
@@ -34,7 +36,7 @@ function pathWpCandidates() {
|
|
|
34
36
|
return (process.env.PATH ?? "")
|
|
35
37
|
.split(delimiter)
|
|
36
38
|
.filter(Boolean)
|
|
37
|
-
.
|
|
39
|
+
.flatMap((entry) => pathWpBinNames.map((name) => join(entry, name)));
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
function resolveAgentKitPackageWp() {
|
|
@@ -46,14 +48,94 @@ function resolveAgentKitPackageWp() {
|
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
|
|
51
|
+
function isPathInsideOrEqual(parent, candidate) {
|
|
52
|
+
const parentRoot = realpathSync(parent);
|
|
53
|
+
const candidateRoot = realpathSync(candidate);
|
|
54
|
+
const rel = relative(resolve(parentRoot), resolve(candidateRoot));
|
|
55
|
+
return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function isAgentKitWp(candidate) {
|
|
59
|
+
if (candidate.toLowerCase().endsWith(".cmd")) return false;
|
|
60
|
+
if (!isExecutableFile(candidate) || sameFile(candidate, shimPath)) return false;
|
|
61
|
+
try {
|
|
62
|
+
const resolved = realpathSync(candidate);
|
|
63
|
+
const packageRoot = dirname(dirname(resolved));
|
|
64
|
+
if (resolved !== join(packageRoot, "bin", "wp")) return false;
|
|
65
|
+
return isTrustedAgentKitPackageRoot(packageRoot);
|
|
66
|
+
} catch {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function isUsableAgentKitPackageRoot(packageRoot) {
|
|
72
|
+
try {
|
|
73
|
+
const pkg = JSON.parse(readFileSync(join(packageRoot, "package.json"), "utf8"));
|
|
74
|
+
return pkg.name === "@webpresso/agent-kit" && isExecutableFile(join(packageRoot, "bin", "wp"));
|
|
75
|
+
} catch {
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function packageWpFromAdjacentNpmCmdShim(candidate) {
|
|
81
|
+
if (!candidate.toLowerCase().endsWith(".cmd")) return null;
|
|
82
|
+
const packageRoot = join(dirname(candidate), "node_modules", "@webpresso", "agent-kit");
|
|
83
|
+
return isTrustedAgentKitPackageRoot(packageRoot) ? join(packageRoot, "bin", "wp") : null;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function currentAgentKitPackageRoot() {
|
|
87
|
+
let current = dirname(shimPath);
|
|
88
|
+
for (let depth = 0; depth < 12; depth += 1) {
|
|
89
|
+
const packagePath = join(current, "package.json");
|
|
90
|
+
if (existsSync(packagePath)) {
|
|
91
|
+
try {
|
|
92
|
+
const pkg = JSON.parse(readFileSync(packagePath, "utf8"));
|
|
93
|
+
if (pkg.name === "@webpresso/agent-kit") return current;
|
|
94
|
+
} catch {
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const parent = dirname(current);
|
|
99
|
+
if (parent === current) break;
|
|
100
|
+
current = parent;
|
|
101
|
+
}
|
|
102
|
+
return null;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
function trustedHomeInstallPackageRoots() {
|
|
106
|
+
const home = process.env.HOME || homedir();
|
|
107
|
+
return [
|
|
108
|
+
join(home, ".claude", "plugins", "cache", "webpresso", "agent-kit"),
|
|
109
|
+
join(home, ".bun", "install", "global", "node_modules", "@webpresso", "agent-kit"),
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function isTrustedAgentKitPackageRoot(packageRoot) {
|
|
114
|
+
try {
|
|
115
|
+
if (!isUsableAgentKitPackageRoot(packageRoot)) return false;
|
|
116
|
+
const realPackageRoot = realpathSync(packageRoot);
|
|
117
|
+
const sourceRoot = currentAgentKitPackageRoot();
|
|
118
|
+
if (sourceRoot !== null && realPackageRoot === realpathSync(sourceRoot)) return true;
|
|
119
|
+
return trustedHomeInstallPackageRoots().some(
|
|
120
|
+
(anchor) => existsSync(anchor) && isPathInsideOrEqual(anchor, realPackageRoot),
|
|
121
|
+
);
|
|
122
|
+
} catch {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function assertAgentKitWp(candidate, label) {
|
|
128
|
+
if (isAgentKitWp(candidate)) return candidate;
|
|
129
|
+
throw new Error(
|
|
130
|
+
`${label} points to ${candidate}, but that executable is not @webpresso/agent-kit. ` +
|
|
131
|
+
"Set WEBPRESSO_WP_BIN to the Webpresso wp executable, install/update @webpresso/agent-kit, or run wp setup.",
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
49
135
|
function resolveAgentKitWp() {
|
|
50
136
|
const explicitPath = process.env.WEBPRESSO_WP_BIN;
|
|
51
137
|
if (explicitPath) {
|
|
52
|
-
|
|
53
|
-
throw new Error(
|
|
54
|
-
`WEBPRESSO_WP_BIN points to ${explicitPath}, but that file is not executable. ` +
|
|
55
|
-
"Set WEBPRESSO_WP_BIN to a valid wp executable, install/update @webpresso/agent-kit, or run wp setup.",
|
|
56
|
-
);
|
|
138
|
+
return assertAgentKitWp(explicitPath, "WEBPRESSO_WP_BIN");
|
|
57
139
|
}
|
|
58
140
|
|
|
59
141
|
const candidates = [
|
|
@@ -63,8 +145,10 @@ function resolveAgentKitWp() {
|
|
|
63
145
|
].filter(Boolean);
|
|
64
146
|
|
|
65
147
|
for (const candidate of candidates) {
|
|
66
|
-
|
|
67
|
-
|
|
148
|
+
const packageWp = packageWpFromAdjacentNpmCmdShim(candidate);
|
|
149
|
+
const command = packageWp ?? candidate;
|
|
150
|
+
if (isAgentKitWp(command)) {
|
|
151
|
+
return command;
|
|
68
152
|
}
|
|
69
153
|
}
|
|
70
154
|
|
package/commands/blueprint.md
CHANGED
|
@@ -12,7 +12,7 @@ Use the focused blueprint MCP tools.
|
|
|
12
12
|
- `wp_blueprint_put` — whole-document structured authoring; writes the canonical blueprint markdown from typed input and returns revision metadata
|
|
13
13
|
- `wp_blueprint_transition` — optimistic-concurrency lifecycle transition; requires `expected_version` and returns updated revision metadata
|
|
14
14
|
- `wp_blueprint_task_next` — return the next ready task; accepts optional `project_id` when the current cwd is a multi-repo workspace container
|
|
15
|
-
- `wp_blueprint_task_advance` — change task status (non-`done`); requires `project_id` and accepts optional `request_id` and `head_at_ingest` for retry-safe mutation
|
|
15
|
+
- `wp_blueprint_task_advance` — change task status (non-`done`); requires `project_id` and `slug` (task ids are not unique across blueprints, so `slug` scopes the mutation to the right one), and accepts optional `request_id` and `head_at_ingest` for retry-safe mutation
|
|
16
16
|
- `wp_blueprint_task_verify` — mark a task `done` with evidence; accepts optional `request_id` and `head_at_ingest` for retry-safe verification
|
|
17
17
|
- `wp_blueprint_promote` / `wp_blueprint_finalize` — accept optional `project_id` for nested-workspace disambiguation
|
|
18
18
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpresso/claude-plugin",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
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",
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"host": "claude",
|
|
4
4
|
"packageName": "@webpresso/claude-plugin",
|
|
5
|
-
"packageVersion": "3.
|
|
5
|
+
"packageVersion": "3.3.0",
|
|
6
6
|
"runtimeDirs": [".claude/skills"],
|
|
7
7
|
"skills": {
|
|
8
8
|
"ai-deslop": {
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"digest": "sha256:a97c243b11a25a893d3149a5545d3d111bc54e72c2e2acea9ce6fad3d333d2f1"
|
|
25
25
|
},
|
|
26
26
|
"codex": {
|
|
27
|
-
"digest": "sha256:
|
|
27
|
+
"digest": "sha256:7093f390749bed751038ad480d68c12380cfa2630e61881c16be46da7f75e238"
|
|
28
28
|
},
|
|
29
29
|
"deep-interview": {
|
|
30
30
|
"digest": "sha256:e80d7e12e486397103108bb473e98e8e8656519770fa20701f8b3e9e66991939"
|
|
@@ -90,7 +90,7 @@
|
|
|
90
90
|
"digest": "sha256:953ab2625287866e5f27e602a89f1752e054d47522d04e1fdc11880867dc2fde"
|
|
91
91
|
},
|
|
92
92
|
"verify": {
|
|
93
|
-
"digest": "sha256:
|
|
93
|
+
"digest": "sha256:47c1d75ef5d1d47b94ef48ac91b0fd4bbf6ba1ab32563cfc28518bb75c7798f0"
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
96
|
}
|
package/skills/codex/SKILL.md
CHANGED
|
@@ -8,13 +8,37 @@ license: MIT
|
|
|
8
8
|
|
|
9
9
|
Use this skill from Claude or another non-Codex host when the user wants Codex to independently review a diff, challenge a plan, or answer a repo question. Keep Codex read-only by default and treat its answer as external advice until independently verified.
|
|
10
10
|
|
|
11
|
+
## Primary path: the `wp_review_run` MCP tool
|
|
12
|
+
|
|
13
|
+
When the webpresso MCP server is available, call `wp_review_run` directly instead of any bash block below — it is the same `wp review run` typed runtime, called in-process, with two ergonomic wins: it takes a `prompt` string (no `--prompt-file` bookkeeping) and it runs the probe stage and the review stage in **one call** by default (the review stage is skipped automatically if the probe fails, so you never waste a full review invocation on a cold/broken provider).
|
|
14
|
+
|
|
15
|
+
```jsonc
|
|
16
|
+
// wp_review_run MCP tool call
|
|
17
|
+
{
|
|
18
|
+
"prompt": "<diff summary + what to look for>",
|
|
19
|
+
"provider": "codex",
|
|
20
|
+
// model, effort, artifactRoot, idleSeconds are all optional and default
|
|
21
|
+
// the same way the `wp review run` CLI does. Omit `stage` for automatic
|
|
22
|
+
// probe-then-review; pass stage: "probe" or stage: "review" only for
|
|
23
|
+
// manual single-stage control.
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Provider fallback lives in this one call.** If your primary provider (e.g. Codex) is unavailable — out of credits, auth expired — switch the `provider` parameter to another supported value (`claude`, `opencode`, `grok`) in the SAME `wp_review_run` call. Never shell into a different provider's CLI directly; that bypasses artifact capture under `.webpresso/reviews`, availability tracking, and the probe-then-review handshake this tool exists to provide. The pretool guard hook actively blocks shelling straight into a provider CLI's review-launching subcommand and redirects here.
|
|
28
|
+
|
|
29
|
+
The bash blocks in this skill (below) are the **MCP-unavailable fallback only** — use them when the webpresso MCP server itself is not reachable in the current host, not as a provider-fallback mechanism.
|
|
30
|
+
|
|
11
31
|
## Single-shot budget (anti-stampede)
|
|
12
32
|
|
|
13
33
|
- Default: **one** review invocation per request.
|
|
14
34
|
- Do **not** fan out parallel multi-host review matrices unless the user set `review_budget`/`N` > 1.
|
|
15
|
-
- Prefer `wp review run` / `wp review gate` over spawn/wait agent loops for review.
|
|
35
|
+
- Prefer `wp_review_run` (MCP) or `wp review run` / `wp review gate` (CLI fallback) over spawn/wait agent loops for review.
|
|
16
36
|
- Keep prompts bounded; no whole-repo paste.
|
|
17
37
|
|
|
38
|
+
## MCP-unavailable fallback (raw CLI)
|
|
39
|
+
|
|
40
|
+
Everything from here down is the manual `wp review run` CLI path documented for hosts or sessions where the webpresso MCP server is not reachable. Prefer `wp_review_run` above whenever MCP is available.
|
|
41
|
+
|
|
18
42
|
## Auth check
|
|
19
43
|
|
|
20
44
|
```bash
|
package/skills/verify/SKILL.md
CHANGED
|
@@ -235,8 +235,10 @@ Reviewer preference (pick **one** path):
|
|
|
235
235
|
|
|
236
236
|
Approval evidence requirements:
|
|
237
237
|
|
|
238
|
-
- Blueprint lifecycle: `wp review gate <blueprint-slug> --target HEAD --json`
|
|
239
|
-
|
|
238
|
+
- Blueprint lifecycle: `wp review gate <blueprint-slug> --purpose delivery --target HEAD --json`
|
|
239
|
+
first. Delivery gates automatically run declared Promotion Gates from the
|
|
240
|
+
Trust Dossier before outside-review provider probes. Use `wp review log` /
|
|
241
|
+
`wp review read` for inspection.
|
|
240
242
|
- Each reviewer must return clear `APPROVED`/`BLOCKED` with enough evidence.
|
|
241
243
|
- Record as PR comments when a PR exists (model/tool, verdict, reviewed commit).
|
|
242
244
|
- Unavailable reviewer → try next preferred; if still short, report gap and
|