@link-assistant/hive-mind 2.0.4 → 2.0.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # @link-assistant/hive-mind
2
2
 
3
+ ## 2.0.5
4
+
5
+ ### Patch Changes
6
+
7
+ - d815c7d: Treat a Claude Code `pending` Playwright MCP `system.init` status as a normal
8
+ still-connecting state instead of a failure (#1901). Claude Code enables Tool
9
+ Search by default, so the deferred `mcp__playwright__*` browser tools load on
10
+ demand and Claude waits for the connecting server before using them. Hive Mind
11
+ no longer aborts the working session on a `pending` status; only a terminal
12
+ `failed`/`error` status surfaces a non-blocking diagnostic in the session-start
13
+ comment. See `docs/case-studies/issue-1901`.
14
+
3
15
  ## 2.0.4
4
16
 
5
17
  ### Patch Changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@link-assistant/hive-mind",
3
- "version": "2.0.4",
3
+ "version": "2.0.5",
4
4
  "description": "AI-powered issue solver and hive mind for collaborative problem solving",
5
5
  "main": "src/hive.mjs",
6
6
  "type": "module",
@@ -1,21 +1,36 @@
1
1
  const PLAYWRIGHT_TOOL_PREFIX = 'mcp__playwright__';
2
2
 
3
- export const isUnavailableMcpStatus = status => {
3
+ // A `pending` (or `connecting`) MCP server is still being connected/reconnected
4
+ // in the background. It is NOT a failure: Claude Code enables Tool Search by
5
+ // default, so MCP tools are deferred and load on demand, and Claude waits for a
6
+ // still-connecting server before it uses one of that server's tools. See
7
+ // https://code.claude.com/docs/en/mcp and issue #1901.
8
+ export const isConnectingMcpStatus = status => /\b(pending|connecting)\b/i.test(String(status || ''));
9
+
10
+ // Terminal/unhealthy states where the MCP client has given up (or the server is
11
+ // turned off). Claude Code reconnects an HTTP/SSE server with exponential
12
+ // backoff and only marks it `failed` after the attempts are exhausted; at that
13
+ // point the server's tools never load.
14
+ export const isFailedMcpStatus = status => {
4
15
  const normalized = String(status || '').toLowerCase();
5
- return /\b(pending|disabled|failed|error|disconnected|not[-_\s]+connected|unavailable|timed[-_\s]+out)\b|(?:^|[^a-z0-9_-])timeout(?:$|[^a-z0-9_-])/.test(normalized);
16
+ return /\b(disabled|failed|error|disconnected|not[-_\s]+connected|unavailable|timed[-_\s]+out)\b|(?:^|[^a-z0-9_-])timeout(?:$|[^a-z0-9_-])/.test(normalized);
6
17
  };
7
18
 
19
+ // Backwards-compatible umbrella: any non-connected status (still connecting OR
20
+ // failed). Prefer the narrower helpers above when the connecting/failed
21
+ // distinction matters (e.g. whether to warn a human reviewer).
22
+ export const isUnavailableMcpStatus = status => isConnectingMcpStatus(status) || isFailedMcpStatus(status);
23
+
8
24
  export const hasPlaywrightMcpTools = tools => (Array.isArray(tools) ? tools : []).some(tool => String(tool || '').startsWith(PLAYWRIGHT_TOOL_PREFIX));
9
25
 
10
26
  export const formatInteractiveMcpServerStatus = server => {
11
27
  const name = server?.name || 'unknown';
12
28
  const status = String(server?.status || 'unknown').trim() || 'unknown';
13
- const normalizedStatus = status.toLowerCase();
14
29
  let displayStatus = status;
15
30
 
16
- if (normalizedStatus === 'pending') {
17
- displayStatus = 'pending - not connected; MCP tools unavailable';
18
- } else if (isUnavailableMcpStatus(status)) {
31
+ if (isConnectingMcpStatus(status)) {
32
+ displayStatus = `${status} - connecting; tools load on demand via Tool Search`;
33
+ } else if (isFailedMcpStatus(status)) {
19
34
  displayStatus = `${status} - MCP tools unavailable`;
20
35
  }
21
36
 
@@ -29,10 +44,16 @@ export const getInteractiveMcpDiagnostics = (mcpServers = [], tools = []) => {
29
44
  for (const server of servers) {
30
45
  const name = String(server?.name || '').toLowerCase();
31
46
  if (!name.includes('playwright')) continue;
32
- if (!isUnavailableMcpStatus(server?.status)) continue;
47
+ // With Tool Search the deferred `mcp__playwright__*` tools are intentionally
48
+ // absent from system.init `tools`, so their absence is not a problem by
49
+ // itself. If they are already present the server is fully connected.
33
50
  if (hasPlaywrightMcpTools(tools)) continue;
51
+ // `pending`/`connecting` is the normal startup state — Claude waits for the
52
+ // server before using a browser tool — so only warn when the MCP client has
53
+ // actually failed to connect.
54
+ if (!isFailedMcpStatus(server?.status)) continue;
34
55
 
35
- diagnostics.push(`⚠️ Playwright MCP server is ${server?.status || 'unknown'}, but no \`${PLAYWRIGHT_TOOL_PREFIX}*\` browser tools were exposed. Browser automation hints are disabled until the MCP client reports the server as connected.`);
56
+ diagnostics.push(`⚠️ Playwright MCP server is ${server?.status || 'unknown'} (failed to connect), so no \`${PLAYWRIGHT_TOOL_PREFIX}*\` browser tools are available. Browser automation stays disabled until the MCP server connects.`);
36
57
  }
37
58
 
38
59
  return diagnostics;