reasonix 0.47.2 → 0.48.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 (122) hide show
  1. package/README.md +5 -26
  2. package/README.zh-CN.md +5 -26
  3. package/dist/cli/{acp-GEOAKSTU.js → acp-4ROCGYNH.js} +17 -17
  4. package/dist/cli/{chat-YTPATMMG.js → chat-GZNB5625.js} +24 -24
  5. package/dist/cli/{chunk-BQ6HC66J.js → chunk-2QSTA2QV.js} +3 -13
  6. package/dist/cli/chunk-2QSTA2QV.js.map +1 -0
  7. package/dist/cli/{chunk-DQ6K5ZQ7.js → chunk-3WGTGXO4.js} +2 -2
  8. package/dist/cli/{chunk-6QC5RQLE.js → chunk-5OHHAQ4W.js} +2 -2
  9. package/dist/cli/{chunk-XMHP7BEE.js → chunk-6MZTZO7A.js} +514 -791
  10. package/dist/cli/chunk-6MZTZO7A.js.map +1 -0
  11. package/dist/cli/chunk-7M4YYMKW.js +5198 -0
  12. package/dist/cli/chunk-7M4YYMKW.js.map +1 -0
  13. package/dist/cli/{chunk-KYQVQ5X4.js → chunk-B5CZL2SE.js} +9 -4
  14. package/dist/cli/chunk-B5CZL2SE.js.map +1 -0
  15. package/dist/cli/chunk-CDVSFSAK.js +17732 -0
  16. package/dist/cli/chunk-CDVSFSAK.js.map +1 -0
  17. package/dist/cli/{chunk-TRWHTFG7.js → chunk-DOWEOA6E.js} +2 -2
  18. package/dist/cli/chunk-EMMENC4O.js +831 -0
  19. package/dist/cli/chunk-EMMENC4O.js.map +1 -0
  20. package/dist/cli/{chunk-TDHXB2ER.js → chunk-H4CCXMDD.js} +2 -2
  21. package/dist/cli/{chunk-T5A7EY6B.js → chunk-HR5NBKEM.js} +2 -2
  22. package/dist/cli/{chunk-CNG32VAB.js → chunk-I4M5QJNL.js} +2 -2
  23. package/dist/cli/{chunk-5QCB62C4.js → chunk-J2TQAWOM.js} +135 -18
  24. package/dist/cli/{chunk-5QCB62C4.js.map → chunk-J2TQAWOM.js.map} +1 -1
  25. package/dist/cli/{chunk-DN4B5S6Y.js → chunk-JMDE6IO3.js} +2 -2
  26. package/dist/cli/{chunk-4MFCAZ2W.js → chunk-MOJYKO2A.js} +3 -3
  27. package/dist/cli/{chunk-HUILPCYX.js → chunk-MRZG4GBF.js} +3 -3
  28. package/dist/cli/{chunk-GH7DC2Y5.js → chunk-NMQSUNLB.js} +2 -2
  29. package/dist/cli/{chunk-ZXSCAODE.js → chunk-OB4BUJBL.js} +67 -2
  30. package/dist/cli/chunk-OB4BUJBL.js.map +1 -0
  31. package/dist/cli/{chunk-QCFLPSPH.js → chunk-OG5JANQ4.js} +2 -2
  32. package/dist/cli/{chunk-JBH5RM7X.js → chunk-OPYALNTT.js} +326 -55
  33. package/dist/cli/chunk-OPYALNTT.js.map +1 -0
  34. package/dist/cli/{chunk-CCJAP7G3.js → chunk-RUDBUHO4.js} +2 -2
  35. package/dist/cli/{chunk-2XY77LW7.js → chunk-S2RMQULY.js} +56 -24
  36. package/dist/cli/chunk-S2RMQULY.js.map +1 -0
  37. package/dist/cli/{chunk-DWPAKZTY.js → chunk-TE5UIIFL.js} +2 -2
  38. package/dist/cli/{chunk-KVZZ5U75.js → chunk-V4Y732RQ.js} +2 -2
  39. package/dist/cli/{chunk-TRSAHHCL.js → chunk-WZGNXR6E.js} +3 -3
  40. package/dist/cli/chunk-WZGNXR6E.js.map +1 -0
  41. package/dist/cli/{chunk-NRQ5UP5T.js → chunk-YW63N3ZR.js} +116 -28
  42. package/dist/cli/chunk-YW63N3ZR.js.map +1 -0
  43. package/dist/cli/{code-Q4NRVEDG.js → code-PMPJWXEO.js} +30 -31
  44. package/dist/cli/code-PMPJWXEO.js.map +1 -0
  45. package/dist/cli/{commands-4CDI4GFM.js → commands-QS6TG4G3.js} +4 -4
  46. package/dist/cli/{commit-GW7LDQP5.js → commit-XPRSKUBF.js} +3 -3
  47. package/dist/cli/{desktop-EG6P5SF2.js → desktop-562OPWIU.js} +461 -43
  48. package/dist/cli/desktop-562OPWIU.js.map +1 -0
  49. package/dist/cli/{diff-VI2YX4FN.js → diff-I6W4AUWJ.js} +8 -8
  50. package/dist/cli/{doctor-CQTTZP27.js → doctor-6XVZKT4U.js} +9 -9
  51. package/dist/cli/index.js +52 -40
  52. package/dist/cli/index.js.map +1 -1
  53. package/dist/cli/{mcp-J2UCD4RZ.js → mcp-7W7ANO2Y.js} +2 -2
  54. package/dist/cli/{mcp-browse-GSX34JEK.js → mcp-browse-LA4I4YIZ.js} +2 -2
  55. package/dist/cli/{mcp-inspect-RRFYF4ZV.js → mcp-inspect-LWXXU7BY.js} +2 -2
  56. package/dist/cli/{prompt-5TQPIVHV.js → prompt-RKZD4X6Y.js} +3 -3
  57. package/dist/cli/{replay-MJCEMODU.js → replay-2X7MVXOI.js} +8 -8
  58. package/dist/cli/{run-P4D5VDYE.js → run-TPKXIJ27.js} +13 -13
  59. package/dist/cli/{server-C25JNNZV.js → server-NHQ3QXOZ.js} +15 -14
  60. package/dist/cli/{server-C25JNNZV.js.map → server-NHQ3QXOZ.js.map} +1 -1
  61. package/dist/cli/{sessions-QIONZJQ6.js → sessions-2A4DGSHA.js} +12 -12
  62. package/dist/cli/{setup-NLQ6G5G4.js → setup-GOLP7J4C.js} +5 -5
  63. package/dist/cli/{stats-DFZEXHP4.js → stats-CGDAFDKI.js} +6 -6
  64. package/dist/cli/{version-GR3X3MPI.js → version-FIL4ZFOS.js} +12 -12
  65. package/dist/grammars/tree-sitter-go.wasm +0 -0
  66. package/dist/grammars/tree-sitter-java.wasm +0 -0
  67. package/dist/grammars/tree-sitter-javascript.wasm +0 -0
  68. package/dist/grammars/tree-sitter-python.wasm +0 -0
  69. package/dist/grammars/tree-sitter-rust.wasm +0 -0
  70. package/dist/grammars/tree-sitter-tsx.wasm +0 -0
  71. package/dist/grammars/tree-sitter-typescript.wasm +0 -0
  72. package/dist/grammars/web-tree-sitter.wasm +0 -0
  73. package/dist/index.d.ts +38 -10
  74. package/dist/index.js +488 -87
  75. package/dist/index.js.map +1 -1
  76. package/package.json +12 -3
  77. package/dist/cli/chunk-2XY77LW7.js.map +0 -1
  78. package/dist/cli/chunk-6CRPCJAU.js +0 -3141
  79. package/dist/cli/chunk-6CRPCJAU.js.map +0 -1
  80. package/dist/cli/chunk-BQ6HC66J.js.map +0 -1
  81. package/dist/cli/chunk-JBH5RM7X.js.map +0 -1
  82. package/dist/cli/chunk-KYQVQ5X4.js.map +0 -1
  83. package/dist/cli/chunk-NRQ5UP5T.js.map +0 -1
  84. package/dist/cli/chunk-TRSAHHCL.js.map +0 -1
  85. package/dist/cli/chunk-XD6P7AFH.js +0 -375
  86. package/dist/cli/chunk-XD6P7AFH.js.map +0 -1
  87. package/dist/cli/chunk-XMHP7BEE.js.map +0 -1
  88. package/dist/cli/chunk-YFP3MYMY.js +0 -323
  89. package/dist/cli/chunk-YFP3MYMY.js.map +0 -1
  90. package/dist/cli/chunk-ZXSCAODE.js.map +0 -1
  91. package/dist/cli/code-Q4NRVEDG.js.map +0 -1
  92. package/dist/cli/desktop-EG6P5SF2.js.map +0 -1
  93. /package/dist/cli/{acp-GEOAKSTU.js.map → acp-4ROCGYNH.js.map} +0 -0
  94. /package/dist/cli/{chat-YTPATMMG.js.map → chat-GZNB5625.js.map} +0 -0
  95. /package/dist/cli/{chunk-DQ6K5ZQ7.js.map → chunk-3WGTGXO4.js.map} +0 -0
  96. /package/dist/cli/{chunk-6QC5RQLE.js.map → chunk-5OHHAQ4W.js.map} +0 -0
  97. /package/dist/cli/{chunk-TRWHTFG7.js.map → chunk-DOWEOA6E.js.map} +0 -0
  98. /package/dist/cli/{chunk-TDHXB2ER.js.map → chunk-H4CCXMDD.js.map} +0 -0
  99. /package/dist/cli/{chunk-T5A7EY6B.js.map → chunk-HR5NBKEM.js.map} +0 -0
  100. /package/dist/cli/{chunk-CNG32VAB.js.map → chunk-I4M5QJNL.js.map} +0 -0
  101. /package/dist/cli/{chunk-DN4B5S6Y.js.map → chunk-JMDE6IO3.js.map} +0 -0
  102. /package/dist/cli/{chunk-4MFCAZ2W.js.map → chunk-MOJYKO2A.js.map} +0 -0
  103. /package/dist/cli/{chunk-HUILPCYX.js.map → chunk-MRZG4GBF.js.map} +0 -0
  104. /package/dist/cli/{chunk-GH7DC2Y5.js.map → chunk-NMQSUNLB.js.map} +0 -0
  105. /package/dist/cli/{chunk-QCFLPSPH.js.map → chunk-OG5JANQ4.js.map} +0 -0
  106. /package/dist/cli/{chunk-CCJAP7G3.js.map → chunk-RUDBUHO4.js.map} +0 -0
  107. /package/dist/cli/{chunk-DWPAKZTY.js.map → chunk-TE5UIIFL.js.map} +0 -0
  108. /package/dist/cli/{chunk-KVZZ5U75.js.map → chunk-V4Y732RQ.js.map} +0 -0
  109. /package/dist/cli/{commands-4CDI4GFM.js.map → commands-QS6TG4G3.js.map} +0 -0
  110. /package/dist/cli/{commit-GW7LDQP5.js.map → commit-XPRSKUBF.js.map} +0 -0
  111. /package/dist/cli/{diff-VI2YX4FN.js.map → diff-I6W4AUWJ.js.map} +0 -0
  112. /package/dist/cli/{doctor-CQTTZP27.js.map → doctor-6XVZKT4U.js.map} +0 -0
  113. /package/dist/cli/{mcp-J2UCD4RZ.js.map → mcp-7W7ANO2Y.js.map} +0 -0
  114. /package/dist/cli/{mcp-browse-GSX34JEK.js.map → mcp-browse-LA4I4YIZ.js.map} +0 -0
  115. /package/dist/cli/{mcp-inspect-RRFYF4ZV.js.map → mcp-inspect-LWXXU7BY.js.map} +0 -0
  116. /package/dist/cli/{prompt-5TQPIVHV.js.map → prompt-RKZD4X6Y.js.map} +0 -0
  117. /package/dist/cli/{replay-MJCEMODU.js.map → replay-2X7MVXOI.js.map} +0 -0
  118. /package/dist/cli/{run-P4D5VDYE.js.map → run-TPKXIJ27.js.map} +0 -0
  119. /package/dist/cli/{sessions-QIONZJQ6.js.map → sessions-2A4DGSHA.js.map} +0 -0
  120. /package/dist/cli/{setup-NLQ6G5G4.js.map → setup-GOLP7J4C.js.map} +0 -0
  121. /package/dist/cli/{stats-DFZEXHP4.js.map → stats-CGDAFDKI.js.map} +0 -0
  122. /package/dist/cli/{version-GR3X3MPI.js.map → version-FIL4ZFOS.js.map} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/qq/channel.ts","../../src/qq/bot.ts","../../src/qq/strings.ts","../../src/mcp/summary.ts","../../src/cli/commands/mcp-runtime.ts"],"sourcesContent":["import { mkdirSync, readFileSync, unlinkSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { loadQQConfig } from \"../config.js\";\nimport { loadDotenv } from \"../env.js\";\nimport { t } from \"../i18n/index.js\";\nimport { decideQQAccess, describeQQAccess, redactQQOpenId } from \"./access.js\";\nimport { type C2CMessage, QQBot } from \"./bot.js\";\nimport { formatQQAccessSummary } from \"./strings.js\";\n\nconst QQ_LOCK_FILE = join(homedir(), \".reasonix\", \"qq-channel.pid\");\nconst QQ_MAX_CHUNK_BYTES = 1500;\nconst NATURAL_SPLIT_MIN_FRACTION = 0.6;\n\nfunction fitUtf8Slice(text: string, maxBytes: number): string {\n let end = 0;\n let bytes = 0;\n for (const char of text) {\n const nextBytes = Buffer.byteLength(char, \"utf8\");\n if (bytes > 0 && bytes + nextBytes > maxBytes) break;\n end += char.length;\n bytes += nextBytes;\n }\n return end > 0 ? text.slice(0, end) : text.slice(0, 1);\n}\n\nfunction pickNaturalSplit(candidate: string): number {\n const minSplit = Math.floor(candidate.length * NATURAL_SPLIT_MIN_FRACTION);\n const splitters = [\"\\n\\n\", \"\\n\", \" \"];\n for (const splitter of splitters) {\n const at = candidate.lastIndexOf(splitter);\n if (at >= minSplit) return at + splitter.length;\n }\n return candidate.length;\n}\n\nexport function splitQQMessage(text: string, maxBytes = QQ_MAX_CHUNK_BYTES): string[] {\n const chunks: string[] = [];\n let remaining = text;\n while (remaining.length > 0) {\n if (Buffer.byteLength(remaining, \"utf8\") <= maxBytes) {\n chunks.push(remaining);\n break;\n }\n\n const candidate = fitUtf8Slice(remaining, maxBytes);\n const splitAt = pickNaturalSplit(candidate);\n chunks.push(candidate.slice(0, splitAt));\n remaining = remaining.slice(splitAt).trimStart();\n }\n return chunks;\n}\n\nexport class QQChannel {\n private bot: QQBot | null = null;\n private qqUserId: string | null = null;\n private qqMessageId: string | null = null;\n private ownerOpenId: string | undefined;\n private allowlist: string[] | undefined;\n private runtimeBoundOpenId: string | null = null;\n private processedMsgIds = new Set<string>();\n private processedMsgIdQueue: string[] = [];\n private lockAcquired = false;\n private nextOutboundMsgSeq = 1;\n\n constructor(\n private callbacks: {\n onSubmitMessage: (text: string) => void;\n onError?: (msg: string) => void;\n },\n ) {}\n\n private rememberMessage(id: string): boolean {\n if (this.processedMsgIds.has(id)) return false;\n this.processedMsgIds.add(id);\n this.processedMsgIdQueue.push(id);\n if (this.processedMsgIdQueue.length > 200) {\n const oldest = this.processedMsgIdQueue.shift();\n if (oldest) this.processedMsgIds.delete(oldest);\n }\n return true;\n }\n\n private acquireLock(): void {\n try {\n const existing = Number(readFileSync(QQ_LOCK_FILE, \"utf8\").trim());\n if (Number.isInteger(existing) && existing > 0 && existing !== process.pid) {\n try {\n process.kill(existing, 0);\n throw new Error(t(\"handlers.qq.lockAlreadyRunning\", { pid: existing }));\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code !== \"ESRCH\") throw err;\n }\n }\n } catch (err) {\n const e = err as NodeJS.ErrnoException;\n if (e.code !== \"ENOENT\") throw err;\n }\n\n mkdirSync(dirname(QQ_LOCK_FILE), { recursive: true });\n writeFileSync(QQ_LOCK_FILE, String(process.pid), \"utf8\");\n this.lockAcquired = true;\n }\n\n private releaseLock(): void {\n if (!this.lockAcquired) return;\n try {\n const existing = Number(readFileSync(QQ_LOCK_FILE, \"utf8\").trim());\n if (existing === process.pid) unlinkSync(QQ_LOCK_FILE);\n } catch {}\n this.lockAcquired = false;\n }\n\n private applyAccessConfig(config: ReturnType<typeof loadQQConfig>): void {\n this.ownerOpenId = config.ownerOpenId;\n this.allowlist = config.allowlist;\n if (this.ownerOpenId || (this.allowlist?.length ?? 0) > 0) {\n this.runtimeBoundOpenId = null;\n }\n }\n\n private handlePrivateMessage(msg: C2CMessage): void {\n const text = msg.content?.trim();\n if (!text) return;\n if (!this.rememberMessage(msg.id)) return;\n\n const openid = msg.author.user_openid;\n const verdict = decideQQAccess(\n {\n ownerOpenId: this.ownerOpenId,\n allowlist: this.allowlist,\n runtimeBoundOpenId: this.runtimeBoundOpenId,\n },\n openid,\n );\n if (!verdict.accept) {\n this.callbacks.onError?.(\n t(\"handlers.qq.unauthorizedMessage\", {\n openid: redactQQOpenId(openid),\n access: formatQQAccessSummary({\n ownerOpenId: this.ownerOpenId,\n allowlist: this.allowlist,\n runtimeBoundOpenId: this.runtimeBoundOpenId,\n }),\n }),\n );\n return;\n }\n if (verdict.bindRuntime) {\n this.runtimeBoundOpenId = openid;\n this.callbacks.onError?.(\n t(\"handlers.qq.runtimeBound\", {\n openid: redactQQOpenId(openid),\n }),\n );\n }\n\n this.qqUserId = openid;\n this.qqMessageId = msg.id;\n this.callbacks.onSubmitMessage(`[QQ] ${text}`);\n }\n\n refreshAccessConfig(): void {\n this.applyAccessConfig(loadQQConfig());\n }\n\n describeAccess(): string {\n return describeQQAccess({\n ownerOpenId: this.ownerOpenId,\n allowlist: this.allowlist,\n runtimeBoundOpenId: this.runtimeBoundOpenId,\n });\n }\n\n getRuntimeBoundOpenId(): string | null {\n return this.runtimeBoundOpenId;\n }\n\n async start(): Promise<void> {\n loadDotenv();\n this.acquireLock();\n\n const config = loadQQConfig();\n if (!config.appId) {\n this.releaseLock();\n throw new Error(t(\"handlers.qq.missingAppId\"));\n }\n if (!config.appSecret) {\n this.releaseLock();\n throw new Error(t(\"handlers.qq.missingAppSecret\"));\n }\n this.applyAccessConfig(config);\n\n const bot = new QQBot({\n appid: config.appId,\n secret: config.appSecret,\n sandbox: config.sandbox ?? false,\n });\n\n bot.on(\"online\", () => {\n process.stderr.write(\"QQ bot is online!\\n\");\n });\n\n bot.on(\"bot_error\", (msg: string) => {\n this.callbacks.onError?.(msg);\n });\n\n bot.on(\"message.private\", (msg: C2CMessage) => {\n this.handlePrivateMessage(msg);\n });\n\n this.bot = bot;\n\n try {\n await bot.start();\n\n const readyOrError = await Promise.race([\n new Promise<\"ready\">((resolve) => bot.once(\"online\", () => resolve(\"ready\"))),\n new Promise<\"error\">((resolve) => bot.once(\"bot_error\", () => resolve(\"error\"))),\n new Promise<\"timeout\">((resolve) => setTimeout(() => resolve(\"timeout\"), 15_000)),\n ]);\n\n if (readyOrError === \"error\") {\n throw new Error(t(\"handlers.qq.authFailed\"));\n }\n if (readyOrError === \"timeout\") {\n throw new Error(t(\"handlers.qq.readyTimeout\"));\n }\n } catch (err) {\n this.releaseLock();\n throw err;\n }\n }\n\n async sendResponse(text: string): Promise<void> {\n if (!this.bot || !this.qqUserId) return;\n const chunks = splitQQMessage(text);\n for (let index = 0; index < chunks.length; index++) {\n const chunk = chunks[index];\n if (!chunk) continue;\n try {\n await this.bot.sendPrivateMessage(\n this.qqUserId,\n chunk,\n this.qqMessageId ?? undefined,\n this.nextOutboundMsgSeq++,\n );\n } catch (err) {\n const msg = `QQ sendResponse chunk ${index + 1}/${chunks.length} failed: ${(err as Error).message}`;\n this.callbacks.onError?.(msg);\n break;\n }\n }\n }\n\n async stop(): Promise<void> {\n await this.bot?.stop();\n this.releaseLock();\n }\n}\n","import { EventEmitter } from \"node:events\";\nimport WebSocket from \"ws\";\n\nconst TOKEN_URL = \"https://bots.qq.com/app/getAppAccessToken\";\nconst BASE_URL = \"https://api.sgroup.qq.com\";\nconst SANDBOX_URL = \"https://sandbox.api.sgroup.qq.com\";\nconst INTENT_C2C_GROUP = 1 << 25;\nconst MIN_HEARTBEAT_INTERVAL_MS = 5_000;\nconst MAX_HEARTBEAT_INTERVAL_MS = 60_000;\nconst ALLOWED_GATEWAY_HOSTS = [\"api.sgroup.qq.com\", \"sandbox.api.sgroup.qq.com\", \"qq.com\"];\n\ninterface QQBotConfig {\n appid: string;\n secret: string;\n sandbox?: boolean;\n}\n\nexport interface C2CMessage {\n author: { user_openid: string };\n content: string;\n id: string;\n timestamp: string;\n}\n\nexport class QQBot extends EventEmitter {\n private config: QQBotConfig;\n private token = \"\";\n private tokenExpiresAt = 0;\n private ws: WebSocket | null = null;\n private heartbeatTimer: ReturnType<typeof setInterval> | null = null;\n private seq = 0;\n private sessionId = \"\";\n private closed = false;\n private readyReceived = false;\n\n constructor(config: QQBotConfig) {\n super();\n this.config = config;\n }\n\n private get baseUrl(): string {\n return this.config.sandbox ? SANDBOX_URL : BASE_URL;\n }\n\n private sanitizeHeartbeatInterval(interval: unknown): number | null {\n if (typeof interval !== \"number\" || !Number.isFinite(interval)) {\n return null;\n }\n if (interval < MIN_HEARTBEAT_INTERVAL_MS) {\n return MIN_HEARTBEAT_INTERVAL_MS;\n }\n if (interval > MAX_HEARTBEAT_INTERVAL_MS) {\n return MAX_HEARTBEAT_INTERVAL_MS;\n }\n return Math.trunc(interval);\n }\n\n private validateGatewayUrl(rawUrl: string): string {\n const url = new URL(rawUrl);\n const trustedHost = ALLOWED_GATEWAY_HOSTS.some(\n (host) => url.hostname === host || url.hostname.endsWith(`.${host}`),\n );\n if (\n url.protocol !== \"wss:\" ||\n !trustedHost ||\n url.username ||\n url.password ||\n url.search ||\n url.hash\n ) {\n throw new Error(`Unexpected QQ gateway URL: ${rawUrl}`);\n }\n return url.toString();\n }\n\n private async ensureToken(): Promise<string> {\n if (this.token && Date.now() < this.tokenExpiresAt - 60_000) {\n return this.token;\n }\n const res = await fetch(TOKEN_URL, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n appId: this.config.appid,\n clientSecret: this.config.secret,\n }),\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to get access token (${res.status}): ${text}`);\n }\n const data = (await res.json()) as {\n access_token: string;\n expires_in: number;\n };\n this.token = data.access_token;\n this.tokenExpiresAt = Date.now() + data.expires_in * 1000;\n return this.token;\n }\n\n private async getGateway(): Promise<string> {\n const token = await this.ensureToken();\n const res = await fetch(`${this.baseUrl}/gateway`, {\n headers: { Authorization: `QQBot ${token}` },\n });\n if (!res.ok) {\n const text = await res.text();\n throw new Error(`Failed to get gateway (${res.status}): ${text}`);\n }\n const data = (await res.json()) as { url: string };\n return this.validateGatewayUrl(data.url);\n }\n\n private sendOp(op: number, data?: unknown) {\n if (!this.ws) return;\n this.ws.send(JSON.stringify({ op, d: data ?? {} }));\n }\n\n private async handlePayload(payload: {\n op: number;\n d?: Record<string, unknown>;\n s?: number;\n t?: string;\n }) {\n switch (payload.op) {\n case 10: {\n const d = payload.d as { heartbeat_interval: number } | undefined;\n this.sendOp(2, {\n token: `QQBot ${await this.ensureToken()}`,\n intents: INTENT_C2C_GROUP,\n shard: [0, 1],\n });\n const heartbeatInterval = this.sanitizeHeartbeatInterval(d?.heartbeat_interval);\n if (heartbeatInterval) {\n this.heartbeatTimer = setInterval(() => {\n this.sendOp(1, this.seq || null);\n }, heartbeatInterval);\n }\n break;\n }\n case 0: {\n if (payload.s) this.seq = payload.s;\n if (payload.t === \"READY\") {\n const d = payload.d as { session_id: string; user?: { id: string } };\n this.sessionId = d.session_id;\n this.readyReceived = true;\n this.emit(\"online\");\n } else if (payload.t === \"C2C_MESSAGE_CREATE\") {\n this.emit(\"message.private\", payload.d as unknown as C2CMessage);\n } else if (payload.t === \"GROUP_AT_MESSAGE_CREATE\") {\n this.emit(\"message.group\", payload.d);\n }\n break;\n }\n case 7: {\n this.reconnect();\n break;\n }\n case 9: {\n this.sessionId = \"\";\n this.sendOp(2, {\n token: `QQBot ${await this.ensureToken()}`,\n intents: INTENT_C2C_GROUP,\n shard: [0, 1],\n });\n break;\n }\n }\n }\n\n private async reconnect() {\n this.cleanup();\n await this.connect();\n }\n\n private cleanup() {\n if (this.heartbeatTimer) {\n clearInterval(this.heartbeatTimer);\n this.heartbeatTimer = null;\n }\n if (this.ws) {\n this.ws.removeAllListeners();\n this.ws.close();\n this.ws = null;\n }\n }\n\n private async connect() {\n const gatewayUrl = await this.getGateway();\n const token = await this.ensureToken();\n this.ws = new WebSocket(gatewayUrl, {\n headers: {\n Authorization: `QQBot ${token}`,\n \"X-Union-Appid\": this.config.appid,\n },\n });\n\n this.ws.on(\"open\", () => {\n if (this.sessionId) {\n this.sendOp(6, {\n token: `QQBot ${this.token}`,\n session_id: this.sessionId,\n seq: this.seq,\n });\n }\n });\n\n this.ws.on(\"message\", (raw: WebSocket.RawData) => {\n try {\n const payload = JSON.parse(raw.toString());\n this.handlePayload(payload).catch(() => {});\n } catch {\n // ignore parse errors\n }\n });\n\n this.ws.on(\"close\", () => {\n if (!this.closed) {\n if (this.readyReceived) {\n // Was online — transient disconnect, reconnect.\n console.error(\"QQ WebSocket reconnecting...\");\n this.cleanup();\n setTimeout(() => this.reconnect(), 3000);\n } else {\n // Never received READY — authentication or network failure.\n const msg =\n \"QQ WebSocket closed before authentication completed — check your appId and appSecret\";\n this.emit(\"bot_error\", msg);\n this.closed = true; // prevent further reconnect attempts\n }\n }\n });\n\n this.ws.on(\"error\", (err: Error) => {\n const msg = `QQ WebSocket error: ${err.message}`;\n console.error(msg);\n this.emit(\"bot_error\", msg);\n });\n }\n\n async start(): Promise<void> {\n this.closed = false;\n this.readyReceived = false;\n await this.connect();\n }\n\n async stop(): Promise<void> {\n this.closed = true;\n this.cleanup();\n }\n\n async sendPrivateMessage(\n openid: string,\n content: string,\n msgId?: string,\n msgSeq?: number,\n ): Promise<void> {\n const token = await this.ensureToken();\n const body: Record<string, unknown> = {\n content,\n msg_type: 0,\n };\n if (msgId) body.msg_id = msgId;\n if (typeof msgSeq === \"number\" && Number.isFinite(msgSeq)) body.msg_seq = Math.trunc(msgSeq);\n const res = await fetch(`${this.baseUrl}/v2/users/${encodeURIComponent(openid)}/messages`, {\n method: \"POST\",\n headers: {\n Authorization: `QQBot ${token}`,\n \"Content-Type\": \"application/json\",\n \"X-Union-Appid\": this.config.appid,\n },\n body: JSON.stringify(body),\n });\n if (!res.ok) {\n const text = await res.text();\n const msg = `QQ sendPrivateMessage failed (${res.status}): ${text}`;\n throw new Error(msg);\n }\n }\n}\n","import { t } from \"../i18n/index.js\";\nimport {\n type QQAccessConfig,\n normalizeQQAllowlist,\n normalizeQQOpenId,\n redactQQOpenId,\n} from \"./access.js\";\n\nexport type QQSetupStep = \"appId\" | \"appSecret\";\n\nexport function formatQQModeLabel(codeMode: boolean): string {\n return t(codeMode ? \"handlers.qq.modeCode\" : \"handlers.qq.modeChat\");\n}\n\nexport function formatQQAccessSummary(config: QQAccessConfig): string {\n const ownerOpenId = normalizeQQOpenId(config.ownerOpenId);\n const allowlist = normalizeQQAllowlist(config.allowlist) ?? [];\n const runtimeBoundOpenId = normalizeQQOpenId(config.runtimeBoundOpenId);\n\n if (ownerOpenId) {\n if (allowlist.length > 0) {\n return t(\"handlers.qq.accessOwnerWithAllowlist\", {\n owner: redactQQOpenId(ownerOpenId),\n count: allowlist.length,\n });\n }\n return t(\"handlers.qq.accessOwner\", {\n owner: redactQQOpenId(ownerOpenId),\n });\n }\n if (allowlist.length > 0) {\n return t(\"handlers.qq.accessAllowlist\", { count: allowlist.length });\n }\n if (runtimeBoundOpenId) {\n return t(\"handlers.qq.accessRuntime\", {\n owner: redactQQOpenId(runtimeBoundOpenId),\n });\n }\n return t(\"handlers.qq.accessOpen\");\n}\n\nexport function formatQQSetupPrompt(step: QQSetupStep): string {\n return t(step === \"appId\" ? \"handlers.qq.promptAppId\" : \"handlers.qq.promptAppSecret\");\n}\n\nexport function formatQQSetupWaiting(step: QQSetupStep): string {\n return t(\n step === \"appId\" ? \"handlers.qq.setupWaitingAppId\" : \"handlers.qq.setupWaitingAppSecret\",\n );\n}\n","import type { InspectionReport } from \"./inspect.js\";\nimport type { BridgeEnv, McpClientHost } from \"./registry.js\";\nimport type { GetPromptResult, ReadResourceResult } from \"./types.js\";\n\nexport interface McpServerSummary {\n label: string;\n spec: string;\n toolCount: number;\n report: InspectionReport;\n host: McpClientHost;\n bridgeEnv: BridgeEnv;\n readResource(uri: string): Promise<ReadResourceResult>;\n getPrompt(name: string, args?: Record<string, string>): Promise<GetPromptResult>;\n}\n\nexport function buildMcpServerSummary(opts: {\n label: string;\n spec: string;\n toolCount: number;\n report: InspectionReport;\n host: McpClientHost;\n bridgeEnv: BridgeEnv;\n}): McpServerSummary {\n return {\n label: opts.label,\n spec: opts.spec,\n toolCount: opts.toolCount,\n report: opts.report,\n host: opts.host,\n bridgeEnv: opts.bridgeEnv,\n readResource(uri) {\n return opts.host.client.readResource(uri);\n },\n getPrompt(name, args) {\n return args !== undefined\n ? opts.host.client.getPrompt(name, args)\n : opts.host.client.getPrompt(name);\n },\n };\n}\n","import { normalizeMcpConfig, readConfig } from \"../../config.js\";\nimport { t } from \"../../i18n/index.js\";\nimport type { CacheFirstLoop } from \"../../loop.js\";\nimport { McpClient } from \"../../mcp/client.js\";\nimport { type InspectionReport, inspectMcpServer } from \"../../mcp/inspect.js\";\nimport { preflightStdioSpec } from \"../../mcp/preflight.js\";\nimport { type McpClientHost, bridgeMcpTools } from \"../../mcp/registry.js\";\nimport { overlayMatchedSpec, parseMcpSpec, specToRaw } from \"../../mcp/spec.js\";\nimport { buildMcpServerSummary } from \"../../mcp/summary.js\";\nimport { buildTransportFromSpec } from \"../../mcp/transport-from-spec.js\";\nimport type { ToolRegistry } from \"../../tools.js\";\nimport type { ToolSpec } from \"../../types.js\";\nimport { type McpLifecycleEvent, formatMcpLifecycleEvent } from \"../ui/mcp-lifecycle.js\";\nimport { formatMcpSlowToast } from \"../ui/mcp-toast.js\";\nimport type { McpServerSummary } from \"../ui/slash.js\";\n\nexport interface ProgressInfo {\n toolName: string;\n progress: number;\n total?: number;\n message?: string;\n}\n\ninterface SpecRecord {\n spec: string;\n client: McpClient;\n summary: McpServerSummary;\n /** Names of bridged tools — used for hot-unbridge. */\n registeredNames: string[];\n /** ToolSpec snapshots captured AFTER bridge — handed to loop.prefix.addTool on hot-add. */\n registeredSpecs: ToolSpec[];\n}\n\nexport interface RuntimeContext {\n getTools: () => ToolRegistry | undefined;\n getMcpPrefix: () => string | undefined;\n getRequestedCount: () => number;\n progressSink: { current: ((info: ProgressInfo) => void) | null };\n}\n\nexport type McpLifecycleNotice =\n | { kind: \"handshake\"; name: string }\n | {\n kind: \"connected\";\n name: string;\n tools: number;\n resources: number;\n prompts: number;\n ms: number;\n }\n | { kind: \"disabled\"; name: string }\n | { kind: \"failed\"; name: string; reason: string }\n | { kind: \"slow\"; serverName: string; p95Ms: number; sampleSize: number }\n | { kind: \"tools-ready\"; name: string; tools: number; ms: number }\n | { kind: \"warn\"; name: string; reason: string };\n\nexport type McpLifecycleSink = (notice: McpLifecycleNotice) => void;\n\nexport const stderrLifecycleSink: McpLifecycleSink = (n) => {\n if (n.kind === \"slow\") {\n process.stderr.write(\n `${formatMcpSlowToast({ name: n.serverName, p95Ms: n.p95Ms, sampleSize: n.sampleSize })}\\n`,\n );\n return;\n }\n if (n.kind === \"failed\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"failed\", name: n.name, reason: n.reason })}\\n → ${t(\"mcpLifecycle.failedSetupHint\")}\\n`,\n );\n return;\n }\n if (n.kind === \"connected\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({\n state: \"connected\",\n name: n.name,\n tools: n.tools,\n resources: n.resources,\n prompts: n.prompts,\n ms: n.ms,\n })}\\n`,\n );\n return;\n }\n if (n.kind === \"tools-ready\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"tools-ready\", name: n.name, tools: n.tools, ms: n.ms })}\\n`,\n );\n return;\n }\n if (n.kind === \"warn\") {\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: \"warn\", name: n.name, reason: n.reason })}\\n`,\n );\n return;\n }\n // handshake / disabled — no extra fields needed\n process.stderr.write(\n `${formatMcpLifecycleEvent({ state: n.kind as \"handshake\" | \"disabled\", name: n.name })}\\n`,\n );\n};\n\nexport interface McpFailure {\n spec: string;\n name: string;\n reason: string;\n at: number;\n}\n\nexport interface McpRuntime {\n size(): number;\n specs(): string[];\n summaries(): McpServerSummary[];\n /** Last bridge failure per spec — drives the \"未桥接\" reason shown in the dashboard. */\n failures(): McpFailure[];\n addSpec(\n raw: string,\n loop?: CacheFirstLoop,\n signal?: AbortSignal,\n ): Promise<{ ok: true; summary: McpServerSummary } | { ok: false; reason: string }>;\n removeSpec(raw: string, loop?: CacheFirstLoop): Promise<boolean>;\n reloadFromConfig(loop?: CacheFirstLoop): Promise<{\n added: string[];\n removed: string[];\n failed: Array<{ spec: string; reason: string }>;\n summaries: McpServerSummary[];\n }>;\n closeAll(): Promise<void>;\n /** Replace the sink that lifecycle events flow through — App.tsx swaps this in on mount so toasts land in the alt-screen UI instead of corrupting it via stderr. */\n setLifecycleSink(sink: McpLifecycleSink): void;\n}\n\nexport function createMcpRuntime(ctx: RuntimeContext): McpRuntime {\n const records = new Map<string, SpecRecord>();\n const insertionOrder: string[] = [];\n const failureMap = new Map<string, McpFailure>();\n let sink: McpLifecycleSink = stderrLifecycleSink;\n\n async function addSpec(\n raw: string,\n loop?: CacheFirstLoop,\n signal?: AbortSignal,\n ): Promise<{ ok: true; summary: McpServerSummary } | { ok: false; reason: string }> {\n if (records.has(raw)) {\n return { ok: true, summary: records.get(raw)!.summary };\n }\n failureMap.delete(raw);\n const tools = ctx.getTools();\n if (!tools) return { ok: false, reason: \"no tool registry available\" };\n const cfg = readConfig();\n const normalized = normalizeMcpConfig(cfg);\n let label = \"anon\";\n let mcp: McpClient | undefined;\n // Per-server readiness gate — tool dispatches via the bridge await\n // this before calling into `live.callTool`. Resolved on `connected`,\n // rejected on `failed`, so a tool invoked mid-handshake waits\n // (capped by `bridgeMcpTools`'s `readyTimeoutMs`) instead of\n // surfacing a transport error.\n let resolveReady!: () => void;\n let rejectReady!: (err: Error) => void;\n const ready = new Promise<void>((resolve, reject) => {\n resolveReady = resolve;\n rejectReady = reject;\n });\n // Avoid unhandledRejection if no consumer awaits `ready` yet.\n ready.catch(() => undefined);\n try {\n const parsed = parseMcpSpec(raw);\n label = parsed.name ?? \"anon\";\n const matched = parsed.name ? normalized.find((s) => s.name === parsed.name) : undefined;\n const spec = overlayMatchedSpec(parsed, matched);\n if (spec.disabled) {\n sink({ kind: \"disabled\", name: label });\n rejectReady(new Error(`MCP server \"${label}\" is disabled`));\n failureMap.set(raw, { spec: raw, name: label, reason: \"disabled by user\", at: Date.now() });\n return { ok: false, reason: \"disabled by user\" };\n }\n sink({ kind: \"handshake\", name: label });\n const t0 = Date.now();\n const namePrefix = spec.name\n ? `${spec.name}_`\n : ctx.getRequestedCount() === 1 && ctx.getMcpPrefix()\n ? (ctx.getMcpPrefix() as string)\n : \"\";\n if (spec.transport === \"stdio\") preflightStdioSpec(spec);\n const transport = buildTransportFromSpec(spec);\n mcp = new McpClient({ transport });\n await mcp.initialize({ signal });\n const host: McpClientHost = { client: mcp };\n const bridge = await bridgeMcpTools(mcp, {\n registry: tools,\n namePrefix,\n serverName: label,\n host,\n ready,\n onProgress: (info) => ctx.progressSink.current?.(info),\n onSlow: (info) =>\n sink({\n kind: \"slow\",\n serverName: info.serverName,\n p95Ms: info.p95Ms,\n sampleSize: info.sampleSize,\n }),\n });\n // Tools are registered — record the bridge NOW so the UI shows\n // \"bridged\" even if later non-critical steps (inspect, hot-add) fail.\n const ms = Date.now() - t0;\n const allSpecs = tools.specs();\n const registeredSpecs = allSpecs.filter((s) =>\n bridge.registeredNames.includes(s.function.name),\n );\n // Create a provisional record immediately (tools already usable).\n records.set(raw, {\n spec: raw,\n client: mcp,\n summary: buildMcpServerSummary({\n label,\n spec: raw,\n toolCount: bridge.registeredNames.length,\n report: {\n protocolVersion: mcp.protocolVersion,\n serverInfo: mcp.serverInfo,\n capabilities: mcp.serverCapabilities ?? {},\n tools: { supported: true, items: [] },\n resources: { supported: false, reason: \"still inspecting\" },\n prompts: { supported: false, reason: \"still inspecting\" },\n elapsedMs: ms,\n },\n host,\n bridgeEnv: bridge.env,\n }),\n registeredNames: bridge.registeredNames,\n registeredSpecs,\n });\n insertionOrder.push(raw);\n resolveReady();\n sink({\n kind: \"tools-ready\",\n name: label,\n tools: bridge.registeredNames.length,\n ms,\n });\n\n // Non-critical: inspect + hot-add. Failures here don't un-bridge.\n let report: InspectionReport;\n try {\n report = await inspectMcpServer(mcp);\n } catch {\n report = {\n protocolVersion: mcp.protocolVersion,\n serverInfo: mcp.serverInfo,\n capabilities: mcp.serverCapabilities ?? {},\n tools: { supported: true, items: [] },\n resources: { supported: false, reason: \"inspect failed\" },\n prompts: { supported: false, reason: \"inspect failed\" },\n elapsedMs: 0,\n };\n }\n const resourceCount = report.resources.supported ? report.resources.items.length : 0;\n const promptCount = report.prompts.supported ? report.prompts.items.length : 0;\n // Re-emit with full inspection data (the provisional event reported 0).\n sink({\n kind: \"connected\",\n name: label,\n tools: bridge.registeredNames.length,\n resources: resourceCount,\n prompts: promptCount,\n ms,\n });\n const summary = buildMcpServerSummary({\n label,\n spec: raw,\n toolCount: bridge.registeredNames.length,\n report,\n host,\n bridgeEnv: bridge.env,\n });\n // Replace the provisional record with the fully-inspected summary.\n records.set(raw, {\n spec: raw,\n client: mcp,\n summary,\n registeredNames: bridge.registeredNames,\n registeredSpecs,\n });\n // Hot-add: shift the prefix so the live loop sees the new tools\n // on the very next turn. Each addTool is one cache-miss turn.\n if (loop)\n for (const s of registeredSpecs)\n try {\n loop.prefix.addTool(s);\n } catch (err) {\n sink({\n kind: \"warn\",\n name: label,\n reason: `addTool failed for ${s.function.name}: ${(err as Error).message}`,\n });\n }\n return { ok: true, summary };\n } catch (err) {\n // If we got far enough to create a provisional record, keep it —\n // tools are already registered and usable even after a late failure.\n const reason = (err as Error).message;\n if (!records.has(raw)) {\n await mcp?.close().catch(() => undefined);\n rejectReady(new Error(`MCP server \"${label}\" failed to start: ${reason}`));\n sink({ kind: \"failed\", name: label, reason });\n failureMap.set(raw, { spec: raw, name: label, reason, at: Date.now() });\n return { ok: false, reason };\n }\n sink({ kind: \"warn\", name: label, reason });\n return { ok: true, summary: records.get(raw)!.summary };\n }\n }\n\n async function removeSpec(raw: string, loop?: CacheFirstLoop): Promise<boolean> {\n failureMap.delete(raw);\n const record = records.get(raw);\n if (!record) return false;\n await record.client.close().catch(() => undefined);\n const tools = ctx.getTools();\n for (const name of record.registeredNames) {\n tools?.unregister(name);\n loop?.prefix.removeTool(name);\n }\n records.delete(raw);\n const idx = insertionOrder.indexOf(raw);\n if (idx >= 0) insertionOrder.splice(idx, 1);\n return true;\n }\n\n async function reloadFromConfig(loop?: CacheFirstLoop): Promise<{\n added: string[];\n removed: string[];\n failed: Array<{ spec: string; reason: string }>;\n summaries: McpServerSummary[];\n }> {\n const normalized = normalizeMcpConfig(readConfig());\n const desired = normalized.map(specToRaw);\n const desiredSet = new Set(desired);\n const currentSet = new Set(records.keys());\n const added: string[] = [];\n const removed: string[] = [];\n const failed: Array<{ spec: string; reason: string }> = [];\n\n for (const spec of [...currentSet]) {\n if (!desiredSet.has(spec)) {\n await removeSpec(spec, loop);\n removed.push(spec);\n }\n }\n for (const spec of desired) {\n if (currentSet.has(spec)) continue;\n const result = await addSpec(spec, loop);\n if (result.ok) added.push(spec);\n else failed.push({ spec, reason: result.reason });\n }\n return { added, removed, failed, summaries: summaries() };\n }\n\n function specs(): string[] {\n return [...insertionOrder];\n }\n function summaries(): McpServerSummary[] {\n return insertionOrder\n .map((s) => records.get(s)?.summary)\n .filter((s): s is McpServerSummary => Boolean(s));\n }\n async function closeAll(): Promise<void> {\n for (const r of records.values()) await r.client.close().catch(() => undefined);\n records.clear();\n insertionOrder.length = 0;\n failureMap.clear();\n }\n function failures(): McpFailure[] {\n return [...failureMap.values()];\n }\n function setLifecycleSink(s: McpLifecycleSink): void {\n sink = s;\n }\n return {\n size: () => records.size,\n specs,\n summaries,\n failures,\n addSpec,\n removeSpec,\n reloadFromConfig,\n closeAll,\n setLifecycleSink,\n };\n}\n"],"mappings":"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","names":[]}
