@herbertgao/pi-extensions 2026.8.1 → 2026.8.3

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 (403) hide show
  1. package/README.md +13 -3
  2. package/node_modules/@czottmann/pi-automode/README.md +16 -2
  3. package/node_modules/@czottmann/pi-automode/docs/GLOSSARY.md +35 -0
  4. package/node_modules/@czottmann/pi-automode/docs/automode-classifier-flow.md +18 -9
  5. package/node_modules/@czottmann/pi-automode/docs/defaults.md +6 -2
  6. package/node_modules/@czottmann/pi-automode/examples/automode.local.json +6 -0
  7. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/classifier.ts +11 -7
  8. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/config.ts +100 -0
  9. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/constants.ts +32 -0
  10. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/extension.ts +78 -3
  11. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/hard-deny.ts +16 -4
  12. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/paths.ts +23 -1
  13. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/permissions.ts +22 -1
  14. package/node_modules/@czottmann/pi-automode/extensions/auto-mode/types.ts +18 -2
  15. package/node_modules/@czottmann/pi-automode/package.json +4 -4
  16. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-audit.md +5 -0
  17. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-debt.md +5 -0
  18. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-gain.md +5 -0
  19. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-help.md +5 -0
  20. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail-review.md +5 -0
  21. package/node_modules/@dietrichgebert/ponytail/.opencode/command/ponytail.md +5 -0
  22. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail-frontmatter.cjs +23 -0
  23. package/node_modules/@dietrichgebert/ponytail/.opencode/plugins/ponytail.mjs +99 -0
  24. package/node_modules/@dietrichgebert/ponytail/.qoder/rules/ponytail.md +30 -0
  25. package/node_modules/@dietrichgebert/ponytail/.qoder-plugin/plugin.json +16 -0
  26. package/node_modules/@dietrichgebert/ponytail/AGENTS.md +32 -0
  27. package/node_modules/@dietrichgebert/ponytail/LICENSE +21 -0
  28. package/node_modules/@dietrichgebert/ponytail/README.es.md +298 -0
  29. package/node_modules/@dietrichgebert/ponytail/README.ko.md +315 -0
  30. package/node_modules/@dietrichgebert/ponytail/README.md +351 -0
  31. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-3model.svg +21 -0
  32. package/node_modules/@dietrichgebert/ponytail/assets/benchmark-agentic.svg +62 -0
  33. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.png +0 -0
  34. package/node_modules/@dietrichgebert/ponytail/assets/logo-dark.svg +115 -0
  35. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt-dark.svg +27 -0
  36. package/node_modules/@dietrichgebert/ponytail/assets/logo-greenpt.svg +27 -0
  37. package/node_modules/@dietrichgebert/ponytail/assets/logo.png +0 -0
  38. package/node_modules/@dietrichgebert/ponytail/assets/social-preview.png +0 -0
  39. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-es.png +0 -0
  40. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner-ko.png +0 -0
  41. package/node_modules/@dietrichgebert/ponytail/assets/waitlist-banner.png +0 -0
  42. package/node_modules/@dietrichgebert/ponytail/hooks/claude-codex-hooks.json +44 -0
  43. package/node_modules/@dietrichgebert/ponytail/hooks/copilot-hooks.json +21 -0
  44. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-activate.js +96 -0
  45. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-config.js +169 -0
  46. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-instructions.js +98 -0
  47. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-mode-tracker.js +130 -0
  48. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-runtime.js +85 -0
  49. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.ps1 +24 -0
  50. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-statusline.sh +18 -0
  51. package/node_modules/@dietrichgebert/ponytail/hooks/ponytail-subagent.js +77 -0
  52. package/node_modules/@dietrichgebert/ponytail/hooks/qoder-hooks.json +26 -0
  53. package/node_modules/@dietrichgebert/ponytail/package.json +47 -0
  54. package/node_modules/@dietrichgebert/ponytail/pi-extension/index.js +211 -0
  55. package/node_modules/@dietrichgebert/ponytail/pi-extension/package.json +8 -0
  56. package/node_modules/@dietrichgebert/ponytail/scripts/uninstall.js +60 -0
  57. package/node_modules/@dietrichgebert/ponytail/skills/ponytail/SKILL.md +120 -0
  58. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-audit/SKILL.md +41 -0
  59. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-debt/SKILL.md +44 -0
  60. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-gain/SKILL.md +50 -0
  61. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-help/SKILL.md +71 -0
  62. package/node_modules/@dietrichgebert/ponytail/skills/ponytail-review/SKILL.md +57 -0
  63. package/node_modules/@herbertgao/pi-cc-extensions/README.en.md +6 -10
  64. package/node_modules/@herbertgao/pi-cc-extensions/README.md +5 -9
  65. package/node_modules/@herbertgao/pi-cc-extensions/assets/readme/hero.en.svg +101 -0
  66. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/config.ts +1 -17
  67. package/node_modules/@herbertgao/pi-cc-extensions/extensions/config/panel.ts +15 -9
  68. package/node_modules/@herbertgao/pi-cc-extensions/extensions/{utils/agent-summary.ts → feature/agent-summary/core.ts} +37 -35
  69. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-summary.ts → agent-summary/index.ts} +3 -3
  70. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/compact-thinking.ts +24 -83
  71. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/context.ts +1 -1
  72. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference.ts → reference/index.ts} +1 -1
  73. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{agent-autocomplete.ts → reference/subagent.ts} +19 -9
  74. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-startup-header.ts → shell/startup-header.ts} +1 -1
  75. package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{working-message.ts → shell/working-message.ts} +5 -2
  76. package/node_modules/@herbertgao/pi-cc-extensions/extensions/index.ts +32 -28
  77. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/compact-mode.ts +452 -94
  78. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/default-mode.ts +727 -0
  79. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/index.ts +66 -776
  80. package/node_modules/@herbertgao/pi-cc-extensions/extensions/{feature → renderer}/markdown-enhance.ts +134 -11
  81. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/hover.ts +130 -0
  82. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{mouse-interaction.ts → mouse/interaction.ts} +90 -568
  83. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/layout.ts +144 -0
  84. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/packets.ts +143 -0
  85. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/mouse/scroll.ts +195 -0
  86. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ansi-utils.ts +56 -1
  87. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-renderer.ts +4 -4
  88. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/line-width-safety.ts +1 -1
  89. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool/diff/write-display-utils.ts +12 -0
  90. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/write-execution.ts +1 -2
  91. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-grouping.ts → tool/grouping.ts} +27 -10
  92. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-result.ts → tool/result.ts} +4 -13
  93. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/transcript-refresh.ts +91 -0
  94. package/node_modules/@herbertgao/pi-cc-extensions/extensions/utils/fullscreen-detect.ts +0 -27
  95. package/node_modules/@herbertgao/pi-cc-extensions/package.json +3 -3
  96. package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-dark.json +1 -0
  97. package/node_modules/@herbertgao/pi-cc-extensions/themes/cc-light.json +2 -2
  98. package/node_modules/@herbertgao/pi-stash/README.md +9 -9
  99. package/node_modules/@herbertgao/pi-stash/package.json +1 -1
  100. package/node_modules/@herbertgao/pi-stash/src/index.ts +2 -1
  101. package/node_modules/@herbertgao/pi-subagents/CHANGELOG.md +20 -0
  102. package/node_modules/@herbertgao/pi-subagents/README.md +6 -2
  103. package/node_modules/@herbertgao/pi-subagents/package.json +3 -3
  104. package/node_modules/@herbertgao/pi-subagents/src/agent-manager.ts +1 -0
  105. package/node_modules/@herbertgao/pi-subagents/src/agent-runner.ts +3 -1
  106. package/node_modules/@herbertgao/pi-subagents/src/custom-agents.ts +85 -11
  107. package/node_modules/@herbertgao/pi-subagents/src/index.ts +61 -39
  108. package/node_modules/@herbertgao/pi-subagents/src/nested-tools.ts +26 -35
  109. package/node_modules/@herbertgao/pi-subagents/src/prompts.ts +15 -1
  110. package/node_modules/@herbertgao/pi-subagents/src/settings.ts +12 -0
  111. package/node_modules/@herbertgao/pi-subagents/src/types.ts +2 -0
  112. package/node_modules/@narumitw/pi-btw/LICENSE +21 -0
  113. package/node_modules/@narumitw/pi-btw/README.md +210 -0
  114. package/node_modules/@narumitw/pi-btw/package.json +53 -0
  115. package/node_modules/@narumitw/pi-btw/src/bring-to-main.ts +632 -0
  116. package/node_modules/@narumitw/pi-btw/src/btw.ts +996 -0
  117. package/node_modules/@narumitw/pi-btw/src/fullscreen-ui.ts +339 -0
  118. package/node_modules/@narumitw/pi-btw/src/index.ts +1 -0
  119. package/node_modules/@narumitw/pi-btw/src/menu.ts +296 -0
  120. package/node_modules/@narumitw/pi-btw/src/settings.ts +237 -0
  121. package/node_modules/@narumitw/pi-btw/src/side-thread.ts +238 -0
  122. package/node_modules/@narumitw/pi-btw/src/text.ts +10 -0
  123. package/node_modules/@narumitw/pi-btw/src/transcript-pager.ts +620 -0
  124. package/node_modules/@pi-plugins/fast-mode/LICENSE +21 -0
  125. package/node_modules/@pi-plugins/fast-mode/README.md +92 -0
  126. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts +6 -0
  127. package/node_modules/@pi-plugins/fast-mode/dist/index.d.mts.map +1 -0
  128. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs +2026 -0
  129. package/node_modules/@pi-plugins/fast-mode/dist/index.mjs.map +1 -0
  130. package/node_modules/@pi-plugins/fast-mode/package.json +73 -0
  131. package/node_modules/pi-mcp-adapter/CHANGELOG.md +78 -0
  132. package/node_modules/pi-mcp-adapter/README.md +80 -16
  133. package/node_modules/pi-mcp-adapter/agent-dir.ts +40 -0
  134. package/node_modules/pi-mcp-adapter/agent-plugin-loader.ts +377 -0
  135. package/node_modules/pi-mcp-adapter/commands.ts +21 -9
  136. package/node_modules/pi-mcp-adapter/config.ts +110 -49
  137. package/node_modules/pi-mcp-adapter/direct-tools.ts +40 -27
  138. package/node_modules/pi-mcp-adapter/elicitation-handler.ts +37 -36
  139. package/node_modules/pi-mcp-adapter/errors.ts +21 -17
  140. package/node_modules/pi-mcp-adapter/host-html-template.ts +13 -7
  141. package/node_modules/pi-mcp-adapter/index.ts +52 -17
  142. package/node_modules/pi-mcp-adapter/init.ts +9 -7
  143. package/node_modules/pi-mcp-adapter/json-schema-validator.ts +2 -2
  144. package/node_modules/pi-mcp-adapter/lifecycle.ts +8 -8
  145. package/node_modules/pi-mcp-adapter/logger.ts +1 -1
  146. package/node_modules/pi-mcp-adapter/mcp-auth-flow.ts +122 -25
  147. package/node_modules/pi-mcp-adapter/mcp-auth.ts +120 -2
  148. package/node_modules/pi-mcp-adapter/mcp-callback-server.ts +138 -61
  149. package/node_modules/pi-mcp-adapter/mcp-code.ts +13 -11
  150. package/node_modules/pi-mcp-adapter/mcp-oauth-provider.ts +62 -17
  151. package/node_modules/pi-mcp-adapter/mcp-output-guard.ts +15 -11
  152. package/node_modules/pi-mcp-adapter/mcp-panel.ts +34 -15
  153. package/node_modules/pi-mcp-adapter/mcp-probe.ts +131 -34
  154. package/node_modules/pi-mcp-adapter/mcp-script-worker.mjs +2 -2
  155. package/node_modules/pi-mcp-adapter/mcp-setup-panel.ts +7 -4
  156. package/node_modules/pi-mcp-adapter/mcp-trace.ts +59 -64
  157. package/node_modules/pi-mcp-adapter/metadata-cache.ts +34 -26
  158. package/node_modules/pi-mcp-adapter/npx-resolver.ts +6 -4
  159. package/node_modules/pi-mcp-adapter/oauth-handler.ts +1 -1
  160. package/node_modules/pi-mcp-adapter/oauth.ts +48 -0
  161. package/node_modules/pi-mcp-adapter/onboarding-state.ts +19 -11
  162. package/node_modules/pi-mcp-adapter/package.json +20 -9
  163. package/node_modules/pi-mcp-adapter/panel-keys.ts +20 -4
  164. package/node_modules/pi-mcp-adapter/prompts.ts +2 -2
  165. package/node_modules/pi-mcp-adapter/proxy-modes.ts +56 -21
  166. package/node_modules/pi-mcp-adapter/sampling-handler.ts +22 -15
  167. package/node_modules/pi-mcp-adapter/search-ranking.ts +2 -1
  168. package/node_modules/pi-mcp-adapter/server-manager.ts +165 -113
  169. package/node_modules/pi-mcp-adapter/session-recovery.ts +11 -12
  170. package/node_modules/pi-mcp-adapter/skills/mcp-scripting/SKILL.md +3 -3
  171. package/node_modules/pi-mcp-adapter/state.ts +3 -1
  172. package/node_modules/pi-mcp-adapter/tool-approval.ts +67 -4
  173. package/node_modules/pi-mcp-adapter/tool-metadata.ts +6 -5
  174. package/node_modules/pi-mcp-adapter/tool-registrar.ts +187 -3
  175. package/node_modules/pi-mcp-adapter/tool-result-renderer.ts +14 -2
  176. package/node_modules/pi-mcp-adapter/ts-shape.ts +9 -2
  177. package/node_modules/pi-mcp-adapter/types.ts +111 -22
  178. package/node_modules/pi-mcp-adapter/ui-app-bridge-helpers.ts +40 -0
  179. package/node_modules/pi-mcp-adapter/ui-resource-handler.ts +28 -19
  180. package/node_modules/pi-mcp-adapter/ui-server.ts +90 -58
  181. package/node_modules/pi-mcp-adapter/ui-session.ts +16 -14
  182. package/node_modules/pi-mcp-adapter/unix-socket-transport.ts +4 -4
  183. package/node_modules/pi-mcp-adapter/utils.ts +23 -9
  184. package/node_modules/pi-web-access/CHANGELOG.md +45 -0
  185. package/node_modules/pi-web-access/README.md +104 -29
  186. package/node_modules/pi-web-access/bocha.ts +221 -0
  187. package/node_modules/pi-web-access/curator-page.ts +113 -12
  188. package/node_modules/pi-web-access/curator-server.ts +56 -20
  189. package/node_modules/pi-web-access/datalab-pdf-extract.ts +568 -0
  190. package/node_modules/pi-web-access/duckduckgo.ts +123 -0
  191. package/node_modules/pi-web-access/extract.ts +288 -143
  192. package/node_modules/pi-web-access/feature-config.ts +29 -0
  193. package/node_modules/pi-web-access/gemini-api.ts +4 -0
  194. package/node_modules/pi-web-access/gemini-search.ts +45 -12
  195. package/node_modules/pi-web-access/gemini-web.ts +68 -3
  196. package/node_modules/pi-web-access/index.ts +160 -71
  197. package/node_modules/pi-web-access/jina-search.ts +284 -0
  198. package/node_modules/pi-web-access/kagi.ts +12 -12
  199. package/node_modules/pi-web-access/openai-search.ts +12 -2
  200. package/node_modules/pi-web-access/package.json +4 -3
  201. package/node_modules/pi-web-access/pdf-extract.ts +327 -228
  202. package/node_modules/pi-web-access/storage.ts +440 -2
  203. package/node_modules/pi-web-access/summary-model-scope.ts +1 -1
  204. package/node_modules/pi-web-access/summary-review.ts +4 -2
  205. package/node_modules/pi-web-access/video-extract.ts +10 -8
  206. package/node_modules/pi-web-access/xai-search.ts +12 -2
  207. package/node_modules/pi-web-access/youtube-extract.ts +2 -1
  208. package/node_modules/remote-pi/LICENSE +21 -0
  209. package/node_modules/remote-pi/README.md +675 -0
  210. package/node_modules/remote-pi/dist/actions/handlers.d.ts +122 -0
  211. package/node_modules/remote-pi/dist/actions/handlers.js +160 -0
  212. package/node_modules/remote-pi/dist/actions/handlers.js.map +1 -0
  213. package/node_modules/remote-pi/dist/actions/registry.d.ts +39 -0
  214. package/node_modules/remote-pi/dist/actions/registry.js +58 -0
  215. package/node_modules/remote-pi/dist/actions/registry.js.map +1 -0
  216. package/node_modules/remote-pi/dist/bin/supervisord.d.ts +2 -0
  217. package/node_modules/remote-pi/dist/bin/supervisord.js +86 -0
  218. package/node_modules/remote-pi/dist/bin/supervisord.js.map +1 -0
  219. package/node_modules/remote-pi/dist/commands/builtin_mirror.d.ts +58 -0
  220. package/node_modules/remote-pi/dist/commands/builtin_mirror.js +71 -0
  221. package/node_modules/remote-pi/dist/commands/builtin_mirror.js.map +1 -0
  222. package/node_modules/remote-pi/dist/commands/list_commands.d.ts +60 -0
  223. package/node_modules/remote-pi/dist/commands/list_commands.js +73 -0
  224. package/node_modules/remote-pi/dist/commands/list_commands.js.map +1 -0
  225. package/node_modules/remote-pi/dist/config.d.ts +62 -0
  226. package/node_modules/remote-pi/dist/config.js +115 -0
  227. package/node_modules/remote-pi/dist/config.js.map +1 -0
  228. package/node_modules/remote-pi/dist/daemon/client.d.ts +20 -0
  229. package/node_modules/remote-pi/dist/daemon/client.js +131 -0
  230. package/node_modules/remote-pi/dist/daemon/client.js.map +1 -0
  231. package/node_modules/remote-pi/dist/daemon/control_protocol.d.ts +176 -0
  232. package/node_modules/remote-pi/dist/daemon/control_protocol.js +63 -0
  233. package/node_modules/remote-pi/dist/daemon/control_protocol.js.map +1 -0
  234. package/node_modules/remote-pi/dist/daemon/cron_log.d.ts +45 -0
  235. package/node_modules/remote-pi/dist/daemon/cron_log.js +72 -0
  236. package/node_modules/remote-pi/dist/daemon/cron_log.js.map +1 -0
  237. package/node_modules/remote-pi/dist/daemon/cron_registry.d.ts +80 -0
  238. package/node_modules/remote-pi/dist/daemon/cron_registry.js +194 -0
  239. package/node_modules/remote-pi/dist/daemon/cron_registry.js.map +1 -0
  240. package/node_modules/remote-pi/dist/daemon/id.d.ts +24 -0
  241. package/node_modules/remote-pi/dist/daemon/id.js +36 -0
  242. package/node_modules/remote-pi/dist/daemon/id.js.map +1 -0
  243. package/node_modules/remote-pi/dist/daemon/install.d.ts +170 -0
  244. package/node_modules/remote-pi/dist/daemon/install.js +547 -0
  245. package/node_modules/remote-pi/dist/daemon/install.js.map +1 -0
  246. package/node_modules/remote-pi/dist/daemon/registry.d.ts +63 -0
  247. package/node_modules/remote-pi/dist/daemon/registry.js +153 -0
  248. package/node_modules/remote-pi/dist/daemon/registry.js.map +1 -0
  249. package/node_modules/remote-pi/dist/daemon/rpc_child.d.ts +194 -0
  250. package/node_modules/remote-pi/dist/daemon/rpc_child.js +389 -0
  251. package/node_modules/remote-pi/dist/daemon/rpc_child.js.map +1 -0
  252. package/node_modules/remote-pi/dist/daemon/supervisor.d.ts +93 -0
  253. package/node_modules/remote-pi/dist/daemon/supervisor.js +596 -0
  254. package/node_modules/remote-pi/dist/daemon/supervisor.js.map +1 -0
  255. package/node_modules/remote-pi/dist/extension_ui_bridge.d.ts +26 -0
  256. package/node_modules/remote-pi/dist/extension_ui_bridge.js +341 -0
  257. package/node_modules/remote-pi/dist/extension_ui_bridge.js.map +1 -0
  258. package/node_modules/remote-pi/dist/index.d.ts +213 -0
  259. package/node_modules/remote-pi/dist/index.js +4996 -0
  260. package/node_modules/remote-pi/dist/index.js.map +1 -0
  261. package/node_modules/remote-pi/dist/mcp/mesh_result.d.ts +10 -0
  262. package/node_modules/remote-pi/dist/mcp/mesh_result.js +42 -0
  263. package/node_modules/remote-pi/dist/mcp/mesh_result.js.map +1 -0
  264. package/node_modules/remote-pi/dist/mcp/mesh_server.d.ts +16 -0
  265. package/node_modules/remote-pi/dist/mcp/mesh_server.js +327 -0
  266. package/node_modules/remote-pi/dist/mcp/mesh_server.js.map +1 -0
  267. package/node_modules/remote-pi/dist/mesh/canonical.d.ts +30 -0
  268. package/node_modules/remote-pi/dist/mesh/canonical.js +61 -0
  269. package/node_modules/remote-pi/dist/mesh/canonical.js.map +1 -0
  270. package/node_modules/remote-pi/dist/mesh/client.d.ts +18 -0
  271. package/node_modules/remote-pi/dist/mesh/client.js +125 -0
  272. package/node_modules/remote-pi/dist/mesh/client.js.map +1 -0
  273. package/node_modules/remote-pi/dist/mesh/encoding.d.ts +38 -0
  274. package/node_modules/remote-pi/dist/mesh/encoding.js +216 -0
  275. package/node_modules/remote-pi/dist/mesh/encoding.js.map +1 -0
  276. package/node_modules/remote-pi/dist/mesh/self_revoke.d.ts +73 -0
  277. package/node_modules/remote-pi/dist/mesh/self_revoke.js +401 -0
  278. package/node_modules/remote-pi/dist/mesh/self_revoke.js.map +1 -0
  279. package/node_modules/remote-pi/dist/mesh/siblings.d.ts +49 -0
  280. package/node_modules/remote-pi/dist/mesh/siblings.js +159 -0
  281. package/node_modules/remote-pi/dist/mesh/siblings.js.map +1 -0
  282. package/node_modules/remote-pi/dist/mesh/types.d.ts +34 -0
  283. package/node_modules/remote-pi/dist/mesh/types.js +11 -0
  284. package/node_modules/remote-pi/dist/mesh/types.js.map +1 -0
  285. package/node_modules/remote-pi/dist/mesh/verify.d.ts +17 -0
  286. package/node_modules/remote-pi/dist/mesh/verify.js +86 -0
  287. package/node_modules/remote-pi/dist/mesh/verify.js.map +1 -0
  288. package/node_modules/remote-pi/dist/pairing/crypto.d.ts +8 -0
  289. package/node_modules/remote-pi/dist/pairing/crypto.js +22 -0
  290. package/node_modules/remote-pi/dist/pairing/crypto.js.map +1 -0
  291. package/node_modules/remote-pi/dist/pairing/handshake.d.ts +28 -0
  292. package/node_modules/remote-pi/dist/pairing/handshake.js +113 -0
  293. package/node_modules/remote-pi/dist/pairing/handshake.js.map +1 -0
  294. package/node_modules/remote-pi/dist/pairing/noise-sha256.d.ts +16 -0
  295. package/node_modules/remote-pi/dist/pairing/noise-sha256.js +103 -0
  296. package/node_modules/remote-pi/dist/pairing/noise-sha256.js.map +1 -0
  297. package/node_modules/remote-pi/dist/pairing/qr.d.ts +59 -0
  298. package/node_modules/remote-pi/dist/pairing/qr.js +125 -0
  299. package/node_modules/remote-pi/dist/pairing/qr.js.map +1 -0
  300. package/node_modules/remote-pi/dist/pairing/storage.d.ts +120 -0
  301. package/node_modules/remote-pi/dist/pairing/storage.js +604 -0
  302. package/node_modules/remote-pi/dist/pairing/storage.js.map +1 -0
  303. package/node_modules/remote-pi/dist/protocol/codec.d.ts +7 -0
  304. package/node_modules/remote-pi/dist/protocol/codec.js +49 -0
  305. package/node_modules/remote-pi/dist/protocol/codec.js.map +1 -0
  306. package/node_modules/remote-pi/dist/protocol/types.d.ts +393 -0
  307. package/node_modules/remote-pi/dist/protocol/types.js +2 -0
  308. package/node_modules/remote-pi/dist/protocol/types.js.map +1 -0
  309. package/node_modules/remote-pi/dist/rooms.d.ts +29 -0
  310. package/node_modules/remote-pi/dist/rooms.js +57 -0
  311. package/node_modules/remote-pi/dist/rooms.js.map +1 -0
  312. package/node_modules/remote-pi/dist/session/address.d.ts +49 -0
  313. package/node_modules/remote-pi/dist/session/address.js +58 -0
  314. package/node_modules/remote-pi/dist/session/address.js.map +1 -0
  315. package/node_modules/remote-pi/dist/session/agent_bridge.d.ts +55 -0
  316. package/node_modules/remote-pi/dist/session/agent_bridge.js +146 -0
  317. package/node_modules/remote-pi/dist/session/agent_bridge.js.map +1 -0
  318. package/node_modules/remote-pi/dist/session/bridge.d.ts +37 -0
  319. package/node_modules/remote-pi/dist/session/bridge.js +130 -0
  320. package/node_modules/remote-pi/dist/session/bridge.js.map +1 -0
  321. package/node_modules/remote-pi/dist/session/broker.d.ts +189 -0
  322. package/node_modules/remote-pi/dist/session/broker.js +507 -0
  323. package/node_modules/remote-pi/dist/session/broker.js.map +1 -0
  324. package/node_modules/remote-pi/dist/session/broker_remote.d.ts +74 -0
  325. package/node_modules/remote-pi/dist/session/broker_remote.js +583 -0
  326. package/node_modules/remote-pi/dist/session/broker_remote.js.map +1 -0
  327. package/node_modules/remote-pi/dist/session/cwd_lock.d.ts +33 -0
  328. package/node_modules/remote-pi/dist/session/cwd_lock.js +126 -0
  329. package/node_modules/remote-pi/dist/session/cwd_lock.js.map +1 -0
  330. package/node_modules/remote-pi/dist/session/envelope.d.ts +33 -0
  331. package/node_modules/remote-pi/dist/session/envelope.js +117 -0
  332. package/node_modules/remote-pi/dist/session/envelope.js.map +1 -0
  333. package/node_modules/remote-pi/dist/session/global_config.d.ts +33 -0
  334. package/node_modules/remote-pi/dist/session/global_config.js +73 -0
  335. package/node_modules/remote-pi/dist/session/global_config.js.map +1 -0
  336. package/node_modules/remote-pi/dist/session/ipc.d.ts +27 -0
  337. package/node_modules/remote-pi/dist/session/ipc.js +22 -0
  338. package/node_modules/remote-pi/dist/session/ipc.js.map +1 -0
  339. package/node_modules/remote-pi/dist/session/leader_election.d.ts +32 -0
  340. package/node_modules/remote-pi/dist/session/leader_election.js +106 -0
  341. package/node_modules/remote-pi/dist/session/leader_election.js.map +1 -0
  342. package/node_modules/remote-pi/dist/session/local_config.d.ts +55 -0
  343. package/node_modules/remote-pi/dist/session/local_config.js +157 -0
  344. package/node_modules/remote-pi/dist/session/local_config.js.map +1 -0
  345. package/node_modules/remote-pi/dist/session/mesh_message.d.ts +20 -0
  346. package/node_modules/remote-pi/dist/session/mesh_message.js +28 -0
  347. package/node_modules/remote-pi/dist/session/mesh_message.js.map +1 -0
  348. package/node_modules/remote-pi/dist/session/mesh_node.d.ts +116 -0
  349. package/node_modules/remote-pi/dist/session/mesh_node.js +573 -0
  350. package/node_modules/remote-pi/dist/session/mesh_node.js.map +1 -0
  351. package/node_modules/remote-pi/dist/session/peer.d.ts +139 -0
  352. package/node_modules/remote-pi/dist/session/peer.js +451 -0
  353. package/node_modules/remote-pi/dist/session/peer.js.map +1 -0
  354. package/node_modules/remote-pi/dist/session/peer_inventory.d.ts +13 -0
  355. package/node_modules/remote-pi/dist/session/peer_inventory.js +48 -0
  356. package/node_modules/remote-pi/dist/session/peer_inventory.js.map +1 -0
  357. package/node_modules/remote-pi/dist/session/peer_limits.d.ts +9 -0
  358. package/node_modules/remote-pi/dist/session/peer_limits.js +21 -0
  359. package/node_modules/remote-pi/dist/session/peer_limits.js.map +1 -0
  360. package/node_modules/remote-pi/dist/session/setup_wizard.d.ts +39 -0
  361. package/node_modules/remote-pi/dist/session/setup_wizard.js +63 -0
  362. package/node_modules/remote-pi/dist/session/setup_wizard.js.map +1 -0
  363. package/node_modules/remote-pi/dist/session/tool_gate.d.ts +5 -0
  364. package/node_modules/remote-pi/dist/session/tool_gate.js +11 -0
  365. package/node_modules/remote-pi/dist/session/tool_gate.js.map +1 -0
  366. package/node_modules/remote-pi/dist/session/tools.d.ts +24 -0
  367. package/node_modules/remote-pi/dist/session/tools.js +252 -0
  368. package/node_modules/remote-pi/dist/session/tools.js.map +1 -0
  369. package/node_modules/remote-pi/dist/session/wizard.d.ts +13 -0
  370. package/node_modules/remote-pi/dist/session/wizard.js +20 -0
  371. package/node_modules/remote-pi/dist/session/wizard.js.map +1 -0
  372. package/node_modules/remote-pi/dist/settings.d.ts +15 -0
  373. package/node_modules/remote-pi/dist/settings.js +52 -0
  374. package/node_modules/remote-pi/dist/settings.js.map +1 -0
  375. package/node_modules/remote-pi/dist/transport/peer_channel.d.ts +37 -0
  376. package/node_modules/remote-pi/dist/transport/peer_channel.js +98 -0
  377. package/node_modules/remote-pi/dist/transport/peer_channel.js.map +1 -0
  378. package/node_modules/remote-pi/dist/transport/pi_forward_client.d.ts +29 -0
  379. package/node_modules/remote-pi/dist/transport/pi_forward_client.js +62 -0
  380. package/node_modules/remote-pi/dist/transport/pi_forward_client.js.map +1 -0
  381. package/node_modules/remote-pi/dist/transport/relay_client.d.ts +91 -0
  382. package/node_modules/remote-pi/dist/transport/relay_client.js +206 -0
  383. package/node_modules/remote-pi/dist/transport/relay_client.js.map +1 -0
  384. package/node_modules/remote-pi/dist/ui/footer.d.ts +32 -0
  385. package/node_modules/remote-pi/dist/ui/footer.js +34 -0
  386. package/node_modules/remote-pi/dist/ui/footer.js.map +1 -0
  387. package/node_modules/remote-pi/docs/daemon.md +289 -0
  388. package/node_modules/remote-pi/package.json +88 -0
  389. package/node_modules/remote-pi/service-templates/launchd.plist.template +35 -0
  390. package/node_modules/remote-pi/service-templates/systemd.service.template +19 -0
  391. package/node_modules/remote-pi/service-templates/task-launcher.vbs.template +10 -0
  392. package/node_modules/remote-pi/service-templates/task-scheduler.xml.template +38 -0
  393. package/node_modules/remote-pi/skills/agent-network/SKILL.md +310 -0
  394. package/package.json +37 -12
  395. package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/tool-diff/write-display-utils.ts +0 -29
  396. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{session-reference-core.ts → reference/session.ts} +0 -0
  397. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/feature/{pi-aliases.ts → shell/aliases.ts} +0 -0
  398. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/ATTRIBUTION.md +0 -0
  399. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/diff-presentation.ts +0 -0
  400. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/index.ts +0 -0
  401. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/render-utils.ts +0 -0
  402. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/shiki-highlight.ts +0 -0
  403. /package/node_modules/@herbertgao/pi-cc-extensions/extensions/renderer/{tool-diff → tool/diff}/types.ts +0 -0
