@cocorograph/hub-agent 0.6.37 → 0.6.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cocorograph/hub-agent",
3
- "version": "0.6.37",
3
+ "version": "0.6.38",
4
4
  "description": "Hub Hosted Cockpit のローカル常駐 agent。Hub と outbound WSS で接続し、ローカルの tmux/pty を中継する。",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",
@@ -998,6 +998,17 @@ class ClaudeStreamSession {
998
998
  }
999
999
  }
1000
1000
 
1001
+ /** このセッションの常駐 query 内で MCP サーバーを再接続する (動作中チャットへ波及)。
1002
+ * 常駐 query が無い (per-message セッション) 場合は false。per-message は毎ターン
1003
+ * 新プロセスで MCP を張り直すため、次メッセージで自動的に再接続される。
1004
+ * @returns {Promise<boolean>} 再接続を発行できたら true */
1005
+ async reconnectMcp(serverName) {
1006
+ const q = this._residentQuery
1007
+ if (!q || typeof q.reconnectMcpServer !== "function") return false
1008
+ await q.reconnectMcpServer(serverName)
1009
+ return true
1010
+ }
1011
+
1001
1012
  /**
1002
1013
  * graceful detach: 実行中ターンがあれば中断せず完走を待つ (完走後に finally で
1003
1014
  * 自動クローズ + onReap)。アイドルなら即クローズする。
@@ -1360,7 +1371,7 @@ export class ClaudeStreamBridge extends EventEmitter {
1360
1371
  return await q.mcpServerStatus()
1361
1372
  }
1362
1373
 
1363
- /** 指定 MCP サーバーを再接続し、最新状態一覧を返す。 */
1374
+ /** 指定 MCP サーバーを control 専用 query 内で再接続し、最新状態一覧を返す。 */
1364
1375
  async reconnectMcp(serverName) {
1365
1376
  const q = await this._ensureMcpControlQuery()
1366
1377
  this._armMcpControlIdle()
@@ -1368,6 +1379,32 @@ export class ClaudeStreamBridge extends EventEmitter {
1368
1379
  return await q.mcpServerStatus()
1369
1380
  }
1370
1381
 
1382
+ /** 指定 MCP サーバーを「動作中の全 resident セッション」+ control query で再接続する。
1383
+ * MCP 接続はプロセス単位のため、control query だけ張り直しても動作中チャットには
1384
+ * 波及しない。そこで全 resident セッションの常駐 query にも reconnect を発行し、
1385
+ * 会話中の MCP 接続を実際に張り直す。reconnect は冪等なので多重発行は無害。
1386
+ * @returns {Promise<{servers: object[], targeted: number}>}
1387
+ * servers: control query の最新状態 (popover 表示用) / targeted: 波及したセッション数 */
1388
+ async reconnectMcpAllSessions(serverName) {
1389
+ const seen = new Set()
1390
+ let targeted = 0
1391
+ for (const session of this.sessions.values()) {
1392
+ if (seen.has(session)) continue
1393
+ seen.add(session)
1394
+ try {
1395
+ if (await session.reconnectMcp(serverName)) targeted += 1
1396
+ } catch (err) {
1397
+ this.logger?.warn(
1398
+ { err: err?.message, server: serverName },
1399
+ "session mcp reconnect failed",
1400
+ )
1401
+ }
1402
+ }
1403
+ // control query も張り直して popover 表示用の最新状態を返す。
1404
+ const servers = await this.reconnectMcp(serverName)
1405
+ return { servers, targeted }
1406
+ }
1407
+
1371
1408
  /** 指定 MCP サーバーの OAuth 認証を開始する。認可 URL を含む応答を返す。 */
1372
1409
  async mcpAuthenticate(serverName, redirectUri) {
1373
1410
  const q = await this._ensureMcpControlQuery()
package/src/main.mjs CHANGED
@@ -990,11 +990,14 @@ async function dispatch(msg, ctx) {
990
990
  case "claude.mcp.status":
991
991
  result = { servers: await ctx.claudeBridge.mcpStatus() }
992
992
  break
993
- case "claude.mcp.reconnect":
994
- result = {
995
- servers: await ctx.claudeBridge.reconnectMcp(msg.server_name),
996
- }
993
+ case "claude.mcp.reconnect": {
994
+ // 動作中の全 resident セッション + control query を再接続 (会話中の MCP に波及)。
995
+ const r = await ctx.claudeBridge.reconnectMcpAllSessions(
996
+ msg.server_name,
997
+ )
998
+ result = { servers: r.servers, targeted: r.targeted }
997
999
  break
1000
+ }
998
1001
  case "claude.mcp.authenticate":
999
1002
  result = {
1000
1003
  auth: await ctx.claudeBridge.mcpAuthenticate(
@@ -1003,14 +1006,20 @@ async function dispatch(msg, ctx) {
1003
1006
  ),
1004
1007
  }
1005
1008
  break
1006
- case "claude.mcp.callback":
1007
- result = {
1008
- auth: await ctx.claudeBridge.mcpSubmitOAuthCallback(
1009
- msg.server_name,
1010
- msg.callback_url,
1011
- ),
1012
- }
1009
+ case "claude.mcp.callback": {
1010
+ const auth = await ctx.claudeBridge.mcpSubmitOAuthCallback(
1011
+ msg.server_name,
1012
+ msg.callback_url,
1013
+ )
1014
+ // 再認証で得たトークンはディスクに永続するが、動作中セッションは別プロセス
1015
+ // のため自動では拾わない。全 resident セッション + control query を再接続し、
1016
+ // 会話中もすぐ新トークンで使えるようにする。
1017
+ const r = await ctx.claudeBridge.reconnectMcpAllSessions(
1018
+ msg.server_name,
1019
+ )
1020
+ result = { auth, servers: r.servers, targeted: r.targeted }
1013
1021
  break
1022
+ }
1014
1023
  case "claude.mcp.clearauth":
1015
1024
  result = {
1016
1025
  cleared: await ctx.claudeBridge.mcpClearAuth(msg.server_name),