@@ -2,7 +2,7 @@
2
2
  import { createRequire as __cr } from 'node:module'; if (typeof globalThis.require === 'undefined') { globalThis.require = __cr(import.meta.url); }
3
3
  import {
4
4
  probeOllama
5
- } from "./chunk-T5A7EY6B.js";
5
+ } from "./chunk-HR5NBKEM.js";
6
6
 
7
7
  // src/index/semantic/ollama-launcher.ts
8
8
  import { spawn, spawnSync } from "child_process";
@@ -98,4 +98,4 @@ export {
98
98
  startOllamaDaemon,
99
99
  pullOllamaModel
100
100
  };
101
- //# sourceMappingURL=chunk-TDHXB2ER.js.map
101
+ //# sourceMappingURL=chunk-H4CCXMDD.js.map
@@ -8,7 +8,7 @@ import {
8
8
  compileFilters,
9
9
  defaultIndexConfig,
10
10
  resolveSemanticEmbeddingConfig
11
- } from "./chunk-6CRPCJAU.js";
11
+ } from "./chunk-CDVSFSAK.js";
12
12
 
13
13
  // src/index/semantic/builder.ts
14
14
  import { promises as fs3 } from "fs";
@@ -882,4 +882,4 @@ export {
882
882
  indexExists,
883
883
  indexCompatible
884
884
  };
