@earendil-works/pi-coding-agent 1.0.3 → 1.1.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 (237) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/dist/bundle/chunks/{anthropic-messages-Y22YDKSW.js → anthropic-messages-KT2ID7DZ.js} +1 -1
  3. package/dist/bundle/chunks/anthropic.js +1 -1
  4. package/dist/bundle/chunks/{azure-openai-responses-YJDJIIDQ.js → azure-openai-responses-6A4PNZTH.js} +1 -1
  5. package/dist/bundle/chunks/bedrock-converse-stream.js +2 -2
  6. package/dist/bundle/chunks/chunk-33CRHCAK.js +2 -0
  7. package/dist/bundle/chunks/{chunk-UBHCV62G.js → chunk-BK6FEHYX.js} +3 -3
  8. package/dist/bundle/chunks/chunk-CH4ZBH45.js +11 -0
  9. package/dist/bundle/chunks/{chunk-6DBOMCBS.js → chunk-GXLAGZ3Z.js} +1 -1
  10. package/dist/bundle/chunks/{chunk-J52J6TFP.js → chunk-HKYL362W.js} +1 -1
  11. package/dist/bundle/chunks/chunk-LPXNMA2W.js +2 -0
  12. package/dist/bundle/chunks/{chunk-TAOL3JFA.js → chunk-LTSARG5Q.js} +1 -1
  13. package/dist/bundle/chunks/{chunk-ZSQEXT6X.js → chunk-MXTZIDYW.js} +4 -4
  14. package/dist/bundle/chunks/chunk-O7YIWAPD.js +2 -0
  15. package/dist/bundle/chunks/{chunk-BFNE7BHG.js → chunk-OIM2DMFI.js} +83 -72
  16. package/dist/bundle/chunks/{chunk-AXOERKKW.js → chunk-OTL6MGLJ.js} +6 -4
  17. package/dist/bundle/chunks/{chunk-LD2P6SFZ.js → chunk-PMRZO46Y.js} +1 -1
  18. package/dist/bundle/chunks/{chunk-7TP2J6F2.js → chunk-SYCGMWFH.js} +1 -1
  19. package/dist/bundle/chunks/{chunk-2VBQLN7Y.js → chunk-UH5J7I7X.js} +9 -6
  20. package/dist/bundle/chunks/{chunk-WE4MXUQS.js → chunk-VLRCF7MR.js} +1 -1
  21. package/dist/bundle/chunks/chunk-W5MPVSHA.js +82 -0
  22. package/dist/bundle/chunks/chunk-Y4NYF362.js +2 -0
  23. package/dist/bundle/chunks/{cli-HTJP6F6Z.js → cli-OQYLWLA3.js} +2 -2
  24. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-U3AH4ODQ.js +2 -0
  25. package/dist/bundle/chunks/codemode-worker.js +101 -5
  26. package/dist/bundle/chunks/{easter-egg-3d-6YCNESG3.js → easter-egg-3d-TQFQS342.js} +1 -1
  27. package/dist/bundle/chunks/{execute-JRUOLYDA.js → execute-7IRB5TUX.js} +110 -8
  28. package/dist/bundle/chunks/github-copilot.js +1 -1
  29. package/dist/bundle/chunks/{google-generative-ai-XMFHGQC5.js → google-generative-ai-X2VFFS4I.js} +1 -1
  30. package/dist/bundle/chunks/{google-vertex-4XRRNP74.js → google-vertex-KMGHFTSP.js} +1 -1
  31. package/dist/bundle/chunks/image-resize-worker.js +1 -1
  32. package/dist/bundle/chunks/{llama-cpp-classify-XT44PI3C.js → llama-cpp-classify-FYN623RH.js} +2 -2
  33. package/dist/bundle/chunks/{mistral-conversations-Q22M3IBG.js → mistral-conversations-PRZLM26U.js} +2 -2
  34. package/dist/bundle/chunks/openai-chatgpt.js +1 -1
  35. package/dist/bundle/chunks/{openai-codex-responses-4MYQSO5E.js → openai-codex-responses-ZSLJZYOE.js} +2 -2
  36. package/dist/bundle/chunks/openai-codex.js +1 -1
  37. package/dist/bundle/chunks/{openai-completions-OSRCWAAA.js → openai-completions-WWQW7S3V.js} +1 -1
  38. package/dist/bundle/chunks/openai-decisions-QLZKZLAK.js +5 -0
  39. package/dist/bundle/chunks/{openai-responses-UHF3DHNG.js → openai-responses-KV7QHJY6.js} +1 -1
  40. package/dist/bundle/chunks/{openrouter-images-ZVXWCSIM.js → openrouter-images-DUPG5DZO.js} +1 -1
  41. package/dist/bundle/chunks/{pi-messages-TM5SOOIW.js → pi-messages-YHKPQIHC.js} +1 -1
  42. package/dist/bundle/chunks/{runtime-NW7GPWKS.js → runtime-ROGZ2EXI.js} +1 -1
  43. package/dist/bundle/chunks/typesafe-system-one-B4NNEG67.js +2 -0
  44. package/dist/bundle/chunks/{virtual-modules-CFHJO5SY.js → virtual-modules-4YN2GNVW.js} +1 -1
  45. package/dist/bundle/cli-runtime.js +1 -1
  46. package/dist/bundle/index.js +1 -1
  47. package/dist/bundle/rpc-entry.js +1 -1
  48. package/dist/cli/args.d.ts +2 -1
  49. package/dist/cli/args.d.ts.map +1 -1
  50. package/dist/cli/args.js +24 -5
  51. package/dist/cli/args.js.map +1 -1
  52. package/dist/core/agent-session.d.ts +33 -4
  53. package/dist/core/agent-session.d.ts.map +1 -1
  54. package/dist/core/agent-session.js +59 -21
  55. package/dist/core/agent-session.js.map +1 -1
  56. package/dist/core/bash-executor.d.ts.map +1 -1
  57. package/dist/core/bash-executor.js +40 -45
  58. package/dist/core/bash-executor.js.map +1 -1
  59. package/dist/core/export-html/tool-renderer.d.ts.map +1 -1
  60. package/dist/core/export-html/tool-renderer.js +2 -0
  61. package/dist/core/export-html/tool-renderer.js.map +1 -1
  62. package/dist/core/extensions/types.d.ts +13 -0
  63. package/dist/core/extensions/types.d.ts.map +1 -1
  64. package/dist/core/extensions/types.js.map +1 -1
  65. package/dist/core/mcp-servers.d.ts +8 -0
  66. package/dist/core/mcp-servers.d.ts.map +1 -1
  67. package/dist/core/mcp-servers.js +30 -7
  68. package/dist/core/mcp-servers.js.map +1 -1
  69. package/dist/core/model-runtime.d.ts.map +1 -1
  70. package/dist/core/model-runtime.js +2 -1
  71. package/dist/core/model-runtime.js.map +1 -1
  72. package/dist/core/nested-tool-calls.d.ts +1 -0
  73. package/dist/core/nested-tool-calls.d.ts.map +1 -1
  74. package/dist/core/nested-tool-calls.js +1 -0
  75. package/dist/core/nested-tool-calls.js.map +1 -1
  76. package/dist/core/resource-loader.d.ts +3 -0
  77. package/dist/core/resource-loader.d.ts.map +1 -1
  78. package/dist/core/resource-loader.js +4 -3
  79. package/dist/core/resource-loader.js.map +1 -1
  80. package/dist/core/sdk.d.ts +13 -4
  81. package/dist/core/sdk.d.ts.map +1 -1
  82. package/dist/core/sdk.js +19 -6
  83. package/dist/core/sdk.js.map +1 -1
  84. package/dist/core/settings-manager.d.ts +13 -0
  85. package/dist/core/settings-manager.d.ts.map +1 -1
  86. package/dist/core/settings-manager.js +37 -13
  87. package/dist/core/settings-manager.js.map +1 -1
  88. package/dist/core/skills.d.ts +4 -1
  89. package/dist/core/skills.d.ts.map +1 -1
  90. package/dist/core/skills.js +6 -1
  91. package/dist/core/skills.js.map +1 -1
  92. package/dist/core/system-prompt.d.ts +6 -0
  93. package/dist/core/system-prompt.d.ts.map +1 -1
  94. package/dist/core/system-prompt.js +9 -4
  95. package/dist/core/system-prompt.js.map +1 -1
  96. package/dist/core/tools/read.d.ts +13 -0
  97. package/dist/core/tools/read.d.ts.map +1 -1
  98. package/dist/core/tools/read.js +18 -1
  99. package/dist/core/tools/read.js.map +1 -1
  100. package/dist/core/tools/renderers/bash.d.ts.map +1 -1
  101. package/dist/core/tools/renderers/bash.js +8 -3
  102. package/dist/core/tools/renderers/bash.js.map +1 -1
  103. package/dist/core/tools/renderers/edit.d.ts.map +1 -1
  104. package/dist/core/tools/renderers/edit.js +5 -4
  105. package/dist/core/tools/renderers/edit.js.map +1 -1
  106. package/dist/extensions/codemode/execute.d.ts.map +1 -1
  107. package/dist/extensions/codemode/execute.js +65 -8
  108. package/dist/extensions/codemode/execute.js.map +1 -1
  109. package/dist/extensions/codemode/index.d.ts.map +1 -1
  110. package/dist/extensions/codemode/index.js +1 -0
  111. package/dist/extensions/codemode/index.js.map +1 -1
  112. package/dist/extensions/codemode/tool.d.ts +9 -2
  113. package/dist/extensions/codemode/tool.d.ts.map +1 -1
  114. package/dist/extensions/codemode/tool.js +14 -6
  115. package/dist/extensions/codemode/tool.js.map +1 -1
  116. package/dist/extensions/llama/provider.d.ts.map +1 -1
  117. package/dist/extensions/llama/provider.js +34 -11
  118. package/dist/extensions/llama/provider.js.map +1 -1
  119. package/dist/extensions/mcp/cli.js +17 -23
  120. package/dist/extensions/mcp/cli.js.map +1 -1
  121. package/dist/extensions/mcp/index.d.ts.map +1 -1
  122. package/dist/extensions/mcp/index.js +165 -64
  123. package/dist/extensions/mcp/index.js.map +1 -1
  124. package/dist/extensions/mcp/oauth.d.ts +5 -3
  125. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  126. package/dist/extensions/mcp/oauth.js +36 -10
  127. package/dist/extensions/mcp/oauth.js.map +1 -1
  128. package/dist/extensions/mcp/resources.d.ts +3 -4
  129. package/dist/extensions/mcp/resources.d.ts.map +1 -1
  130. package/dist/extensions/mcp/resources.js +3 -4
  131. package/dist/extensions/mcp/resources.js.map +1 -1
  132. package/dist/extensions/mcp/runtime.d.ts +4 -1
  133. package/dist/extensions/mcp/runtime.d.ts.map +1 -1
  134. package/dist/extensions/mcp/runtime.js +22 -5
  135. package/dist/extensions/mcp/runtime.js.map +1 -1
  136. package/dist/extensions/mcp/tools.d.ts +2 -1
  137. package/dist/extensions/mcp/tools.d.ts.map +1 -1
  138. package/dist/extensions/mcp/tools.js +2 -1
  139. package/dist/extensions/mcp/tools.js.map +1 -1
  140. package/dist/extensions/mcp/ui.d.ts +3 -3
  141. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  142. package/dist/extensions/mcp/ui.js +10 -2
  143. package/dist/extensions/mcp/ui.js.map +1 -1
  144. package/dist/main.d.ts.map +1 -1
  145. package/dist/main.js +1 -0
  146. package/dist/main.js.map +1 -1
  147. package/dist/modes/interactive/components/bash-execution.d.ts +5 -1
  148. package/dist/modes/interactive/components/bash-execution.d.ts.map +1 -1
  149. package/dist/modes/interactive/components/bash-execution.js +17 -14
  150. package/dist/modes/interactive/components/bash-execution.js.map +1 -1
  151. package/dist/modes/interactive/components/branch-summary-message.d.ts +2 -1
  152. package/dist/modes/interactive/components/branch-summary-message.d.ts.map +1 -1
  153. package/dist/modes/interactive/components/branch-summary-message.js +5 -2
  154. package/dist/modes/interactive/components/branch-summary-message.js.map +1 -1
  155. package/dist/modes/interactive/components/compaction-summary-message.d.ts +2 -1
  156. package/dist/modes/interactive/components/compaction-summary-message.d.ts.map +1 -1
  157. package/dist/modes/interactive/components/compaction-summary-message.js +5 -2
  158. package/dist/modes/interactive/components/compaction-summary-message.js.map +1 -1
  159. package/dist/modes/interactive/components/custom-entry.d.ts +3 -1
  160. package/dist/modes/interactive/components/custom-entry.d.ts.map +1 -1
  161. package/dist/modes/interactive/components/custom-entry.js +8 -2
  162. package/dist/modes/interactive/components/custom-entry.js.map +1 -1
  163. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  164. package/dist/modes/interactive/components/custom-message.js +1 -0
  165. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  166. package/dist/modes/interactive/components/settings-selector.js +1 -1
  167. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  168. package/dist/modes/interactive/components/skill-invocation-message.d.ts +2 -1
  169. package/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  170. package/dist/modes/interactive/components/skill-invocation-message.js +5 -2
  171. package/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  172. package/dist/modes/interactive/components/tool-execution.d.ts +5 -0
  173. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  174. package/dist/modes/interactive/components/tool-execution.js +10 -0
  175. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  176. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  177. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  178. package/dist/modes/interactive/interactive-mode.js +50 -29
  179. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  180. package/dist/modes/interactive/program-status-reporter.d.ts +34 -0
  181. package/dist/modes/interactive/program-status-reporter.d.ts.map +1 -0
  182. package/dist/modes/interactive/program-status-reporter.js +110 -0
  183. package/dist/modes/interactive/program-status-reporter.js.map +1 -0
  184. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  185. package/dist/modes/interactive/theme/theme.js +1 -0
  186. package/dist/modes/interactive/theme/theme.js.map +1 -1
  187. package/dist/package-manager-cli.d.ts.map +1 -1
  188. package/dist/package-manager-cli.js +24 -0
  189. package/dist/package-manager-cli.js.map +1 -1
  190. package/dist/utils/ansi.d.ts +8 -0
  191. package/dist/utils/ansi.d.ts.map +1 -1
  192. package/dist/utils/ansi.js +30 -11
  193. package/dist/utils/ansi.js.map +1 -1
  194. package/dist/utils/clipboard.d.ts.map +1 -1
  195. package/dist/utils/clipboard.js +12 -11
  196. package/dist/utils/clipboard.js.map +1 -1
  197. package/dist/utils/image-resize-core.d.ts +12 -0
  198. package/dist/utils/image-resize-core.d.ts.map +1 -1
  199. package/dist/utils/image-resize-core.js +5 -0
  200. package/dist/utils/image-resize-core.js.map +1 -1
  201. package/dist/utils/image-resize-worker.js +3 -2
  202. package/dist/utils/image-resize-worker.js.map +1 -1
  203. package/dist/utils/image-resize.d.ts.map +1 -1
  204. package/dist/utils/image-resize.js +9 -10
  205. package/dist/utils/image-resize.js.map +1 -1
  206. package/dist/utils/syntax-highlight.d.ts.map +1 -1
  207. package/dist/utils/syntax-highlight.js +6 -1
  208. package/dist/utils/syntax-highlight.js.map +1 -1
  209. package/docs/cli.md +18 -6
  210. package/docs/codemode.md +26 -5
  211. package/docs/environment-variables.md +1 -0
  212. package/docs/extensions.md +1 -1
  213. package/docs/json.md +3 -3
  214. package/docs/llama-cpp.md +8 -1
  215. package/docs/mcp.md +3 -1
  216. package/docs/message-types.md +22 -4
  217. package/docs/models.md +4 -1
  218. package/docs/providers.md +27 -0
  219. package/docs/settings.md +3 -3
  220. package/docs/terminal-setup.md +14 -0
  221. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  222. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  223. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  224. package/examples/extensions/gondolin/package-lock.json +2 -2
  225. package/examples/extensions/gondolin/package.json +1 -1
  226. package/examples/extensions/sandbox/package-lock.json +2 -2
  227. package/examples/extensions/sandbox/package.json +1 -1
  228. package/examples/extensions/with-deps/package-lock.json +2 -2
  229. package/examples/extensions/with-deps/package.json +1 -1
  230. package/package.json +12 -12
  231. package/dist/bundle/chunks/chunk-A3JYRWB6.js +0 -2
  232. package/dist/bundle/chunks/chunk-C47CLQZK.js +0 -2
  233. package/dist/bundle/chunks/chunk-HQHD6PZI.js +0 -2
  234. package/dist/bundle/chunks/chunk-KJUDFE6Y.js +0 -11
  235. package/dist/bundle/chunks/chunk-PSQJVYXD.js +0 -82
  236. package/dist/bundle/chunks/cloudflare-workers-ai-system-one-NM3JRRWQ.js +0 -2
  237. package/dist/bundle/chunks/typesafe-system-one-PRR5K6CI.js +0 -2
