@letrquan/book 0.3.0 → 0.4.0-beta.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 (148) hide show
  1. package/CHANGELOG.md +1024 -0
  2. package/README.md +6 -3
  3. package/dist/{additional-roots-H7UNAEHS.js → additional-roots-VAWRQ625.js} +8 -7
  4. package/dist/{app-GE4OHJOC.js → app-J7BVPSUH.js} +5397 -2953
  5. package/dist/app-J7BVPSUH.js.map +1 -0
  6. package/dist/chunk-32WBCUAN.js +660 -0
  7. package/dist/chunk-32WBCUAN.js.map +1 -0
  8. package/dist/{chunk-525CAZPY.js → chunk-4DKHLZRI.js} +6 -6
  9. package/dist/{chunk-4AS7LKKQ.js → chunk-62EEAUID.js} +2 -2
  10. package/dist/{chunk-AQEQX4FF.js → chunk-AHC7OU75.js} +385 -55
  11. package/dist/chunk-AHC7OU75.js.map +1 -0
  12. package/dist/{chunk-EFJ2NH6E.js → chunk-AJZWLKLQ.js} +63 -14
  13. package/dist/chunk-AJZWLKLQ.js.map +1 -0
  14. package/dist/chunk-B5FC3MYZ.js +395 -0
  15. package/dist/chunk-B5FC3MYZ.js.map +1 -0
  16. package/dist/{chunk-67UZEWWF.js → chunk-DNFQTSMJ.js} +53 -11
  17. package/dist/chunk-DNFQTSMJ.js.map +1 -0
  18. package/dist/{chunk-TLX3H2CL.js → chunk-E5WLQSKA.js} +231 -40
  19. package/dist/chunk-E5WLQSKA.js.map +1 -0
  20. package/dist/chunk-ECLC4CIJ.js +1181 -0
  21. package/dist/chunk-ECLC4CIJ.js.map +1 -0
  22. package/dist/chunk-EEX6QNXV.js +127 -0
  23. package/dist/chunk-EEX6QNXV.js.map +1 -0
  24. package/dist/chunk-EFXVSQ5J.js +931 -0
  25. package/dist/chunk-EFXVSQ5J.js.map +1 -0
  26. package/dist/{chunk-RFJ6Q6LE.js → chunk-ENLB7NYV.js} +577 -164
  27. package/dist/chunk-ENLB7NYV.js.map +1 -0
  28. package/dist/{chunk-IME7R2UI.js → chunk-FPR7SKIE.js} +1268 -883
  29. package/dist/chunk-FPR7SKIE.js.map +1 -0
  30. package/dist/{chunk-VPNLCMVR.js → chunk-HFB74CLM.js} +13 -5
  31. package/dist/chunk-HFB74CLM.js.map +1 -0
  32. package/dist/{chunk-5RDRAO4B.js → chunk-HOZXKOE3.js} +37 -1
  33. package/dist/chunk-HOZXKOE3.js.map +1 -0
  34. package/dist/chunk-IDYWN37T.js +36 -0
  35. package/dist/chunk-IDYWN37T.js.map +1 -0
  36. package/dist/{chunk-YC6W4EJH.js → chunk-JGF5HLSI.js} +193 -75
  37. package/dist/chunk-JGF5HLSI.js.map +1 -0
  38. package/dist/{chunk-5YHTKWJN.js → chunk-KDNWMKXV.js} +2447 -907
  39. package/dist/chunk-KDNWMKXV.js.map +1 -0
  40. package/dist/{chunk-Y2VHN7TC.js → chunk-MEOB2DZA.js} +11 -1
  41. package/dist/chunk-MEOB2DZA.js.map +1 -0
  42. package/dist/{chunk-KBQS35OV.js → chunk-MV5PQNIA.js} +2 -2
  43. package/dist/chunk-N2G4Q7ME.js +2672 -0
  44. package/dist/chunk-N2G4Q7ME.js.map +1 -0
  45. package/dist/{chunk-62QL5QUP.js → chunk-OJBMDM5H.js} +17 -1
  46. package/dist/chunk-OJBMDM5H.js.map +1 -0
  47. package/dist/{chunk-56SIEMDX.js → chunk-PTDC7ZUP.js} +2 -2
  48. package/dist/{chunk-X4NJT436.js → chunk-REASC2QG.js} +67 -28
  49. package/dist/chunk-REASC2QG.js.map +1 -0
  50. package/dist/chunk-SBTU5BEC.js +114 -0
  51. package/dist/chunk-SBTU5BEC.js.map +1 -0
  52. package/dist/{chunk-HQI7NYGX.js → chunk-SWPDKLNM.js} +2 -2
  53. package/dist/{chunk-W3XFHEF4.js → chunk-UCFJ43OS.js} +140 -28
  54. package/dist/chunk-UCFJ43OS.js.map +1 -0
  55. package/dist/{chunk-QYBD22H5.js → chunk-W7SLYS3M.js} +80 -16
  56. package/dist/chunk-W7SLYS3M.js.map +1 -0
  57. package/dist/{chunk-SOW4WRQP.js → chunk-WV3O5PGX.js} +3 -3
  58. package/dist/{chunk-JTPOI3KU.js → chunk-XJRJVXJR.js} +262 -38
  59. package/dist/chunk-XJRJVXJR.js.map +1 -0
  60. package/dist/{chunk-224FJZLH.js → chunk-YIL6HTJX.js} +228 -5
  61. package/dist/chunk-YIL6HTJX.js.map +1 -0
  62. package/dist/{command-approvals-VBIU6BLM.js → command-approvals-ZRY66LCW.js} +5 -4
  63. package/dist/context-C3RAP6K5.js +41 -0
  64. package/dist/{hook-approvals-ZVT4V7IM.js → hook-approvals-DPQD5H65.js} +5 -4
  65. package/dist/index.js +657 -754
  66. package/dist/index.js.map +1 -1
  67. package/dist/{interactive-assets-T4I4SEHU.js → interactive-assets-73AQO5WP.js} +11 -6
  68. package/dist/{interactive-assets-T4I4SEHU.js.map → interactive-assets-73AQO5WP.js.map} +1 -1
  69. package/dist/job-runner.js +10 -3
  70. package/dist/job-runner.js.map +1 -1
  71. package/dist/job-supervisor.js +13 -4
  72. package/dist/job-supervisor.js.map +1 -1
  73. package/dist/loader-DQNPDKOX.js +27 -0
  74. package/dist/{mcp-approvals-HJ2VDYMC.js → mcp-approvals-27LJYADQ.js} +5 -4
  75. package/dist/{mcp-config-RNB5LEVE.js → mcp-config-GXSODNCM.js} +3 -2
  76. package/dist/memory-store-I6Z54VUN.js +51 -0
  77. package/dist/{model-window-store-MTSQ5JDJ.js → model-window-store-6VKXXTPJ.js} +4 -3
  78. package/dist/{openai-compatible-2OB54YST.js → openai-compatible-IPUNBJ53.js} +5 -3
  79. package/dist/{permission-approvals-YLV6UC5W.js → permission-approvals-Q5IMFEZI.js} +5 -4
  80. package/dist/{permissions-DHOKF3W2.js → permissions-7Y35X6HZ.js} +26 -9
  81. package/dist/provider-approvals-5AGH3RVT.js +76 -0
  82. package/dist/{sandbox-WRYTZH3D.js → sandbox-N2RY72GN.js} +6 -5
  83. package/dist/{scrollback-35ME2GFX.js → scrollback-GD76GNM4.js} +36 -28
  84. package/dist/scrollback-GD76GNM4.js.map +1 -0
  85. package/dist/sdk.d.ts +876 -64
  86. package/dist/sdk.js +57 -37
  87. package/dist/sdk.js.map +1 -1
  88. package/dist/settings-loader-KDBH45AQ.js +43 -0
  89. package/dist/{settings-removed-JWWPT4WA.js → settings-removed-3ATWJEF3.js} +2 -2
  90. package/dist/shell-selection-Z5WORZU4.js +31 -0
  91. package/dist/shell-selection-Z5WORZU4.js.map +1 -0
  92. package/package.json +5 -5
  93. package/dist/app-GE4OHJOC.js.map +0 -1
  94. package/dist/chunk-224FJZLH.js.map +0 -1
  95. package/dist/chunk-5RDRAO4B.js.map +0 -1
  96. package/dist/chunk-5YHTKWJN.js.map +0 -1
  97. package/dist/chunk-62QL5QUP.js.map +0 -1
  98. package/dist/chunk-67UZEWWF.js.map +0 -1
  99. package/dist/chunk-6OQQOMZR.js +0 -785
  100. package/dist/chunk-6OQQOMZR.js.map +0 -1
  101. package/dist/chunk-AQEQX4FF.js.map +0 -1
  102. package/dist/chunk-C7ADUNPR.js +0 -273
  103. package/dist/chunk-C7ADUNPR.js.map +0 -1
  104. package/dist/chunk-EFJ2NH6E.js.map +0 -1
  105. package/dist/chunk-IME7R2UI.js.map +0 -1
  106. package/dist/chunk-J62VZYOB.js +0 -1339
  107. package/dist/chunk-J62VZYOB.js.map +0 -1
  108. package/dist/chunk-JTPOI3KU.js.map +0 -1
  109. package/dist/chunk-QYBD22H5.js.map +0 -1
  110. package/dist/chunk-RFJ6Q6LE.js.map +0 -1
  111. package/dist/chunk-S4JMID4G.js +0 -259
  112. package/dist/chunk-S4JMID4G.js.map +0 -1
  113. package/dist/chunk-TLX3H2CL.js.map +0 -1
  114. package/dist/chunk-VPNLCMVR.js.map +0 -1
  115. package/dist/chunk-W3XFHEF4.js.map +0 -1
  116. package/dist/chunk-X4NJT436.js.map +0 -1
  117. package/dist/chunk-X66I2NQO.js +0 -137
  118. package/dist/chunk-X66I2NQO.js.map +0 -1
  119. package/dist/chunk-Y2VHN7TC.js.map +0 -1
  120. package/dist/chunk-YC6W4EJH.js.map +0 -1
  121. package/dist/context-CBOBDY5Q.js +0 -38
  122. package/dist/loader-S77OVTHH.js +0 -18
  123. package/dist/memory-store-DZUT5HUH.js +0 -75
  124. package/dist/scrollback-35ME2GFX.js.map +0 -1
  125. package/dist/settings-loader-JUNPGAAM.js +0 -35
  126. package/dist/shell-selection-CDHGJ4GC.js +0 -17
  127. /package/dist/{additional-roots-H7UNAEHS.js.map → additional-roots-VAWRQ625.js.map} +0 -0
  128. /package/dist/{chunk-525CAZPY.js.map → chunk-4DKHLZRI.js.map} +0 -0
  129. /package/dist/{chunk-4AS7LKKQ.js.map → chunk-62EEAUID.js.map} +0 -0
  130. /package/dist/{chunk-KBQS35OV.js.map → chunk-MV5PQNIA.js.map} +0 -0
  131. /package/dist/{chunk-56SIEMDX.js.map → chunk-PTDC7ZUP.js.map} +0 -0
  132. /package/dist/{chunk-HQI7NYGX.js.map → chunk-SWPDKLNM.js.map} +0 -0
  133. /package/dist/{chunk-SOW4WRQP.js.map → chunk-WV3O5PGX.js.map} +0 -0
  134. /package/dist/{command-approvals-VBIU6BLM.js.map → command-approvals-ZRY66LCW.js.map} +0 -0
  135. /package/dist/{context-CBOBDY5Q.js.map → context-C3RAP6K5.js.map} +0 -0
  136. /package/dist/{hook-approvals-ZVT4V7IM.js.map → hook-approvals-DPQD5H65.js.map} +0 -0
  137. /package/dist/{loader-S77OVTHH.js.map → loader-DQNPDKOX.js.map} +0 -0
  138. /package/dist/{mcp-approvals-HJ2VDYMC.js.map → mcp-approvals-27LJYADQ.js.map} +0 -0
  139. /package/dist/{mcp-config-RNB5LEVE.js.map → mcp-config-GXSODNCM.js.map} +0 -0
  140. /package/dist/{memory-store-DZUT5HUH.js.map → memory-store-I6Z54VUN.js.map} +0 -0
  141. /package/dist/{model-window-store-MTSQ5JDJ.js.map → model-window-store-6VKXXTPJ.js.map} +0 -0
  142. /package/dist/{openai-compatible-2OB54YST.js.map → openai-compatible-IPUNBJ53.js.map} +0 -0
  143. /package/dist/{permission-approvals-YLV6UC5W.js.map → permission-approvals-Q5IMFEZI.js.map} +0 -0
  144. /package/dist/{permissions-DHOKF3W2.js.map → permissions-7Y35X6HZ.js.map} +0 -0
  145. /package/dist/{sandbox-WRYTZH3D.js.map → provider-approvals-5AGH3RVT.js.map} +0 -0
  146. /package/dist/{settings-loader-JUNPGAAM.js.map → sandbox-N2RY72GN.js.map} +0 -0
  147. /package/dist/{settings-removed-JWWPT4WA.js.map → settings-loader-KDBH45AQ.js.map} +0 -0
  148. /package/dist/{shell-selection-CDHGJ4GC.js.map → settings-removed-3ATWJEF3.js.map} +0 -0