885
- //# sourceMappingURL=chunk-T5A7EY6B.js.map
885
+ //# sourceMappingURL=chunk-HR5NBKEM.js.map
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-X53B3JIX.js";
8
8
  import {
9
9
  t
10
- } from "./chunk-NRQ5UP5T.js";
10
+ } from "./chunk-YW63N3ZR.js";
11
11
  import {
12
12
  __toESM
13
13
  } from "./chunk-TUK7OWJA.js";
@@ -51,4 +51,4 @@ function truncate(s, max) {
51
51
  export {
52
52
  RecordView
53
53
  };
54
- //# sourceMappingURL=chunk-CNG32VAB.js.map
54
+ //# sourceMappingURL=chunk-I4M5QJNL.js.map
@@ -9659,7 +9659,7 @@ var require_agent = __commonJS({
9659
9659
  function defaultFactory(origin, opts) {
9660
9660
  return opts && opts.connections === 1 ? new Client(origin, opts) : new Pool(origin, opts);
9661
9661
  }
9662
- var Agent = class extends DispatcherBase {
9662
+ var Agent2 = class extends DispatcherBase {
9663
9663
  constructor({ factory = defaultFactory, maxOrigins = Infinity, connect, ...options } = {}) {
9664
9664
  if (typeof factory !== "function") {
9665
9665
  throw new InvalidArgumentError("factory must be a function.");
@@ -9773,7 +9773,7 @@ var require_agent = __commonJS({
9773
9773
  return allClientStats;
9774
9774
  }
9775
9775
  };
9776
- module.exports = Agent;
9776
+ module.exports = Agent2;
9777
9777
  }
9778
9778
  });
9779
9779
 
@@ -10559,7 +10559,7 @@ var require_proxy_agent = __commonJS({
10559
10559
  "node_modules/undici/lib/dispatcher/proxy-agent.js"(exports, module) {
10560
10560
  "use strict";
10561
10561
  var { kProxy, kClose, kDestroy, kDispatch } = require_symbols();
10562
- var Agent = require_agent();
10562
+ var Agent2 = require_agent();
10563
10563
  var Pool = require_pool();
10564
10564
  var DispatcherBase = require_dispatcher_base();
10565
10565
  var { InvalidArgumentError, RequestAbortedError, SecureProxyConnectionError } = require_errors();
@@ -10693,7 +10693,7 @@ var require_proxy_agent = __commonJS({
10693
10693
  } else {
10694
10694
  this[kClient] = clientFactory(url, { connect });
10695
10695
  }
10696
- this[kAgent] = new Agent({
10696
+ this[kAgent] = new Agent2({
10697
10697
  ...opts,
10698
10698
  factory,
10699
10699
  connect: async (opts2, callback) => {
@@ -10822,7 +10822,7 @@ var require_env_http_proxy_agent = __commonJS({
10822
10822
  var DispatcherBase = require_dispatcher_base();
10823
10823
  var { kClose, kDestroy, kClosed, kDestroyed, kDispatch, kNoProxyAgent, kHttpProxyAgent, kHttpsProxyAgent } = require_symbols();
10824
10824
  var ProxyAgent2 = require_proxy_agent();
10825
- var Agent = require_agent();
10825
+ var Agent2 = require_agent();
10826
10826
  var DEFAULT_PORTS = {
10827
10827
  "http:": 80,
10828
10828
  "https:": 443
@@ -10835,7 +10835,7 @@ var require_env_http_proxy_agent = __commonJS({
10835
10835
  super();
10836
10836
  this.#opts = opts;
10837
10837
  const { httpProxy, httpsProxy, noProxy, ...agentOpts } = opts;
10838
- this[kNoProxyAgent] = new Agent(agentOpts);
10838
+ this[kNoProxyAgent] = new Agent2(agentOpts);
10839
10839
  const HTTP_PROXY = httpProxy ?? process.env.http_proxy ?? process.env.HTTP_PROXY;
10840
10840
  if (HTTP_PROXY) {
10841
10841
  this[kHttpProxyAgent] = new ProxyAgent2({ ...agentOpts, uri: HTTP_PROXY });
@@ -13543,7 +13543,7 @@ var require_mock_agent = __commonJS({
13543
13543
  "node_modules/undici/lib/mock/mock-agent.js"(exports, module) {
13544
13544
  "use strict";
13545
13545
  var { kClients } = require_symbols();
13546
- var Agent = require_agent();
13546
+ var Agent2 = require_agent();
13547
13547
  var {
13548
13548
  kAgent,
13549
13549
  kMockAgentSet,
@@ -13581,7 +13581,7 @@ var require_mock_agent = __commonJS({
13581
13581
  if (opts?.agent && typeof opts.agent.dispatch !== "function") {
13582
13582
  throw new InvalidArgumentError("Argument opts.agent must implement Agent");
13583
13583
  }
13584
- const agent = opts?.agent ? opts.agent : new Agent(opts);
13584
+ const agent = opts?.agent ? opts.agent : new Agent2(opts);
13585
13585
  this[kAgent] = agent;
13586
13586
  this[kClients] = agent[kClients];
13587
13587
  this[kOptions] = mockOptions;
@@ -14188,7 +14188,7 @@ var require_snapshot_recorder = __commonJS({
14188
14188
  var require_snapshot_agent = __commonJS({
14189
14189
  "node_modules/undici/lib/mock/snapshot-agent.js"(exports, module) {
14190
14190
  "use strict";
14191
- var Agent = require_agent();
14191
+ var Agent2 = require_agent();
14192
14192
  var MockAgent = require_mock_agent();
14193
14193
  var { SnapshotRecorder } = require_snapshot_recorder();
14194
14194
  var { InvalidArgumentError, UndiciError } = require_errors();
@@ -14239,7 +14239,7 @@ var require_snapshot_agent = __commonJS({
14239
14239
  });
14240
14240
  this[kSnapshotLoaded] = false;
14241
14241
  if (this[kSnapshotMode] === "record" || this[kSnapshotMode] === "update" || this[kSnapshotMode] === "playback" && opts.excludeUrls && opts.excludeUrls.length > 0) {
14242
- this[kRealAgent] = new Agent(opts);
14242
+ this[kRealAgent] = new Agent2(opts);
14243
14243
  }
14244
14244
  if ((this[kSnapshotMode] === "playback" || this[kSnapshotMode] === "update") && this[kSnapshotPath]) {
14245
14245
  this.loadSnapshots().catch(() => {
@@ -14484,10 +14484,10 @@ var require_global2 = __commonJS({
14484
14484
  var globalDispatcher = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.2");
14485
14485
  var legacyGlobalDispatcher = /* @__PURE__ */ Symbol.for("undici.globalDispatcher.1");
14486
14486
  var { InvalidArgumentError } = require_errors();
14487
- var Agent = require_agent();
14487
+ var Agent2 = require_agent();
14488
14488
  var Dispatcher1Wrapper = require_dispatcher1_wrapper();
14489
14489
  if (getGlobalDispatcher() === void 0) {
14490
- setGlobalDispatcher2(new Agent());
14490
+ setGlobalDispatcher2(new Agent2());
14491
14491
  }
14492
14492
  function setGlobalDispatcher2(agent) {
14493
14493
  if (!agent || typeof agent.dispatch !== "function") {
@@ -25061,7 +25061,7 @@ var require_undici = __commonJS({
25061
25061
  var Pool = require_pool();
25062
25062
  var BalancedPool = require_balanced_pool();
25063
25063
  var RoundRobinPool = require_round_robin_pool();
25064
- var Agent = require_agent();
25064
+ var Agent2 = require_agent();
25065
25065
  var Dispatcher1Wrapper = require_dispatcher1_wrapper();
25066
25066
  var ProxyAgent2 = require_proxy_agent();
25067
25067
  var Socks5ProxyAgent = require_socks5_proxy_agent();
@@ -25089,7 +25089,7 @@ var require_undici = __commonJS({
25089
25089
  module.exports.Pool = Pool;
25090
25090
  module.exports.BalancedPool = BalancedPool;
25091
25091
  module.exports.RoundRobinPool = RoundRobinPool;
25092
- module.exports.Agent = Agent;
25092
+ module.exports.Agent = Agent2;
25093
25093
  module.exports.Dispatcher1Wrapper = Dispatcher1Wrapper;
25094
25094
  module.exports.ProxyAgent = ProxyAgent2;
25095
25095
  module.exports.Socks5ProxyAgent = Socks5ProxyAgent;
@@ -25259,6 +25259,14 @@ var PROXY_ENV_KEYS = [
25259
25259
  "ALL_PROXY",
25260
25260
  "all_proxy"
25261
25261
  ];
25262
+ var NO_PROXY_ENV_KEYS = ["NO_PROXY", "no_proxy"];
25263
+ var DEFAULT_NO_PROXY = [
25264
+ "api.deepseek.com",
25265
+ "*.deepseek.com",
25266
+ "localhost",
25267
+ "127.0.0.1",
25268
+ "::1"
25269
+ ];
25262
25270
  function detectProxyUrl(env = process.env) {
25263
25271
  for (const key of PROXY_ENV_KEYS) {
25264
25272
  const raw = env[key];
@@ -25268,6 +25276,15 @@ function detectProxyUrl(env = process.env) {
25268
25276
  }
25269
25277
  return null;
25270
25278
  }
25279
+ function detectNoProxyRaw(env = process.env) {
25280
+ for (const key of NO_PROXY_ENV_KEYS) {
25281
+ const raw = env[key];
25282
+ if (typeof raw !== "string") continue;
25283
+ const trimmed = raw.trim();
25284
+ if (trimmed) return trimmed;
25285
+ }
25286
+ return null;
25287
+ }
25271
25288
  function normalizeProxyUrl(raw) {
25272
25289
  const trimmed = raw.trim();
25273
25290
  if (!trimmed) return null;
@@ -25278,8 +25295,102 @@ function normalizeProxyUrl(raw) {
25278
25295
  return null;
25279
25296
  }
25280
25297
  }
25298
+ function parseNoProxy(raw) {
25299
+ if (!raw) return [];
25300
+ const out = [];
25301
+ for (const segment of raw.split(",")) {
25302
+ const trimmed = segment.trim();
25303
+ if (!trimmed) continue;
25304
+ out.push(buildPattern(trimmed));
25305
+ }
25306
+ return out;
25307
+ }
25308
+ function buildPattern(raw) {
25309
+ const colon = raw.lastIndexOf(":");
25310
+ const hostPart = colon !== -1 && /^\d+$/.test(raw.slice(colon + 1)) ? raw.slice(0, colon) : raw;
25311
+ const normalized = hostPart.toLowerCase();
25312
+ if (normalized === "*") {
25313
+ return { raw, matches: () => true };
25314
+ }
25315
+ if (normalized.startsWith("*.")) {
25316
+ const suffix = normalized.slice(1);
25317
+ const bare = normalized.slice(2);
25318
+ return {
25319
+ raw,
25320
+ matches: (host) => {
25321
+ const h = host.toLowerCase();
25322
+ return h === bare || h.endsWith(suffix);
25323
+ }
25324
+ };
25325
+ }
25326
+ if (normalized.startsWith(".")) {
25327
+ return {
25328
+ raw,
25329
+ matches: (host) => host.toLowerCase().endsWith(normalized)
25330
+ };
25331
+ }
25332
+ return {
25333
+ raw,
25334
+ matches: (host) => {
25335
+ const h = host.toLowerCase();
25336
+ return h === normalized || h.endsWith(`.${normalized}`);
25337
+ }
25338
+ };
25339
+ }
25340
+ function matchesNoProxy(host, patterns) {
25341
+ for (const p of patterns) {
25342
+ if (p.matches(host)) return true;
25343
+ }
25344
+ return false;
25345
+ }
25346
+ var SelectiveProxyDispatcher = class {
25347
+ direct;
25348
+ proxied;
25349
+ patterns;
25350
+ constructor(proxyUrl, patterns) {
25351
+ this.direct = new import_undici.Agent();
25352
+ this.proxied = new import_undici.ProxyAgent(proxyUrl);
25353
+ this.patterns = patterns;
25354
+ }
25355
+ dispatch(opts, handler) {
25356
+ const origin = opts.origin;
25357
+ let host = "";
25358
+ try {
25359
+ if (typeof origin === "string") {
25360
+ host = new URL(origin).hostname;
25361
+ } else if (origin instanceof URL) {
25362
+ host = origin.hostname;
25363
+ }
25364
+ } catch {
25365
+ }
25366
+ const target = host && matchesNoProxy(host, this.patterns) ? this.direct : this.proxied;
25367
+ return target.dispatch(opts, handler);
25368
+ }
25369
+ async close() {
25370
+ await Promise.allSettled([this.direct.close(), this.proxied.close()]);
25371
+ }
25372
+ async destroy() {
25373
+ await Promise.allSettled([this.direct.destroy(), this.proxied.destroy()]);
25374
+ }
25375
+ };
25281
25376
  var installed = false;
25282
- function installProxyIfConfigured(env = process.env) {
25377
+ function resolveNoProxy(env = process.env, opts = {}) {
25378
+ const defaults = parseNoProxy(DEFAULT_NO_PROXY.join(","));
25379
+ const envSystem = parseNoProxy(detectNoProxyRaw(env));
25380
+ const envReasonix = parseNoProxy(
25381
+ typeof env.REASONIX_NO_PROXY === "string" ? env.REASONIX_NO_PROXY : null
25382
+ );
25383
+ const extra = parseNoProxy((opts.extraNoProxy ?? []).join(","));
25384
+ return {
25385
+ defaults,
25386
+ envSystem,
25387
+ envReasonix,
25388
+ extra,
25389
+ all: [...defaults, ...envSystem, ...envReasonix, ...extra]
25390
+ };
25391
+ }
25392
+ function installProxyIfConfigured(env = process.env, opts = {}) {
25393
+ if (opts.disabled) return null;
25283
25394
  const raw = detectProxyUrl(env);
25284
25395
  if (!raw) return null;
25285
25396
  const url = normalizeProxyUrl(raw);
@@ -25290,11 +25401,15 @@ function installProxyIfConfigured(env = process.env) {
25290
25401
  );
25291
25402
  return null;
25292
25403
  }
25404
+ const { all: patterns } = resolveNoProxy(env, { extraNoProxy: opts.extraNoProxy });
25293
25405
  try {
25294
25406
  const reinstalled = installed;
25295
- (0, import_undici.setGlobalDispatcher)(new import_undici.ProxyAgent(url));
25407
+ (0, import_undici.setGlobalDispatcher)(new SelectiveProxyDispatcher(url, patterns));
25296
25408
  installed = true;
25297
- return { url, reinstalled };
25409
+ const bypassList = patterns.map((p) => p.raw).join(",");
25410
+ process.stderr.write(`[proxy] using ${url} (NO_PROXY: ${bypassList})
25411
+ `);
25412
+ return { url, reinstalled, noProxy: patterns };
25298
25413
  } catch (err) {
25299
25414
  process.stderr.write(
25300
25415
  `\u25B2 proxy install failed (${err.message}); continuing without proxy.
@@ -25306,6 +25421,8 @@ function installProxyIfConfigured(env = process.env) {
25306
25421
 
25307
25422
  export {
25308
25423
  detectProxyUrl,
25424
+ matchesNoProxy,
25425
+ resolveNoProxy,
25309
25426
  installProxyIfConfigured
25310
25427
  };
25311
25428
  /*! Bundled license information:
@@ -25316,4 +25433,4 @@ undici/lib/web/fetch/body.js:
25316
25433
  undici/lib/web/websocket/frame.js:
25317
25434
  (*! ws. MIT License. Einar Otto Stangvik <einaros@gmail.com> *)
25318
25435
  */
25319
- //# sourceMappingURL=chunk-5QCB62C4.js.map
25436
+ //# sourceMappingURL=chunk-J2TQAWOM.js.map