browser-debug-mcp-bridge 1.12.0 → 1.14.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/.agents/skills/browser-debug-cli/SKILL.md +44 -0
- package/README.md +17 -1
- package/apps/mcp-server/dist/cli/agent-instructions.js +89 -0
- package/apps/mcp-server/dist/cli/agent-instructions.js.map +1 -0
- package/apps/mcp-server/dist/cli/audit-log.js +12 -0
- package/apps/mcp-server/dist/cli/audit-log.js.map +1 -0
- package/apps/mcp-server/dist/cli/auth.js +66 -0
- package/apps/mcp-server/dist/cli/auth.js.map +1 -0
- package/apps/mcp-server/dist/cli/gateway.js +116 -0
- package/apps/mcp-server/dist/cli/gateway.js.map +1 -0
- package/apps/mcp-server/dist/cli/main.js +483 -0
- package/apps/mcp-server/dist/cli/main.js.map +1 -0
- package/apps/mcp-server/dist/db/migrations.js +221 -1
- package/apps/mcp-server/dist/db/migrations.js.map +1 -1
- package/apps/mcp-server/dist/db/schema.js +167 -2
- package/apps/mcp-server/dist/db/schema.js.map +1 -1
- package/apps/mcp-server/dist/lighthouse-report.js +1001 -0
- package/apps/mcp-server/dist/lighthouse-report.js.map +1 -0
- package/apps/mcp-server/dist/main.js +253 -1
- package/apps/mcp-server/dist/main.js.map +1 -1
- package/apps/mcp-server/dist/mcp/server.js +793 -1
- package/apps/mcp-server/dist/mcp/server.js.map +1 -1
- package/apps/mcp-server/dist/mock-store.js +408 -0
- package/apps/mcp-server/dist/mock-store.js.map +1 -0
- package/apps/mcp-server/dist/override-audit-contract.js +58 -0
- package/apps/mcp-server/dist/override-audit-contract.js.map +1 -1
- package/apps/mcp-server/dist/override-audit.js +97 -1
- package/apps/mcp-server/dist/override-audit.js.map +1 -1
- package/apps/mcp-server/dist/ssr-mock.js +480 -0
- package/apps/mcp-server/dist/ssr-mock.js.map +1 -0
- package/apps/mcp-server/package.json +5 -0
- package/package.json +12 -5
- package/scripts/browser-debug-cli.cjs +79 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: browser-debug-cli
|
|
3
|
+
description: Use when MCP tools are unavailable or blocked but terminal commands are allowed, and Codex needs browser debugging evidence from Browser Debug MCP Bridge. Provides workflows for using the packaged bdmcp CLI to inspect sessions, console logs, network failures, page state, snapshots, Lighthouse reports, and generic bridge tool calls.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Browser Debug CLI
|
|
7
|
+
|
|
8
|
+
Use `bdmcp` when Browser Debug MCP Bridge evidence is needed and MCP tools are not available.
|
|
9
|
+
|
|
10
|
+
Start with:
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
bdmcp health
|
|
14
|
+
bdmcp sessions --live
|
|
15
|
+
bdmcp summary @recommended
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Session aliases:
|
|
19
|
+
|
|
20
|
+
- `@recommended`: prefer a connected live session
|
|
21
|
+
- `@live`: connected live session
|
|
22
|
+
- `@latest`: most recent persisted session
|
|
23
|
+
- `@auto`: connected first, latest fallback
|
|
24
|
+
|
|
25
|
+
Common commands:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
bdmcp console @recommended --level error
|
|
29
|
+
bdmcp live-console @recommended
|
|
30
|
+
bdmcp network @recommended --failures
|
|
31
|
+
bdmcp page-state @recommended
|
|
32
|
+
bdmcp snapshot @recommended --mode png
|
|
33
|
+
bdmcp tool list
|
|
34
|
+
bdmcp tool schema list_sessions
|
|
35
|
+
bdmcp tool run list_sessions --args-file browser-debug-args.json --json
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Prefer compact output first. Use `--json` only when structured output is needed. Use `--max-bytes` for large responses.
|
|
39
|
+
|
|
40
|
+
If `bdmcp health` cannot connect, ask the user to start the bridge:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
browser-debug-mcp-bridge --standalone
|
|
44
|
+
```
|
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ It captures console logs, network calls, navigation, UI events, DOM snapshots, s
|
|
|
16
16
|
|
|
17
17
|
## Requirements
|
|
18
18
|
|
|
19
|
-
- Node.js `>=
|
|
19
|
+
- Node.js `>=22.19`
|
|
20
20
|
- Chrome or Chromium with extension Developer Mode enabled
|
|
21
21
|
- An MCP-capable AI client
|
|
22
22
|
|
|
@@ -46,6 +46,8 @@ Load the extension:
|
|
|
46
46
|
|
|
47
47
|
Recommended launch method: direct `node` command pointing at the installed package script.
|
|
48
48
|
|
|
49
|
+
Studio or MCPS is not required. The package launcher is a standard MCP stdio server entrypoint, so any MCP host that supports command/args server configuration can use it directly and gets the same tool surface.
|
|
50
|
+
|
|
49
51
|
Find the global npm root:
|
|
50
52
|
|
|
51
53
|
```bash
|
|
@@ -96,6 +98,20 @@ Quick secondary option:
|
|
|
96
98
|
|
|
97
99
|
Keep `-y` in `npx` configs. Without it, npm can wait for an interactive install confirmation that MCP hosts such as VS Code Copilot cannot answer, so the server appears to start but no tools are registered.
|
|
98
100
|
|
|
101
|
+
## Copilot Without MCP
|
|
102
|
+
|
|
103
|
+
If a Copilot organization disables MCP servers but terminal commands are allowed, use the packaged CLI workflow instead:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
browser-debug-mcp-bridge --standalone
|
|
107
|
+
bdmcp init-copilot
|
|
108
|
+
bdmcp health
|
|
109
|
+
bdmcp sessions --live
|
|
110
|
+
bdmcp summary @recommended
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The CLI exposes the same bridge tool handlers through local commands and a token-protected local gateway. See [Browser Debug CLI](docs/BROWSER_DEBUG_CLI.md).
|
|
114
|
+
|
|
99
115
|
## First Debug Session
|
|
100
116
|
|
|
101
117
|
1. Start your MCP client so it launches the bridge.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
export const COPILOT_INSTRUCTIONS_FILENAME = 'browser-debug-cli.instructions.md';
|
|
2
|
+
export const BROWSER_DEBUG_CLI_SKILL_NAME = 'browser-debug-cli';
|
|
3
|
+
export const BROWSER_DEBUG_AGENT_INSTRUCTIONS = `---
|
|
4
|
+
applyTo: "**"
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Browser Debug CLI
|
|
8
|
+
|
|
9
|
+
When browser debugging evidence is needed and MCP tools are unavailable, use the packaged CLI instead of guessing from source alone.
|
|
10
|
+
|
|
11
|
+
Start with:
|
|
12
|
+
|
|
13
|
+
\`\`\`bash
|
|
14
|
+
bdmcp health
|
|
15
|
+
bdmcp sessions --live
|
|
16
|
+
bdmcp summary @recommended
|
|
17
|
+
\`\`\`
|
|
18
|
+
|
|
19
|
+
Use session aliases:
|
|
20
|
+
|
|
21
|
+
- \`@recommended\` or \`@live\` for the best connected browser session
|
|
22
|
+
- \`@latest\` for the most recent persisted session
|
|
23
|
+
- \`@auto\` for connected session first, then latest
|
|
24
|
+
|
|
25
|
+
Useful commands:
|
|
26
|
+
|
|
27
|
+
\`\`\`bash
|
|
28
|
+
bdmcp console @recommended --level error
|
|
29
|
+
bdmcp live-console @recommended
|
|
30
|
+
bdmcp network @recommended --failures
|
|
31
|
+
bdmcp page-state @recommended
|
|
32
|
+
bdmcp snapshot @recommended --mode png
|
|
33
|
+
bdmcp tool run list_sessions --args-file browser-debug-args.json
|
|
34
|
+
\`\`\`
|
|
35
|
+
|
|
36
|
+
Prefer compact output unless raw JSON is required. Use \`--json\` for machine-readable output and \`--max-bytes\` to bound large responses.
|
|
37
|
+
`;
|
|
38
|
+
export const BROWSER_DEBUG_CLI_SKILL = `---
|
|
39
|
+
name: browser-debug-cli
|
|
40
|
+
description: Use when MCP tools are unavailable or blocked but terminal commands are allowed, and Codex needs browser debugging evidence from Browser Debug MCP Bridge. Provides workflows for using the packaged bdmcp CLI to inspect sessions, console logs, network failures, page state, snapshots, Lighthouse reports, and generic bridge tool calls.
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
# Browser Debug CLI
|
|
44
|
+
|
|
45
|
+
Use \`bdmcp\` when Browser Debug MCP Bridge evidence is needed and MCP tools are not available.
|
|
46
|
+
|
|
47
|
+
Start with:
|
|
48
|
+
|
|
49
|
+
\`\`\`bash
|
|
50
|
+
bdmcp health
|
|
51
|
+
bdmcp sessions --live
|
|
52
|
+
bdmcp summary @recommended
|
|
53
|
+
\`\`\`
|
|
54
|
+
|
|
55
|
+
Session aliases:
|
|
56
|
+
|
|
57
|
+
- \`@recommended\`: prefer a connected live session
|
|
58
|
+
- \`@live\`: connected live session
|
|
59
|
+
- \`@latest\`: most recent persisted session
|
|
60
|
+
- \`@auto\`: connected first, latest fallback
|
|
61
|
+
|
|
62
|
+
Common commands:
|
|
63
|
+
|
|
64
|
+
\`\`\`bash
|
|
65
|
+
bdmcp console @recommended --level error
|
|
66
|
+
bdmcp live-console @recommended
|
|
67
|
+
bdmcp network @recommended --failures
|
|
68
|
+
bdmcp page-state @recommended
|
|
69
|
+
bdmcp snapshot @recommended --mode png
|
|
70
|
+
bdmcp tool list
|
|
71
|
+
bdmcp tool schema list_sessions
|
|
72
|
+
bdmcp tool run list_sessions --args-file browser-debug-args.json --json
|
|
73
|
+
\`\`\`
|
|
74
|
+
|
|
75
|
+
Prefer compact output first. Use \`--json\` only when structured output is needed. Use \`--max-bytes\` for large responses.
|
|
76
|
+
|
|
77
|
+
If \`bdmcp health\` cannot connect, ask the user to start the bridge:
|
|
78
|
+
|
|
79
|
+
\`\`\`bash
|
|
80
|
+
browser-debug-mcp-bridge --standalone
|
|
81
|
+
\`\`\`
|
|
82
|
+
`;
|
|
83
|
+
export function getAgentInstructions() {
|
|
84
|
+
return BROWSER_DEBUG_AGENT_INSTRUCTIONS;
|
|
85
|
+
}
|
|
86
|
+
export function getSkillInstructions() {
|
|
87
|
+
return BROWSER_DEBUG_CLI_SKILL;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=agent-instructions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent-instructions.js","sourceRoot":"","sources":["../../src/cli/agent-instructions.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,6BAA6B,GAAG,mCAAmC,CAAC;AACjF,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB,CAAC;AAEhE,MAAM,CAAC,MAAM,gCAAgC,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAkC/C,CAAC;AAEF,MAAM,CAAC,MAAM,uBAAuB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA4CtC,CAAC;AAEF,MAAM,UAAU,oBAAoB;IAClC,OAAO,gCAAgC,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,uBAAuB,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { appendFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { getRuntimeDataDir } from '../runtime-paths.js';
|
|
4
|
+
export function appendCliAuditEvent(event) {
|
|
5
|
+
const path = join(getRuntimeDataDir(), 'cli-audit.ndjson');
|
|
6
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
7
|
+
appendFileSync(path, `${JSON.stringify({
|
|
8
|
+
ts: new Date().toISOString(),
|
|
9
|
+
...event,
|
|
10
|
+
})}\n`, 'utf8');
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=audit-log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"audit-log.js","sourceRoot":"","sources":["../../src/cli/audit-log.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAUxD,MAAM,UAAU,mBAAmB,CAAC,KAAoB;IACtD,MAAM,IAAI,GAAG,IAAI,CAAC,iBAAiB,EAAE,EAAE,kBAAkB,CAAC,CAAC;IAC3D,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC9C,cAAc,CACZ,IAAI,EACJ,GAAG,IAAI,CAAC,SAAS,CAAC;QAChB,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAC5B,GAAG,KAAK;KACT,CAAC,IAAI,EACN,MAAM,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
|
|
2
|
+
import { dirname, join } from 'path';
|
|
3
|
+
import { randomBytes } from 'crypto';
|
|
4
|
+
import { getRuntimeDataDir } from '../runtime-paths.js';
|
|
5
|
+
const CLI_TOKEN_FILE = 'cli-token.json';
|
|
6
|
+
export const CLI_TOKEN_HEADER = 'x-browser-debug-cli-token';
|
|
7
|
+
export function getCliTokenPath() {
|
|
8
|
+
return join(getRuntimeDataDir(), CLI_TOKEN_FILE);
|
|
9
|
+
}
|
|
10
|
+
function normalizeTokenRecord(value) {
|
|
11
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const record = value;
|
|
15
|
+
if (typeof record.token !== 'string' || record.token.length < 32) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
if (typeof record.createdAt !== 'string' || record.createdAt.length === 0) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return {
|
|
22
|
+
token: record.token,
|
|
23
|
+
createdAt: record.createdAt,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function readTokenRecord(path = getCliTokenPath()) {
|
|
27
|
+
if (!existsSync(path)) {
|
|
28
|
+
return null;
|
|
29
|
+
}
|
|
30
|
+
try {
|
|
31
|
+
return normalizeTokenRecord(JSON.parse(readFileSync(path, 'utf8')));
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function ensureCliToken() {
|
|
38
|
+
const tokenPath = getCliTokenPath();
|
|
39
|
+
const existing = readTokenRecord(tokenPath);
|
|
40
|
+
if (existing) {
|
|
41
|
+
return existing.token;
|
|
42
|
+
}
|
|
43
|
+
const record = {
|
|
44
|
+
token: randomBytes(32).toString('base64url'),
|
|
45
|
+
createdAt: new Date().toISOString(),
|
|
46
|
+
};
|
|
47
|
+
mkdirSync(dirname(tokenPath), { recursive: true });
|
|
48
|
+
writeFileSync(tokenPath, `${JSON.stringify(record, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 });
|
|
49
|
+
return record.token;
|
|
50
|
+
}
|
|
51
|
+
export function getBearerToken(value) {
|
|
52
|
+
if (typeof value !== 'string') {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
const match = /^Bearer\s+(.+)$/i.exec(value.trim());
|
|
56
|
+
return match?.[1];
|
|
57
|
+
}
|
|
58
|
+
export function isAuthorizedCliRequest(headers) {
|
|
59
|
+
const expected = ensureCliToken();
|
|
60
|
+
const headerValue = headers[CLI_TOKEN_HEADER] ?? headers[CLI_TOKEN_HEADER.toLowerCase()];
|
|
61
|
+
const explicitToken = Array.isArray(headerValue) ? headerValue[0] : headerValue;
|
|
62
|
+
const authorization = headers.authorization;
|
|
63
|
+
const bearer = Array.isArray(authorization) ? getBearerToken(authorization[0]) : getBearerToken(authorization);
|
|
64
|
+
return explicitToken === expected || bearer === expected;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/cli/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { getConnection } from '../db/index.js';
|
|
2
|
+
import { createToolRegistry, createV1ToolHandlers, createV2ToolHandlers, routeToolCall, } from '../mcp/server.js';
|
|
3
|
+
import { createToolLoopGuard } from '../mcp/tool-loop-guard.js';
|
|
4
|
+
import { getAgentInstructions } from './agent-instructions.js';
|
|
5
|
+
import { ensureCliToken, isAuthorizedCliRequest } from './auth.js';
|
|
6
|
+
function getHeaders(request) {
|
|
7
|
+
return request.headers;
|
|
8
|
+
}
|
|
9
|
+
function requireCliAuthorization(request, reply) {
|
|
10
|
+
if (isAuthorizedCliRequest(getHeaders(request))) {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
13
|
+
void reply.code(401).send({
|
|
14
|
+
ok: false,
|
|
15
|
+
error: 'CLI authorization required',
|
|
16
|
+
hint: 'Use the packaged bdmcp CLI so it can read the local CLI token automatically.',
|
|
17
|
+
});
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
function serializeTools(tools) {
|
|
21
|
+
return tools.map((tool) => ({
|
|
22
|
+
name: tool.name,
|
|
23
|
+
description: tool.description,
|
|
24
|
+
inputSchema: tool.inputSchema,
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
export function createCliToolRegistry(options) {
|
|
28
|
+
const captureClient = {
|
|
29
|
+
execute: async (sessionId, command, payload, timeoutMs) => {
|
|
30
|
+
const manager = options.getWebSocketManager();
|
|
31
|
+
if (!manager) {
|
|
32
|
+
return {
|
|
33
|
+
ok: false,
|
|
34
|
+
payload: {},
|
|
35
|
+
error: 'WebSocket manager unavailable. Start the bridge runtime before using live CLI tools.',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return manager.sendCaptureCommand(sessionId, command, payload, timeoutMs);
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const getSessionConnectionState = (sessionId) => {
|
|
42
|
+
const manager = options.getWebSocketManager();
|
|
43
|
+
const state = manager?.getSessionConnectionState(sessionId);
|
|
44
|
+
if (!state) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return {
|
|
48
|
+
connected: state.connected,
|
|
49
|
+
connectedAt: state.connectedAt,
|
|
50
|
+
lastHeartbeatAt: state.lastHeartbeatAt,
|
|
51
|
+
disconnectedAt: state.disconnectedAt,
|
|
52
|
+
disconnectReason: state.disconnectReason,
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
return createToolRegistry({
|
|
56
|
+
...createV1ToolHandlers(() => getConnection().db, getSessionConnectionState),
|
|
57
|
+
...createV2ToolHandlers(captureClient, () => getConnection().db, getSessionConnectionState),
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
export function registerCliGateway(fastify, options) {
|
|
61
|
+
ensureCliToken();
|
|
62
|
+
const loopGuard = createToolLoopGuard({
|
|
63
|
+
getDb: () => getConnection().db,
|
|
64
|
+
onEvent: (event) => {
|
|
65
|
+
fastify.log.info({
|
|
66
|
+
component: 'cli-gateway',
|
|
67
|
+
...event,
|
|
68
|
+
}, `[CLI][Gateway] ${event.event}`);
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
fastify.get('/cli/tools', async () => {
|
|
72
|
+
const tools = createCliToolRegistry(options);
|
|
73
|
+
return {
|
|
74
|
+
ok: true,
|
|
75
|
+
tools: serializeTools(tools),
|
|
76
|
+
};
|
|
77
|
+
});
|
|
78
|
+
fastify.get('/cli/agent-instructions', async () => {
|
|
79
|
+
return {
|
|
80
|
+
ok: true,
|
|
81
|
+
instructions: getAgentInstructions(),
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
fastify.post('/cli/tools/:toolName', async (request, reply) => {
|
|
85
|
+
if (!requireCliAuthorization(request, reply)) {
|
|
86
|
+
return reply;
|
|
87
|
+
}
|
|
88
|
+
const params = request.params;
|
|
89
|
+
const toolName = params.toolName;
|
|
90
|
+
if (!toolName) {
|
|
91
|
+
return reply.code(400).send({ ok: false, error: 'toolName is required' });
|
|
92
|
+
}
|
|
93
|
+
const body = request.body && typeof request.body === 'object' && !Array.isArray(request.body)
|
|
94
|
+
? request.body
|
|
95
|
+
: {};
|
|
96
|
+
const input = body.arguments && typeof body.arguments === 'object' && !Array.isArray(body.arguments)
|
|
97
|
+
? body.arguments
|
|
98
|
+
: body;
|
|
99
|
+
try {
|
|
100
|
+
const response = await routeToolCall(createCliToolRegistry(options), toolName, input, { loopGuard });
|
|
101
|
+
return {
|
|
102
|
+
ok: true,
|
|
103
|
+
toolName,
|
|
104
|
+
response,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
catch (error) {
|
|
108
|
+
return reply.code(400).send({
|
|
109
|
+
ok: false,
|
|
110
|
+
toolName,
|
|
111
|
+
error: error instanceof Error ? error.message : 'CLI tool call failed',
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=gateway.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway.js","sourceRoot":"","sources":["../../src/cli/gateway.ts"],"names":[],"mappings":"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"}
|