@@ -1,3 +1,6 @@
1
+ import {
2
+ createUncGuard
3
+ } from "./chunk-EEX6QNXV.js";
1
4
  import {
2
5
  resolveBookHome
3
6
  } from "./chunk-ZPSZZUWF.js";
@@ -121,7 +124,14 @@ function resolveMcpServerList(workspace, options = {}) {
121
124
  { path: join(workspace, ".mcp.json"), source: "project" }
122
125
  ];
123
126
  const servers = /* @__PURE__ */ new Map();
127
+ const reachesUnc = createUncGuard();
124
128
  for (const { path, source } of sources) {
129
+ if (source === "project" && reachesUnc(path)) {
130
+ if (!reachesUnc(workspace)) {
131
+ onDiagnostic({ level: "warn", message: `Skipped MCP config on a network path: ${path}` });
132
+ }
133
+ continue;
134
+ }
125
135
  if (!existsSync(path)) continue;
126
136
  let parsed;
127
137
  try {
@@ -210,4 +220,4 @@ export {
210
220
  loadMcpConfig,
211
221
  formatMcpServerCommand
212
222
  };
213
- //# sourceMappingURL=chunk-Y2VHN7TC.js.map
223
+ //# sourceMappingURL=chunk-MEOB2DZA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp-config.ts"],"sourcesContent":["import { readFileSync, existsSync } from 'fs';\nimport { createUncGuard } from './unc-path.js';\nimport { join } from 'path';\nimport { resolveBookHome } from './book-home.js';\n\nexport type McpTransportType = 'stdio' | 'http' | 'sse';\n\nexport interface McpServerConfig {\n /** Explicit transport. Omitted means stdio when `command` is present. */\n type?: McpTransportType;\n /** Executable for stdio servers. */\n command?: string;\n args?: string[];\n env?: Record<string, string>;\n /** Optional working directory for stdio servers. */\n cwd?: string;\n /** Endpoint for HTTP/SSE servers. */\n url?: string;\n /** Additional request headers for HTTP/SSE servers. Values are never shown in diagnostics. */\n headers?: Record<string, string>;\n}\n\nconst SAFE_SERVER_NAME = /^[A-Za-z0-9_-]+$/;\n\nexport function isValidMcpServerName(name: string): boolean {\n return SAFE_SERVER_NAME.test(name) && !name.includes('__');\n}\n\ninterface McpConfigDocument {\n mcpServers?: Record<string, unknown>;\n}\n\n/** Where a server declaration came from; project declarations require approval. */\nexport type McpServerSource = 'user' | 'project';\n\nexport interface ResolvedMcpServer {\n name: string;\n config: McpServerConfig;\n source: McpServerSource;\n /** Config file that defined (or, on a name collision, last overrode) this server. */\n path: string;\n}\n\nexport interface McpDiagnostic {\n level: 'warn';\n message: string;\n server?: string;\n}\n\nexport type McpDiagnosticSink = (diagnostic: McpDiagnostic) => void;\n\n/** Preserves the historical stderr warning behavior for headless/SDK hosts. */\nexport const consoleMcpDiagnosticSink: McpDiagnosticSink = (diagnostic) => {\n console.warn(`⚠ ${diagnostic.message}`);\n};\n\nexport interface ResolveMcpServersOptions {\n home?: string;\n onDiagnostic?: McpDiagnosticSink;\n /** Environment used for `${VAR}` interpolation; defaults to process.env. */\n env?: NodeJS.ProcessEnv;\n}\n\ninterface ExpandedValue {\n value: string;\n missing: string[];\n}\n\n/**\n * Expand the small interpolation language used by the de-facto mcpServers\n * config format. We deliberately support only `${NAME}` and `${NAME:-default}`\n * here; shell syntax is never evaluated.\n *\n * A project `.mcp.json` is repository-controlled, and its `env`, `headers`, `url` and `command`\n * can name any variable of this process (#418 audit). The expansion only builds a config in\n * memory: it reaches a child process or a request only for a server `mcp-approvals.ts` approved\n * against a fingerprint of the expanded values, `connectMcpServers` skips project servers it was\n * given no approved list for, and every disclosure of a config is redacted.\n */\nfunction expandValue(raw: string, env: NodeJS.ProcessEnv): ExpandedValue {\n const missing = new Set<string>();\n const value = raw.replace(\n /\\$\\{([A-Za-z_][A-Za-z0-9_]*)(?::-([^}]*))?\\}/g,\n (_match, name: string, fallback?: string) => {\n const configured = env[name];\n if (configured !== undefined) return configured;\n if (fallback !== undefined) return fallback;\n missing.add(name);\n return '';\n },\n );\n return { value, missing: [...missing] };\n}\n\nfunction expandRecord(\n raw: unknown,\n env: NodeJS.ProcessEnv,\n): { value: Record<string, string>; missing: string[]; invalid: string[] } {\n const value: Record<string, string> = {};\n const missing = new Set<string>();\n const invalid: string[] = [];\n if (raw === undefined) return { value, missing: [], invalid };\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { value, missing: [], invalid: ['expected an object'] };\n }\n for (const [key, item] of Object.entries(raw as Record<string, unknown>)) {\n if (typeof item !== 'string') {\n invalid.push(`${key} must be a string`);\n continue;\n }\n const expanded = expandValue(item, env);\n value[key] = expanded.value;\n for (const name of expanded.missing) missing.add(name);\n }\n return { value, missing: [...missing], invalid };\n}\n\nfunction normalizeServerConfig(\n name: string,\n raw: unknown,\n env: NodeJS.ProcessEnv,\n): { config?: McpServerConfig; error?: string } {\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) {\n return { error: 'expected an object' };\n }\n const source = raw as Record<string, unknown>;\n const requestedType = source.type ?? source.transport;\n const type =\n requestedType === undefined\n ? source.url !== undefined\n ? 'http'\n : 'stdio'\n : String(requestedType).toLowerCase();\n if (!['stdio', 'http', 'sse'].includes(type)) {\n return { error: `unsupported transport type \"${String(requestedType)}\"` };\n }\n\n const commandExpanded =\n typeof source.command === 'string' ? expandValue(source.command, env) : undefined;\n const urlExpanded = typeof source.url === 'string' ? expandValue(source.url, env) : undefined;\n const missing = new Set([...(commandExpanded?.missing ?? []), ...(urlExpanded?.missing ?? [])]);\n const args: string[] = [];\n if (source.args !== undefined) {\n if (!Array.isArray(source.args)) return { error: 'args must be an array' };\n for (const [index, item] of source.args.entries()) {\n if (typeof item !== 'string') return { error: `args[${index}] must be a string` };\n const expanded = expandValue(item, env);\n args.push(expanded.value);\n for (const variable of expanded.missing) missing.add(variable);\n }\n }\n const envValues = expandRecord(source.env, env);\n const headerValues = expandRecord(source.headers, env);\n for (const variable of [...envValues.missing, ...headerValues.missing]) missing.add(variable);\n if (envValues.invalid.length > 0) return { error: `env ${envValues.invalid.join(', ')}` };\n if (headerValues.invalid.length > 0)\n return { error: `headers ${headerValues.invalid.join(', ')}` };\n if (missing.size > 0)\n return { error: `missing environment variable(s): ${[...missing].join(', ')}` };\n\n if (type === 'stdio') {\n if (!commandExpanded?.value.trim())\n return { error: 'stdio server requires a non-empty command' };\n const cwd = typeof source.cwd === 'string' ? expandValue(source.cwd, env) : undefined;\n if (cwd?.missing.length)\n return { error: `missing environment variable(s): ${cwd.missing.join(', ')}` };\n return {\n config: {\n type: 'stdio',\n command: commandExpanded.value,\n args,\n env: envValues.value,\n ...(cwd?.value ? { cwd: cwd.value } : {}),\n },\n };\n }\n\n if (!urlExpanded?.value.trim()) return { error: `${type} server requires a non-empty url` };\n let parsedUrl: URL;\n try {\n parsedUrl = new URL(urlExpanded.value);\n } catch {\n return { error: 'url must be a valid absolute URL' };\n }\n if (!['http:', 'https:'].includes(parsedUrl.protocol)) {\n return { error: 'url must use http:// or https://' };\n }\n if (parsedUrl.username || parsedUrl.password)\n return { error: 'url must not contain credentials' };\n return {\n config: {\n type: type as 'http' | 'sse',\n url: parsedUrl.toString(),\n headers: headerValues.value,\n },\n };\n}\n\n/**\n * Resolve the declared MCP servers with provenance.\n *\n * Sources, later wins on a name collision: <BOOK_HOME>/.book/mcp.json (user),\n * then <workspace>/.mcp.json (project). A project entry that overrides a\n * user-global name keeps `source: 'project'` so it cannot inherit the trust of\n * the name it shadows.\n */\nexport function resolveMcpServerList(\n workspace: string,\n options: ResolveMcpServersOptions = {},\n): ResolvedMcpServer[] {\n const onDiagnostic = options.onDiagnostic ?? consoleMcpDiagnosticSink;\n const env = options.env ?? process.env;\n const bookHome = options.home ? join(options.home, '.book') : resolveBookHome();\n const sources: Array<{ path: string; source: McpServerSource }> = [\n { path: join(bookHome, 'mcp.json'), source: 'user' },\n { path: join(workspace, '.mcp.json'), source: 'project' },\n ];\n const servers = new Map<string, ResolvedMcpServer>();\n const reachesUnc = createUncGuard();\n\n for (const { path, source } of sources) {\n // A project file on a network (UNC) path is not opened (#579): it counts as absent. Said\n // only of a link out of a local workspace: one on a share loads no project file at all.\n if (source === 'project' && reachesUnc(path)) {\n if (!reachesUnc(workspace)) {\n onDiagnostic({ level: 'warn', message: `Skipped MCP config on a network path: ${path}` });\n }\n continue;\n }\n if (!existsSync(path)) continue;\n let parsed: McpConfigDocument;\n try {\n parsed = JSON.parse(readFileSync(path, 'utf-8')) as McpConfigDocument;\n } catch {\n onDiagnostic({ level: 'warn', message: `Failed to load MCP config: ${path}` });\n continue;\n }\n if (!parsed || typeof parsed !== 'object' || !parsed.mcpServers) continue;\n if (typeof parsed.mcpServers !== 'object' || Array.isArray(parsed.mcpServers)) {\n onDiagnostic({ level: 'warn', message: `Invalid mcpServers object: ${path}` });\n continue;\n }\n for (const [name, rawConfig] of Object.entries(parsed.mcpServers)) {\n if (!isValidMcpServerName(name)) {\n onDiagnostic({\n level: 'warn',\n message: `Ignoring invalid MCP server name: ${name} (${path}); use letters, numbers, hyphens, or underscores, without a double underscore`,\n server: name,\n });\n continue;\n }\n const normalized = normalizeServerConfig(name, rawConfig, env);\n if (!normalized.config) {\n onDiagnostic({\n level: 'warn',\n message: `Ignoring invalid MCP server config: ${name} (${path}): ${normalized.error ?? 'invalid configuration'}`,\n server: name,\n });\n continue;\n }\n servers.set(name, {\n name,\n source,\n path,\n config: normalized.config,\n });\n }\n }\n\n return [...servers.values()];\n}\n\n/** Merged name → config view used by doctor and ambient-run fingerprinting. */\nexport function loadMcpConfig(workspace: string, home?: string): Record<string, McpServerConfig> {\n const servers: Record<string, McpServerConfig> = {};\n for (const server of resolveMcpServerList(workspace, { home })) {\n servers[server.name] = server.config;\n }\n return servers;\n}\n\n/** Render one server as the exact command line a host is being asked to trust. */\nexport function formatMcpServerCommand(config: McpServerConfig): string {\n const sensitiveValues = [\n ...Object.values(config.env ?? {}),\n ...Object.values(config.headers ?? {}),\n ]\n .filter((value) => value.length >= 4)\n .sort((left, right) => right.length - left.length);\n const redact = (value: string): string => {\n let rendered = value;\n for (const sensitive of sensitiveValues)\n rendered = rendered.replaceAll(sensitive, '<redacted>');\n return rendered;\n };\n if (config.type === 'http' || config.type === 'sse' || (!config.command && config.url)) {\n const headers = Object.keys(config.headers ?? {}).sort();\n let endpoint = config.url ?? '';\n let queryConfigured = false;\n try {\n const url = new URL(endpoint);\n queryConfigured = Boolean(url.search);\n url.search = '';\n url.hash = '';\n endpoint = url.toString();\n } catch {\n endpoint = redact(endpoint);\n }\n const metadata = [\n ...(queryConfigured ? ['query configured'] : []),\n ...(headers.length ? [`headers: ${headers.join(', ')}`] : []),\n ];\n return `${config.type === 'sse' ? 'sse' : 'http'} ${endpoint}${metadata.length ? ` (${metadata.join('; ')})` : ''}`;\n }\n return [config.command ?? '', ...(config.args ?? [])].filter(Boolean).map(redact).join(' ');\n}\n"],"mappings":";;;;;;;;AAAA,SAAS,cAAc,kBAAkB;AAEzC,SAAS,YAAY;AAoBrB,IAAM,mBAAmB;AAElB,SAAS,qBAAqB,MAAuB;AAC1D,SAAO,iBAAiB,KAAK,IAAI,KAAK,CAAC,KAAK,SAAS,IAAI;AAC3D;AA0BO,IAAM,2BAA8C,CAAC,eAAe;AACzE,UAAQ,KAAK,WAAM,WAAW,OAAO,EAAE;AACzC;AAyBA,SAAS,YAAY,KAAa,KAAuC;AACvE,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,QAAQ,IAAI;AAAA,IAChB;AAAA,IACA,CAAC,QAAQ,MAAc,aAAsB;AAC3C,YAAM,aAAa,IAAI,IAAI;AAC3B,UAAI,eAAe,OAAW,QAAO;AACrC,UAAI,aAAa,OAAW,QAAO;AACnC,cAAQ,IAAI,IAAI;AAChB,aAAO;AAAA,IACT;AAAA,EACF;AACA,SAAO,EAAE,OAAO,SAAS,CAAC,GAAG,OAAO,EAAE;AACxC;AAEA,SAAS,aACP,KACA,KACyE;AACzE,QAAM,QAAgC,CAAC;AACvC,QAAM,UAAU,oBAAI,IAAY;AAChC,QAAM,UAAoB,CAAC;AAC3B,MAAI,QAAQ,OAAW,QAAO,EAAE,OAAO,SAAS,CAAC,GAAG,QAAQ;AAC5D,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG;AACzD,WAAO,EAAE,OAAO,SAAS,CAAC,GAAG,SAAS,CAAC,oBAAoB,EAAE;AAAA,EAC/D;AACA,aAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,GAA8B,GAAG;AACxE,QAAI,OAAO,SAAS,UAAU;AAC5B,cAAQ,KAAK,GAAG,GAAG,mBAAmB;AACtC;AAAA,IACF;AACA,UAAM,WAAW,YAAY,MAAM,GAAG;AACtC,UAAM,GAAG,IAAI,SAAS;AACtB,eAAW,QAAQ,SAAS,QAAS,SAAQ,IAAI,IAAI;AAAA,EACvD;AACA,SAAO,EAAE,OAAO,SAAS,CAAC,GAAG,OAAO,GAAG,QAAQ;AACjD;AAEA,SAAS,sBACP,MACA,KACA,KAC8C;AAC9C,MAAI,CAAC,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAQ,GAAG,GAAG;AACzD,WAAO,EAAE,OAAO,qBAAqB;AAAA,EACvC;AACA,QAAM,SAAS;AACf,QAAM,gBAAgB,OAAO,QAAQ,OAAO;AAC5C,QAAM,OACJ,kBAAkB,SACd,OAAO,QAAQ,SACb,SACA,UACF,OAAO,aAAa,EAAE,YAAY;AACxC,MAAI,CAAC,CAAC,SAAS,QAAQ,KAAK,EAAE,SAAS,IAAI,GAAG;AAC5C,WAAO,EAAE,OAAO,+BAA+B,OAAO,aAAa,CAAC,IAAI;AAAA,EAC1E;AAEA,QAAM,kBACJ,OAAO,OAAO,YAAY,WAAW,YAAY,OAAO,SAAS,GAAG,IAAI;AAC1E,QAAM,cAAc,OAAO,OAAO,QAAQ,WAAW,YAAY,OAAO,KAAK,GAAG,IAAI;AACpF,QAAM,UAAU,oBAAI,IAAI,CAAC,GAAI,iBAAiB,WAAW,CAAC,GAAI,GAAI,aAAa,WAAW,CAAC,CAAE,CAAC;AAC9F,QAAM,OAAiB,CAAC;AACxB,MAAI,OAAO,SAAS,QAAW;AAC7B,QAAI,CAAC,MAAM,QAAQ,OAAO,IAAI,EAAG,QAAO,EAAE,OAAO,wBAAwB;AACzE,eAAW,CAAC,OAAO,IAAI,KAAK,OAAO,KAAK,QAAQ,GAAG;AACjD,UAAI,OAAO,SAAS,SAAU,QAAO,EAAE,OAAO,QAAQ,KAAK,qBAAqB;AAChF,YAAM,WAAW,YAAY,MAAM,GAAG;AACtC,WAAK,KAAK,SAAS,KAAK;AACxB,iBAAW,YAAY,SAAS,QAAS,SAAQ,IAAI,QAAQ;AAAA,IAC/D;AAAA,EACF;AACA,QAAM,YAAY,aAAa,OAAO,KAAK,GAAG;AAC9C,QAAM,eAAe,aAAa,OAAO,SAAS,GAAG;AACrD,aAAW,YAAY,CAAC,GAAG,UAAU,SAAS,GAAG,aAAa,OAAO,EAAG,SAAQ,IAAI,QAAQ;AAC5F,MAAI,UAAU,QAAQ,SAAS,EAAG,QAAO,EAAE,OAAO,OAAO,UAAU,QAAQ,KAAK,IAAI,CAAC,GAAG;AACxF,MAAI,aAAa,QAAQ,SAAS;AAChC,WAAO,EAAE,OAAO,WAAW,aAAa,QAAQ,KAAK,IAAI,CAAC,GAAG;AAC/D,MAAI,QAAQ,OAAO;AACjB,WAAO,EAAE,OAAO,oCAAoC,CAAC,GAAG,OAAO,EAAE,KAAK,IAAI,CAAC,GAAG;AAEhF,MAAI,SAAS,SAAS;AACpB,QAAI,CAAC,iBAAiB,MAAM,KAAK;AAC/B,aAAO,EAAE,OAAO,4CAA4C;AAC9D,UAAM,MAAM,OAAO,OAAO,QAAQ,WAAW,YAAY,OAAO,KAAK,GAAG,IAAI;AAC5E,QAAI,KAAK,QAAQ;AACf,aAAO,EAAE,OAAO,oCAAoC,IAAI,QAAQ,KAAK,IAAI,CAAC,GAAG;AAC/E,WAAO;AAAA,MACL,QAAQ;AAAA,QACN,MAAM;AAAA,QACN,SAAS,gBAAgB;AAAA,QACzB;AAAA,QACA,KAAK,UAAU;AAAA,QACf,GAAI,KAAK,QAAQ,EAAE,KAAK,IAAI,MAAM,IAAI,CAAC;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,aAAa,MAAM,KAAK,EAAG,QAAO,EAAE,OAAO,GAAG,IAAI,mCAAmC;AAC1F,MAAI;AACJ,MAAI;AACF,gBAAY,IAAI,IAAI,YAAY,KAAK;AAAA,EACvC,QAAQ;AACN,WAAO,EAAE,OAAO,mCAAmC;AAAA,EACrD;AACA,MAAI,CAAC,CAAC,SAAS,QAAQ,EAAE,SAAS,UAAU,QAAQ,GAAG;AACrD,WAAO,EAAE,OAAO,mCAAmC;AAAA,EACrD;AACA,MAAI,UAAU,YAAY,UAAU;AAClC,WAAO,EAAE,OAAO,mCAAmC;AACrD,SAAO;AAAA,IACL,QAAQ;AAAA,MACN;AAAA,MACA,KAAK,UAAU,SAAS;AAAA,MACxB,SAAS,aAAa;AAAA,IACxB;AAAA,EACF;AACF;AAUO,SAAS,qBACd,WACA,UAAoC,CAAC,GAChB;AACrB,QAAM,eAAe,QAAQ,gBAAgB;AAC7C,QAAM,MAAM,QAAQ,OAAO,QAAQ;AACnC,QAAM,WAAW,QAAQ,OAAO,KAAK,QAAQ,MAAM,OAAO,IAAI,gBAAgB;AAC9E,QAAM,UAA4D;AAAA,IAChE,EAAE,MAAM,KAAK,UAAU,UAAU,GAAG,QAAQ,OAAO;AAAA,IACnD,EAAE,MAAM,KAAK,WAAW,WAAW,GAAG,QAAQ,UAAU;AAAA,EAC1D;AACA,QAAM,UAAU,oBAAI,IAA+B;AACnD,QAAM,aAAa,eAAe;AAElC,aAAW,EAAE,MAAM,OAAO,KAAK,SAAS;AAGtC,QAAI,WAAW,aAAa,WAAW,IAAI,GAAG;AAC5C,UAAI,CAAC,WAAW,SAAS,GAAG;AAC1B,qBAAa,EAAE,OAAO,QAAQ,SAAS,yCAAyC,IAAI,GAAG,CAAC;AAAA,MAC1F;AACA;AAAA,IACF;AACA,QAAI,CAAC,WAAW,IAAI,EAAG;AACvB,QAAI;AACJ,QAAI;AACF,eAAS,KAAK,MAAM,aAAa,MAAM,OAAO,CAAC;AAAA,IACjD,QAAQ;AACN,mBAAa,EAAE,OAAO,QAAQ,SAAS,8BAA8B,IAAI,GAAG,CAAC;AAC7E;AAAA,IACF;AACA,QAAI,CAAC,UAAU,OAAO,WAAW,YAAY,CAAC,OAAO,WAAY;AACjE,QAAI,OAAO,OAAO,eAAe,YAAY,MAAM,QAAQ,OAAO,UAAU,GAAG;AAC7E,mBAAa,EAAE,OAAO,QAAQ,SAAS,8BAA8B,IAAI,GAAG,CAAC;AAC7E;AAAA,IACF;AACA,eAAW,CAAC,MAAM,SAAS,KAAK,OAAO,QAAQ,OAAO,UAAU,GAAG;AACjE,UAAI,CAAC,qBAAqB,IAAI,GAAG;AAC/B,qBAAa;AAAA,UACX,OAAO;AAAA,UACP,SAAS,qCAAqC,IAAI,KAAK,IAAI;AAAA,UAC3D,QAAQ;AAAA,QACV,CAAC;AACD;AAAA,MACF;AACA,YAAM,aAAa,sBAAsB,MAAM,WAAW,GAAG;AAC7D,UAAI,CAAC,WAAW,QAAQ;AACtB,qBAAa;AAAA,UACX,OAAO;AAAA,UACP,SAAS,uCAAuC,IAAI,KAAK,IAAI,MAAM,WAAW,SAAS,uBAAuB;AAAA,UAC9G,QAAQ;AAAA,QACV,CAAC;AACD;AAAA,MACF;AACA,cAAQ,IAAI,MAAM;AAAA,QAChB;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ,WAAW;AAAA,MACrB,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO,CAAC,GAAG,QAAQ,OAAO,CAAC;AAC7B;AAGO,SAAS,cAAc,WAAmB,MAAgD;AAC/F,QAAM,UAA2C,CAAC;AAClD,aAAW,UAAU,qBAAqB,WAAW,EAAE,KAAK,CAAC,GAAG;AAC9D,YAAQ,OAAO,IAAI,IAAI,OAAO;AAAA,EAChC;AACA,SAAO;AACT;AAGO,SAAS,uBAAuB,QAAiC;AACtE,QAAM,kBAAkB;AAAA,IACtB,GAAG,OAAO,OAAO,OAAO,OAAO,CAAC,CAAC;AAAA,IACjC,GAAG,OAAO,OAAO,OAAO,WAAW,CAAC,CAAC;AAAA,EACvC,EACG,OAAO,CAAC,UAAU,MAAM,UAAU,CAAC,EACnC,KAAK,CAAC,MAAM,UAAU,MAAM,SAAS,KAAK,MAAM;AACnD,QAAM,SAAS,CAAC,UAA0B;AACxC,QAAI,WAAW;AACf,eAAW,aAAa;AACtB,iBAAW,SAAS,WAAW,WAAW,YAAY;AACxD,WAAO;AAAA,EACT;AACA,MAAI,OAAO,SAAS,UAAU,OAAO,SAAS,SAAU,CAAC,OAAO,WAAW,OAAO,KAAM;AACtF,UAAM,UAAU,OAAO,KAAK,OAAO,WAAW,CAAC,CAAC,EAAE,KAAK;AACvD,QAAI,WAAW,OAAO,OAAO;AAC7B,QAAI,kBAAkB;AACtB,QAAI;AACF,YAAM,MAAM,IAAI,IAAI,QAAQ;AAC5B,wBAAkB,QAAQ,IAAI,MAAM;AACpC,UAAI,SAAS;AACb,UAAI,OAAO;AACX,iBAAW,IAAI,SAAS;AAAA,IAC1B,QAAQ;AACN,iBAAW,OAAO,QAAQ;AAAA,IAC5B;AACA,UAAM,WAAW;AAAA,MACf,GAAI,kBAAkB,CAAC,kBAAkB,IAAI,CAAC;AAAA,MAC9C,GAAI,QAAQ,SAAS,CAAC,YAAY,QAAQ,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,IAC7D;AACA,WAAO,GAAG,OAAO,SAAS,QAAQ,QAAQ,MAAM,IAAI,QAAQ,GAAG,SAAS,SAAS,KAAK,SAAS,KAAK,IAAI,CAAC,MAAM,EAAE;AAAA,EACnH;AACA,SAAO,CAAC,OAAO,WAAW,IAAI,GAAI,OAAO,QAAQ,CAAC,CAAE,EAAE,OAAO,OAAO,EAAE,IAAI,MAAM,EAAE,KAAK,GAAG;AAC5F;","names":[]}
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  updateWorkspaceTrust
3
- } from "./chunk-VPNLCMVR.js";
3
+ } from "./chunk-HFB74CLM.js";
4
4
 
5
5
  // src/permission-approvals.ts
6
6
  function evaluateProjectAllowRule(store, rule) {
@@ -31,4 +31,4 @@ export {
31
31
  partitionProjectAllowRules,
32
32
  persistProjectAllowRuleChoice
33
33
  };
34
- //# sourceMappingURL=chunk-KBQS35OV.js.map
34
+ //# sourceMappingURL=chunk-MV5PQNIA.js.map