@@ -12,15 +12,15 @@ export class McpLifecycleManager {
12
12
  private allServers = new Map<string, ServerDefinition>();
13
13
  private serverSettings = new Map<string, { idleTimeout?: number }>();
14
14
  private globalIdleTimeout = 10 * 60 * 1000;
15
- private healthCheckInterval?: NodeJS.Timeout;
16
- private onReconnect?: ReconnectCallback;
17
- private onReconnectFailure?: ReconnectFailureCallback;
18
- private onIdleShutdown?: (serverName: string) => void;
19
- private activeHealthCheck?: Promise<void>;
20
- private shutdownPromise?: Promise<void>;
15
+ private healthCheckInterval: NodeJS.Timeout | undefined;
16
+ private onReconnect: ReconnectCallback | undefined;
17
+ private onReconnectFailure: ReconnectFailureCallback | undefined;
18
+ private onIdleShutdown: ((serverName: string) => void) | undefined;
19
+ private activeHealthCheck: Promise<void> | undefined;
20
+ private shutdownPromise: Promise<void> | undefined;
21
21
  private stopped = false;
22
- private healthSignal?: AbortSignal;
23
- private removeHealthAbortListener?: () => void;
22
+ private healthSignal: AbortSignal | undefined;
23
+ private removeHealthAbortListener: (() => void) | undefined;
24
24
 
25
25
  constructor(
26
26
  private readonly manager: McpServerManager,
@@ -69,7 +69,7 @@ class Logger {
69
69
  level,
70
70
  message,
71
71
  context: { ...this.defaultContext, ...context },
72
- error,
72
+ ...(error !== undefined ? { error } : {}),
73
73
  timestamp: new Date(),
74
74
  };
75
75
 
@@ -7,9 +7,10 @@
7
7
  import {
8
8
  auth as runSdkAuth,
9
9
  extractWWWAuthenticateParams,
10
+ LATEST_PROTOCOL_VERSION,
10
11
  UnauthorizedError,
11
- } from "@modelcontextprotocol/sdk/client/auth.js"
12
- import { LATEST_PROTOCOL_VERSION } from "@modelcontextprotocol/sdk/types.js"
12
+ type AuthOptions,
13
+ } from "@modelcontextprotocol/client"
13
14
  import open from "open"
14
15
  import { McpOAuthProvider, type McpOAuthConfig } from "./mcp-oauth-provider.ts"
15
16
  import {
@@ -30,6 +31,7 @@ import {
30
31
  getOAuthState,
31
32
  clearOAuthState,
32
33
  getAuthBaseDir,
34
+ OAuthCredentialStoreError,
33
35
  type AuthStorageOptions,
34
36
  type StoredTokens,
35
37
  } from "./mcp-auth.ts"
@@ -47,18 +49,24 @@ export interface McpOAuthRuntime {
47
49
 
48
50
  export interface AuthenticateOptions {
49
51
  onAuthorizationUrl?: (authorizationUrl: string) => void | Promise<void>
52
+ onAuthorizationInput?: (
53
+ authorizationUrl: string,
54
+ signal: AbortSignal,
55
+ ) => Promise<string | undefined>
50
56
  authStorageOptions?: AuthStorageOptions
51
57
  signal?: AbortSignal
52
58
  runtime?: McpOAuthRuntime
59
+ skipIssuerMetadataValidation?: boolean
53
60
  }
54
61
 
55
- type AuthDiscovery = {
56
- resourceMetadataUrl?: URL
57
- scope?: string
58
- }
62
+ type AuthDiscovery = Pick<AuthOptions, "resourceMetadataUrl" | "scope" | "skipIssuerMetadataValidation">
59
63
 
60
- function applyConfiguredScope(discovery: AuthDiscovery, config: McpOAuthConfig): AuthDiscovery {
61
- return config.scope !== undefined ? { ...discovery, scope: config.scope } : discovery
64
+ function applyOAuthConfig(discovery: AuthDiscovery, config: McpOAuthConfig): AuthDiscovery {
65
+ return {
66
+ ...discovery,
67
+ ...(config.scope !== undefined ? { scope: config.scope } : {}),
68
+ ...(config.skipIssuerMetadataValidation === true ? { skipIssuerMetadataValidation: true } : {}),
69
+ }
62
70
  }
63
71
 
64
72
  type PendingAuth = {
@@ -208,6 +216,33 @@ export function extractOAuthConfig(definition: ServerEntry): McpOAuthConfig {
208
216
  }
209
217
  config.clientUri = clientUri
210
218
  }
219
+ if (definition.oauth?.logoUri !== undefined) {
220
+ if (typeof definition.oauth.logoUri !== "string") {
221
+ throw new Error("OAuth logoUri must be a string")
222
+ }
223
+ const logoUri = interpolateEnvVars(definition.oauth.logoUri).trim()
224
+ if (!logoUri) {
225
+ throw new Error("OAuth logoUri must not be empty")
226
+ }
227
+ // Consent screens fetch this server-side, so a local path silently renders
228
+ // nothing. Fail here instead, where the message can say why.
229
+ let parsed: URL
230
+ try {
231
+ parsed = new URL(logoUri)
232
+ } catch {
233
+ throw new Error("OAuth logoUri must be an absolute http(s) URL")
234
+ }
235
+ if (parsed.protocol !== "https:" && parsed.protocol !== "http:") {
236
+ throw new Error("OAuth logoUri must be an absolute http(s) URL")
237
+ }
238
+ config.logoUri = logoUri
239
+ }
240
+ if (definition.oauth?.skipIssuerMetadataValidation !== undefined) {
241
+ if (typeof definition.oauth.skipIssuerMetadataValidation !== "boolean") {
242
+ throw new Error("OAuth skipIssuerMetadataValidation must be a boolean")
243
+ }
244
+ config.skipIssuerMetadataValidation = definition.oauth.skipIssuerMetadataValidation
245
+ }
211
246
  return config
212
247
  }
213
248
 
@@ -239,7 +274,7 @@ async function probeAuthDiscovery(serverUrl: string, definition?: ServerEntry, s
239
274
  clientInfo: { name: "pi-mcp-adapter", version: "2.11.0" },
240
275
  },
241
276
  }),
242
- signal: discoverySignal,
277
+ ...(discoverySignal ? { signal: discoverySignal } : {}),
243
278
  })
