@webpresso/agent-kit 0.26.0 → 0.26.1
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/dist/esm/audit/toolchain-isolation.js +5 -0
- package/dist/esm/cli/commands/init/index.js +19 -1
- package/dist/esm/cli/commands/init/scaffolders/codex-cli/index.js +5 -1
- package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.d.ts +29 -1
- package/dist/esm/cli/commands/init/scaffolders/codex-mcp/index.js +72 -2
- package/package.json +6 -6
|
@@ -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": "0.26.
|
|
9
|
+
"version": "0.26.1"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
@@ -23,5 +23,5 @@
|
|
|
23
23
|
]
|
|
24
24
|
}
|
|
25
25
|
],
|
|
26
|
-
"version": "0.26.
|
|
26
|
+
"version": "0.26.1"
|
|
27
27
|
}
|
|
@@ -114,6 +114,11 @@ function shouldSkipDirectory(name) {
|
|
|
114
114
|
'.omx',
|
|
115
115
|
'.omc',
|
|
116
116
|
'.codex',
|
|
117
|
+
// Gitignored Claude Code agent surface — agent worktree scratch under
|
|
118
|
+
// .claude/worktrees/* carries vendored package manifests that are not the
|
|
119
|
+
// repo's own packages; walking it produces false positives on local dev
|
|
120
|
+
// machines and in consumer repos that run agent worktrees.
|
|
121
|
+
'.claude',
|
|
117
122
|
].includes(name);
|
|
118
123
|
}
|
|
119
124
|
function readPackageJson(file) {
|
|
@@ -35,7 +35,7 @@ import { scaffoldAuditHooks } from './scaffolders/audit-hooks/index.js';
|
|
|
35
35
|
import { ensureClaudeCodeUserPlugin } from './scaffolders/claude-plugin/index.js';
|
|
36
36
|
import { scaffoldClaudeRules } from './scaffolders/claude-rules/index.js';
|
|
37
37
|
import { ensureCodexCli } from './scaffolders/codex-cli/index.js';
|
|
38
|
-
import { ensureCodexWebpressoMcp, ensureCodexPlaywrightMcp } from './scaffolders/codex-mcp/index.js';
|
|
38
|
+
import { ensureCodexWebpressoMcp, ensureCodexPlaywrightMcp, ensureClaudePlaywrightMcp, } from './scaffolders/codex-mcp/index.js';
|
|
39
39
|
import { scaffoldExampleSkill } from './scaffolders/example-skill/index.js';
|
|
40
40
|
import { ensureGstack } from './scaffolders/gstack/index.js';
|
|
41
41
|
import { scaffoldLoreCommits } from './scaffolders/lore-commits/index.js';
|
|
@@ -437,6 +437,24 @@ export async function runInit(flags) {
|
|
|
437
437
|
console.log(' codex playwright mcp: skipped (--dry-run)');
|
|
438
438
|
break;
|
|
439
439
|
}
|
|
440
|
+
const claudePlaywrightMcpResult = ensureClaudePlaywrightMcp({
|
|
441
|
+
options,
|
|
442
|
+
repoRoot: consumer.repoRoot,
|
|
443
|
+
});
|
|
444
|
+
switch (claudePlaywrightMcpResult.kind) {
|
|
445
|
+
case 'claude-playwright-mcp-written':
|
|
446
|
+
console.log(` claude playwright mcp: ✓ ${claudePlaywrightMcpResult.path}`);
|
|
447
|
+
break;
|
|
448
|
+
case 'claude-playwright-mcp-unchanged':
|
|
449
|
+
console.log(` claude playwright mcp: already configured at ${claudePlaywrightMcpResult.path}`);
|
|
450
|
+
break;
|
|
451
|
+
case 'claude-playwright-mcp-skipped-dry-run':
|
|
452
|
+
console.log(' claude playwright mcp: skipped (--dry-run)');
|
|
453
|
+
break;
|
|
454
|
+
case 'claude-playwright-mcp-invalid-json':
|
|
455
|
+
console.warn(` claude playwright mcp: ⚠ ${claudePlaywrightMcpResult.path} is not valid JSON; left unchanged`);
|
|
456
|
+
break;
|
|
457
|
+
}
|
|
440
458
|
}
|
|
441
459
|
if (presets.includes('omx')) {
|
|
442
460
|
agentHooksResult = await scaffoldAgentHooks({
|
|
@@ -20,7 +20,11 @@ export function ensureCodexCli(input) {
|
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
else if (!shouldSkipCodexRefresh()) {
|
|
23
|
-
|
|
23
|
+
// `--latest` ignores the recorded semver range so the global is pulled to
|
|
24
|
+
// the absolute newest published release, matching the force-to-latest
|
|
25
|
+
// guarantee `vp install -g <bare>` gives the agent-kit self-update. Plain
|
|
26
|
+
// `vp update -g` is range-bound and can strand the global on an old major.
|
|
27
|
+
spawn('vp', ['update', '-g', '--latest', '@openai/codex'], { stdio: 'inherit' });
|
|
24
28
|
}
|
|
25
29
|
return { kind: 'codex-cli-ok', installed };
|
|
26
30
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { MergeOptions } from '#cli/commands/init/merge';
|
|
2
2
|
export declare const PLAYWRIGHT_MCP_SERVER_NAME = "playwright";
|
|
3
3
|
export declare const PLAYWRIGHT_MCP_HEADER = "[mcp_servers.playwright]";
|
|
4
|
-
export declare const PLAYWRIGHT_MCP_BLOCK
|
|
4
|
+
export declare const PLAYWRIGHT_MCP_BLOCK: string;
|
|
5
5
|
export declare const WEBPRESSO_MCP_SERVER_NAME = "webpresso";
|
|
6
6
|
export declare const WEBPRESSO_MCP_HEADER = "[mcp_servers.webpresso]";
|
|
7
7
|
export interface EnsureCodexPlaywrightMcpInput {
|
|
@@ -21,6 +21,34 @@ export type EnsureCodexPlaywrightMcpResult = {
|
|
|
21
21
|
};
|
|
22
22
|
export declare function upsertPlaywrightMcpServer(raw: string): string;
|
|
23
23
|
export declare function ensureCodexPlaywrightMcp(input: EnsureCodexPlaywrightMcpInput): EnsureCodexPlaywrightMcpResult;
|
|
24
|
+
/**
|
|
25
|
+
* Upsert the `playwright` server into a `.mcp.json` document, preserving every
|
|
26
|
+
* other server (e.g. `context7`, `exa`) and any non-server top-level keys.
|
|
27
|
+
* Output is normalized to 2-space JSON with a trailing newline so repeated runs
|
|
28
|
+
* converge — idempotent after the first write.
|
|
29
|
+
*/
|
|
30
|
+
export declare function upsertClaudePlaywrightMcpServer(raw: string): string;
|
|
31
|
+
export interface EnsureClaudePlaywrightMcpInput {
|
|
32
|
+
options: MergeOptions;
|
|
33
|
+
/** Project root whose `.mcp.json` is managed. */
|
|
34
|
+
repoRoot: string;
|
|
35
|
+
/** Test seam. Defaults to `<repoRoot>/.mcp.json`. */
|
|
36
|
+
configPath?: string;
|
|
37
|
+
}
|
|
38
|
+
export type EnsureClaudePlaywrightMcpResult = {
|
|
39
|
+
kind: 'claude-playwright-mcp-written';
|
|
40
|
+
path: string;
|
|
41
|
+
} | {
|
|
42
|
+
kind: 'claude-playwright-mcp-unchanged';
|
|
43
|
+
path: string;
|
|
44
|
+
} | {
|
|
45
|
+
kind: 'claude-playwright-mcp-skipped-dry-run';
|
|
46
|
+
path: string;
|
|
47
|
+
} | {
|
|
48
|
+
kind: 'claude-playwright-mcp-invalid-json';
|
|
49
|
+
path: string;
|
|
50
|
+
};
|
|
51
|
+
export declare function ensureClaudePlaywrightMcp(input: EnsureClaudePlaywrightMcpInput): EnsureClaudePlaywrightMcpResult;
|
|
24
52
|
export interface WebpressoInstallProbe {
|
|
25
53
|
/** Test seam — override the candidate roots. Default: probe in fixed order. */
|
|
26
54
|
candidates?: readonly string[];
|
|
@@ -22,10 +22,27 @@ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
|
22
22
|
import { homedir } from 'node:os';
|
|
23
23
|
import { dirname, join } from 'node:path';
|
|
24
24
|
export const PLAYWRIGHT_MCP_SERVER_NAME = 'playwright';
|
|
25
|
+
/**
|
|
26
|
+
* Single source of truth for how the Playwright MCP server is launched. Both
|
|
27
|
+
* the Codex TOML block and the Claude Code `.mcp.json` block render from these.
|
|
28
|
+
* The portable `vp dlx` facade fetches the npm-published server on demand, so
|
|
29
|
+
* there is no machine-specific bin path to rot — the failure mode a hand-
|
|
30
|
+
* authored `~/.bun/bin/playwright-mcp` entry hits the moment that global bin
|
|
31
|
+
* disappears (ENOENT on spawn).
|
|
32
|
+
*/
|
|
33
|
+
const PLAYWRIGHT_MCP_COMMAND = 'vp';
|
|
34
|
+
const PLAYWRIGHT_MCP_ARGS = [
|
|
35
|
+
'dlx',
|
|
36
|
+
'@playwright/mcp@latest',
|
|
37
|
+
'--caps=testing,storage,network,devtools',
|
|
38
|
+
];
|
|
39
|
+
function tomlStringArray(values) {
|
|
40
|
+
return `[${values.map((value) => `"${value}"`).join(', ')}]`;
|
|
41
|
+
}
|
|
25
42
|
export const PLAYWRIGHT_MCP_HEADER = `[mcp_servers.${PLAYWRIGHT_MCP_SERVER_NAME}]`;
|
|
26
43
|
export const PLAYWRIGHT_MCP_BLOCK = `${PLAYWRIGHT_MCP_HEADER}
|
|
27
|
-
command = "
|
|
28
|
-
args =
|
|
44
|
+
command = "${PLAYWRIGHT_MCP_COMMAND}"
|
|
45
|
+
args = ${tomlStringArray(PLAYWRIGHT_MCP_ARGS)}
|
|
29
46
|
enabled = true
|
|
30
47
|
startup_timeout_sec = 30
|
|
31
48
|
`;
|
|
@@ -70,6 +87,59 @@ export function ensureCodexPlaywrightMcp(input) {
|
|
|
70
87
|
writeFileSync(configPath, next, 'utf8');
|
|
71
88
|
return { kind: 'codex-playwright-mcp-written', path: configPath };
|
|
72
89
|
}
|
|
90
|
+
function claudePlaywrightServer() {
|
|
91
|
+
return { command: PLAYWRIGHT_MCP_COMMAND, args: [...PLAYWRIGHT_MCP_ARGS] };
|
|
92
|
+
}
|
|
93
|
+
function isJsonRecord(value) {
|
|
94
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
95
|
+
}
|
|
96
|
+
function parseJson(raw) {
|
|
97
|
+
try {
|
|
98
|
+
return { ok: true, value: JSON.parse(raw) };
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return { ok: false };
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Upsert the `playwright` server into a `.mcp.json` document, preserving every
|
|
106
|
+
* other server (e.g. `context7`, `exa`) and any non-server top-level keys.
|
|
107
|
+
* Output is normalized to 2-space JSON with a trailing newline so repeated runs
|
|
108
|
+
* converge — idempotent after the first write.
|
|
109
|
+
*/
|
|
110
|
+
export function upsertClaudePlaywrightMcpServer(raw) {
|
|
111
|
+
const parsed = raw.trim().length > 0 ? parseJson(raw) : { ok: true, value: {} };
|
|
112
|
+
if (!parsed.ok) {
|
|
113
|
+
throw new Error('cannot upsert playwright into .mcp.json: existing file is not valid JSON');
|
|
114
|
+
}
|
|
115
|
+
const root = isJsonRecord(parsed.value) ? parsed.value : {};
|
|
116
|
+
const servers = isJsonRecord(root.mcpServers) ? root.mcpServers : {};
|
|
117
|
+
const next = {
|
|
118
|
+
...root,
|
|
119
|
+
mcpServers: {
|
|
120
|
+
...servers,
|
|
121
|
+
[PLAYWRIGHT_MCP_SERVER_NAME]: claudePlaywrightServer(),
|
|
122
|
+
},
|
|
123
|
+
};
|
|
124
|
+
return `${JSON.stringify(next, null, 2)}\n`;
|
|
125
|
+
}
|
|
126
|
+
export function ensureClaudePlaywrightMcp(input) {
|
|
127
|
+
const configPath = input.configPath ?? join(input.repoRoot, '.mcp.json');
|
|
128
|
+
if (input.options.dryRun) {
|
|
129
|
+
return { kind: 'claude-playwright-mcp-skipped-dry-run', path: configPath };
|
|
130
|
+
}
|
|
131
|
+
const existing = existsSync(configPath) ? readFileSync(configPath, 'utf8') : '';
|
|
132
|
+
if (existing.trim().length > 0 && !parseJson(existing).ok) {
|
|
133
|
+
return { kind: 'claude-playwright-mcp-invalid-json', path: configPath };
|
|
134
|
+
}
|
|
135
|
+
const next = upsertClaudePlaywrightMcpServer(existing);
|
|
136
|
+
if (next === existing) {
|
|
137
|
+
return { kind: 'claude-playwright-mcp-unchanged', path: configPath };
|
|
138
|
+
}
|
|
139
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
140
|
+
writeFileSync(configPath, next, 'utf8');
|
|
141
|
+
return { kind: 'claude-playwright-mcp-written', path: configPath };
|
|
142
|
+
}
|
|
73
143
|
// ────────────────────────────────────────────────────────────────────────────
|
|
74
144
|
// Agent-kit MCP server registration
|
|
75
145
|
// ────────────────────────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@webpresso/agent-kit",
|
|
3
|
-
"version": "0.26.
|
|
3
|
+
"version": "0.26.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -710,10 +710,10 @@
|
|
|
710
710
|
"@stryker-mutator/typescript-checker": "^9.6.1",
|
|
711
711
|
"@playwright/test": "^1.55.0",
|
|
712
712
|
"wrangler": "^4.50.0",
|
|
713
|
-
"@webpresso/agent-kit-runtime-darwin-arm64": "0.26.
|
|
714
|
-
"@webpresso/agent-kit-runtime-darwin-x64": "0.26.
|
|
715
|
-
"@webpresso/agent-kit-runtime-linux-x64": "0.26.
|
|
716
|
-
"@webpresso/agent-kit-runtime-linux-arm64": "0.26.
|
|
717
|
-
"@webpresso/agent-kit-runtime-windows-x64": "0.26.
|
|
713
|
+
"@webpresso/agent-kit-runtime-darwin-arm64": "0.26.1",
|
|
714
|
+
"@webpresso/agent-kit-runtime-darwin-x64": "0.26.1",
|
|
715
|
+
"@webpresso/agent-kit-runtime-linux-x64": "0.26.1",
|
|
716
|
+
"@webpresso/agent-kit-runtime-linux-arm64": "0.26.1",
|
|
717
|
+
"@webpresso/agent-kit-runtime-windows-x64": "0.26.1"
|
|
718
718
|
}
|
|
719
719
|
}
|