@@ -1,82 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{FileAuthStorageBackend,JSON_RPC_ERROR_CODES,LATEST_PROTOCOL_VERSION,McpAuthRequiredError,McpClient,McpError,McpHttpError,McpSessionExpiredError,StdioTransport,StreamableHttpTransport,isMcpAppResource,isObject,mcpNamespace,require_proper_lockfile,resolveConfigValueOrThrow,resolveHeadersOrThrow}from"./chunk-ZSQEXT6X.js";import{APP_NAME,VERSION,getAgentDir}from"./chunk-AXOERKKW.js";import{__toESM}from"./chunk-4L3WN2XY.js";import{homedir}from"node:os";import{basename,join as join2,resolve}from"node:path";import{pathToFileURL}from"node:url";import{createServer}from"node:http";function plainText(page){return page.ok?"Authorization complete. You may close this window.":page.details?`${page.message}
3
-
4
- ${page.details}`:page.message}var OAuthCallbackServer=class _OAuthCallbackServer{redirectUrl;server;paths;timeoutMs;renderPage;pending=new Map;constructor(server,redirectUrl,paths,timeoutMs,renderPage2){this.server=server,this.redirectUrl=redirectUrl,this.paths=paths,this.timeoutMs=timeoutMs,this.renderPage=renderPage2}static async listen(options={}){let host=options.host??"127.0.0.1",redirectHost=options.redirectHost??host,path=options.path??"/callback",instance,server=createServer((request,response)=>instance?.handle(request.url??"/",response));await new Promise((resolve2,reject)=>{server.once("error",reject),server.listen(options.port??0,host,()=>{server.off("error",reject),resolve2()})});let address=server.address();if(!address||typeof address=="string")throw new Error("OAuth callback server did not bind to TCP");return instance=new _OAuthCallbackServer(server,`http://${redirectHost.includes(":")?`[${redirectHost}]`:redirectHost}:${address.port}${path}`,[path,...options.extraPaths??[]],options.timeoutMs??5*6e4,options.renderPage),instance}waitForCallback(state,path){if(this.pending.has(state))throw new Error("OAuth state is already pending");return new Promise((resolve2,reject)=>{let timer=setTimeout(()=>{this.pending.delete(state),reject(new Error("OAuth callback timed out"))},this.timeoutMs);this.pending.set(state,{resolve:resolve2,reject,timer,path})})}async close(){for(let pending of this.pending.values())clearTimeout(pending.timer),pending.reject(new Error("OAuth callback server closed"));this.pending.clear(),await new Promise((resolve2,reject)=>{this.server.close(error=>error?reject(error):resolve2())})}reply(response,status,page){this.renderPage?(response.writeHead(status,{"content-type":"text/html; charset=utf-8","cache-control":"no-store"}),response.end(this.renderPage(page))):response.writeHead(status,{"content-type":"text/plain; charset=utf-8"}).end(plainText(page))}handle(rawUrl,response){let url=new URL(rawUrl,this.redirectUrl);if(!this.paths.includes(url.pathname)){this.reply(response,404,{ok:!1,message:"Not found"});return}let state=url.searchParams.get("state"),pending=state?this.pending.get(state):void 0;if(!state||!pending){this.reply(response,400,{ok:!1,message:"Invalid or expired OAuth state"});return}if(clearTimeout(pending.timer),this.pending.delete(state),pending.path!==void 0&&url.pathname!==pending.path){pending.reject(new Error("The authorization response arrived on another redirect URI")),this.reply(response,400,{ok:!1,message:"Unexpected redirect URI"});return}let error=url.searchParams.get("error");if(error){let description=url.searchParams.get("error_description")??error;pending.reject(new Error(description)),this.reply(response,200,{ok:!1,message:"Authorization failed. You may close this window.",details:description});return}let code=url.searchParams.get("code");if(!code){pending.reject(new Error("OAuth callback did not include an authorization code")),this.reply(response,400,{ok:!1,message:"Missing authorization code"});return}let iss=url.searchParams.get("iss");pending.resolve({code,state,...iss?{iss}:{}}),this.reply(response,200,{ok:!0})}};var OAuthError=class extends Error{code;errorUri;constructor(code,message,errorUri){super(message||code),this.name="OAuthError",this.code=code,this.errorUri=errorUri}},OAuthIssuerMismatchError=class extends Error{expected;received;constructor(expected,received){super(`OAuth issuer mismatch: expected ${JSON.stringify(expected)}, received ${received===void 0?"none":JSON.stringify(received)}`),this.name="OAuthIssuerMismatchError",this.expected=expected,this.received=received}},OAuthInsecureEndpointError=class extends Error{endpoint;constructor(endpoint){super(`Refusing to send OAuth credentials to non-HTTPS endpoint ${endpoint}`),this.name="OAuthInsecureEndpointError",this.endpoint=endpoint}},OAuthRegistrationError=class extends Error{status;body;constructor(status,body){super(`OAuth dynamic client registration failed with status ${status}: ${body}`),this.name="OAuthRegistrationError",this.status=status,this.body=body}},McpOAuthAuthorizationRequiredError=class extends Error{constructor(){super("MCP OAuth authorization requires user interaction"),this.name="McpOAuthAuthorizationRequiredError"}};function object(value,name){if(!isObject(value))throw new Error(`Invalid ${name}`);return value}function compact(value){return Object.fromEntries(Object.entries(value).filter(([,item])=>item!==void 0))}function requiredString(value,name){if(typeof value!="string"||value.length===0)throw new Error(`Invalid ${name}`);return value}function absent(value){return value==null||value===""}function optionalString(value,name){if(!absent(value))return requiredString(value,name)}function optionalStrings(value,name){if(value!=null){if(!Array.isArray(value)||value.some(item=>typeof item!="string"))throw new Error(`Invalid ${name}`);return[...value]}}function safeUrl(value,name){let text=requiredString(value,name);if(!URL.canParse(text))throw new Error(`Invalid ${name}`);let url=new URL(text);if(["javascript:","data:","vbscript:"].includes(url.protocol))throw new Error(`Invalid ${name}`);return text}function optionalUrl(value,name){return absent(value)?void 0:safeUrl(value,name)}function parseProtectedResourceMetadata(value){let input=object(value,"OAuth protected resource metadata");return compact({...input,resource:safeUrl(input.resource,"OAuth protected resource metadata resource"),authorization_servers:optionalStrings(input.authorization_servers,"authorization_servers")?.map(url=>safeUrl(url,"authorization server URL")),scopes_supported:optionalStrings(input.scopes_supported,"scopes_supported")})}function parseAuthorizationServerMetadata(value){let input=object(value,"authorization server metadata"),responseTypes=optionalStrings(input.response_types_supported,"response_types_supported");if(!responseTypes)throw new Error("Invalid response_types_supported");return compact({...input,issuer:safeUrl(input.issuer,"authorization server issuer"),authorization_endpoint:safeUrl(input.authorization_endpoint,"authorization endpoint"),token_endpoint:safeUrl(input.token_endpoint,"token endpoint"),registration_endpoint:optionalUrl(input.registration_endpoint,"registration endpoint"),scopes_supported:optionalStrings(input.scopes_supported,"scopes_supported"),response_types_supported:responseTypes,grant_types_supported:optionalStrings(input.grant_types_supported,"grant_types_supported"),token_endpoint_auth_methods_supported:optionalStrings(input.token_endpoint_auth_methods_supported,"token_endpoint_auth_methods_supported"),code_challenge_methods_supported:optionalStrings(input.code_challenge_methods_supported,"code_challenge_methods_supported"),client_id_metadata_document_supported:typeof input.client_id_metadata_document_supported=="boolean"?input.client_id_metadata_document_supported:void 0,authorization_response_iss_parameter_supported:typeof input.authorization_response_iss_parameter_supported=="boolean"?input.authorization_response_iss_parameter_supported:void 0})}function parseOAuthTokens(value){let input=object(value,"OAuth token response"),expires=absent(input.expires_in)?void 0:Number(input.expires_in);if(expires!==void 0&&!Number.isFinite(expires))throw new Error("Invalid expires_in");return compact({access_token:requiredString(input.access_token,"access_token"),token_type:requiredString(input.token_type,"token_type"),expires_in:expires,scope:optionalString(input.scope,"scope"),refresh_token:optionalString(input.refresh_token,"refresh_token"),id_token:optionalString(input.id_token,"id_token")})}function parseClientInformation(value){let input=object(value,"OAuth client registration response");return compact({...input,client_id:requiredString(input.client_id,"client_id"),client_secret:optionalString(input.client_secret,"client_secret"),client_id_issued_at:typeof input.client_id_issued_at=="number"?input.client_id_issued_at:void 0,client_secret_expires_at:typeof input.client_secret_expires_at=="number"?input.client_secret_expires_at:void 0,redirect_uris:optionalStrings(input.redirect_uris,"redirect_uris")??[]})}function discard(response){response?.body?.cancel().catch(()=>{})}function isDiscoveryMiss(status){return status>=400&&status<500||status===502}function pathSuffix(pathname){return pathname.endsWith("/")?pathname.slice(0,-1):pathname}function field(header,name){let match=header.match(new RegExp(String.raw`(?:^|[,\s])${name}=(?:"([^"]*)"|([^\s,]+))`,"i"));return match?.[1]||match?.[2]||void 0}function parseWwwAuthenticate(header){if(!header)return{};let scheme=header.trimStart().split(/\s+/,1)[0]?.toLowerCase();if(scheme!=="bearer"&&scheme!=="dpop")return{};let resourceMetadata=field(header,"resource_metadata"),resourceMetadataUrl;if(resourceMetadata)try{resourceMetadataUrl=new URL(resourceMetadata)}catch{}return{resourceMetadataUrl,scope:field(header,"scope"),error:field(header,"error"),errorDescription:field(header,"error_description")}}async function fetchMetadata(url,fetch,protocolVersion){return fetch(url,{headers:{Accept:"application/json","MCP-Protocol-Version":protocolVersion}})}async function discoverProtectedResourceMetadata(serverUrl,options={}){let server=new URL(serverUrl),fetch=options.fetch??globalThis.fetch,version=options.protocolVersion??LATEST_PROTOCOL_VERSION,response=await fetchMetadata(options.resourceMetadataUrl?new URL(options.resourceMetadataUrl):new URL(`/.well-known/oauth-protected-resource${pathSuffix(server.pathname)}`,server.origin),fetch,version);if(!options.resourceMetadataUrl&&server.pathname!=="/"&&isDiscoveryMiss(response.status)&&(discard(response),response=await fetchMetadata(new URL("/.well-known/oauth-protected-resource",server.origin),fetch,version)),!response.ok)throw discard(response),new Error(`HTTP ${response.status} loading OAuth protected resource metadata`);return parseProtectedResourceMetadata(await response.json())}function buildAuthorizationServerDiscoveryUrls(authorizationServerUrl){let issuer=new URL(authorizationServerUrl),path=pathSuffix(issuer.pathname),urls=[{url:new URL(`/.well-known/oauth-authorization-server${path}`,issuer.origin),type:"oauth"},{url:new URL(`/.well-known/openid-configuration${path}`,issuer.origin),type:"oidc"}];return path&&urls.push({url:new URL(`${path}/.well-known/openid-configuration`,issuer.origin),type:"oidc"}),urls}async function discoverAuthorizationServerMetadata(authorizationServerUrl,options={}){let fetch=options.fetch??globalThis.fetch;for(let{url}of buildAuthorizationServerDiscoveryUrls(authorizationServerUrl)){let response=await fetchMetadata(url,fetch,options.protocolVersion??LATEST_PROTOCOL_VERSION);if(!response.ok){if(discard(response),isDiscoveryMiss(response.status))continue;throw new Error(`HTTP ${response.status} loading authorization server metadata from ${url}`)}let metadata=parseAuthorizationServerMetadata(await response.json());if(!options.skipIssuerValidation){let expected=String(authorizationServerUrl),trim=value=>value.endsWith("/")?value.slice(0,-1):value;if(trim(metadata.issuer)!==trim(expected))throw new OAuthIssuerMismatchError(expected,metadata.issuer)}return metadata}}async function discoverOAuthServerInfo(serverUrl,options={}){let resourceMetadata;try{resourceMetadata=await discoverProtectedResourceMetadata(serverUrl,{resourceMetadataUrl:options.resourceMetadataUrl,fetch:options.fetch})}catch(error){if(error instanceof TypeError)throw error}if(options.authorizationServerMetadataUrl){let url=options.authorizationServerMetadataUrl,response=await fetchMetadata(url,options.fetch??globalThis.fetch,LATEST_PROTOCOL_VERSION);if(!response.ok)throw discard(response),new Error(`HTTP ${response.status} loading authorization server metadata from ${url}`);let metadata=parseAuthorizationServerMetadata(await response.json());return{authorizationServerUrl:metadata.issuer,authorizationServerMetadata:metadata,resourceMetadata}}let authorizationServerUrl=resourceMetadata?.authorization_servers?.[0]??String(new URL("/",serverUrl));return{authorizationServerUrl,authorizationServerMetadata:await discoverAuthorizationServerMetadata(authorizationServerUrl,{fetch:options.fetch,skipIssuerValidation:options.skipIssuerValidation}),resourceMetadata}}function resourceUrlFromServerUrl(value){let url=new URL(value);return url.hash="",url}function selectResource(serverUrl,metadata){if(!metadata)return;let requested=resourceUrlFromServerUrl(serverUrl),configured=new URL(metadata.resource);if(requested.origin!==configured.origin)throw new Error(`Protected resource ${metadata.resource} does not match MCP server ${requested}`);let requestedPath=requested.pathname.endsWith("/")?requested.pathname:`${requested.pathname}/`,configuredPath=configured.pathname.endsWith("/")?configured.pathname:`${configured.pathname}/`;if(!requestedPath.startsWith(configuredPath))throw new Error(`Protected resource ${metadata.resource} does not match MCP server ${requested}`);return metadata.resource}function loopback(hostname){return hostname==="localhost"||hostname==="127.0.0.1"||hostname==="[::1]"||hostname==="::1"}function secureEndpoint(value){let url=new URL(value);if(url.protocol!=="https:"&&!loopback(url.hostname))throw new OAuthInsecureEndpointError(url.href);return url}function selectClientAuthMethod(information,supported){let hinted="token_endpoint_auth_method"in information?information.token_endpoint_auth_method:void 0;return hinted&&["client_secret_basic","client_secret_post","none"].includes(hinted)&&(supported.length===0||supported.includes(hinted))?hinted:supported.length===0?information.client_secret?"client_secret_basic":"none":information.client_secret&&supported.includes("client_secret_basic")?"client_secret_basic":information.client_secret&&supported.includes("client_secret_post")?"client_secret_post":supported.includes("none")?"none":information.client_secret?"client_secret_post":"none"}function applyClientAuthentication(method,information,headers,params){if(method==="client_secret_basic"){if(!information.client_secret)throw new Error("client_secret_basic requires a client secret");headers.set("Authorization",`Basic ${Buffer.from(`${information.client_id}:${information.client_secret}`).toString("base64")}`)}else params.set("client_id",information.client_id),method==="client_secret_post"&&information.client_secret&&params.set("client_secret",information.client_secret)}async function pkce(){let bytes=crypto.getRandomValues(new Uint8Array(32)),verifier=Buffer.from(bytes).toString("base64url"),digest=await crypto.subtle.digest("SHA-256",new TextEncoder().encode(verifier));return{verifier,challenge:Buffer.from(digest).toString("base64url")}}async function startAuthorization(authorizationServerUrl,options){let metadata=options.metadata;if(metadata&&!metadata.response_types_supported.includes("code"))throw new Error("Authorization server does not support authorization codes");if(metadata?.code_challenge_methods_supported&&!metadata.code_challenge_methods_supported.includes("S256"))throw new Error("Authorization server does not support PKCE S256");let url=new URL(metadata?.authorization_endpoint??new URL("/authorize",authorizationServerUrl)),{verifier,challenge}=await pkce();return url.searchParams.set("response_type","code"),url.searchParams.set("client_id",options.clientInformation.client_id),url.searchParams.set("code_challenge",challenge),url.searchParams.set("code_challenge_method","S256"),url.searchParams.set("redirect_uri",String(options.redirectUrl)),options.state&&url.searchParams.set("state",options.state),options.scope&&url.searchParams.set("scope",options.scope),options.scope?.split(/\s+/).includes("offline_access")&&url.searchParams.set("prompt","consent"),options.resource&&url.searchParams.set("resource",options.resource),{authorizationUrl:url,codeVerifier:verifier}}async function tokenRequest(authorizationServerUrl,options,params){let url=secureEndpoint(options.metadata?.token_endpoint??new URL("/token",authorizationServerUrl)),headers=new Headers({Accept:"application/json","content-type":"application/x-www-form-urlencoded"});options.resource&&params.set("resource",options.resource),options.addClientAuthentication?await options.addClientAuthentication(headers,params,url,options.metadata):applyClientAuthentication(selectClientAuthMethod(options.clientInformation,options.metadata?.token_endpoint_auth_methods_supported??[]),options.clientInformation,headers,params);let response=await(options.fetch??globalThis.fetch)(url,{method:"POST",headers,body:params}),text=await response.text(),value;try{value=JSON.parse(text)}catch{}if(isObject(value)&&typeof value.error=="string")throw new OAuthError(value.error,typeof value.error_description=="string"?value.error_description:value.error,typeof value.error_uri=="string"?value.error_uri:void 0);if(!response.ok)throw new OAuthError("server_error",`HTTP ${response.status}: ${text}`);return parseOAuthTokens(value)}async function registerClient(authorizationServerUrl,options){let endpoint=options.metadata?.registration_endpoint;if(options.metadata&&!endpoint)throw new Error("Authorization server does not support dynamic client registration");let response=await(options.fetch??globalThis.fetch)(new URL(endpoint??new URL("/register",authorizationServerUrl)),{method:"POST",headers:{Accept:"application/json","content-type":"application/json"},body:JSON.stringify({...options.clientMetadata,...options.scope?{scope:options.scope}:{}})});if(!response.ok)throw new OAuthRegistrationError(response.status,await response.text());return parseClientInformation(await response.json())}async function exchangeAuthorizationCode(authorizationServerUrl,options){return tokenRequest(authorizationServerUrl,options,new URLSearchParams({grant_type:"authorization_code",code:options.code,code_verifier:options.codeVerifier,redirect_uri:String(options.redirectUrl)}))}async function refreshAuthorization(authorizationServerUrl,options){let tokens=await tokenRequest(authorizationServerUrl,options,new URLSearchParams({grant_type:"refresh_token",refresh_token:options.refreshToken}));return{refresh_token:options.refreshToken,...tokens}}function withScope(tokens,scope){return tokens.scope===void 0&&scope?{...tokens,scope}:tokens}function stepUpScope(granted,challenged){if(!challenged)return;let scopes=[granted,challenged].flatMap(scope=>scope?.split(/\s+/).filter(Boolean)??[]);return[...new Set(scopes)].join(" ")}async function runFlow(provider,options){let metadataUrl=options.authorizationServerMetadataUrl&&secureEndpoint(options.authorizationServerMetadataUrl),cached=metadataUrl?void 0:await provider.discoveryState?.(),discovered=cached?.authorizationServerUrl?{authorizationServerUrl:cached.authorizationServerUrl,authorizationServerMetadata:cached.authorizationServerMetadata??await discoverAuthorizationServerMetadata(cached.authorizationServerUrl,{fetch:options.fetch,skipIssuerValidation:options.skipIssuerValidation}),resourceMetadata:cached.resourceMetadata}:await discoverOAuthServerInfo(options.serverUrl,{resourceMetadataUrl:options.resourceMetadataUrl,authorizationServerMetadataUrl:metadataUrl,fetch:options.fetch,skipIssuerValidation:options.skipIssuerValidation});metadataUrl||await provider.saveDiscoveryState?.({...discovered,...options.resourceMetadataUrl?{resourceMetadataUrl:options.resourceMetadataUrl.href}:{}});let metadata=discovered.authorizationServerMetadata,resource=selectResource(options.serverUrl,discovered.resourceMetadata),scope=options.scope||discovered.resourceMetadata?.scopes_supported?.join(" ")||provider.clientMetadata.scope,stored=await provider.clientInformation(),clientDocument=stored?void 0:provider.clientMetadataDocument?.(metadata);if(clientDocument){let url=new URL(clientDocument.url);if(url.protocol!=="https:"||url.pathname==="/")throw new Error("Invalid OAuth client metadata URL")}let client=stored??(clientDocument&&{client_id:clientDocument.url});if(!client){if(options.authorizationCode)throw new Error("OAuth client information is missing during code exchange");if(!provider.saveClientInformation)throw new Error("OAuth client information cannot be persisted");client=await registerClient(discovered.authorizationServerUrl,{metadata,clientMetadata:provider.clientMetadata,scope,fetch:options.fetch}),await provider.saveClientInformation(client)}let redirectUrl=clientDocument?.redirectUrl??provider.redirectUrl,tokenOptions={metadata,clientInformation:client,resource,addClientAuthentication:provider.addClientAuthentication,fetch:options.fetch};if(options.authorizationCode){let iss=options.iss;if(metadata&&(iss!==void 0||metadata.authorization_response_iss_parameter_supported)&&iss!==metadata.issuer)throw new OAuthIssuerMismatchError(metadata.issuer,iss);let tokens=await exchangeAuthorizationCode(discovered.authorizationServerUrl,{...tokenOptions,code:options.authorizationCode,codeVerifier:await provider.codeVerifier(),redirectUrl});return await provider.saveTokens(withScope(tokens,scope)),"AUTHORIZED"}let existing=options.skipRefresh?void 0:await provider.tokens();if(existing?.refresh_token)try{let tokens=await refreshAuthorization(discovered.authorizationServerUrl,{...tokenOptions,refreshToken:existing.refresh_token});return await provider.saveTokens(withScope(tokens,existing.scope)),"AUTHORIZED"}catch(error){if(error instanceof OAuthInsecureEndpointError||error instanceof OAuthError&&error.code!=="server_error")throw error}let state=await provider.state?.(),authorization=await startAuthorization(discovered.authorizationServerUrl,{metadata,clientInformation:client,redirectUrl,scope,state,resource});return await provider.saveCodeVerifier(authorization.codeVerifier),await provider.redirectToAuthorization(authorization.authorizationUrl),"REDIRECT"}async function authorizeMcp(provider,options){try{return await runFlow(provider,options)}catch(error){if(error instanceof OAuthError&&["invalid_client","unauthorized_client"].includes(error.code))return await provider.invalidateCredentials?.("all"),runFlow(provider,options);if(error instanceof OAuthError&&error.code==="invalid_grant")return await provider.invalidateCredentials?.("tokens"),runFlow(provider,options);throw error}}var MemoryOAuthStateStore=class{value;load(){return this.value===void 0?void 0:structuredClone(this.value)}save(state){this.value=structuredClone(state)}},McpOAuthProvider=class{redirectUrl;clientMetadata;clientMetadataDocument;serverUrl;configuredClient;store;onRedirect;writes=Promise.resolve();constructor(options){this.serverUrl=String(new URL(options.serverUrl)),this.redirectUrl=String(options.redirectUrl),this.clientMetadata={...options.clientMetadata,redirect_uris:options.clientMetadata.redirect_uris??[this.redirectUrl],grant_types:options.clientMetadata.grant_types??["authorization_code","refresh_token"],response_types:options.clientMetadata.response_types??["code"],token_endpoint_auth_method:options.clientMetadata.token_endpoint_auth_method??(options.clientSecret?"client_secret_post":"none")},this.clientMetadataDocument=options.clientMetadataDocument,this.configuredClient=options.clientId?{client_id:options.clientId,...options.clientSecret?{client_secret:options.clientSecret}:{}}:void 0,this.store=options.store??new MemoryOAuthStateStore,this.onRedirect=options.onRedirect}async state(){let existing=(await this.load()).oauthState;if(existing)return existing;let state=Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString("hex");return await this.update(value=>({...value,oauthState:state})),state}async clientInformation(){return this.configuredClient??(await this.load()).clientInformation}async saveClientInformation(information){this.configuredClient||await this.update(value=>({...value,clientInformation:information}))}async tokens(){return(await this.load()).tokens}async saveTokens(tokens){let expiresAt=tokens.expires_in===void 0?void 0:Date.now()+tokens.expires_in*1e3;await this.update(value=>{let next={...value,tokens};return expiresAt===void 0?delete next.tokensExpireAt:next.tokensExpireAt=expiresAt,next})}async redirectToAuthorization(url){await this.onRedirect(url)}async saveCodeVerifier(verifier){await this.update(value=>({...value,codeVerifier:verifier}))}async codeVerifier(){let verifier=(await this.load()).codeVerifier;if(!verifier)throw new Error("No OAuth PKCE code verifier is stored");return verifier}async invalidateCredentials(kind){await this.update(value=>{let next={...value};return(kind==="all"||kind==="client")&&delete next.clientInformation,(kind==="all"||kind==="tokens")&&(delete next.tokens,delete next.tokensExpireAt),(kind==="all"||kind==="verifier")&&delete next.codeVerifier,(kind==="all"||kind==="discovery")&&delete next.discovery,kind==="all"&&delete next.oauthState,next})}async saveDiscoveryState(discovery){await this.update(value=>({...value,discovery}))}async discoveryState(){return(await this.load()).discovery}async load(){return await this.writes,this.own(await this.store.load())}async update(update){this.writes=this.writes.then(async()=>{await this.store.save(update(this.own(await this.store.load())))}),await this.writes}own(state){return state?.serverUrl===this.serverUrl?state:{serverUrl:this.serverUrl}}};import{createHash}from"node:crypto";import{mkdirSync}from"node:fs";import{join}from"node:path";var LOGO_SVG='<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 800 800" aria-hidden="true"><path fill="#F09082" d="M165.29 165.29H517.36V400H400V282.65H165.29Z"/><path fill="#4D9ABF" d="M165.29 282.65H282.65V400H400V517.36H282.65V634.72H165.29Z"/><path fill="#F1BE58" d="M517.36 400H634.72V634.72H517.36Z"/></svg>';function escapeHtml(value){return value.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#39;")}function renderPage(options){let title=escapeHtml(options.title),heading=escapeHtml(options.heading),message=escapeHtml(options.message),details=options.details?escapeHtml(options.details):void 0;return`<!doctype html>
5
- <html lang="en">
6
- <head>
7
- <meta charset="utf-8" />
8
- <meta name="viewport" content="width=device-width, initial-scale=1" />
9
- <title>${title}</title>
10
- <style>
11
- :root {
12
- --text: #fafafa;
13
- --text-dim: #a1a1aa;
14
- --page-bg: #09090b;
15
- --font-sans: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
16
- --font-mono: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
17
- }
18
- * { box-sizing: border-box; }
19
- html { color-scheme: dark; }
20
- body {
21
- margin: 0;
22
- min-height: 100vh;
23
- display: flex;
24
- align-items: center;
25
- justify-content: center;
26
- padding: 24px;
27
- background: var(--page-bg);
28
- color: var(--text);
29
- font-family: var(--font-sans);
30
- text-align: center;
31
- }
32
- main {
33
- width: 100%;
34
- max-width: 560px;
35
- display: flex;
36
- flex-direction: column;
37
- align-items: center;
38
- justify-content: center;
39
- }
40
- .logo {
41
- width: 72px;
42
- height: 72px;
43
- display: block;
44
- margin-bottom: 24px;
45
- }
46
- h1 {
47
- margin: 0 0 10px;
48
- font-size: 28px;
49
- line-height: 1.15;
50
- font-weight: 650;
51
- color: var(--text);
52
- }
53
- p {
54
- margin: 0;
55
- line-height: 1.7;
56
- color: var(--text-dim);
57
- font-size: 15px;
58
- }
59
- .details {
60
- margin-top: 16px;
61
- font-family: var(--font-mono);
62
- font-size: 13px;
63
- color: var(--text-dim);
64
- white-space: pre-wrap;
65
- word-break: break-word;
66
- }
67
- </style>
68
- </head>
69
- <body>
70
- <main>
71
- <div class="logo">${LOGO_SVG}</div>
72
- <h1>${heading}</h1>
73
- <p>${message}</p>
74
- ${details?`<div class="details">${details}</div>`:""}
75
- </main>
76
- </body>
77
- </html>`}function oauthSuccessHtml(message){return renderPage({title:"Authentication successful",heading:"Authentication successful",message})}function oauthErrorHtml(message,details){return renderPage({title:"Authentication failed",heading:"Authentication failed",message,details})}var import_proper_lockfile=__toESM(require_proper_lockfile(),1);var CALLBACK_HOST="127.0.0.1",CALLBACK_PATH="/callback",CLIENT_METADATA_BASE_URL="https://pi.dev/oauth",FALLBACK_REDIRECT_URL=`http://${CALLBACK_HOST}${CALLBACK_PATH}`,REFRESH_SKEW_MS=3e4,REFRESH_REQUEST_TIMEOUT_MS=15e3,REFRESH_LOCK_STALE_MS=2e4,REFRESH_LOCK_WAIT_MS=25e3,REFRESH_LOCK_RETRY_MS=100;function callbackSettings(settings){let url=new URL(settings.callbackUrl??`http://${CALLBACK_HOST}${CALLBACK_PATH}`),address=url.hostname.replace(/^\[|\]$/g,""),port=url.port?Number(url.port):settings.callbackPort,fixedRedirectUrl;return url.port?fixedRedirectUrl=settings.callbackUrl:port!==void 0&&(url.port=String(port),fixedRedirectUrl=url.href),{host:address==="localhost"?CALLBACK_HOST:address,redirectHost:address,port,path:url.pathname,fixedRedirectUrl}}function mergeScopes(...scopes){let merged=[...new Set(scopes.flatMap(scope=>scope?.split(/\s+/).filter(Boolean)??[]))];return merged.length>0?merged.join(" "):void 0}function parseStates(content){if(!content?.trim())return{};let parsed=JSON.parse(content);return typeof parsed=="object"&&parsed!==null&&!Array.isArray(parsed)?parsed:{}}function serializeStates(states){return`${JSON.stringify(states,null,2)}
78
- `}function storeKeys(name,serverUrl){let legacyKey=String(new URL(serverUrl));return{key:`${mcpNamespace(name)}|${legacyKey}`,legacyKey}}var McpOAuthCredentialStore=class{backend;lockDir;constructor(backend,lockDir){this.backend=backend??new FileAuthStorageBackend(join(getAgentDir(),"mcp-auth.json")),this.lockDir=backend?lockDir:getAgentDir()}forServer(name,serverUrl){let{key,legacyKey}=storeKeys(name,serverUrl);return{load:()=>this.backend.withLock(current=>{let states=parseStates(current);return states[key]||!states[legacyKey]?{result:states[key]}:(states[key]=states[legacyKey],delete states[legacyKey],{result:states[key],next:serializeStates(states)})}),save:state=>this.write(states=>{states[key]=state}),withRefreshLock:fn=>this.withRefreshLock(key,fn)}}async withRefreshLock(key,fn){if(!this.lockDir)return fn();mkdirSync(this.lockDir,{recursive:!0,mode:448});let hash=createHash("sha256").update(key).digest("hex").slice(0,16),release=await import_proper_lockfile.default.lock(join(this.lockDir,`mcp-auth-refresh-${hash}`),{realpath:!1,stale:REFRESH_LOCK_STALE_MS,retries:{retries:REFRESH_LOCK_WAIT_MS/REFRESH_LOCK_RETRY_MS,factor:1,minTimeout:REFRESH_LOCK_RETRY_MS,maxTimeout:REFRESH_LOCK_RETRY_MS},onCompromised:()=>{}});try{return await fn()}finally{await release().catch(()=>{})}}tokens(name,serverUrl){let{key,legacyKey}=storeKeys(name,serverUrl),states=this.backend.withLock(current=>({result:parseStates(current)}));return(states[key]??states[legacyKey])?.tokens}remove(name,serverUrl){let{key,legacyKey}=storeKeys(name,serverUrl);return this.backend.withLock(current=>{let states=parseStates(current),stored=key in states?key:legacyKey in states?legacyKey:void 0;return stored?(delete states[stored],{result:!0,next:serializeStates(states)}):{result:!1}})}write(update){this.backend.withLock(current=>{let states=parseStates(current);return update(states),{result:void 0,next:serializeStates(states)}})}};function registeredRedirectUrls(client){return client&&"redirect_uris"in client?client.redirect_uris:[]}function callbackId(serverUrl){let url=new URL(serverUrl);return url.hash="",createHash("sha256").update(url.href).digest().subarray(0,9).toString("base64url")}function clientMetadataDocument(serverUrl,redirectUrl,metadata){if(!metadata?.client_id_metadata_document_supported||!metadata.token_endpoint_auth_methods_supported?.includes("none"))throw new Error('The authorization server does not support Client ID Metadata Documents for public clients; remove oauth.clientRegistration "cimd"');if(metadata.authorization_response_iss_parameter_supported)return{url:`${CLIENT_METADATA_BASE_URL}/client.json`,redirectUrl};let id=callbackId(serverUrl),redirect=new URL(redirectUrl);return redirect.pathname=`${CALLBACK_PATH}/${id}`,{url:`${CLIENT_METADATA_BASE_URL}/${id}/client.json`,redirectUrl:redirect.href}}function createProvider(serverUrl,store,settings,redirectUrl,onRedirect){return new McpOAuthProvider({serverUrl,redirectUrl,clientMetadata:{client_name:settings.clientName??APP_NAME},clientMetadataDocument:settings.clientRegistration==="cimd"?metadata=>clientMetadataDocument(serverUrl,redirectUrl,metadata):void 0,clientId:settings.clientId,clientSecret:settings.clientSecret,store,onRedirect})}function createMcpAuthProvider(options){let{serverUrl,store}=options,refreshing,refresh=(staleToken,fetch=globalThis.fetch,challenge)=>(refreshing??=store.withRefreshLock(async()=>{let state=await store.load();if(state?.tokens?.access_token!==staleToken)return;if(!state?.tokens?.refresh_token)throw new McpOAuthAuthorizationRequiredError;let settings=options.settings(),redirectUrl=callbackSettings(settings).fixedRedirectUrl??registeredRedirectUrls(state.clientInformation)[0]??FALLBACK_REDIRECT_URL,provider=createProvider(serverUrl,store,settings,redirectUrl,()=>{});if(await authorizeMcp(provider,{serverUrl,resourceMetadataUrl:challenge?.resourceMetadataUrl,authorizationServerMetadataUrl:settings.authServerMetadataUrl,scope:challenge?.scope,fetch:(input,init)=>fetch(input,{...init,signal:AbortSignal.timeout(REFRESH_REQUEST_TIMEOUT_MS)})})==="REDIRECT")throw new McpOAuthAuthorizationRequiredError}).finally(()=>{refreshing=void 0}),refreshing);return{token:async()=>{await refreshing?.catch(()=>{});let state=await store.load(),token=state?.tokens?.access_token;return!(state?.tokensExpireAt!==void 0&&state.tokensExpireAt-REFRESH_SKEW_MS<=Date.now())||!state?.tokens?.refresh_token?token:(await refresh(token).catch(()=>{}),(await store.load())?.tokens?.access_token)},onUnauthorized:async context=>{let challenge=parseWwwAuthenticate(context.response.headers.get("www-authenticate"));if(options.onChallenge(challenge),challenge.error==="insufficient_scope")throw new McpOAuthAuthorizationRequiredError;await refresh(context.token,context.fetch,challenge)},settled:async()=>{await refreshing?.catch(()=>{})}}}var McpSignInCancelledError=class extends Error{constructor(){super("Sign-in cancelled"),this.name="McpSignInCancelledError"}};function responseFromRedirectUrl(input,state,redirectUrl){let url;try{url=new URL(input.trim())}catch{throw new Error("Expected the full redirect URL from the browser address bar")}if(url.origin!==redirectUrl.origin||url.pathname!==redirectUrl.pathname)throw new Error("The redirect URL does not match this sign-in's redirect URI");let error=url.searchParams.get("error");if(error)throw new Error(url.searchParams.get("error_description")??error);if(url.searchParams.get("state")!==state)throw new Error("The redirect URL belongs to a different sign-in");let code=url.searchParams.get("code");if(!code)throw new Error("The redirect URL does not contain an authorization code");return{code,iss:url.searchParams.get("iss")??void 0}}async function waitForAuthorizationResponse(callback,state,redirectUrl,prompt){let controller=new AbortController,fromBrowser=callback.waitForCallback(state,redirectUrl.pathname),fromUser=prompt.promptForRedirectUrl(controller.signal).then(input=>{if(!input?.trim())throw new McpSignInCancelledError;return responseFromRedirectUrl(input,state,redirectUrl)});try{return await Promise.race([fromBrowser,fromUser])}finally{controller.abort(),fromBrowser.catch(()=>{}),fromUser.catch(()=>{})}}async function listenForCallback(settings,extraPaths,port,required){let options={host:settings.host,redirectHost:settings.redirectHost,path:settings.path,extraPaths,renderPage:page=>page.ok?oauthSuccessHtml("Signed in to the MCP server. You may now close this page."):oauthErrorHtml(page.message,page.details)};try{return await OAuthCallbackServer.listen({...options,port:port??0})}catch(error){if(required||port===void 0)throw error;return OAuthCallbackServer.listen(options)}}async function signInMcpServer(options){let{serverUrl,store,settings}=options,stored=await store.load(),stepUp=options.challenge?.error==="insufficient_scope",callbackOptions=callbackSettings(settings),registered=registeredRedirectUrls(stored?.clientInformation)[0],preferredPort=callbackOptions.port??(registered&&Number(new URL(registered).port)||void 0),cimd=settings.clientRegistration==="cimd",callback=await listenForCallback(callbackOptions,cimd?[`${CALLBACK_PATH}/${callbackId(serverUrl)}`]:[],preferredPort,callbackOptions.port!==void 0),redirectUrl=callbackOptions.fixedRedirectUrl??callback.redirectUrl;try{if(stored){let next={...stored};delete next.oauthState,settings.clientId||(cimd?!stored.clientInformation:registeredRedirectUrls(stored.clientInformation).includes(redirectUrl))||(delete next.clientInformation,delete next.tokens,delete next.tokensExpireAt),await store.save(next)}let authorizationUrl,provider=createProvider(serverUrl,store,settings,redirectUrl,url=>{authorizationUrl=url}),flow={serverUrl,resourceMetadataUrl:options.challenge?.resourceMetadataUrl,authorizationServerMetadataUrl:settings.authServerMetadataUrl,scope:mergeScopes(settings.scope,stepUp?stepUpScope(stored?.tokens?.scope,options.challenge?.scope):options.challenge?.scope)};if(await authorizeMcp(provider,{...flow,skipRefresh:stepUp})==="AUTHORIZED")return;if(!authorizationUrl)throw new Error("OAuth flow did not produce an authorization URL");let state=await provider.state(),authorizationRedirectUrl=new URL(authorizationUrl.searchParams.get("redirect_uri")??redirectUrl);options.prompt.showAuthorizationUrl(authorizationUrl);let{code,iss}=await waitForAuthorizationResponse(callback,state,authorizationRedirectUrl,options.prompt);await authorizeMcp(provider,{...flow,authorizationCode:code,iss})}finally{await callback.close()}}import{appendFileSync,mkdirSync as mkdirSync2,renameSync,statSync}from"node:fs";import{dirname}from"node:path";var MAX_LOG_BYTES=5*1024*1024;function isRecord(value){return typeof value=="object"&&value!==null&&!Array.isArray(value)}function formatData(data){if(typeof data=="string")return data;try{return JSON.stringify(data)??String(data)}catch{return String(data)}}function formatMcpLogMessage(server,params,now=new Date){let message=isRecord(params)?params:{data:params},level=typeof message.level=="string"?message.level:"info",logger=typeof message.logger=="string"&&message.logger?` ${message.logger}:`:"",text=formatData(message.data).replace(/\r?\n/g,`
79
- `);return`${now.toISOString()} [${server}] ${level}${logger} ${text}
80
- `}var McpServerLog=class{path;size;constructor(path){this.path=path}write(server,params){let line=formatMcpLogMessage(server,params);try{this.size===void 0&&(mkdirSync2(dirname(this.path),{recursive:!0}),this.size=this.currentSize()),this.size>MAX_LOG_BYTES&&(this.currentSize()>MAX_LOG_BYTES&&renameSync(this.path,`${this.path}.1`),this.size=this.currentSize()),appendFileSync(this.path,line),this.size+=Buffer.byteLength(line)}catch{}}currentSize(){try{return statSync(this.path).size}catch{return 0}}};var DEFAULT_TIMEOUT_SECONDS=60,STDERR_TAIL_CHARS=2e3,CONNECT_RETRY_DELAYS_MS=[250,1e3];function errorMessage(error){return error instanceof Error?error.message:String(error)}function isTransientError(error){return error instanceof McpHttpError?error.status===408||error.status===429||error.status>=500&&error.status!==501:error instanceof TypeError}function signInRequiredMessage(entry){let provider="url"in entry.config?entry.config.auth?.provider:void 0;return`MCP server "${entry.name}" requires sign-in. Run ${provider?`/login ${provider}`:"/mcp"} to sign in.`}function usesOAuth(entry){let{config}=entry;return!("url"in config)||config.auth?!1:!Object.keys(config.headers??{}).some(header=>header.toLowerCase()==="authorization")}function expandHome(value){return value==="~"?homedir():value.startsWith("~/")||process.platform==="win32"&&value.startsWith("~\\")?join2(homedir(),value.slice(2)):value}function createDefaultTransport(entry,cwd,authProvider){let{config,name}=entry;if("url"in config)return new StreamableHttpTransport({url:config.url,headers:resolveHeadersOrThrow(config.headers,`MCP server "${name}"`),authProvider});let env={};for(let[key,value]of Object.entries(config.env??{}))env[key]=resolveConfigValueOrThrow(value,`MCP server "${name}" env "${key}"`);return new StdioTransport({command:expandHome(config.command),args:config.args?.map(expandHome),cwd:resolve(cwd,expandHome(config.cwd??".")),env,stderr:"pipe"})}async function withoutTemplates(list,empty){try{return await list()}catch(error){if(error instanceof McpError&&error.code===JSON_RPC_ERROR_CODES.methodNotFound)return empty;throw error}}function listTemplates(client,options={}){return withoutTemplates(()=>client.listResourceTemplates(options),[])}async function fetchResources(client){let[resources,resourceTemplates]=await Promise.all([client.listResources().catch(()=>[]),listTemplates(client).catch(()=>[])]);return{resources:resources.filter(resource=>!isMcpAppResource(resource)),resourceTemplates:resourceTemplates.filter(template=>!isMcpAppResource(template))}}var McpServerConnection=class{entry;state="connecting";error;tools=[];hasResources=!1;resources=[];resourceTemplates=[];instructions;challenge;client;opening;closed=!1;stderrTail;cwd;createTransport;authProvider;onTools;onChange;log;constructor(options){this.entry=options.entry,this.cwd=options.cwd,this.createTransport=options.createTransport,this.onTools=options.onTools,this.onChange=options.onChange,this.log=options.log;let url=this.oauthUrl,provider="url"in this.entry.config?this.entry.config.auth?.provider:void 0;this.authProvider=url?createMcpAuthProvider({serverUrl:url,store:options.credentials.forServer(this.entry.name,url),settings:()=>this.oauthSettings(),onChallenge:challenge=>{this.challenge=challenge}}):provider?{token:async()=>options.providerToken?.(provider),settled:async()=>{}}:void 0}get name(){return this.entry.name}get timeoutMs(){return(this.entry.config.timeout??DEFAULT_TIMEOUT_SECONDS)*1e3}get oauthUrl(){return usesOAuth(this.entry)&&"url"in this.entry.config?this.entry.config.url:void 0}oauthSettings(){let oauth="url"in this.entry.config?this.entry.config.oauth:void 0;return oauth?{clientId:oauth.clientId,clientSecret:oauth.clientSecret===void 0?void 0:resolveConfigValueOrThrow(oauth.clientSecret,`MCP server "${this.entry.name}" oauth.clientSecret`),callbackPort:oauth.callbackPort,callbackUrl:oauth.callbackUrl,scope:oauth.scope,clientName:oauth.clientName,clientRegistration:oauth.clientRegistration,authServerMetadataUrl:oauth.authServerMetadataUrl?new URL(oauth.authServerMetadataUrl):void 0}:{}}getClient(){return this.closed?Promise.reject(new Error(`MCP server "${this.entry.name}" is shut down`)):this.client?.connectionState==="connected"?Promise.resolve(this.client):(this.opening??=this.open().finally(()=>{this.opening=void 0}),this.opening)}callTool(name,args,options){return this.withClient(client=>client.callTool(name,args,options))}readResource(uri,options){return this.withClient(client=>client.readResource(uri,options),!0)}resourcesPage(cursor,options){return this.withClient(client=>client.listResourcesPage(cursor,options),!0)}resourceTemplatesPage(cursor,options){return this.withClient(client=>withoutTemplates(()=>client.listResourceTemplatesPage(cursor,options),{resourceTemplates:[]}),!0)}allResources(options){return this.withClient(client=>client.listResources(options),!0)}allResourceTemplates(options){return this.withClient(client=>listTemplates(client,options),!0)}async withClient(run,readOnly=!1){for(let attempt=1;;attempt++){let client=await this.getClient();try{return await run(client)}catch(error){if(readOnly&&attempt===1&&error instanceof McpHttpError&&isTransientError(error)){await new Promise(resolve2=>setTimeout(resolve2,CONNECT_RETRY_DELAYS_MS[0]));continue}if(error instanceof McpSessionExpiredError&&attempt===1){this.client===client&&(this.client=void 0);continue}throw this.needsSignIn(error)?(await this.dropClient(client),this.markNeedsAuth(),new Error(signInRequiredMessage(this.entry))):error}}}async reconnect(){await this.opening?.catch(()=>{}),this.client&&await this.dropClient(this.client),await this.getClient()}async signOut(){await this.opening?.catch(()=>{}),this.client&&await this.dropClient(this.client),this.closed||this.markNeedsAuth()}needsSignIn(error){return error instanceof McpOAuthAuthorizationRequiredError||this.authProvider!==void 0&&error instanceof McpAuthRequiredError}markNeedsAuth(){this.state="needs-auth",this.error=void 0,this.changed()}changed(){this.onChange?.(this)}async dropClient(client){this.client===client&&(this.client=void 0),await client.close().catch(()=>{})}async open(){this.state="connecting",this.changed();let retries="url"in this.entry.config?CONNECT_RETRY_DELAYS_MS:[];for(let attempt=0;;attempt++){this.stderrTail=void 0;try{return await this.connectOnce()}catch(error){let delay=retries[attempt];if(this.closed||delay===void 0||!isTransientError(error))throw this.connectFailed(error);if(await new Promise(resolve2=>setTimeout(resolve2,delay)),this.closed)throw this.connectFailed(error)}}}async connectOnce(){let client=new McpClient({name:"pi",version:VERSION,requestTimeoutMs:this.timeoutMs,roots:[{uri:pathToFileURL(this.cwd).href,name:basename(this.cwd)}]}),log=this.log;log&&client.onNotification("notifications/message",params=>log.write(this.entry.name,params));let transport;try{transport=this.createTransport(this.entry,this.cwd,this.authProvider),await client.connect(transport),client.onNotification("notifications/tools/list_changed",()=>{this.refreshTools(client)}),client.onNotification("notifications/resources/list_changed",()=>{this.refreshResources(client)});let stdio=transport instanceof StdioTransport?transport:void 0;client.onClose(()=>this.handleClientClose(client,stdio));let hasResources=client.serverCapabilities?.resources!==void 0,[tools,resources]=await Promise.all([client.serverCapabilities?.tools?client.listTools():[],hasResources?fetchResources(client):{resources:[],resourceTemplates:[]}]);if(this.closed)throw new Error("shut down while connecting");if(client.connectionState!=="connected")throw new Error("connection closed during setup");return this.client=client,this.tools=tools,this.hasResources=hasResources,this.resources=resources.resources,this.resourceTemplates=resources.resourceTemplates,this.instructions=client.instructions?.trim()||void 0,this.state="connected",this.error=void 0,this.onTools(this),this.changed(),client}catch(error){throw await client.close().catch(()=>{}),transport instanceof StdioTransport&&(this.stderrTail=transport.stderr.trim().slice(-STDERR_TAIL_CHARS)||void 0),error}}connectFailed(error){return this.needsSignIn(error)&&!this.closed?(this.markNeedsAuth(),new Error(signInRequiredMessage(this.entry))):(this.state=this.closed?"closed":"failed",this.error=this.stderrTail?`${errorMessage(error)}
81
- ${this.stderrTail}`:errorMessage(error),this.changed(),new Error(`MCP server "${this.entry.name}" failed to connect: ${this.error}`))}handleClientClose(client,stdio){if(this.client!==client||this.closed)return;this.client=void 0,this.state="disconnected";let stderr=stdio?.stderr.trim().slice(-STDERR_TAIL_CHARS);this.error=stderr?`Connection closed
82
- ${stderr}`:"Connection closed",this.changed()}async refreshTools(client){try{let tools=await client.listTools();if(this.client!==client||this.closed)return;this.tools=tools,this.onTools(this)}catch(error){this.error=`Failed to refresh tools: ${errorMessage(error)}`}this.changed()}async refreshResources(client){let{resources,resourceTemplates}=await fetchResources(client);this.client!==client||this.closed||(this.resources=resources,this.resourceTemplates=resourceTemplates,this.onTools(this),this.changed())}async close(){this.closed=!0,this.state="closed",this.changed();let client=this.client;this.client=void 0,await client?.close().catch(()=>{}),await this.authProvider?.settled()}};export{McpOAuthCredentialStore,McpSignInCancelledError,signInMcpServer,McpServerLog,createDefaultTransport,McpServerConnection};
@@ -1,2 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{classifySystemOne,isRecord}from"./chunk-C47CLQZK.js";import"./chunk-TEPMHNKQ.js";import"./chunk-LD2P6SFZ.js";import"./chunk-UTB4DTYQ.js";import"./chunk-KJUDFE6Y.js";import"./chunk-A3JYRWB6.js";import"./chunk-4L3WN2XY.js";var LABEL="Cloudflare Workers AI";function cloudflareErrorMessage(errors){if(Array.isArray(errors)){let messages=errors.map(error=>isRecord(error)&&typeof error.message=="string"?error.message:void 0).filter(message=>message!==void 0);if(messages.length>0)return`${LABEL} error: ${messages.join("; ")}`}return`${LABEL} request failed`}var transport={api:"cloudflare-workers-ai-system-one",label:LABEL,url:model=>new URL("run",`${model.baseUrl.replace(/\/+$/u,"")}/`),payload:(model,request)=>({model:model.id,input:request}),output:body=>{if(!isRecord(body))throw new Error(`${LABEL} returned an unexpected response`);if(body.success===!1)throw new Error(cloudflareErrorMessage(body.errors));let result=body.result;if(!isRecord(result))throw new Error(`${LABEL} returned an unexpected response`);if("answers"in result)return result;if(result.state!=="Completed")throw new Error(`${LABEL} run did not complete (state: ${String(result.state)})`);if(!isRecord(result.result))throw new Error(`${LABEL} returned an unexpected response`);return result.result}},classify=(model,context,options)=>classifySystemOne(transport,model,context,options);export{classify};
@@ -1,2 +0,0 @@
1
- import { createRequire as __piCreateRequire } from "node:module"; const require = __piCreateRequire(import.meta.url);
2
- import{classifySystemOne,isRecord}from"./chunk-C47CLQZK.js";import"./chunk-TEPMHNKQ.js";import"./chunk-LD2P6SFZ.js";import"./chunk-UTB4DTYQ.js";import"./chunk-KJUDFE6Y.js";import"./chunk-A3JYRWB6.js";import"./chunk-4L3WN2XY.js";var transport={api:"typesafe-system-one",label:"System One API",url:model=>new URL("systemone",`${model.baseUrl.replace(/\/+$/u,"")}/`),payload:(model,request)=>({model:model.id,...request}),output:body=>{if(!isRecord(body))throw new Error("System One API returned an unexpected response");return body}},classify=(model,context,options)=>classifySystemOne(transport,model,context,options);export{classify};