244
279
  const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response)
245
280
  await response.body?.cancel().catch(() => {})
@@ -320,7 +355,7 @@ export async function startAuth(
320
355
  },
321
356
  }, authStorageOptions, runtime.signal)
322
357
  try {
323
- const discovery = applyConfiguredScope(await probeAuthDiscovery(serverUrl, definition, signal), config)
358
+ const discovery = applyOAuthConfig(await probeAuthDiscovery(serverUrl, definition, signal), config)
324
359
  throwIfAborted(signal)
325
360
  const result = await abortable(runSdkAuth(authProvider, { serverUrl, ...discovery }), signal)
326
361
  throwIfAborted(signal)
@@ -386,7 +421,7 @@ export async function startAuth(
386
421
 
387
422
  throwIfAborted(signal)
388
423
 
389
- const discovery = applyConfiguredScope(await probeAuthDiscovery(serverUrl, definition, signal), config)
424
+ const discovery = applyOAuthConfig(await probeAuthDiscovery(serverUrl, definition, signal), config)
390
425
  throwIfAborted(signal)
391
426
  const result = await abortable(runSdkAuth(authProvider, { serverUrl, ...discovery }), signal)
392
427
  throwIfAborted(signal)
@@ -537,6 +572,53 @@ export function parseAuthorizationCodeInput(input: string, expectedState?: strin
537
572
  return parseAuthorizationRedirectInput(input, expectedState).code
538
573
  }
539
574
 
575
+ type AuthorizationResponse = {
576
+ input: AuthorizationCodeInput
577
+ source: "callback" | "manual"
578
+ }
579
+
580
+ /**
581
+ * Wait for either the localhost callback or a manually pasted redirect URL.
582
+ * The manual input prompt is dismissed as soon as either path finishes.
583
+ */
584
+ export async function waitForAuthorizationResponse(
585
+ callbackPromise: Promise<AuthorizationCodeInput>,
586
+ authorizationUrl: string,
587
+ expectedState: string,
588
+ onAuthorizationInput?: AuthenticateOptions["onAuthorizationInput"],
589
+ signal?: AbortSignal,
590
+ ): Promise<AuthorizationResponse> {
591
+ if (!onAuthorizationInput) {
592
+ return {
593
+ input: await abortable(callbackPromise, signal),
594
+ source: "callback",
595
+ }
596
+ }
597
+
598
+ const inputController = new AbortController()
599
+ try {
600
+ const response = await abortable(Promise.race([
601
+ callbackPromise.then((input) => ({ input, source: "callback" as const })),
602
+ onAuthorizationInput(authorizationUrl, inputController.signal).then((input) => ({
603
+ input,
604
+ source: "manual" as const,
605
+ })),
606
+ ]), signal)
607
+
608
+ if (response.source === "callback") return response
609
+ if (!response.input?.trim()) throw new Error("OAuth authentication cancelled")
610
+ if (!getSearchParamsFromInput(response.input.trim())) {
611
+ throw new Error("Paste the full OAuth callback URL, including its code and state parameters")
612
+ }
613
+ return {
614
+ input: parseAuthorizationRedirectInput(response.input, expectedState),
615
+ source: "manual",
616
+ }
617
+ } finally {
618
+ inputController.abort()
619
+ }
620
+ }
621
+
540
622
  /**
541
623
  * Complete OAuth authentication from manual user input.
542
624
  */
@@ -606,6 +688,7 @@ export async function completeAuth(
606
688
  const result = await abortable(runSdkAuth(pendingAuth.authProvider, {
607
689
  serverUrl: pendingAuth.serverUrl,
608
690
  authorizationCode: code,
691
+ ...(iss !== undefined ? { iss } : {}),
609
692
  ...pendingAuth.discovery,
610
693
  }), signal)
611
694
  throwIfAborted(signal)
@@ -657,10 +740,12 @@ export async function authenticate(
657
740
  }
658
741
 
659
742
  const operation = (async (): Promise<AuthStatus> => {
660
- // Start auth flow
661
- const { authorizationUrl } = await startAuth(serverName, serverUrl, definition, { ...options, signal, runtime })
743
+ const { authorizationUrl } = await startAuth(serverName, serverUrl, definition, {
744
+ ...options,
745
+ ...(signal ? { signal } : {}),
746
+ runtime,
747
+ })
662
748
 
663
- // If no auth URL needed, already authenticated
664
749
  if (!authorizationUrl) {
665
750
  return "authenticated"
666
751
  }
@@ -694,14 +779,26 @@ export async function authenticate(
694
779
  console.warn(`MCP Auth: Failed to open browser for ${serverName}; waiting for manual callback`, { error })
695
780
  }
696
781
 
697
- // Wait for callback
698
- const callbackResult = await abortable(callbackPromise, signal)
782
+ const authorizationResponse = await waitForAuthorizationResponse(
783
+ callbackPromise,
784
+ authorizationUrl,
785
+ oauthState,
786
+ options.onAuthorizationInput,
787
+ signal,
788
+ )
789
+ if (authorizationResponse.source === "manual") {
790
+ cancelPendingCallback(oauthState)
791
+ }
699
792
 
700
- // The callback server accepted only the flow-local reserved state.
793
+ // The callback server accepted only the flow-local reserved state. Manual
794
+ // input is checked against the same state before token exchange.
701
795
  throwIfAborted(signal)
702
796
 
703
- // Complete the auth
704
- return await completeAuth(serverName, callbackResult, { ...options, signal, runtime })
797
+ return await completeAuth(serverName, authorizationResponse.input, {
798
+ ...options,
799
+ ...(signal ? { signal } : {}),
800
+ runtime,
801
+ })
705
802
  } catch (error) {
706
803
  if (oauthState) cancelPendingCallback(oauthState)
707
804
  try {
@@ -740,25 +837,21 @@ export async function getValidToken(
740
837
  const authStorageOptions = options.authStorageOptions ?? {}
741
838
  const signal = combineAbortSignals(runtime.signal, options.signal)
742
839
  throwIfAborted(signal)
743
- // Check if we have valid tokens
744
840
  const entry = await getAuthForUrl(serverName, serverUrl, authStorageOptions)
745
841
  throwIfAborted(signal)
746
842
  if (!entry?.tokens) {
747
843
  return null
748
844
  }
749
845
 
750
- // Check expiration
751
846
  const expired = await isTokenExpired(serverName, authStorageOptions)
752
847
  if (expired === false) {
753
848
  return entry.tokens
754
849
  }
755
850
 
756
851
  if (expired === true && entry.tokens.refreshToken) {
757
- // Token is expired, try to refresh
758
852
  console.log(`MCP Auth: Token expired for ${serverName}, attempting refresh`)
759
853
 
760
854
  try {
761
- // Create auth provider for token refresh
762
855
  const authProvider = new McpOAuthProvider(serverName, serverUrl, {}, {
763
856
  onRedirect: async () => {},
764
857
  }, authStorageOptions, runtime.signal)
@@ -773,7 +866,11 @@ export async function getValidToken(
773
866
 
774
867
  const discovery = await probeAuthDiscovery(serverUrl, undefined, signal)
775
868
  throwIfAborted(signal)
776
- const result = await abortable(runSdkAuth(authProvider, { serverUrl, ...discovery }), signal)
869
+ const result = await abortable(runSdkAuth(authProvider, {
870
+ serverUrl,
871
+ ...discovery,
872
+ ...(options.skipIssuerMetadataValidation === true ? { skipIssuerMetadataValidation: true } : {}),
873
+ }), signal)
777
874
  throwIfAborted(signal)
778
875
  if (result !== "AUTHORIZED") {
779
876
  return null
@@ -785,7 +882,7 @@ export async function getValidToken(
785
882
  authProvider.deactivate()
786
883
  }
787
884
  } catch (error) {
788
- if (isAbortError(error, signal)) throw error
885
+ if (isAbortError(error, signal) || error instanceof OAuthCredentialStoreError) throw error
789
886
  console.error(`MCP Auth: Token refresh failed for ${serverName}`, { error })
790
887
  return null
791
888
  }
@@ -22,7 +22,16 @@ import { resolveConfiguredOAuthDir } from './config.ts';
22
22
  const require = createRequire(import.meta.url);
23
23
  const AUTH_SECRET_SERVICE = 'pi-mcp-adapter.oauth';
24
24
  const TEST_AUTH_STORE_ENV = 'PI_MCP_ADAPTER_TEST_AUTH_STORE';
25
- const AUTH_SECRET_CHUNK_SIZE = 1800;
25
+ /**
26
+ * Windows Credential Manager caps one value at CRED_MAX_CREDENTIAL_BLOB_SIZE
27
+ * (2560 bytes) and stores it as UTF-16, so the real ceiling is
28
+ * AUTH_SECRET_VALUE_LIMIT characters. Chunks must stay below that, and so must
29
+ * the threshold that decides whether to chunk at all, or oversized records still
30
+ * fail to persist on Windows.
31
+ */
32
+ const AUTH_SECRET_CHUNK_SIZE = 1000;
33
+ /** Largest single value the strictest supported credential store accepts. */
34
+ const AUTH_SECRET_VALUE_LIMIT = 1280;
26
35
  const KEYRING_RECOVERY_DISABLED_ENV = 'PI_MCP_ADAPTER_DISABLE_KEYRING_RECOVERY';
27
36
  const KEYRING_RECOVERY_KEYCTL_ENV = 'PI_MCP_ADAPTER_KEYRING_RECOVERY_KEYCTL';
28
37
  const KEYRING_RECOVERY_NODE_ENV = 'PI_MCP_ADAPTER_KEYRING_RECOVERY_NODE';
@@ -163,6 +172,22 @@ const keyringAuthSecretStore: AuthSecretStore = {
163
172
  },
164
173
  };
165
174
 
175
+ /** Mimics the Windows Credential Manager per-value ceiling for tests. */
176
+ const sizeLimitedAuthSecretStore: AuthSecretStore = {
177
+ read(account) {
178
+ return memoryAuthEntries.get(account);
179
+ },
180
+ write(account, payload) {
181
+ if (payload.length > AUTH_SECRET_VALUE_LIMIT) {
182
+ throw new Error(`Value of 'password encoded as UTF-16' is longer than the platform limit of ${AUTH_SECRET_VALUE_LIMIT * 2} chars`);
183
+ }
184
+ memoryAuthEntries.set(account, payload);
185
+ },
186
+ remove(account) {
187
+ memoryAuthEntries.delete(account);
188
+ },
189
+ };
190
+
166
191
  const unavailableAuthSecretStore: AuthSecretStore = {
167
192
  read() {
168
193
  throw new Error('simulated secure credential store unavailable');
@@ -205,6 +230,7 @@ export function removeTestAuthSecretStoreEntry(account: string): void {
205
230
 
206
231
  function getAuthSecretStore(): AuthSecretStore {
207
232
  if (process.env[TEST_AUTH_STORE_ENV] === 'memory') return memoryAuthSecretStore;
233
+ if (process.env[TEST_AUTH_STORE_ENV] === 'sizelimited') return sizeLimitedAuthSecretStore;
208
234
  if (process.env[TEST_AUTH_STORE_ENV] === 'unavailable') return unavailableAuthSecretStore;
209
235
  if (process.env[TEST_AUTH_STORE_ENV] === 'keyrevoked') return keyRevokedAuthSecretStore;
210
236
  return keyringAuthSecretStore;
@@ -401,7 +427,99 @@ function parseJsonPayload(serverName: string, payload: string, source: string):
401
427
  }
402
428
 
403
429
  function parseAuthEntryPayload(serverName: string, payload: string, source: string): AuthEntry {
404
- return parseJsonPayload(serverName, payload, source) as AuthEntry;
430
+ const parsed = parseJsonPayload(serverName, payload, source);
431
+ const entry = toAuthEntry(parsed);
432
+ if (!entry) {
433
+ throw new Error(`Failed to parse OAuth credentials for ${serverName} from ${source}: invalid credential shape`);
434
+ }
435
+ return entry;
436
+ }
437
+
438
+ function toAuthEntry(value: unknown): AuthEntry | undefined {
439
+ const entry = toRecord(value);
440
+ if (!entry) return undefined;
441
+
442
+ const codeVerifier = optionalString(entry.codeVerifier);
443
+ const oauthState = optionalString(entry.oauthState);
444
+ const serverUrl = optionalString(entry.serverUrl);
445
+ if (codeVerifier === null || oauthState === null || serverUrl === null) return undefined;
446
+
447
+ const tokens = entry.tokens === undefined ? undefined : toStoredTokens(entry.tokens);
448
+ const clientInfo = entry.clientInfo === undefined ? undefined : toStoredClientInfo(entry.clientInfo);
449
+ if ((entry.tokens !== undefined && !tokens) || (entry.clientInfo !== undefined && !clientInfo)) return undefined;
450
+
451
+ const authEntry: AuthEntry = {};
452
+ if (tokens) authEntry.tokens = tokens;
453
+ if (clientInfo) authEntry.clientInfo = clientInfo;
454
+ if (codeVerifier !== undefined) authEntry.codeVerifier = codeVerifier;
455
+ if (oauthState !== undefined) authEntry.oauthState = oauthState;
456
+ if (serverUrl !== undefined) authEntry.serverUrl = serverUrl;
457
+ return authEntry;
458
+ }
459
+
460
+ function toStoredTokens(value: unknown): StoredTokens | undefined {
461
+ const tokens = toRecord(value);
462
+ if (!tokens || typeof tokens.accessToken !== 'string') return undefined;
463
+
464
+ const refreshToken = optionalString(tokens.refreshToken);
465
+ const scope = optionalString(tokens.scope);
466
+ const issuer = optionalString(tokens.issuer);
467
+ const expiresAt = optionalNumber(tokens.expiresAt);
468
+ if (refreshToken === null || scope === null || issuer === null || expiresAt === null) return undefined;
469
+
470
+ const storedTokens: StoredTokens = { accessToken: tokens.accessToken };
471
+ if (refreshToken !== undefined) storedTokens.refreshToken = refreshToken;
472
+ if (expiresAt !== undefined) storedTokens.expiresAt = expiresAt;
473
+ if (scope !== undefined) storedTokens.scope = scope;
474
+ if (issuer !== undefined) storedTokens.issuer = issuer;
475
+ return storedTokens;
476
+ }
477
+
478
+ function toStoredClientInfo(value: unknown): StoredClientInfo | undefined {
479
+ const clientInfo = toRecord(value);
480
+ if (!clientInfo || typeof clientInfo.clientId !== 'string') return undefined;
481
+
482
+ const clientSecret = optionalString(clientInfo.clientSecret);
483
+ const issuer = optionalString(clientInfo.issuer);
484
+ const clientIdIssuedAt = optionalNumber(clientInfo.clientIdIssuedAt);
485
+ const clientSecretExpiresAt = optionalNumber(clientInfo.clientSecretExpiresAt);
486
+ const configPreRegistered = optionalBoolean(clientInfo.configPreRegistered);
487
+ if (clientSecret === null || issuer === null || clientIdIssuedAt === null || clientSecretExpiresAt === null || configPreRegistered === null) return undefined;
488
+
489
+ const storedClient: StoredClientInfo = { clientId: clientInfo.clientId };
490
+ const redirectUris = stringArray(clientInfo.redirectUris);
491
+ if (clientSecret !== undefined) storedClient.clientSecret = clientSecret;
492
+ if (clientIdIssuedAt !== undefined) storedClient.clientIdIssuedAt = clientIdIssuedAt;
493
+ if (clientSecretExpiresAt !== undefined) storedClient.clientSecretExpiresAt = clientSecretExpiresAt;
494
+ if (redirectUris !== undefined) storedClient.redirectUris = redirectUris;
495
+ if (issuer !== undefined) storedClient.issuer = issuer;
496
+ if (configPreRegistered !== undefined) storedClient.configPreRegistered = configPreRegistered;
497
+ return storedClient;
498
+ }
499
+
500
+ function toRecord(value: unknown): Record<string, unknown> | undefined {
501
+ return typeof value === 'object' && value !== null && !Array.isArray(value)
502
+ ? value as Record<string, unknown>
503
+ : undefined;
504
+ }
505
+
506
+ function optionalString(value: unknown): string | null | undefined {
507
+ if (value === undefined) return undefined;
508
+ return typeof value === 'string' ? value : null;
509
+ }
510
+
511
+ function optionalNumber(value: unknown): number | null | undefined {
512
+ if (value === undefined) return undefined;
513
+ return typeof value === 'number' ? value : null;
514
+ }
515
+
516
+ function optionalBoolean(value: unknown): boolean | null | undefined {
517
+ if (value === undefined) return undefined;
518
+ return typeof value === 'boolean' ? value : null;
519
+ }
520
+
521
+ function stringArray(value: unknown): string[] | undefined {
522
+ return Array.isArray(value) && value.every(uri => typeof uri === 'string') ? value : undefined;
405
523
  }
406
524
 
407
525
  function isAuthEntryChunkManifest(value: unknown): value is AuthEntryChunkManifest {