@chatpanel/bridge 0.10.36 → 0.10.38
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/package.json +1 -1
- package/src/engines/cli-agents.js +16 -4
- package/src/engines/custom.js +36 -4
- package/src/server.js +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chatpanel/bridge",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.38",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Local bridge that exposes the AI coding agents installed on your machine \u2014 Claude Code (CLI), Codex (CLI), and Antigravity CLI (formerly Gemini CLI, which remains available for business/enterprise) \u2014 to the ChatPanel Chrome extension over a localhost SSE endpoint. Bring your own agent.",
|
|
6
6
|
"keywords": [
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
// kiro — kiro-cli chat --no-interactive "<prompt>" · --model · --list-models
|
|
9
9
|
// hermes — hermes -z "<prompt>" · -m model · config get model (no list command)
|
|
10
10
|
|
|
11
|
-
import { runSpec, listSpecModels, runForStdout } from './custom.js';
|
|
12
|
-
import { findAgentBin } from '../env.js';
|
|
11
|
+
import { runSpec, listSpecModels, runForStdout, CHATPANEL_STABLE_MCP_URL } from './custom.js';
|
|
12
|
+
import { findAgentBin, selfMcpStdio } from '../env.js';
|
|
13
13
|
|
|
14
14
|
// `listModels` override hook: a CLI whose model listing isn't "one id per line"
|
|
15
15
|
// (Copilot prints a quoted list inside `help config`) passes its own parser here
|
|
@@ -275,8 +275,20 @@ export const hermes = makeCliAgent(
|
|
|
275
275
|
requiresStableMcp: true,
|
|
276
276
|
autoSetupStableMcp: true,
|
|
277
277
|
stableMcpConfigCheck: 'hermes',
|
|
278
|
-
|
|
279
|
-
|
|
278
|
+
// STDIO, not --url. Hermes's bundled MCP client has no HTTP transport ("requires HTTP
|
|
279
|
+
// transport but mcp.client.streamable_http is not available"), so a URL registration
|
|
280
|
+
// saves a config that can never connect. The bridge also speaks MCP over stdio — the
|
|
281
|
+
// same mode Codex uses — so we register that instead. A function because the executable
|
|
282
|
+
// is only known at runtime (a compiled binary runs itself; under node it re-runs its
|
|
283
|
+
// entry script). `--args` must come last, per `hermes mcp add`.
|
|
284
|
+
stableMcpSetupArgs: () => {
|
|
285
|
+
const { command, args } = selfMcpStdio(CHATPANEL_STABLE_MCP_URL);
|
|
286
|
+
return ['mcp', 'add', 'chatpanel_browser', '--command', command, '--args', ...args];
|
|
287
|
+
},
|
|
288
|
+
stableMcpSetupCommand: (() => {
|
|
289
|
+
const { command, args } = selfMcpStdio(CHATPANEL_STABLE_MCP_URL);
|
|
290
|
+
return `hermes mcp add chatpanel_browser --command ${command} --args ${args.join(' ')}`;
|
|
291
|
+
})(),
|
|
280
292
|
label: 'Hermes',
|
|
281
293
|
},
|
|
282
294
|
'hermes not found on PATH. Install Hermes Agent, then run `hermes setup` to sign in.',
|
package/src/engines/custom.js
CHANGED
|
@@ -64,7 +64,7 @@ const IDLE_MS = Number(process.env.CHATPANEL_CUSTOM_TIMEOUT_MS) || 180_000;
|
|
|
64
64
|
// ANSI stripping moved to stream-formats.js (imported above), which is where
|
|
65
65
|
// text output is actually rendered - one implementation for every format.
|
|
66
66
|
const OPENCODE_STABLE_MCP_URL = 'http://127.0.0.1:4319/mcp';
|
|
67
|
-
const CHATPANEL_STABLE_MCP_URL = 'http://127.0.0.1:4319/mcp';
|
|
67
|
+
export const CHATPANEL_STABLE_MCP_URL = 'http://127.0.0.1:4319/mcp';
|
|
68
68
|
|
|
69
69
|
export async function available() {
|
|
70
70
|
// The engine ships in every bridge; individual custom agents are user-defined
|
|
@@ -167,7 +167,10 @@ export function stableMcpSetupCommand(spec = {}) {
|
|
|
167
167
|
}
|
|
168
168
|
|
|
169
169
|
export function stableMcpSetupPlan(spec = {}) {
|
|
170
|
-
|
|
170
|
+
// A FUNCTION is allowed as well as an array: a stdio registration has to name the bridge's
|
|
171
|
+
// own executable, which is only known at runtime (compiled binary vs. node + entry script).
|
|
172
|
+
const raw = typeof spec.stableMcpSetupArgs === 'function' ? spec.stableMcpSetupArgs() : spec.stableMcpSetupArgs;
|
|
173
|
+
const args = Array.isArray(raw) ? raw.filter((a) => a != null).map(String) : null;
|
|
171
174
|
if (!args?.length) return null;
|
|
172
175
|
return { command: spec.stableMcpSetupCommandName || spec.command, args };
|
|
173
176
|
}
|
|
@@ -348,6 +351,20 @@ async function runStableMcpSetup(plan, cwd) {
|
|
|
348
351
|
});
|
|
349
352
|
}
|
|
350
353
|
|
|
354
|
+
// Turn a browser-tool setup failure into something the user can act on. The CLI's own words
|
|
355
|
+
// are the most accurate signal available, so we forward them — but when they name a missing
|
|
356
|
+
// SDK we say the fix, rather than repeating an `mcp add` that will fail identically.
|
|
357
|
+
export function mcpSetupHint(label, err) {
|
|
358
|
+
const msg = String(err?.message || err || '');
|
|
359
|
+
if (/mcp['" ]* Python SDK|No module named ['"]?mcp|MCP support/i.test(msg)) {
|
|
360
|
+
return `${label} has no MCP support installed. Run \`hermes setup\` (or install the \`mcp\` package in its environment), then retry.`;
|
|
361
|
+
}
|
|
362
|
+
if (/streamable_http|HTTP transport/i.test(msg)) {
|
|
363
|
+
return `${label}'s MCP client has no HTTP transport; ChatPanel registers a stdio server instead. Upgrade its \`mcp\` package if this persists.`;
|
|
364
|
+
}
|
|
365
|
+
return msg.slice(0, 200) || 'the CLI could not register the tools';
|
|
366
|
+
}
|
|
367
|
+
|
|
351
368
|
export async function ensureStableMcpConfig(spec, cwd, label, emit, deps = {}) {
|
|
352
369
|
if (!spec.requiresStableMcp) return true;
|
|
353
370
|
const hasConfig = deps.hasConfig || hasStableMcpConfig;
|
|
@@ -471,10 +488,25 @@ export async function runSpec(spec, { messages, system, options = {}, images },
|
|
|
471
488
|
: [...tmpl.split(/\s+/).filter(Boolean), cfgFile];
|
|
472
489
|
args = [...tokens, ...args];
|
|
473
490
|
}
|
|
474
|
-
if (options.mcp?.url) args.push(...mcpTrustArgs(spec, options.mcp));
|
|
475
491
|
// Some CLIs only load MCP from their persistent config, so ensure that stable
|
|
476
492
|
// /mcp endpoint is present before letting the agent answer with no tools.
|
|
477
|
-
|
|
493
|
+
//
|
|
494
|
+
// DEGRADE, DON'T FAIL. Browser tools are an ENHANCEMENT on top of a CLI that already has
|
|
495
|
+
// its own; a turn that could have been answered should not die because they couldn't be
|
|
496
|
+
// registered. (Hermes ships without the `mcp` Python SDK unless `hermes setup` installed
|
|
497
|
+
// it, so every tool-armed turn failed — and the error told the user to run a command that
|
|
498
|
+
// fails the same way.) We now say what happened, drop the browser tools, and answer.
|
|
499
|
+
if (options.mcp?.url) {
|
|
500
|
+
try {
|
|
501
|
+
await ensureStableMcpConfig(spec, cwd, label, emit);
|
|
502
|
+
} catch (e) {
|
|
503
|
+
emit({ type: 'status', text: `${label}: continuing without ChatPanel's browser tools — ${mcpSetupHint(label, e)}` });
|
|
504
|
+
options = { ...options, mcp: null };
|
|
505
|
+
}
|
|
506
|
+
}
|
|
507
|
+
// Trust flags only make sense once the server is actually registered — pushing them for
|
|
508
|
+
// tools we then dropped would widen the CLI's permissions for nothing.
|
|
509
|
+
if (options.mcp?.url) args.push(...mcpTrustArgs(spec, options.mcp));
|
|
478
510
|
|
|
479
511
|
// Model via a CONFIG-PATCH FILE, for agents with no --model flag (dsh takes the
|
|
480
512
|
// model as a Cordis config overlay: `--patch <file>` replacing one row by id).
|
package/src/server.js
CHANGED
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
// Hardcoded (not read from package.json) so it survives Bun's single-file
|
|
68
68
|
// --compile, where package.json isn't on a readable FS. CI fails the publish if
|
|
69
69
|
// this drifts from package.json, so the two can't silently diverge.
|
|
70
|
-
const VERSION = '0.10.
|
|
70
|
+
const VERSION = '0.10.38';
|
|
71
71
|
const HOST = process.env.CHATPANEL_BRIDGE_HOST || '127.0.0.1';
|
|
72
72
|
const PORT = Number(process.env.CHATPANEL_BRIDGE_PORT) || 4319;
|
|
73
73
|
|