@humain/terminal 0.0.2 → 0.0.3-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (680) hide show
  1. package/CHANGELOG.md +241 -24
  2. package/README.md +143 -119
  3. package/dist/cli/args.d.ts +4 -2
  4. package/dist/cli/args.d.ts.map +1 -1
  5. package/dist/cli/args.js +37 -39
  6. package/dist/cli/args.js.map +1 -1
  7. package/dist/cli/auth-check.d.ts +19 -0
  8. package/dist/cli/auth-check.d.ts.map +1 -0
  9. package/dist/cli/auth-check.js +50 -0
  10. package/dist/cli/auth-check.js.map +1 -0
  11. package/dist/cli/auth-command.d.ts +24 -0
  12. package/dist/cli/auth-command.d.ts.map +1 -0
  13. package/dist/cli/auth-command.js +103 -0
  14. package/dist/cli/auth-command.js.map +1 -0
  15. package/dist/cli/config-selector.d.ts.map +1 -1
  16. package/dist/cli/config-selector.js +2 -2
  17. package/dist/cli/config-selector.js.map +1 -1
  18. package/dist/cli/credential-print.d.ts +5 -15
  19. package/dist/cli/credential-print.d.ts.map +1 -1
  20. package/dist/cli/credential-print.js +42 -83
  21. package/dist/cli/credential-print.js.map +1 -1
  22. package/dist/cli/experimental/auth.d.ts +16 -0
  23. package/dist/cli/experimental/auth.d.ts.map +1 -0
  24. package/dist/cli/experimental/auth.js +13 -0
  25. package/dist/cli/experimental/auth.js.map +1 -0
  26. package/dist/cli/experimental/cli.d.ts +6 -0
  27. package/dist/cli/experimental/cli.d.ts.map +1 -0
  28. package/dist/cli/experimental/cli.js +5 -0
  29. package/dist/cli/experimental/cli.js.map +1 -0
  30. package/dist/cli/experimental/command-options.d.ts +17 -0
  31. package/dist/cli/experimental/command-options.d.ts.map +1 -0
  32. package/dist/cli/experimental/command-options.js +35 -0
  33. package/dist/cli/experimental/command-options.js.map +1 -0
  34. package/dist/cli/experimental/command.d.ts +63 -0
  35. package/dist/cli/experimental/command.d.ts.map +1 -0
  36. package/dist/cli/experimental/command.js +130 -0
  37. package/dist/cli/experimental/command.js.map +1 -0
  38. package/dist/cli/experimental/commands/client.d.ts +13 -0
  39. package/dist/cli/experimental/commands/client.d.ts.map +1 -0
  40. package/dist/cli/experimental/commands/client.js +25 -0
  41. package/dist/cli/experimental/commands/client.js.map +1 -0
  42. package/dist/cli/experimental/commands/pi.d.ts +15 -0
  43. package/dist/cli/experimental/commands/pi.d.ts.map +1 -0
  44. package/dist/cli/experimental/commands/pi.js +28 -0
  45. package/dist/cli/experimental/commands/pi.js.map +1 -0
  46. package/dist/cli/experimental/commands/server.d.ts +13 -0
  47. package/dist/cli/experimental/commands/server.d.ts.map +1 -0
  48. package/dist/cli/experimental/commands/server.js +25 -0
  49. package/dist/cli/experimental/commands/server.js.map +1 -0
  50. package/dist/cli/experimental/transport-address.d.ts +10 -0
  51. package/dist/cli/experimental/transport-address.d.ts.map +1 -0
  52. package/dist/cli/experimental/transport-address.js +38 -0
  53. package/dist/cli/experimental/transport-address.js.map +1 -0
  54. package/dist/cli/list-models.d.ts +1 -1
  55. package/dist/cli/list-models.d.ts.map +1 -1
  56. package/dist/cli/list-models.js +2 -2
  57. package/dist/cli/list-models.js.map +1 -1
  58. package/dist/cli/startup-ui.d.ts +1 -1
  59. package/dist/cli/startup-ui.d.ts.map +1 -1
  60. package/dist/cli/startup-ui.js +2 -2
  61. package/dist/cli/startup-ui.js.map +1 -1
  62. package/dist/client/index.d.ts +3 -0
  63. package/dist/client/index.d.ts.map +1 -0
  64. package/dist/client/index.js +3 -0
  65. package/dist/client/index.js.map +1 -0
  66. package/dist/client/remote-session.d.ts +53 -0
  67. package/dist/client/remote-session.d.ts.map +1 -0
  68. package/dist/client/remote-session.js +340 -0
  69. package/dist/client/remote-session.js.map +1 -0
  70. package/dist/client/transcript.d.ts +12 -0
  71. package/dist/client/transcript.d.ts.map +1 -0
  72. package/dist/client/transcript.js +98 -0
  73. package/dist/client/transcript.js.map +1 -0
  74. package/dist/core/agent-session-services.d.ts +1 -0
  75. package/dist/core/agent-session-services.d.ts.map +1 -1
  76. package/dist/core/agent-session-services.js +1 -0
  77. package/dist/core/agent-session-services.js.map +1 -1
  78. package/dist/core/agent-session.d.ts +1 -10
  79. package/dist/core/agent-session.d.ts.map +1 -1
  80. package/dist/core/agent-session.js +72 -70
  81. package/dist/core/agent-session.js.map +1 -1
  82. package/dist/core/auth-storage.d.ts +25 -9
  83. package/dist/core/auth-storage.d.ts.map +1 -1
  84. package/dist/core/auth-storage.js +237 -39
  85. package/dist/core/auth-storage.js.map +1 -1
  86. package/dist/core/extensions/index.d.ts +1 -1
  87. package/dist/core/extensions/index.d.ts.map +1 -1
  88. package/dist/core/extensions/index.js.map +1 -1
  89. package/dist/core/extensions/loader.d.ts.map +1 -1
  90. package/dist/core/extensions/loader.js +60 -41
  91. package/dist/core/extensions/loader.js.map +1 -1
  92. package/dist/core/extensions/runner.d.ts +2 -1
  93. package/dist/core/extensions/runner.d.ts.map +1 -1
  94. package/dist/core/extensions/runner.js +3 -0
  95. package/dist/core/extensions/runner.js.map +1 -1
  96. package/dist/core/extensions/types.d.ts +27 -4
  97. package/dist/core/extensions/types.d.ts.map +1 -1
  98. package/dist/core/extensions/types.js.map +1 -1
  99. package/dist/core/http-dispatcher.d.ts.map +1 -1
  100. package/dist/core/http-dispatcher.js +5 -0
  101. package/dist/core/http-dispatcher.js.map +1 -1
  102. package/dist/core/keybindings.d.ts +45 -5
  103. package/dist/core/keybindings.d.ts.map +1 -1
  104. package/dist/core/keybindings.js.map +1 -1
  105. package/dist/core/model-config.d.ts +29 -5
  106. package/dist/core/model-config.d.ts.map +1 -1
  107. package/dist/core/model-config.js +4 -0
  108. package/dist/core/model-config.js.map +1 -1
  109. package/dist/core/model-registry.d.ts +5 -3
  110. package/dist/core/model-registry.d.ts.map +1 -1
  111. package/dist/core/model-registry.js +13 -10
  112. package/dist/core/model-registry.js.map +1 -1
  113. package/dist/core/model-resolver.d.ts +4 -3
  114. package/dist/core/model-resolver.d.ts.map +1 -1
  115. package/dist/core/model-resolver.js +42 -10
  116. package/dist/core/model-resolver.js.map +1 -1
  117. package/dist/core/model-runtime.d.ts +30 -13
  118. package/dist/core/model-runtime.d.ts.map +1 -1
  119. package/dist/core/model-runtime.js +233 -73
  120. package/dist/core/model-runtime.js.map +1 -1
  121. package/dist/core/models-store.d.ts +12 -7
  122. package/dist/core/models-store.d.ts.map +1 -1
  123. package/dist/core/models-store.js +83 -14
  124. package/dist/core/models-store.js.map +1 -1
  125. package/dist/core/package-manager.d.ts +6 -3
  126. package/dist/core/package-manager.d.ts.map +1 -1
  127. package/dist/core/package-manager.js +80 -61
  128. package/dist/core/package-manager.js.map +1 -1
  129. package/dist/core/pi-manifest.d.ts +8 -0
  130. package/dist/core/pi-manifest.d.ts.map +1 -0
  131. package/dist/core/pi-manifest.js +28 -0
  132. package/dist/core/pi-manifest.js.map +1 -0
  133. package/dist/core/provider-composer.d.ts +4 -1
  134. package/dist/core/provider-composer.d.ts.map +1 -1
  135. package/dist/core/provider-composer.js +36 -15
  136. package/dist/core/provider-composer.js.map +1 -1
  137. package/dist/core/remote-catalog-provider.d.ts.map +1 -1
  138. package/dist/core/remote-catalog-provider.js +73 -67
  139. package/dist/core/remote-catalog-provider.js.map +1 -1
  140. package/dist/core/resource-loader.d.ts.map +1 -1
  141. package/dist/core/resource-loader.js +2 -2
  142. package/dist/core/resource-loader.js.map +1 -1
  143. package/dist/core/runtime-credentials.d.ts +5 -5
  144. package/dist/core/runtime-credentials.d.ts.map +1 -1
  145. package/dist/core/runtime-credentials.js +11 -8
  146. package/dist/core/runtime-credentials.js.map +1 -1
  147. package/dist/core/sdk.d.ts +1 -1
  148. package/dist/core/sdk.d.ts.map +1 -1
  149. package/dist/core/sdk.js +2 -2
  150. package/dist/core/sdk.js.map +1 -1
  151. package/dist/core/session-manager.d.ts.map +1 -1
  152. package/dist/core/session-manager.js +3 -1
  153. package/dist/core/session-manager.js.map +1 -1
  154. package/dist/core/settings-manager.d.ts +12 -0
  155. package/dist/core/settings-manager.d.ts.map +1 -1
  156. package/dist/core/settings-manager.js +40 -16
  157. package/dist/core/settings-manager.js.map +1 -1
  158. package/dist/core/system-prompt.d.ts.map +1 -1
  159. package/dist/core/system-prompt.js +8 -0
  160. package/dist/core/system-prompt.js.map +1 -1
  161. package/dist/core/tools/bash.d.ts +5 -1
  162. package/dist/core/tools/bash.d.ts.map +1 -1
  163. package/dist/core/tools/bash.js +16 -15
  164. package/dist/core/tools/bash.js.map +1 -1
  165. package/dist/core/tools/edit.d.ts +4 -0
  166. package/dist/core/tools/edit.d.ts.map +1 -1
  167. package/dist/core/tools/edit.js +11 -7
  168. package/dist/core/tools/edit.js.map +1 -1
  169. package/dist/core/tools/find.d.ts +7 -0
  170. package/dist/core/tools/find.d.ts.map +1 -1
  171. package/dist/core/tools/find.js +16 -19
  172. package/dist/core/tools/find.js.map +1 -1
  173. package/dist/core/tools/grep.d.ts +4 -0
  174. package/dist/core/tools/grep.d.ts.map +1 -1
  175. package/dist/core/tools/grep.js +5 -1
  176. package/dist/core/tools/grep.js.map +1 -1
  177. package/dist/core/tools/ls.d.ts +4 -0
  178. package/dist/core/tools/ls.d.ts.map +1 -1
  179. package/dist/core/tools/ls.js +5 -1
  180. package/dist/core/tools/ls.js.map +1 -1
  181. package/dist/core/tools/read.d.ts +4 -0
  182. package/dist/core/tools/read.d.ts.map +1 -1
  183. package/dist/core/tools/read.js +7 -3
  184. package/dist/core/tools/read.js.map +1 -1
  185. package/dist/core/tools/write.d.ts +4 -0
  186. package/dist/core/tools/write.d.ts.map +1 -1
  187. package/dist/core/tools/write.js +6 -2
  188. package/dist/core/tools/write.js.map +1 -1
  189. package/dist/extensions/llama/index.d.ts.map +1 -1
  190. package/dist/extensions/llama/index.js +11 -2
  191. package/dist/extensions/llama/index.js.map +1 -1
  192. package/dist/extensions/llama/provider.d.ts.map +1 -1
  193. package/dist/extensions/llama/provider.js +21 -7
  194. package/dist/extensions/llama/provider.js.map +1 -1
  195. package/dist/humain/agent-execution-protocol.d.ts +218 -0
  196. package/dist/humain/agent-execution-protocol.d.ts.map +1 -0
  197. package/dist/humain/agent-execution-protocol.js +204 -0
  198. package/dist/humain/agent-execution-protocol.js.map +1 -0
  199. package/dist/humain/agent-execution-runtime.d.ts +35 -0
  200. package/dist/humain/agent-execution-runtime.d.ts.map +1 -0
  201. package/dist/humain/agent-execution-runtime.js +170 -0
  202. package/dist/humain/agent-execution-runtime.js.map +1 -0
  203. package/dist/humain/index.d.ts.map +1 -1
  204. package/dist/humain/index.js +8 -7
  205. package/dist/humain/index.js.map +1 -1
  206. package/dist/humain/mcp-adapter/vendor/CHANGELOG.md +660 -0
  207. package/dist/humain/mcp-adapter/vendor/LICENSE +21 -0
  208. package/dist/humain/mcp-adapter/vendor/README.md +733 -0
  209. package/dist/humain/mcp-adapter/vendor/abort.ts +34 -0
  210. package/dist/humain/mcp-adapter/vendor/agent-dir.ts +60 -0
  211. package/dist/humain/mcp-adapter/vendor/agent-plugin-loader.ts +377 -0
  212. package/dist/humain/mcp-adapter/vendor/app-bridge.bundle.js +67 -0
  213. package/dist/humain/mcp-adapter/vendor/banner.png +0 -0
  214. package/dist/humain/mcp-adapter/vendor/cli.js +209 -0
  215. package/dist/humain/mcp-adapter/vendor/commands.ts +627 -0
  216. package/dist/humain/mcp-adapter/vendor/config.ts +1226 -0
  217. package/dist/humain/mcp-adapter/vendor/consent-manager.ts +64 -0
  218. package/dist/humain/mcp-adapter/vendor/direct-tools.ts +604 -0
  219. package/dist/humain/mcp-adapter/vendor/elicitation-handler.ts +348 -0
  220. package/dist/humain/mcp-adapter/vendor/error-signal.ts +21 -0
  221. package/dist/humain/mcp-adapter/vendor/errors.ts +223 -0
  222. package/dist/humain/mcp-adapter/vendor/glimpse-ui.ts +80 -0
  223. package/dist/humain/mcp-adapter/vendor/host-html-template.ts +461 -0
  224. package/dist/humain/mcp-adapter/vendor/index.bundle.d.mts +4 -0
  225. package/dist/humain/mcp-adapter/vendor/index.bundle.mjs +15923 -0
  226. package/dist/humain/mcp-adapter/vendor/index.ts +898 -0
  227. package/dist/humain/mcp-adapter/vendor/init.ts +649 -0
  228. package/dist/humain/mcp-adapter/vendor/json-schema-validator.ts +69 -0
  229. package/dist/humain/mcp-adapter/vendor/lifecycle.ts +147 -0
  230. package/dist/humain/mcp-adapter/vendor/logger.ts +169 -0
  231. package/dist/humain/mcp-adapter/vendor/mcp-auth-flow.ts +993 -0
  232. package/dist/humain/mcp-adapter/vendor/mcp-auth.ts +1000 -0
  233. package/dist/humain/mcp-adapter/vendor/mcp-callback-server.ts +510 -0
  234. package/dist/humain/mcp-adapter/vendor/mcp-code.ts +354 -0
  235. package/dist/humain/mcp-adapter/vendor/mcp-keyring-helper.cjs +89 -0
  236. package/dist/humain/mcp-adapter/vendor/mcp-oauth-provider.ts +616 -0
  237. package/dist/humain/mcp-adapter/vendor/mcp-output-guard.ts +408 -0
  238. package/dist/humain/mcp-adapter/vendor/mcp-panel.ts +1015 -0
  239. package/dist/humain/mcp-adapter/vendor/mcp-probe.ts +187 -0
  240. package/dist/humain/mcp-adapter/vendor/mcp-script-worker.mjs +130 -0
  241. package/dist/humain/mcp-adapter/vendor/mcp-setup-panel.ts +666 -0
  242. package/dist/humain/mcp-adapter/vendor/mcp-status.ts +109 -0
  243. package/dist/humain/mcp-adapter/vendor/mcp-trace.ts +306 -0
  244. package/dist/humain/mcp-adapter/vendor/metadata-cache.ts +353 -0
  245. package/dist/humain/mcp-adapter/vendor/npx-resolver.ts +543 -0
  246. package/dist/humain/mcp-adapter/vendor/oauth-handler.ts +30 -0
  247. package/dist/humain/mcp-adapter/vendor/oauth.ts +48 -0
  248. package/dist/humain/mcp-adapter/vendor/onboarding-state.ts +76 -0
  249. package/dist/humain/mcp-adapter/vendor/package.json +178 -0
  250. package/dist/humain/mcp-adapter/vendor/panel-keys.ts +53 -0
  251. package/dist/humain/mcp-adapter/vendor/prompts.ts +353 -0
  252. package/dist/humain/mcp-adapter/vendor/proxy-modes.ts +1331 -0
  253. package/dist/humain/mcp-adapter/vendor/resource-tools.ts +17 -0
  254. package/dist/humain/mcp-adapter/vendor/runtime-owner.ts +91 -0
  255. package/dist/humain/mcp-adapter/vendor/sampling-handler.ts +284 -0
  256. package/dist/humain/mcp-adapter/vendor/search-ranking.ts +206 -0
  257. package/dist/humain/mcp-adapter/vendor/server-manager.ts +1124 -0
  258. package/dist/humain/mcp-adapter/vendor/session-recovery.ts +151 -0
  259. package/dist/humain/mcp-adapter/vendor/skills/mcp-scripting/SKILL.md +38 -0
  260. package/dist/humain/mcp-adapter/vendor/state.ts +62 -0
  261. package/dist/humain/mcp-adapter/vendor/tool-approval.ts +182 -0
  262. package/dist/humain/mcp-adapter/vendor/tool-metadata.ts +276 -0
  263. package/dist/humain/mcp-adapter/vendor/tool-registrar.ts +253 -0
  264. package/dist/humain/mcp-adapter/vendor/tool-result-renderer.ts +423 -0
  265. package/dist/humain/mcp-adapter/vendor/ts-shape.ts +149 -0
  266. package/dist/humain/mcp-adapter/vendor/types.ts +859 -0
  267. package/dist/humain/mcp-adapter/vendor/ui-app-bridge-helpers.ts +40 -0
  268. package/dist/humain/mcp-adapter/vendor/ui-resource-handler.ts +250 -0
  269. package/dist/humain/mcp-adapter/vendor/ui-server.ts +866 -0
  270. package/dist/humain/mcp-adapter/vendor/ui-session.ts +570 -0
  271. package/dist/humain/mcp-adapter/vendor/ui-stream-types.ts +89 -0
  272. package/dist/humain/mcp-adapter/vendor/ui-tool-visibility.ts +25 -0
  273. package/dist/humain/mcp-adapter/vendor/unix-socket-transport.ts +85 -0
  274. package/dist/humain/mcp-adapter/vendor/utils.ts +310 -0
  275. package/dist/humain/mcp-adapter.d.ts +3 -0
  276. package/dist/humain/mcp-adapter.d.ts.map +1 -0
  277. package/dist/humain/mcp-adapter.js +5 -0
  278. package/dist/humain/mcp-adapter.js.map +1 -0
  279. package/dist/humain/pi-agent-execution-host.d.ts +34 -0
  280. package/dist/humain/pi-agent-execution-host.d.ts.map +1 -0
  281. package/dist/humain/pi-agent-execution-host.js +77 -0
  282. package/dist/humain/pi-agent-execution-host.js.map +1 -0
  283. package/dist/humain/web-access/host.d.ts +4 -0
  284. package/dist/humain/web-access/host.d.ts.map +1 -0
  285. package/dist/humain/web-access/host.js +3 -0
  286. package/dist/humain/web-access/host.js.map +1 -0
  287. package/dist/humain/web-access/index.d.ts +3 -0
  288. package/dist/humain/web-access/index.d.ts.map +1 -0
  289. package/dist/humain/web-access/index.js +5 -0
  290. package/dist/humain/web-access/index.js.map +1 -0
  291. package/dist/humain/web-access/vendor/activity.d.ts +34 -0
  292. package/dist/humain/web-access/vendor/activity.d.ts.map +1 -0
  293. package/dist/humain/web-access/vendor/activity.js +68 -0
  294. package/dist/humain/web-access/vendor/activity.js.map +1 -0
  295. package/dist/humain/web-access/vendor/anysearch.d.ts +8 -0
  296. package/dist/humain/web-access/vendor/anysearch.d.ts.map +1 -0
  297. package/dist/humain/web-access/vendor/anysearch.js +167 -0
  298. package/dist/humain/web-access/vendor/anysearch.js.map +1 -0
  299. package/dist/humain/web-access/vendor/bocha.d.ts +4 -0
  300. package/dist/humain/web-access/vendor/bocha.d.ts.map +1 -0
  301. package/dist/humain/web-access/vendor/bocha.js +219 -0
  302. package/dist/humain/web-access/vendor/bocha.js.map +1 -0
  303. package/dist/humain/web-access/vendor/brave.d.ts +4 -0
  304. package/dist/humain/web-access/vendor/brave.d.ts.map +1 -0
  305. package/dist/humain/web-access/vendor/brave.js +194 -0
  306. package/dist/humain/web-access/vendor/brave.js.map +1 -0
  307. package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts +12 -0
  308. package/dist/humain/web-access/vendor/brightdata-unlocker.d.ts.map +1 -0
  309. package/dist/humain/web-access/vendor/brightdata-unlocker.js +230 -0
  310. package/dist/humain/web-access/vendor/brightdata-unlocker.js.map +1 -0
  311. package/dist/humain/web-access/vendor/brightdata.d.ts +8 -0
  312. package/dist/humain/web-access/vendor/brightdata.d.ts.map +1 -0
  313. package/dist/humain/web-access/vendor/brightdata.js +519 -0
  314. package/dist/humain/web-access/vendor/brightdata.js.map +1 -0
  315. package/dist/humain/web-access/vendor/chrome-cookies.d.ts +10 -0
  316. package/dist/humain/web-access/vendor/chrome-cookies.d.ts.map +1 -0
  317. package/dist/humain/web-access/vendor/chrome-cookies.js +438 -0
  318. package/dist/humain/web-access/vendor/chrome-cookies.js.map +1 -0
  319. package/dist/humain/web-access/vendor/content-find.d.ts +11 -0
  320. package/dist/humain/web-access/vendor/content-find.d.ts.map +1 -0
  321. package/dist/humain/web-access/vendor/content-find.js +117 -0
  322. package/dist/humain/web-access/vendor/content-find.js.map +1 -0
  323. package/dist/humain/web-access/vendor/credential-source.d.ts +28 -0
  324. package/dist/humain/web-access/vendor/credential-source.d.ts.map +1 -0
  325. package/dist/humain/web-access/vendor/credential-source.js +151 -0
  326. package/dist/humain/web-access/vendor/credential-source.js.map +1 -0
  327. package/dist/humain/web-access/vendor/curator-page.d.ts +29 -0
  328. package/dist/humain/web-access/vendor/curator-page.d.ts.map +1 -0
  329. package/dist/humain/web-access/vendor/curator-page.js +3554 -0
  330. package/dist/humain/web-access/vendor/curator-page.js.map +1 -0
  331. package/dist/humain/web-access/vendor/curator-server.d.ts +93 -0
  332. package/dist/humain/web-access/vendor/curator-server.d.ts.map +1 -0
  333. package/dist/humain/web-access/vendor/curator-server.js +688 -0
  334. package/dist/humain/web-access/vendor/curator-server.js.map +1 -0
  335. package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts +60 -0
  336. package/dist/humain/web-access/vendor/datalab-pdf-extract.d.ts.map +1 -0
  337. package/dist/humain/web-access/vendor/datalab-pdf-extract.js +416 -0
  338. package/dist/humain/web-access/vendor/datalab-pdf-extract.js.map +1 -0
  339. package/dist/humain/web-access/vendor/declared-web-links.d.ts +16 -0
  340. package/dist/humain/web-access/vendor/declared-web-links.d.ts.map +1 -0
  341. package/dist/humain/web-access/vendor/declared-web-links.js +168 -0
  342. package/dist/humain/web-access/vendor/declared-web-links.js.map +1 -0
  343. package/dist/humain/web-access/vendor/duckduckgo.d.ts +4 -0
  344. package/dist/humain/web-access/vendor/duckduckgo.d.ts.map +1 -0
  345. package/dist/humain/web-access/vendor/duckduckgo.js +123 -0
  346. package/dist/humain/web-access/vendor/duckduckgo.js.map +1 -0
  347. package/dist/humain/web-access/vendor/exa.d.ts +10 -0
  348. package/dist/humain/web-access/vendor/exa.d.ts.map +1 -0
  349. package/dist/humain/web-access/vendor/exa.js +426 -0
  350. package/dist/humain/web-access/vendor/exa.js.map +1 -0
  351. package/dist/humain/web-access/vendor/extract.d.ts +46 -0
  352. package/dist/humain/web-access/vendor/extract.d.ts.map +1 -0
  353. package/dist/humain/web-access/vendor/extract.js +1064 -0
  354. package/dist/humain/web-access/vendor/extract.js.map +1 -0
  355. package/dist/humain/web-access/vendor/feature-config.d.ts +3 -0
  356. package/dist/humain/web-access/vendor/feature-config.d.ts.map +1 -0
  357. package/dist/humain/web-access/vendor/feature-config.js +27 -0
  358. package/dist/humain/web-access/vendor/feature-config.js.map +1 -0
  359. package/dist/humain/web-access/vendor/fetch-params.d.ts +25 -0
  360. package/dist/humain/web-access/vendor/fetch-params.d.ts.map +1 -0
  361. package/dist/humain/web-access/vendor/fetch-params.js +57 -0
  362. package/dist/humain/web-access/vendor/fetch-params.js.map +1 -0
  363. package/dist/humain/web-access/vendor/firecrawl.d.ts +12 -0
  364. package/dist/humain/web-access/vendor/firecrawl.d.ts.map +1 -0
  365. package/dist/humain/web-access/vendor/firecrawl.js +239 -0
  366. package/dist/humain/web-access/vendor/firecrawl.js.map +1 -0
  367. package/dist/humain/web-access/vendor/gemini-api.d.ts +27 -0
  368. package/dist/humain/web-access/vendor/gemini-api.d.ts.map +1 -0
  369. package/dist/humain/web-access/vendor/gemini-api.js +230 -0
  370. package/dist/humain/web-access/vendor/gemini-api.js.map +1 -0
  371. package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts +9 -0
  372. package/dist/humain/web-access/vendor/gemini-pdf-extract.d.ts.map +1 -0
  373. package/dist/humain/web-access/vendor/gemini-pdf-extract.js +85 -0
  374. package/dist/humain/web-access/vendor/gemini-pdf-extract.js.map +1 -0
  375. package/dist/humain/web-access/vendor/gemini-search.d.ts +40 -0
  376. package/dist/humain/web-access/vendor/gemini-search.d.ts.map +1 -0
  377. package/dist/humain/web-access/vendor/gemini-search.js +814 -0
  378. package/dist/humain/web-access/vendor/gemini-search.js.map +1 -0
  379. package/dist/humain/web-access/vendor/gemini-url-context.d.ts +4 -0
  380. package/dist/humain/web-access/vendor/gemini-url-context.d.ts.map +1 -0
  381. package/dist/humain/web-access/vendor/gemini-url-context.js +101 -0
  382. package/dist/humain/web-access/vendor/gemini-url-context.js.map +1 -0
  383. package/dist/humain/web-access/vendor/gemini-web-config.d.ts +4 -0
  384. package/dist/humain/web-access/vendor/gemini-web-config.d.ts.map +1 -0
  385. package/dist/humain/web-access/vendor/gemini-web-config.js +42 -0
  386. package/dist/humain/web-access/vendor/gemini-web-config.js.map +1 -0
  387. package/dist/humain/web-access/vendor/gemini-web.d.ts +18 -0
  388. package/dist/humain/web-access/vendor/gemini-web.d.ts.map +1 -0
  389. package/dist/humain/web-access/vendor/gemini-web.js +385 -0
  390. package/dist/humain/web-access/vendor/gemini-web.js.map +1 -0
  391. package/dist/humain/web-access/vendor/github-api.d.ts +7 -0
  392. package/dist/humain/web-access/vendor/github-api.d.ts.map +1 -0
  393. package/dist/humain/web-access/vendor/github-api.js +160 -0
  394. package/dist/humain/web-access/vendor/github-api.js.map +1 -0
  395. package/dist/humain/web-access/vendor/github-extract.d.ts +13 -0
  396. package/dist/humain/web-access/vendor/github-extract.d.ts.map +1 -0
  397. package/dist/humain/web-access/vendor/github-extract.js +635 -0
  398. package/dist/humain/web-access/vendor/github-extract.js.map +1 -0
  399. package/dist/humain/web-access/vendor/index.d.ts +4 -0
  400. package/dist/humain/web-access/vendor/index.d.ts.map +1 -0
  401. package/dist/humain/web-access/vendor/index.js +3002 -0
  402. package/dist/humain/web-access/vendor/index.js.map +1 -0
  403. package/dist/humain/web-access/vendor/jina-search.d.ts +8 -0
  404. package/dist/humain/web-access/vendor/jina-search.d.ts.map +1 -0
  405. package/dist/humain/web-access/vendor/jina-search.js +255 -0
  406. package/dist/humain/web-access/vendor/jina-search.js.map +1 -0
  407. package/dist/humain/web-access/vendor/kagi.d.ts +15 -0
  408. package/dist/humain/web-access/vendor/kagi.d.ts.map +1 -0
  409. package/dist/humain/web-access/vendor/kagi.js +262 -0
  410. package/dist/humain/web-access/vendor/kagi.js.map +1 -0
  411. package/dist/humain/web-access/vendor/ollama.d.ts +15 -0
  412. package/dist/humain/web-access/vendor/ollama.d.ts.map +1 -0
  413. package/dist/humain/web-access/vendor/ollama.js +216 -0
  414. package/dist/humain/web-access/vendor/ollama.js.map +1 -0
  415. package/dist/humain/web-access/vendor/openai-search.d.ts +15 -0
  416. package/dist/humain/web-access/vendor/openai-search.d.ts.map +1 -0
  417. package/dist/humain/web-access/vendor/openai-search.js +459 -0
  418. package/dist/humain/web-access/vendor/openai-search.js.map +1 -0
  419. package/dist/humain/web-access/vendor/page-query.d.ts +16 -0
  420. package/dist/humain/web-access/vendor/page-query.d.ts.map +1 -0
  421. package/dist/humain/web-access/vendor/page-query.js +79 -0
  422. package/dist/humain/web-access/vendor/page-query.js.map +1 -0
  423. package/dist/humain/web-access/vendor/parallel.d.ts +12 -0
  424. package/dist/humain/web-access/vendor/parallel.d.ts.map +1 -0
  425. package/dist/humain/web-access/vendor/parallel.js +343 -0
  426. package/dist/humain/web-access/vendor/parallel.js.map +1 -0
  427. package/dist/humain/web-access/vendor/pdf-extract.d.ts +44 -0
  428. package/dist/humain/web-access/vendor/pdf-extract.d.ts.map +1 -0
  429. package/dist/humain/web-access/vendor/pdf-extract.js +298 -0
  430. package/dist/humain/web-access/vendor/pdf-extract.js.map +1 -0
  431. package/dist/humain/web-access/vendor/perplexity.d.ts +20 -0
  432. package/dist/humain/web-access/vendor/perplexity.d.ts.map +1 -0
  433. package/dist/humain/web-access/vendor/perplexity.js +159 -0
  434. package/dist/humain/web-access/vendor/perplexity.js.map +1 -0
  435. package/dist/humain/web-access/vendor/querit.d.ts +10 -0
  436. package/dist/humain/web-access/vendor/querit.d.ts.map +1 -0
  437. package/dist/humain/web-access/vendor/querit.js +335 -0
  438. package/dist/humain/web-access/vendor/querit.js.map +1 -0
  439. package/dist/humain/web-access/vendor/render-search-error.d.ts +57 -0
  440. package/dist/humain/web-access/vendor/render-search-error.d.ts.map +1 -0
  441. package/dist/humain/web-access/vendor/render-search-error.js +130 -0
  442. package/dist/humain/web-access/vendor/render-search-error.js.map +1 -0
  443. package/dist/humain/web-access/vendor/rsc-extract.d.ts +12 -0
  444. package/dist/humain/web-access/vendor/rsc-extract.d.ts.map +1 -0
  445. package/dist/humain/web-access/vendor/rsc-extract.js +329 -0
  446. package/dist/humain/web-access/vendor/rsc-extract.js.map +1 -0
  447. package/dist/humain/web-access/vendor/search1api.d.ts +10 -0
  448. package/dist/humain/web-access/vendor/search1api.d.ts.map +1 -0
  449. package/dist/humain/web-access/vendor/search1api.js +251 -0
  450. package/dist/humain/web-access/vendor/search1api.js.map +1 -0
  451. package/dist/humain/web-access/vendor/searchinfinity.d.ts +8 -0
  452. package/dist/humain/web-access/vendor/searchinfinity.d.ts.map +1 -0
  453. package/dist/humain/web-access/vendor/searchinfinity.js +229 -0
  454. package/dist/humain/web-access/vendor/searchinfinity.js.map +1 -0
  455. package/dist/humain/web-access/vendor/searxng.d.ts +4 -0
  456. package/dist/humain/web-access/vendor/searxng.d.ts.map +1 -0
  457. package/dist/humain/web-access/vendor/searxng.js +238 -0
  458. package/dist/humain/web-access/vendor/searxng.js.map +1 -0
  459. package/dist/humain/web-access/vendor/serpbase.d.ts +4 -0
  460. package/dist/humain/web-access/vendor/serpbase.d.ts.map +1 -0
  461. package/dist/humain/web-access/vendor/serpbase.js +211 -0
  462. package/dist/humain/web-access/vendor/serpbase.js.map +1 -0
  463. package/dist/humain/web-access/vendor/serpdive.d.ts +8 -0
  464. package/dist/humain/web-access/vendor/serpdive.d.ts.map +1 -0
  465. package/dist/humain/web-access/vendor/serpdive.js +267 -0
  466. package/dist/humain/web-access/vendor/serpdive.js.map +1 -0
  467. package/dist/humain/web-access/vendor/source-check.d.ts +99 -0
  468. package/dist/humain/web-access/vendor/source-check.d.ts.map +1 -0
  469. package/dist/humain/web-access/vendor/source-check.js +205 -0
  470. package/dist/humain/web-access/vendor/source-check.js.map +1 -0
  471. package/dist/humain/web-access/vendor/ssrf-protection.d.ts +50 -0
  472. package/dist/humain/web-access/vendor/ssrf-protection.d.ts.map +1 -0
  473. package/dist/humain/web-access/vendor/ssrf-protection.js +466 -0
  474. package/dist/humain/web-access/vendor/ssrf-protection.js.map +1 -0
  475. package/dist/humain/web-access/vendor/storage.d.ts +55 -0
  476. package/dist/humain/web-access/vendor/storage.d.ts.map +1 -0
  477. package/dist/humain/web-access/vendor/storage.js +485 -0
  478. package/dist/humain/web-access/vendor/storage.js.map +1 -0
  479. package/dist/humain/web-access/vendor/summary-model-scope.d.ts +25 -0
  480. package/dist/humain/web-access/vendor/summary-model-scope.d.ts.map +1 -0
  481. package/dist/humain/web-access/vendor/summary-model-scope.js +98 -0
  482. package/dist/humain/web-access/vendor/summary-model-scope.js.map +1 -0
  483. package/dist/humain/web-access/vendor/summary-review.d.ts +24 -0
  484. package/dist/humain/web-access/vendor/summary-review.d.ts.map +1 -0
  485. package/dist/humain/web-access/vendor/summary-review.js +341 -0
  486. package/dist/humain/web-access/vendor/summary-review.js.map +1 -0
  487. package/dist/humain/web-access/vendor/tavily.d.ts +8 -0
  488. package/dist/humain/web-access/vendor/tavily.d.ts.map +1 -0
  489. package/dist/humain/web-access/vendor/tavily.js +194 -0
  490. package/dist/humain/web-access/vendor/tavily.js.map +1 -0
  491. package/dist/humain/web-access/vendor/tinyfish.d.ts +11 -0
  492. package/dist/humain/web-access/vendor/tinyfish.d.ts.map +1 -0
  493. package/dist/humain/web-access/vendor/tinyfish.js +331 -0
  494. package/dist/humain/web-access/vendor/tinyfish.js.map +1 -0
  495. package/dist/humain/web-access/vendor/utils.d.ts +20 -0
  496. package/dist/humain/web-access/vendor/utils.d.ts.map +1 -0
  497. package/dist/humain/web-access/vendor/utils.js +91 -0
  498. package/dist/humain/web-access/vendor/utils.js.map +1 -0
  499. package/dist/humain/web-access/vendor/video-extract.d.ts +16 -0
  500. package/dist/humain/web-access/vendor/video-extract.d.ts.map +1 -0
  501. package/dist/humain/web-access/vendor/video-extract.js +335 -0
  502. package/dist/humain/web-access/vendor/video-extract.js.map +1 -0
  503. package/dist/humain/web-access/vendor/xai-search.d.ts +13 -0
  504. package/dist/humain/web-access/vendor/xai-search.d.ts.map +1 -0
  505. package/dist/humain/web-access/vendor/xai-search.js +331 -0
  506. package/dist/humain/web-access/vendor/xai-search.js.map +1 -0
  507. package/dist/humain/web-access/vendor/youtube-extract.d.ts +27 -0
  508. package/dist/humain/web-access/vendor/youtube-extract.d.ts.map +1 -0
  509. package/dist/humain/web-access/vendor/youtube-extract.js +282 -0
  510. package/dist/humain/web-access/vendor/youtube-extract.js.map +1 -0
  511. package/dist/index.d.ts +7 -4
  512. package/dist/index.d.ts.map +1 -1
  513. package/dist/index.js +5 -2
  514. package/dist/index.js.map +1 -1
  515. package/dist/main.d.ts +2 -2
  516. package/dist/main.d.ts.map +1 -1
  517. package/dist/main.js +169 -102
  518. package/dist/main.js.map +1 -1
  519. package/dist/modes/agent-exec-mode.d.ts +14 -0
  520. package/dist/modes/agent-exec-mode.d.ts.map +1 -0
  521. package/dist/modes/agent-exec-mode.js +92 -0
  522. package/dist/modes/agent-exec-mode.js.map +1 -0
  523. package/dist/modes/index.d.ts +4 -2
  524. package/dist/modes/index.d.ts.map +1 -1
  525. package/dist/modes/index.js +2 -1
  526. package/dist/modes/index.js.map +1 -1
  527. package/dist/modes/interactive/components/assistant-message.d.ts +5 -2
  528. package/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  529. package/dist/modes/interactive/components/assistant-message.js +13 -4
  530. package/dist/modes/interactive/components/assistant-message.js.map +1 -1
  531. package/dist/modes/interactive/components/custom-editor.d.ts.map +1 -1
  532. package/dist/modes/interactive/components/custom-editor.js +7 -0
  533. package/dist/modes/interactive/components/custom-editor.js.map +1 -1
  534. package/dist/modes/interactive/components/earendil-announcement.d.ts +5 -0
  535. package/dist/modes/interactive/components/earendil-announcement.d.ts.map +1 -0
  536. package/dist/modes/interactive/components/earendil-announcement.js +40 -0
  537. package/dist/modes/interactive/components/earendil-announcement.js.map +1 -0
  538. package/dist/modes/interactive/components/footer.d.ts.map +1 -1
  539. package/dist/modes/interactive/components/footer.js +1 -1
  540. package/dist/modes/interactive/components/footer.js.map +1 -1
  541. package/dist/modes/interactive/components/markdown-transform.d.ts +3 -0
  542. package/dist/modes/interactive/components/markdown-transform.d.ts.map +1 -0
  543. package/dist/modes/interactive/components/markdown-transform.js +19 -0
  544. package/dist/modes/interactive/components/markdown-transform.js.map +1 -0
  545. package/dist/modes/interactive/components/mermaid.d.ts +11 -0
  546. package/dist/modes/interactive/components/mermaid.d.ts.map +1 -0
  547. package/dist/modes/interactive/components/mermaid.js +75 -0
  548. package/dist/modes/interactive/components/mermaid.js.map +1 -0
  549. package/dist/modes/interactive/components/model-selector.d.ts +1 -1
  550. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  551. package/dist/modes/interactive/components/model-selector.js +16 -4
  552. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  553. package/dist/modes/interactive/components/scoped-models-selector.d.ts +4 -0
  554. package/dist/modes/interactive/components/scoped-models-selector.d.ts.map +1 -1
  555. package/dist/modes/interactive/components/scoped-models-selector.js +26 -0
  556. package/dist/modes/interactive/components/scoped-models-selector.js.map +1 -1
  557. package/dist/modes/interactive/components/settings-selector.d.ts +8 -2
  558. package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  559. package/dist/modes/interactive/components/settings-selector.js +30 -0
  560. package/dist/modes/interactive/components/settings-selector.js.map +1 -1
  561. package/dist/modes/interactive/components/user-message.d.ts +3 -1
  562. package/dist/modes/interactive/components/user-message.d.ts.map +1 -1
  563. package/dist/modes/interactive/components/user-message.js +9 -2
  564. package/dist/modes/interactive/components/user-message.js.map +1 -1
  565. package/dist/modes/interactive/interactive-mode.d.ts +45 -9
  566. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  567. package/dist/modes/interactive/interactive-mode.js +581 -211
  568. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  569. package/dist/modes/interactive/theme/dark.json +1 -0
  570. package/dist/modes/interactive/theme/light.json +1 -0
  571. package/dist/modes/interactive/theme/theme-controller.d.ts +3 -0
  572. package/dist/modes/interactive/theme/theme-controller.d.ts.map +1 -1
  573. package/dist/modes/interactive/theme/theme-controller.js +10 -1
  574. package/dist/modes/interactive/theme/theme-controller.js.map +1 -1
  575. package/dist/modes/interactive/theme/theme-schema.json +5 -1
  576. package/dist/modes/interactive/theme/theme.d.ts +2 -2
  577. package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  578. package/dist/modes/interactive/theme/theme.js +24 -6
  579. package/dist/modes/interactive/theme/theme.js.map +1 -1
  580. package/dist/modes/json-event.d.ts +28 -0
  581. package/dist/modes/json-event.d.ts.map +1 -0
  582. package/dist/modes/json-event.js +12 -0
  583. package/dist/modes/json-event.js.map +1 -0
  584. package/dist/modes/print-mode.d.ts.map +1 -1
  585. package/dist/modes/print-mode.js +12 -2
  586. package/dist/modes/print-mode.js.map +1 -1
  587. package/dist/modes/rpc/rpc-client.d.ts +12 -5
  588. package/dist/modes/rpc/rpc-client.d.ts.map +1 -1
  589. package/dist/modes/rpc/rpc-client.js +55 -1
  590. package/dist/modes/rpc/rpc-client.js.map +1 -1
  591. package/dist/modes/rpc/rpc-mode.d.ts +1 -1
  592. package/dist/modes/rpc/rpc-mode.d.ts.map +1 -1
  593. package/dist/modes/rpc/rpc-mode.js +13 -3
  594. package/dist/modes/rpc/rpc-mode.js.map +1 -1
  595. package/dist/modes/rpc/rpc-types.d.ts +15 -0
  596. package/dist/modes/rpc/rpc-types.d.ts.map +1 -1
  597. package/dist/modes/rpc/rpc-types.js.map +1 -1
  598. package/dist/package-manager-cli.d.ts.map +1 -1
  599. package/dist/package-manager-cli.js +11 -9
  600. package/dist/package-manager-cli.js.map +1 -1
  601. package/dist/rpc-entry.d.ts.map +1 -1
  602. package/dist/rpc-entry.js +3 -2
  603. package/dist/rpc-entry.js.map +1 -1
  604. package/dist/server/create-harness.d.ts +26 -0
  605. package/dist/server/create-harness.d.ts.map +1 -0
  606. package/dist/server/create-harness.js +104 -0
  607. package/dist/server/create-harness.js.map +1 -0
  608. package/dist/utils/abort.d.ts +5 -0
  609. package/dist/utils/abort.d.ts.map +1 -0
  610. package/dist/utils/abort.js +48 -0
  611. package/dist/utils/abort.js.map +1 -0
  612. package/dist/utils/clipboard.d.ts +1 -1
  613. package/dist/utils/clipboard.d.ts.map +1 -1
  614. package/dist/utils/clipboard.js +22 -2
  615. package/dist/utils/clipboard.js.map +1 -1
  616. package/dist/utils/management-http.d.ts +23 -0
  617. package/dist/utils/management-http.d.ts.map +1 -0
  618. package/dist/utils/management-http.js +50 -0
  619. package/dist/utils/management-http.js.map +1 -0
  620. package/dist/utils/paths.d.ts +3 -0
  621. package/dist/utils/paths.d.ts.map +1 -1
  622. package/dist/utils/paths.js +23 -1
  623. package/dist/utils/paths.js.map +1 -1
  624. package/dist/utils/tool-result-images.d.ts +19 -0
  625. package/dist/utils/tool-result-images.d.ts.map +1 -0
  626. package/dist/utils/tool-result-images.js +45 -0
  627. package/dist/utils/tool-result-images.js.map +1 -0
  628. package/dist/utils/tools-manager.d.ts.map +1 -1
  629. package/dist/utils/tools-manager.js +13 -25
  630. package/dist/utils/tools-manager.js.map +1 -1
  631. package/dist/utils/version-check.d.ts +4 -0
  632. package/dist/utils/version-check.d.ts.map +1 -1
  633. package/dist/utils/version-check.js +23 -5
  634. package/dist/utils/version-check.js.map +1 -1
  635. package/docs/compaction.md +2 -2
  636. package/docs/custom-provider.md +7 -5
  637. package/docs/extensions.md +30 -5
  638. package/docs/humain-terminal.md +21 -1
  639. package/docs/json.md +24 -19
  640. package/docs/keybindings.md +46 -14
  641. package/docs/models.md +32 -11
  642. package/docs/providers.md +9 -1
  643. package/docs/quickstart.md +39 -37
  644. package/docs/rpc.md +31 -11
  645. package/docs/sdk.md +21 -2
  646. package/docs/security.md +21 -21
  647. package/docs/session-format.md +14 -14
  648. package/docs/settings.md +4 -1
  649. package/docs/themes.md +5 -3
  650. package/docs/usage.md +7 -0
  651. package/examples/extensions/custom-compaction.ts +3 -18
  652. package/examples/extensions/custom-provider-anthropic/index.ts +5 -1
  653. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  654. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  655. package/examples/extensions/custom-provider-gitlab-duo/index.ts +5 -1
  656. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  657. package/examples/extensions/doom-overlay/wad-finder.ts +7 -3
  658. package/examples/extensions/gondolin/package-lock.json +2 -2
  659. package/examples/extensions/gondolin/package.json +1 -1
  660. package/examples/extensions/handoff.ts +4 -13
  661. package/examples/extensions/qna.ts +5 -9
  662. package/examples/extensions/sandbox/package-lock.json +2 -2
  663. package/examples/extensions/sandbox/package.json +1 -1
  664. package/examples/extensions/summarize.ts +9 -20
  665. package/examples/extensions/with-deps/package-lock.json +2 -2
  666. package/examples/extensions/with-deps/package.json +1 -1
  667. package/examples/rpc-extension-ui.ts +11 -2
  668. package/examples/sdk/02-custom-model.ts +2 -3
  669. package/examples/sdk/09-api-keys-and-oauth.ts +1 -1
  670. package/examples/sdk/12-full-control.ts +1 -1
  671. package/examples/sdk/README.md +1 -1
  672. package/npm-shrinkwrap.json +2771 -535
  673. package/package.json +40 -11
  674. package/src/humain/mcp-adapter/UPSTREAM.md +15 -0
  675. package/src/humain/mcp-adapter/upstream.json +7 -0
  676. package/src/humain/mcp-adapter/vendor/CHANGELOG.md +660 -0
  677. package/src/humain/mcp-adapter/vendor/LICENSE +21 -0
  678. package/src/humain/web-access/UPSTREAM.md +17 -0
  679. package/src/humain/web-access/upstream.json +23 -0
  680. package/src/humain/web-access/vendor/LICENSE +21 -0
