@1presence/bridge 0.83.0 → 0.84.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.
Files changed (2) hide show
  1. package/dist/claude.js +28 -0
  2. package/package.json +1 -1
package/dist/claude.js CHANGED
@@ -127,16 +127,25 @@ const PERMISSION_TRANSPORT_DEAD_RE = /Tool permission request failed/i;
127
127
  export function isPermissionTransportFailure(text) {
128
128
  return PERMISSION_TRANSPORT_DEAD_RE.test(text);
129
129
  }
130
+ const MCP_TOOL_UNREGISTERED_RE = /No such tool available:\s*mcp__1presence__/i;
130
131
  export function shouldReconnectRemoteMcp(args) {
131
132
  const { toolName, isError, text } = args;
132
133
  if (MCP_SESSION_EXPIRED_RE.test(text))
133
134
  return true;
135
+ if (MCP_TOOL_UNREGISTERED_RE.test(text))
136
+ return true;
134
137
  if (!isError || !toolName.startsWith('mcp__1presence__'))
135
138
  return false;
136
139
  if (OUTBOUND_NETWORK_TOOLS.has(toolName))
137
140
  return false;
138
141
  return MCP_TRANSPORT_DEAD_RE.test(text);
139
142
  }
143
+ export function assessRemoteMcpSurface(init) {
144
+ const entry = (init.mcp_servers ?? []).find((s) => s?.name === REMOTE_MCP_SERVER_NAME);
145
+ const status = entry?.status ?? 'absent';
146
+ const toolCount = (init.tools ?? []).filter((t) => t.startsWith('mcp__1presence__')).length;
147
+ return { status, toolCount, usable: status === 'connected' && toolCount > 0 };
148
+ }
140
149
  function toolResultText(content) {
141
150
  if (typeof content === 'string')
142
151
  return content;
@@ -551,6 +560,25 @@ export function spawnClaude(params) {
551
560
  const event = { type: 'system', subtype: 'init', model: init.model, apiKeySource: init.apiKeySource, claude_code_version: init.claude_code_version };
552
561
  if (handleEvent(event))
553
562
  onEvent(event);
563
+ const surface = assessRemoteMcpSurface(m);
564
+ process.stderr.write(paint(surface.usable ? SECTION_COLORS.system : SECTION_COLORS.error, `[bridge] mcp surface: ${REMOTE_MCP_SERVER_NAME}=${surface.status}, ${surface.toolCount} tool(s)`) + '\n');
565
+ if (!surface.usable) {
566
+ let detail = '';
567
+ try {
568
+ const statuses = await q.mcpServerStatus();
569
+ const remote = statuses.find((st) => st.name === REMOTE_MCP_SERVER_NAME);
570
+ if (remote?.error)
571
+ detail = ` — ${remote.error.replace(/\s+/g, ' ').trim().slice(0, 300)}`;
572
+ }
573
+ catch { }
574
+ process.stderr.write(paint(SECTION_COLORS.error, `[bridge] FATAL no 1Presence tools this turn (${surface.status}) — ending the turn rather than answering blind${detail}`) + '\n');
575
+ active.delete(conversationId);
576
+ clearTimeout(inputReleaseTimer);
577
+ input.release();
578
+ abort.abort();
579
+ onError('Local Mode could not reach your 1Presence tools, so nothing was read or changed. Please send that again.', usage, extractedModel);
580
+ return;
581
+ }
554
582
  }
555
583
  else if (subtype === 'api_retry') {
556
584
  const r = m;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@1presence/bridge",
3
- "version": "0.83.0",
3
+ "version": "0.84.0",
4
4
  "description": "Run 1Presence on your Mac and use your Claude.ai Pro subscription from any device",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",