@@ -0,0 +1,993 @@
1
+ /**
2
+ * MCP Auth Flow
3
+ *
4
+ * High-level OAuth flow management using the MCP SDK's built-in auth functions.
5
+ */
6
+
7
+ import {
8
+ auth as runSdkAuth,
9
+ extractWWWAuthenticateParams,
10
+ LATEST_PROTOCOL_VERSION,
11
+ UnauthorizedError,
12
+ type AuthOptions,
13
+ } from "@modelcontextprotocol/client"
14
+ import open from "open"
15
+ import { McpOAuthProvider, type McpOAuthConfig } from "./mcp-oauth-provider.ts"
16
+ import {
17
+ ensureCallbackServer,
18
+ waitForCallback,
19
+ cancelPendingCallback,
20
+ stopCallbackServer,
21
+ releaseCallbackServer,
22
+ } from "./mcp-callback-server.ts"
23
+ import {
24
+ getAuthForUrl,
25
+ isTokenExpired,
26
+ hasStoredTokens,
27
+ clearAllCredentials,
28
+ clearClientInfo,
29
+ clearTokens,
30
+ clearCodeVerifier,
31
+ getOAuthState,
32
+ clearOAuthState,
33
+ getAuthBaseDir,
34
+ OAuthCredentialStoreError,
35
+ type AuthStorageOptions,
36
+ type StoredTokens,
37
+ } from "./mcp-auth.ts"
38
+ import { isServerDisabled, type ServerEntry } from "./types.ts"
39
+ import { formatTerminalError, interpolateEnvRecord, interpolateEnvVars } from "./utils.ts"
40
+ import { abortable, throwIfAborted } from "./abort.ts"
41
+ import { combineAbortSignals, isAbortError } from "./runtime-owner.ts"
42
+
43
+ /** Auth status for a server */
44
+ export type AuthStatus = "authenticated" | "expired" | "not_authenticated"
45
+
46
+ export interface McpOAuthRuntime {
47
+ readonly signal: AbortSignal
48
+ }
49
+
50
+ export interface AuthenticateOptions {
51
+ onAuthorizationUrl?: (authorizationUrl: string) => void | Promise<void>
52
+ onAuthorizationInput?: (
53
+ authorizationUrl: string,
54
+ signal: AbortSignal,
55
+ ) => Promise<string | undefined>
56
+ authStorageOptions?: AuthStorageOptions
57
+ signal?: AbortSignal
58
+ runtime?: McpOAuthRuntime
59
+ skipIssuerMetadataValidation?: boolean
60
+ }
61
+
62
+ type AuthDiscovery = Pick<AuthOptions, "resourceMetadataUrl" | "scope" | "skipIssuerMetadataValidation">
63
+
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
+ }
70
+ }
71
+
72
+ type PendingAuth = {
73
+ serverName: string
74
+ authProvider: McpOAuthProvider
75
+ serverUrl: string
76
+ authorizationUrl: string
77
+ discovery: AuthDiscovery
78
+ authStorageOptions: AuthStorageOptions
79
+ }
80
+
81
+ type RuntimeState = {
82
+ controller: AbortController
83
+ generation: number
84
+ pendingAuths: Map<string, PendingAuth>
85
+ pendingAuthStates: Map<string, string>
86
+ pendingAuthCleanupTimers: Map<string, ReturnType<typeof setTimeout>>
87
+ pendingAuthentications: Map<string, Promise<AuthStatus>>
88
+ }
89
+
90
+ const runtimeStates = new WeakMap<McpOAuthRuntime, RuntimeState>()
91
+ const activeRuntimes = new Set<McpOAuthRuntime>()
92
+
93
+ export function createOAuthRuntime(signal?: AbortSignal): McpOAuthRuntime {
94
+ const controller = new AbortController()
95
+ const runtime = { signal: combineAbortSignals(signal, controller.signal)! } satisfies McpOAuthRuntime
96
+ runtimeStates.set(runtime, {
97
+ controller,
98
+ generation: 0,
99
+ pendingAuths: new Map(),
100
+ pendingAuthStates: new Map(),
101
+ pendingAuthCleanupTimers: new Map(),
102
+ pendingAuthentications: new Map(),
103
+ })
104
+ activeRuntimes.add(runtime)
105
+ return runtime
106
+ }
107
+
108
+ let legacyRuntime = createOAuthRuntime()
109
+ activeRuntimes.delete(legacyRuntime)
110
+
111
+ function getRuntime(options?: AuthenticateOptions): McpOAuthRuntime {
112
+ if (options?.runtime) {
113
+ options.runtime.signal.throwIfAborted()
114
+ activeRuntimes.add(options.runtime)
115
+ return options.runtime
116
+ }
117
+ if (legacyRuntime.signal.aborted) legacyRuntime = createOAuthRuntime()
118
+ activeRuntimes.add(legacyRuntime)
119
+ return legacyRuntime
120
+ }
121
+
122
+ function getRuntimeState(runtime: McpOAuthRuntime): RuntimeState {
123
+ const state = runtimeStates.get(runtime)
124
+ if (!state) throw new Error("Unknown OAuth runtime")
125
+ return state
126
+ }
127
+
128
+ function getPendingAuthKey(serverName: string, options: AuthStorageOptions): string {
129
+ return `${serverName}|${getAuthBaseDir(options)}`
130
+ }
131
+
132
+ export function hasPendingAuth(serverName: string, options?: AuthStorageOptions, runtime?: McpOAuthRuntime): boolean {
133
+ const state = getRuntimeState(runtime ?? legacyRuntime)
134
+ if (options) {
135
+ return state.pendingAuths.has(getPendingAuthKey(serverName, options))
136
+ }
137
+ return Array.from(state.pendingAuths.values()).some(pendingAuth => pendingAuth.serverName === serverName)
138
+ }
139
+
140
+ /** Timeout for manual auth completion (5 minutes) */
141
+ const MANUAL_AUTH_TIMEOUT_MS = 5 * 60 * 1000
142
+
143
+ /**
144
+ * Generate a cryptographically secure random state parameter.
145
+ */
146
+ function generateState(): string {
147
+ return Array.from(crypto.getRandomValues(new Uint8Array(32)))
148
+ .map((b) => b.toString(16).padStart(2, "0"))
149
+ .join("")
150
+ }
151
+
152
+ /**
153
+ * Extract OAuth configuration from a ServerEntry.
154
+ */
155
+ export function extractOAuthConfig(definition: ServerEntry): McpOAuthConfig {
156
+ if (definition.oauth === false) {
157
+ return {}
158
+ }
159
+
160
+ const config: McpOAuthConfig = {}
161
+ if (definition.oauth?.grantType !== undefined) config.grantType = definition.oauth.grantType
162
+ if (definition.oauth?.clientId !== undefined) {
163
+ if (typeof definition.oauth.clientId !== "string") throw new Error("OAuth clientId must be a string")
164
+ config.clientId = interpolateEnvVars(definition.oauth.clientId)
165
+ }
166
+ if (definition.oauth?.clientSecret !== undefined) {
167
+ if (typeof definition.oauth.clientSecret !== "string") throw new Error("OAuth clientSecret must be a string")
168
+ // Preserve command expressions for the provider; interpolation remains eager for ordinary values.
169
+ config.clientSecret = definition.oauth.clientSecret.startsWith("!")
170
+ ? definition.oauth.clientSecret
171
+ : interpolateEnvVars(definition.oauth.clientSecret)
172
+ }
173
+ if (definition.oauth?.scope !== undefined) {
174
+ if (typeof definition.oauth.scope !== "string") throw new Error("OAuth scope must be a string")
175
+ config.scope = interpolateEnvVars(definition.oauth.scope)
176
+ }
177
+ if (definition.oauth?.authorizationParams !== undefined) {
178
+ const params = definition.oauth.authorizationParams
179
+ if (!params || typeof params !== "object" || Array.isArray(params)) {
180
+ throw new Error("OAuth authorizationParams must be an object")
181
+ }
182
+ config.authorizationParams = {}
183
+ for (const [key, value] of Object.entries(params)) {
184
+ if (!key) throw new Error("OAuth authorizationParams keys must not be empty")
185
+ if (typeof value !== "string") throw new Error(`OAuth authorizationParams.${key} must be a string`)
186
+ config.authorizationParams[key] = interpolateEnvVars(value)
187
+ }
188
+ }
189
+ if (definition.oauth?.redirectUri !== undefined) {
190
+ if (typeof definition.oauth.redirectUri !== "string") {
191
+ throw new Error("OAuth redirectUri must be a string")
192
+ }
193
+ const redirectUri = interpolateEnvVars(definition.oauth.redirectUri).trim()
194
+ if (!redirectUri) {
195
+ throw new Error("OAuth redirectUri must not be empty")
196
+ }
197
+ config.redirectUri = redirectUri
198
+ }
199
+ if (definition.oauth?.clientName !== undefined) {
200
+ if (typeof definition.oauth.clientName !== "string") {
201
+ throw new Error("OAuth clientName must be a string")
202
+ }
203
+ const clientName = interpolateEnvVars(definition.oauth.clientName).trim()
204
+ if (!clientName) {
205
+ throw new Error("OAuth clientName must not be empty")
206
+ }
207
+ config.clientName = clientName
208
+ }
209
+ if (definition.oauth?.clientUri !== undefined) {
210
+ if (typeof definition.oauth.clientUri !== "string") {
211
+ throw new Error("OAuth clientUri must be a string")
212
+ }
213
+ const clientUri = interpolateEnvVars(definition.oauth.clientUri).trim()
214
+ if (!clientUri) {
215
+ throw new Error("OAuth clientUri must not be empty")
216
+ }
217
+ config.clientUri = clientUri
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
+ }
246
+ return config
247
+ }
248
+
249
+ async function probeAuthDiscovery(serverUrl: string, definition?: ServerEntry, signal?: AbortSignal): Promise<AuthDiscovery> {
250
+ // Discovery must not execute config commands or send their source text.
251
+ const discoveryHeaders = definition?.headers
252
+ ? Object.fromEntries(Object.entries(definition.headers).filter(([, value]) => !value.startsWith("!") || value.startsWith("!!")))
253
+ : undefined
254
+ const headers = new Headers(interpolateEnvRecord(discoveryHeaders))
255
+ headers.set("content-type", "application/json")
256
+
257
+ const controller = new AbortController()
258
+ const discoverySignal = combineAbortSignals(signal, controller.signal)
259
+ const timer = setTimeout(() => controller.abort(), 5000)
260
+
261
+ try {
262
+ headers.set("accept", "application/json, text/event-stream")
263
+
264
+ const response = await fetch(new URL(serverUrl), {
265
+ method: "POST",
266
+ headers,
267
+ body: JSON.stringify({
268
+ jsonrpc: "2.0",
269
+ id: 0,
270
+ method: "initialize",
271
+ params: {
272
+ protocolVersion: LATEST_PROTOCOL_VERSION,
273
+ capabilities: {},
274
+ clientInfo: { name: "pi-mcp-adapter", version: "2.11.0" },
275
+ },
276
+ }),
277
+ ...(discoverySignal ? { signal: discoverySignal } : {}),
278
+ })
279
+ const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response)
280
+ await response.body?.cancel().catch(() => {})
281
+ return { ...(resourceMetadataUrl ? { resourceMetadataUrl } : {}), ...(scope ? { scope } : {}) }
282
+ } catch (error) {
283
+ if (signal?.aborted) throwIfAborted(signal)
284
+ return {}
285
+ } finally {
286
+ clearTimeout(timer)
287
+ }
288
+ }
289
+
290
+ function parseOAuthRedirectUri(redirectUri: string): { port: number; callbackHost: string; callbackPath: string } {
291
+ let url: URL
292
+ try {
293
+ url = new URL(redirectUri)
294
+ } catch (error) {
295
+ throw new Error(`Invalid OAuth redirectUri: ${redirectUri}`, { cause: error })
296
+ }
297
+
298
+ const hostname = url.hostname.toLowerCase()
299
+ const isLocalhost = hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1"
300
+ if (url.protocol !== "http:" || !isLocalhost) {
301
+ throw new Error("OAuth redirectUri must be an http:// localhost or loopback URI")
302
+ }
303
+
304
+ if (url.username || url.password) {
305
+ throw new Error("OAuth redirectUri must not include username or password")
306
+ }
307
+
308
+ if (url.hash) {
309
+ throw new Error("OAuth redirectUri must not include a fragment")
310
+ }
311
+
312
+ if (!url.port) {
313
+ throw new Error("OAuth redirectUri must include an explicit numeric port")
314
+ }
315
+
316
+ const port = Number.parseInt(url.port, 10)
317
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
318
+ throw new Error("OAuth redirectUri must include an explicit numeric port")
319
+ }
320
+
321
+ const callbackHost = hostname === "[::1]" ? "::1" : hostname
322
+ return { port, callbackHost, callbackPath: url.pathname }
323
+ }
324
+
325
+ /**
326
+ * Start OAuth authentication flow for a server.
327
+ * Returns the authorization URL when browser authorization is required.
328
+ */
329
+ export async function startAuth(
330
+ serverName: string,
331
+ serverUrl: string,
332
+ definition?: ServerEntry,
333
+ options: AuthenticateOptions = {},
334
+ ): Promise<{ authorizationUrl: string }> {
335
+ if (isServerDisabled(definition)) throw new Error(`MCP server "${serverName}" is disabled`)
336
+ const runtime = getRuntime(options)
337
+ const runtimeState = getRuntimeState(runtime)
338
+ const config = definition ? extractOAuthConfig(definition) : {}
339
+ const authStorageOptions = options.authStorageOptions ?? {}
340
+ const signal = combineAbortSignals(runtime.signal, options.signal)
341
+ const generation = runtimeState.generation
342
+ throwIfAborted(signal)
343
+
344
+ if (config.grantType === "client_credentials") {
345
+ const storedAuth = await getAuthForUrl(serverName, serverUrl, authStorageOptions)
346
+ if (storedAuth?.clientInfo && !storedAuth.tokens && !config.clientId) {
347
+ clearClientInfo(serverName, authStorageOptions)
348
+ clearCodeVerifier(serverName, authStorageOptions)
349
+ await clearOAuthState(serverName, authStorageOptions)
350
+ }
351
+
352
+ const authProvider = new McpOAuthProvider(serverName, serverUrl, config, {
353
+ onRedirect: async () => {
354
+ throw new Error("Browser redirect is not used for client_credentials flow")
355
+ },
356
+ }, authStorageOptions, runtime.signal)
357
+ try {
358
+ const discovery = applyOAuthConfig(await probeAuthDiscovery(serverUrl, definition, signal), config)
359
+ throwIfAborted(signal)
360
+ const result = await abortable(runSdkAuth(authProvider, { serverUrl, ...discovery }), signal)
361
+ throwIfAborted(signal)
362
+ if (result !== "AUTHORIZED") {
363
+ throw new UnauthorizedError("Failed to authorize")
364
+ }
365
+ return { authorizationUrl: "" }
366
+ } finally {
367
+ authProvider.deactivate()
368
+ }
369
+ }
370
+
371
+ const existingPendingAuth = runtimeState.pendingAuths.get(getPendingAuthKey(serverName, authStorageOptions))
372
+ if (existingPendingAuth?.serverUrl === serverUrl) {
373
+ return { authorizationUrl: existingPendingAuth.authorizationUrl }
374
+ }
375
+
376
+ const redirectCallback = config.redirectUri !== undefined ? parseOAuthRedirectUri(config.redirectUri) : undefined
377
+ const oauthState = generateState()
378
+
379
+ try {
380
+ await ensureCallbackServer({
381
+ strictPort: Boolean(config.clientId) || config.redirectUri !== undefined,
382
+ oauthState,
383
+ reserveState: true,
384
+ ...(redirectCallback ? { port: redirectCallback.port, callbackHost: redirectCallback.callbackHost, callbackPath: redirectCallback.callbackPath } : {}),
385
+ })
386
+ throwIfAborted(signal)
387
+ } catch (error) {
388
+ releaseCallbackServer(oauthState)
389
+ try {
390
+ await clearOAuthState(serverName, authStorageOptions)
391
+ } catch (cleanupError) {
392
+ throw new AggregateError([error, cleanupError], "OAuth startup cleanup failed")
393
+ }
394
+ throw error
395
+ }
396
+
397
+ let capturedUrl: URL | undefined
398
+ const authProvider = new McpOAuthProvider(serverName, serverUrl, config, {
399
+ onRedirect: async (url) => {
400
+ capturedUrl = url
401
+ },
402
+ }, authStorageOptions, runtime.signal, oauthState)
403
+
404
+ try {
405
+ const storedAuth = await getAuthForUrl(serverName, serverUrl, authStorageOptions)
406
+ if (storedAuth?.clientInfo && !config.clientId) {
407
+ if (!storedAuth.tokens) {
408
+ clearClientInfo(serverName, authStorageOptions)
409
+ clearCodeVerifier(serverName, authStorageOptions)
410
+ await clearOAuthState(serverName, authStorageOptions)
411
+ } else {
412
+ const redirectUris = storedAuth.clientInfo.redirectUris
413
+ if (!Array.isArray(redirectUris) || !redirectUris.includes(authProvider.redirectUrl ?? "")) {
414
+ clearClientInfo(serverName, authStorageOptions)
415
+ clearTokens(serverName, authStorageOptions)
416
+ clearCodeVerifier(serverName, authStorageOptions)
417
+ await clearOAuthState(serverName, authStorageOptions)
418
+ }
419
+ }
420
+ }
421
+
422
+ throwIfAborted(signal)
423
+
424
+ const discovery = applyOAuthConfig(await probeAuthDiscovery(serverUrl, definition, signal), config)
425
+ throwIfAborted(signal)
426
+ const result = await abortable(runSdkAuth(authProvider, { serverUrl, ...discovery }), signal)
427
+ throwIfAborted(signal)
428
+ if (result === "AUTHORIZED") {
429
+ authProvider.deactivate()
430
+ releaseCallbackServer(oauthState)
431
+ await clearOAuthState(serverName, authStorageOptions)
432
+ return { authorizationUrl: "" }
433
+ }
434
+ if (!capturedUrl) {
435
+ throw new UnauthorizedError("OAuth authorization URL was not provided")
436
+ }
437
+ await setPendingAuth(runtime, serverName, { serverName, authProvider, serverUrl, authorizationUrl: capturedUrl.toString(), discovery, authStorageOptions }, oauthState, signal, generation)
438
+ return { authorizationUrl: capturedUrl.toString() }
439
+ } catch (error) {
440
+ authProvider.deactivate()
441
+ try {
442
+ await clearPendingAuth(runtime, serverName, oauthState, authStorageOptions)
443
+ } catch (cleanupError) {
444
+ throw new AggregateError([error, cleanupError], "OAuth startup cleanup failed")
445
+ }
446
+ throw error
447
+ }
448
+ }
449
+
450
+ async function setPendingAuth(
451
+ runtime: McpOAuthRuntime,
452
+ serverName: string,
453
+ pendingAuth: PendingAuth,
454
+ oauthState: string,
455
+ signal?: AbortSignal,
456
+ generation = getRuntimeState(runtime).generation,
457
+ ): Promise<void> {
458
+ const state = getRuntimeState(runtime)
459
+ const key = getPendingAuthKey(serverName, pendingAuth.authStorageOptions)
460
+ await clearPendingAuth(runtime, serverName, undefined, pendingAuth.authStorageOptions)
461
+ throwIfAborted(signal)
462
+ if (generation !== state.generation) throw new Error("OAuth runtime stopped")
463
+ state.pendingAuths.set(key, pendingAuth)
464
+ state.pendingAuthStates.set(key, oauthState)
465
+ const cleanupTimer = setTimeout(() => {
466
+ void clearPendingAuth(runtime, serverName, oauthState, pendingAuth.authStorageOptions).catch(error => {
467
+ console.error(`MCP Auth: Timed-out flow cleanup failed: ${formatTerminalError(error)}`)
468
+ })
469
+ }, MANUAL_AUTH_TIMEOUT_MS)
470
+ cleanupTimer.unref?.()
471
+ state.pendingAuthCleanupTimers.set(key, cleanupTimer)
472
+ }
473
+
474
+ async function clearPendingAuth(runtime: McpOAuthRuntime, serverName: string, oauthState?: string, fallbackStorageOptions: AuthStorageOptions = {}): Promise<void> {
475
+ const state = getRuntimeState(runtime)
476
+ const key = getPendingAuthKey(serverName, fallbackStorageOptions)
477
+ const pendingAuth = state.pendingAuths.get(key)
478
+ const authStorageOptions = pendingAuth?.authStorageOptions ?? fallbackStorageOptions
479
+ const pendingState = state.pendingAuthStates.get(key)
480
+ if (oauthState && pendingState && pendingState !== oauthState) return
481
+
482
+ const timer = state.pendingAuthCleanupTimers.get(key)
483
+ if (timer) {
484
+ clearTimeout(timer)
485
+ state.pendingAuthCleanupTimers.delete(key)
486
+ }
487
+
488
+ pendingAuth?.authProvider.deactivate()
489
+ state.pendingAuths.delete(key)
490
+ state.pendingAuthStates.delete(key)
491
+ const stateToRelease = pendingState ?? oauthState
492
+ if (stateToRelease) {
493
+ cancelPendingCallback(stateToRelease)
494
+ const storedState = await getOAuthState(serverName, authStorageOptions)
495
+ if (storedState === stateToRelease) {
496
+ await clearOAuthState(serverName, authStorageOptions)
497
+ }
498
+ }
499
+ }
500
+
501
+ function getSearchParamsFromInput(input: string): URLSearchParams | undefined {
502
+ try {
503
+ const url = new URL(input)
504
+ const params = new URLSearchParams(url.search)
505
+ if (url.hash) {
506
+ const hash = url.hash.startsWith("#") ? url.hash.slice(1) : url.hash
507
+ const hashParams = new URLSearchParams(hash)
508
+ for (const [key, value] of hashParams) {
509
+ if (!params.has(key)) params.set(key, value)
510
+ }
511
+ }
512
+ return params
513
+ } catch {
514
+ const query = input.includes("?") ? input.slice(input.indexOf("?") + 1) : input
515
+ const params = new URLSearchParams(query.startsWith("#") ? query.slice(1) : query)
516
+ return params.has("code") || params.has("state") || params.has("error") ? params : undefined
517
+ }
518
+ }
519
+
520
+ /** Authorization code plus the optional RFC 9207 `iss` callback parameter. */
521
+ export interface AuthorizationCodeInput {
522
+ code: string
523
+ iss?: string
524
+ }
525
+
526
+ /**
527
+ * Extract an OAuth authorization code (and the RFC 9207 `iss` parameter, when
528
+ * present) from either a raw code, a query string, or the full localhost
529
+ * redirect URL copied from the browser address bar.
530
+ */
531
+ export function parseAuthorizationRedirectInput(input: string, expectedState?: string): AuthorizationCodeInput {
532
+ const trimmed = input.trim()
533
+ if (!trimmed) {
534
+ throw new Error("Authorization code or redirect URL is required")
535
+ }
536
+
537
+ const params = getSearchParamsFromInput(trimmed)
538
+ if (params) {
539
+ const error = params.get("error")
540
+ if (error) {
541
+ const description = params.get("error_description")
542
+ throw new Error(description ? `${error}: ${description}` : error)
543
+ }
544
+
545
+ const state = params.get("state")
546
+ if (expectedState && !state) {
547
+ throw new Error("OAuth state missing from redirect URL")
548
+ }
549
+ if (expectedState && state !== expectedState) {
550
+ throw new Error("OAuth state mismatch - potential CSRF attack")
551
+ }
552
+
553
+ const code = params.get("code")
554
+ if (code) {
555
+ const iss = params.get("iss")
556
+ return { code, ...(iss !== null ? { iss } : {}) }
557
+ }
558
+ }
559
+
560
+ if (/^[A-Za-z0-9._~+/=-]+$/.test(trimmed)) {
561
+ return { code: trimmed }
562
+ }
563
+
564
+ throw new Error("Could not find an OAuth authorization code in the provided input")
565
+ }
566
+
567
+ /**
568
+ * Extract an OAuth authorization code from either a raw code, a query string,
569
+ * or the full localhost redirect URL copied from the browser address bar.
570
+ */
571
+ export function parseAuthorizationCodeInput(input: string, expectedState?: string): string {
572
+ return parseAuthorizationRedirectInput(input, expectedState).code
573
+ }
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
+
622
+ /**
623
+ * Complete OAuth authentication from manual user input.
624
+ */
625
+ export async function completeAuthFromInput(
626
+ serverName: string,
627
+ input: string,
628
+ options: AuthenticateOptions = {},
629
+ ): Promise<AuthStatus> {
630
+ const runtime = getRuntime(options)
631
+ const runtimeState = getRuntimeState(runtime)
632
+ const fallbackAuthStorageOptions = options.authStorageOptions ?? {}
633
+ const signal = combineAbortSignals(runtime.signal, options.signal)
634
+ throwIfAborted(signal)
635
+ const key = getPendingAuthKey(serverName, fallbackAuthStorageOptions)
636
+ const oauthState = runtimeState.pendingAuthStates.get(key)
637
+ throwIfAborted(signal)
638
+ const parsed = parseAuthorizationRedirectInput(input, oauthState)
639
+ return completeAuth(serverName, parsed, options)
640
+ }
641
+
642
+ /**
643
+ * Complete OAuth authentication with the authorization code.
644
+ */
645
+ export async function completeAuth(
646
+ serverName: string,
647
+ authorizationCode: string | AuthorizationCodeInput,
648
+ options: AuthenticateOptions = {},
649
+ ): Promise<AuthStatus> {
650
+ const runtime = getRuntime(options)
651
+ const runtimeState = getRuntimeState(runtime)
652
+ const { code, iss } = typeof authorizationCode === "string"
653
+ ? { code: authorizationCode, iss: undefined }
654
+ : authorizationCode
655
+ const fallbackAuthStorageOptions = options.authStorageOptions ?? {}
656
+ const signal = combineAbortSignals(runtime.signal, options.signal)
657
+ throwIfAborted(signal)
658
+ const key = getPendingAuthKey(serverName, fallbackAuthStorageOptions)
659
+ const pendingAuth = runtimeState.pendingAuths.get(key)
660
+ const authStorageOptions = pendingAuth?.authStorageOptions ?? fallbackAuthStorageOptions
661
+ if (!pendingAuth) {
662
+ throw new Error(`No pending OAuth flow for server: ${serverName}`)
663
+ }
664
+
665
+ const oauthState = runtimeState.pendingAuthStates.get(key)
666
+ throwIfAborted(signal)
667
+
668
+ let keepPendingForRetry = false
669
+ let caughtError: unknown
670
+ try {
671
+ const discoveryState = await pendingAuth.authProvider.discoveryState()
672
+ const metadata = discoveryState?.authorizationServerMetadata
673
+ const expectedIssuer = metadata?.issuer ?? discoveryState?.authorizationServerUrl
674
+ const requiresIssuer = (metadata as { authorization_response_iss_parameter_supported?: unknown } | undefined)
675
+ ?.authorization_response_iss_parameter_supported === true
676
+ if (expectedIssuer !== undefined && iss === undefined && requiresIssuer) {
677
+ keepPendingForRetry = true
678
+ throw new Error(
679
+ `The authorization server for ${serverName} requires the RFC 9207 "iss" parameter. ` +
680
+ "Paste the full redirect URL from the browser address bar (not just the authorization code).",
681
+ )
682
+ }
683
+ if (expectedIssuer !== undefined && iss !== undefined && iss !== expectedIssuer) {
684
+ throw new Error(`The OAuth authorization response issuer does not match the discovered issuer for ${serverName}.`)
685
+ }
686
+
687
+ const result = await abortable(runSdkAuth(pendingAuth.authProvider, {
688
+ serverUrl: pendingAuth.serverUrl,
689
+ authorizationCode: code,
690
+ ...(iss !== undefined ? { iss } : {}),
691
+ ...pendingAuth.discovery,
692
+ }), signal)
693
+ throwIfAborted(signal)
694
+ if (result !== "AUTHORIZED") {
695
+ throw new UnauthorizedError("Failed to authorize")
696
+ }
697
+ return "authenticated"
698
+ } catch (error) {
699
+ caughtError = error
700
+ throw error
701
+ } finally {
702
+ if (!keepPendingForRetry) {
703
+ try {
704
+ await clearPendingAuth(runtime, serverName, oauthState, authStorageOptions)
705
+ } catch (cleanupError) {
706
+ if (caughtError !== undefined) {
707
+ throw new AggregateError([caughtError, cleanupError], "OAuth completion cleanup failed")
708
+ }
709
+ throw cleanupError
710
+ }
711
+ }
712
+ }
713
+ }
714
+
715
+ /**
716
+ * Perform the complete OAuth authentication flow for a server.
717
+ *
718
+ * @param serverName - The name of the MCP server
719
+ * @param serverUrl - The URL of the MCP server
720
+ * @param definition - The server definition (optional)
721
+ * @returns The final auth status
722
+ */
723
+ export async function authenticate(
724
+ serverName: string,
725
+ serverUrl: string,
726
+ definition?: ServerEntry,
727
+ options: AuthenticateOptions = {},
728
+ ): Promise<AuthStatus> {
729
+ if (isServerDisabled(definition)) throw new Error(`MCP server "${serverName}" is disabled`)
730
+ const runtime = getRuntime(options)
731
+ const runtimeState = getRuntimeState(runtime)
732
+ const authStorageOptions = options.authStorageOptions ?? {}
733
+ const signal = combineAbortSignals(runtime.signal, options.signal)
734
+ throwIfAborted(signal)
735
+ const authKey = `${serverName}|${serverUrl}|${getAuthBaseDir(authStorageOptions)}`
736
+ const inFlight = runtimeState.pendingAuthentications.get(authKey)
737
+ if (inFlight) {
738
+ return inFlight
739
+ }
740
+
741
+ const operation = (async (): Promise<AuthStatus> => {
742
+ const { authorizationUrl } = await startAuth(serverName, serverUrl, definition, {
743
+ ...options,
744
+ ...(signal ? { signal } : {}),
745
+ runtime,
746
+ })
747
+
748
+ if (!authorizationUrl) {
749
+ return "authenticated"
750
+ }
751
+
752
+ let oauthState: string | undefined
753
+ try {
754
+ // Get the state that was already generated and stored in startAuth().
755
+ // Keep this lookup and its abort check inside the cleanup boundary because
756
+ // startAuth has already reserved callback state at this point.
757
+ oauthState = runtimeState.pendingAuthStates.get(getPendingAuthKey(serverName, authStorageOptions))
758
+ throwIfAborted(signal)
759
+ if (!oauthState) {
760
+ throw new Error("OAuth state not found - this should not happen")
761
+ }
762
+
763
+ // Register the callback BEFORE opening the browser.
764
+ const callbackPromise = waitForCallback(oauthState)
765
+ void callbackPromise.catch(() => {})
766
+
767
+ // Open browser. Always surface the URL first so remote/headless users can copy it
768
+ // even when the OS browser handoff is unavailable or invisible.
769
+ if (options.onAuthorizationUrl) {
770
+ await abortable(Promise.resolve(options.onAuthorizationUrl(authorizationUrl)), signal)
771
+ } else {
772
+ console.log(`MCP Auth: Open this URL to authenticate ${serverName}:\n${authorizationUrl}`)
773
+ }
774
+ try {
775
+ await abortable(open(authorizationUrl), signal)
776
+ } catch (error) {
777
+ if (isAbortError(error, signal)) throw error
778
+ console.warn(`MCP Auth: Failed to open browser for ${serverName}; waiting for manual callback`, { error })
779
+ }
780
+
781
+ const authorizationResponse = await waitForAuthorizationResponse(
782
+ callbackPromise,
783
+ authorizationUrl,
784
+ oauthState,
785
+ options.onAuthorizationInput,
786
+ signal,
787
+ )
788
+ if (authorizationResponse.source === "manual") {
789
+ cancelPendingCallback(oauthState)
790
+ }
791
+
792
+ // The callback server accepted only the flow-local reserved state. Manual
793
+ // input is checked against the same state before token exchange.
794
+ throwIfAborted(signal)
795
+
796
+ return await completeAuth(serverName, authorizationResponse.input, {
797
+ ...options,
798
+ ...(signal ? { signal } : {}),
799
+ runtime,
800
+ })
801
+ } catch (error) {
802
+ if (oauthState) cancelPendingCallback(oauthState)
803
+ try {
804
+ await clearPendingAuth(runtime, serverName, oauthState, authStorageOptions)
805
+ } catch (cleanupError) {
806
+ throw new AggregateError([error, cleanupError], "OAuth cancellation cleanup failed")
807
+ }
808
+ throw error
809
+ }
810
+ })()
811
+
812
+ runtimeState.pendingAuthentications.set(authKey, operation)
813
+
814
+ try {
815
+ return await operation
816
+ } finally {
817
+ if (runtimeState.pendingAuthentications.get(authKey) === operation) {
818
+ runtimeState.pendingAuthentications.delete(authKey)
819
+ }
820
+ }
821
+ }
822
+
823
+ /**
824
+ * Get a valid access token for a server, refreshing if necessary.
825
+ *
826
+ * @param serverName - The name of the MCP server
827
+ * @param serverUrl - The URL of the MCP server
828
+ * @returns The valid tokens or null if not authenticated
829
+ */
830
+ export async function getValidToken(
831
+ serverName: string,
832
+ serverUrl: string,
833
+ options: AuthenticateOptions = {},
834
+ ): Promise<StoredTokens | null> {
835
+ const runtime = getRuntime(options)
836
+ const authStorageOptions = options.authStorageOptions ?? {}
837
+ const signal = combineAbortSignals(runtime.signal, options.signal)
838
+ throwIfAborted(signal)
839
+ const entry = await getAuthForUrl(serverName, serverUrl, authStorageOptions)
840
+ throwIfAborted(signal)
841
+ if (!entry?.tokens) {
842
+ return null
843
+ }
844
+
845
+ const expired = await isTokenExpired(serverName, authStorageOptions)
846
+ if (expired === false) {
847
+ return entry.tokens
848
+ }
849
+
850
+ if (expired === true && entry.tokens.refreshToken) {
851
+ console.log(`MCP Auth: Token expired for ${serverName}, attempting refresh`)
852
+
853
+ try {
854
+ const authProvider = new McpOAuthProvider(serverName, serverUrl, {}, {
855
+ onRedirect: async () => {},
856
+ }, authStorageOptions, runtime.signal)
857
+
858
+ try {
859
+ const clientInfo = await authProvider.clientInformation()
860
+ throwIfAborted(signal)
861
+ if (!clientInfo) {
862
+ console.log(`MCP Auth: No client info for refresh for ${serverName}`)
863
+ return null
864
+ }
865
+
866
+ const discovery = await probeAuthDiscovery(serverUrl, undefined, signal)
867
+ throwIfAborted(signal)
868
+ const result = await abortable(runSdkAuth(authProvider, {
869
+ serverUrl,
870
+ ...discovery,
871
+ ...(options.skipIssuerMetadataValidation === true ? { skipIssuerMetadataValidation: true } : {}),
872
+ }), signal)
873
+ throwIfAborted(signal)
874
+ if (result !== "AUTHORIZED") {
875
+ return null
876
+ }
877
+ const refreshed = await getAuthForUrl(serverName, serverUrl, authStorageOptions)
878
+ throwIfAborted(signal)
879
+ return refreshed?.tokens ?? null
880
+ } finally {
881
+ authProvider.deactivate()
882
+ }
883
+ } catch (error) {
884
+ if (isAbortError(error, signal) || error instanceof OAuthCredentialStoreError) throw error
885
+ console.error(`MCP Auth: Token refresh failed for ${serverName}`, { error })
886
+ return null
887
+ }
888
+ }
889
+
890
+ // No expiration info or no refresh token, assume valid
891
+ return entry.tokens
892
+ }
893
+
894
+ /**
895
+ * Check the authentication status for a server.
896
+ *
897
+ * @param serverName - The name of the MCP server
898
+ * @returns The current auth status
899
+ */
900
+ export async function getAuthStatus(serverName: string, options: AuthenticateOptions = {}): Promise<AuthStatus> {
901
+ getRuntime(options)
902
+ const authStorageOptions = options.authStorageOptions ?? {}
903
+ const hasTokens = await hasStoredTokens(serverName, authStorageOptions)
904
+ if (!hasTokens) return "not_authenticated"
905
+
906
+ const expired = await isTokenExpired(serverName, authStorageOptions)
907
+ return expired ? "expired" : "authenticated"
908
+ }
909
+
910
+ /**
911
+ * Remove all OAuth credentials for a server.
912
+ *
913
+ * @param serverName - The name of the MCP server
914
+ */
915
+ export async function removeAuth(serverName: string, options: AuthenticateOptions = {}): Promise<void> {
916
+ const runtime = getRuntime(options)
917
+ const signal = combineAbortSignals(runtime.signal, options.signal)
918
+ throwIfAborted(signal)
919
+ const authStorageOptions = options.authStorageOptions ?? {}
920
+ const oauthState = await getOAuthState(serverName, authStorageOptions)
921
+ throwIfAborted(signal)
922
+ if (oauthState) {
923
+ cancelPendingCallback(oauthState)
924
+ }
925
+ await clearPendingAuth(runtime, serverName, oauthState, authStorageOptions)
926
+ throwIfAborted(signal)
927
+ clearAllCredentials(serverName, authStorageOptions)
928
+ await clearOAuthState(serverName, authStorageOptions)
929
+ throwIfAborted(signal)
930
+ console.log(`MCP Auth: Removed credentials for ${serverName}`)
931
+ }
932
+
933
+ /**
934
+ * Check if OAuth is supported for a server configuration.
935
+ * OAuth is supported for HTTP servers unless explicitly disabled.
936
+ *
937
+ * @param definition - The server definition
938
+ * @returns True if OAuth is supported
939
+ */
940
+ export function supportsOAuth(definition: ServerEntry): boolean {
941
+ // OAuth requires a URL
942
+ if (!definition.url) return false
943
+
944
+ // Explicitly disabled via auth: false or oauth: false
945
+ if (definition.auth === false) return false
946
+ if (definition.oauth === false) return false
947
+ if (definition.auth === "oauth") return true
948
+
949
+ // Configured custom headers take precedence over implicit OAuth auto-detection.
950
+ if (definition.headers && Object.keys(definition.headers).length > 0) return false
951
+
952
+ // OAuth is enabled when auth is not specified (auto-detect)
953
+ return definition.auth === undefined
954
+ }
955
+
956
+ /**
957
+ * Initialize the OAuth system on startup.
958
+ * OAuth callback binding is lazy and starts from startAuth() only.
959
+ */
960
+ export async function initializeOAuth(
961
+ runtimeOrSignal?: McpOAuthRuntime | AbortSignal,
962
+ ): Promise<McpOAuthRuntime> {
963
+ if (runtimeOrSignal && "signal" in runtimeOrSignal) {
964
+ runtimeOrSignal.signal.throwIfAborted()
965
+ activeRuntimes.add(runtimeOrSignal)
966
+ return runtimeOrSignal
967
+ }
968
+
969
+ await shutdownOAuth(legacyRuntime)
970
+ legacyRuntime = createOAuthRuntime(runtimeOrSignal as AbortSignal | undefined)
971
+ return legacyRuntime
972
+ }
973
+
974
+ /**
975
+ * Shutdown one OAuth runtime. The callback server remains process-shared while
976
+ * another runtime has pending/reserved callback state or is still active.
977
+ */
978
+ export async function shutdownOAuth(runtime: McpOAuthRuntime = legacyRuntime): Promise<void> {
979
+ const state = getRuntimeState(runtime)
980
+ if (state.controller.signal.aborted) return
981
+ state.generation += 1
982
+ state.controller.abort(new Error("OAuth runtime stopped"))
983
+ for (const callbackState of Array.from(state.pendingAuthStates.values())) cancelPendingCallback(callbackState)
984
+ for (const pendingAuth of Array.from(state.pendingAuths.values())) {
985
+ await clearPendingAuth(runtime, pendingAuth.serverName, undefined, pendingAuth.authStorageOptions)
986
+ }
987
+ state.pendingAuthentications.clear()
988
+ activeRuntimes.delete(runtime)
989
+
990
+ if (activeRuntimes.size === 0) {
991
+ await stopCallbackServer()
992
+ }
993
+ }