@akon-labs/nexus-cli 0.1.9 → 0.1.11-rc.2

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 (369) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/LICENSE +1 -0
  3. package/README.md +3 -2
  4. package/dist/app-bridge.bundle.js +67 -0
  5. package/dist/cli/require-login.d.ts.map +1 -1
  6. package/dist/cli/require-login.js +2 -2
  7. package/dist/cli/require-login.js.map +1 -1
  8. package/dist/cli.js +20866 -1882
  9. package/dist/core/agent-session.d.ts +3 -1
  10. package/dist/core/agent-session.d.ts.map +1 -1
  11. package/dist/core/agent-session.js +5 -1
  12. package/dist/core/agent-session.js.map +1 -1
  13. package/dist/core/auto-model.d.ts +1 -1
  14. package/dist/core/auto-model.d.ts.map +1 -1
  15. package/dist/core/auto-model.js +1 -1
  16. package/dist/core/auto-model.js.map +1 -1
  17. package/dist/core/extensions/index.d.ts +1 -1
  18. package/dist/core/extensions/index.d.ts.map +1 -1
  19. package/dist/core/extensions/index.js.map +1 -1
  20. package/dist/core/extensions/loader.d.ts.map +1 -1
  21. package/dist/core/extensions/loader.js +6 -0
  22. package/dist/core/extensions/loader.js.map +1 -1
  23. package/dist/core/extensions/runner.d.ts +7 -1
  24. package/dist/core/extensions/runner.d.ts.map +1 -1
  25. package/dist/core/extensions/runner.js +14 -0
  26. package/dist/core/extensions/runner.js.map +1 -1
  27. package/dist/core/extensions/types.d.ts +18 -0
  28. package/dist/core/extensions/types.d.ts.map +1 -1
  29. package/dist/core/extensions/types.js.map +1 -1
  30. package/dist/core/model-resolver.d.ts +2 -2
  31. package/dist/core/model-resolver.d.ts.map +1 -1
  32. package/dist/core/model-resolver.js +3 -3
  33. package/dist/core/model-resolver.js.map +1 -1
  34. package/dist/core/package-manager.d.ts +15 -0
  35. package/dist/core/package-manager.d.ts.map +1 -1
  36. package/dist/core/package-manager.js +50 -0
  37. package/dist/core/package-manager.js.map +1 -1
  38. package/dist/core/sdk.d.ts.map +1 -1
  39. package/dist/core/sdk.js +1 -1
  40. package/dist/core/sdk.js.map +1 -1
  41. package/dist/core/slash-commands.d.ts.map +1 -1
  42. package/dist/core/slash-commands.js +3 -3
  43. package/dist/core/slash-commands.js.map +1 -1
  44. package/dist/core/system-prompt.d.ts.map +1 -1
  45. package/dist/core/system-prompt.js +1 -1
  46. package/dist/core/system-prompt.js.map +1 -1
  47. package/dist/core/tools/find.d.ts.map +1 -1
  48. package/dist/core/tools/find.js +1 -1
  49. package/dist/core/tools/find.js.map +1 -1
  50. package/dist/core/tools/grep.d.ts.map +1 -1
  51. package/dist/core/tools/grep.js +1 -1
  52. package/dist/core/tools/grep.js.map +1 -1
  53. package/dist/core/tools/index.d.ts +1 -1
  54. package/dist/core/tools/index.d.ts.map +1 -1
  55. package/dist/core/tools/index.js +5 -5
  56. package/dist/core/tools/index.js.map +1 -1
  57. package/dist/core/tools/websearch.d.ts.map +1 -1
  58. package/dist/core/tools/websearch.js +3 -3
  59. package/dist/core/tools/websearch.js.map +1 -1
  60. package/dist/extensions/gitnexus/config.d.ts +15 -1
  61. package/dist/extensions/gitnexus/config.d.ts.map +1 -1
  62. package/dist/extensions/gitnexus/config.js +86 -2
  63. package/dist/extensions/gitnexus/config.js.map +1 -1
  64. package/dist/extensions/gitnexus/gateway.d.ts +6 -6
  65. package/dist/extensions/gitnexus/gateway.d.ts.map +1 -1
  66. package/dist/extensions/gitnexus/gateway.js +4 -4
  67. package/dist/extensions/gitnexus/gateway.js.map +1 -1
  68. package/dist/extensions/gitnexus/index.d.ts.map +1 -1
  69. package/dist/extensions/gitnexus/index.js +6 -4
  70. package/dist/extensions/gitnexus/index.js.map +1 -1
  71. package/dist/extensions/gitnexus/observatory.d.ts.map +1 -1
  72. package/dist/extensions/gitnexus/observatory.js +2 -2
  73. package/dist/extensions/gitnexus/observatory.js.map +1 -1
  74. package/dist/extensions/index.d.ts.map +1 -1
  75. package/dist/extensions/index.js +3 -0
  76. package/dist/extensions/index.js.map +1 -1
  77. package/dist/extensions/mcp/abort.d.ts +3 -0
  78. package/dist/extensions/mcp/abort.d.ts.map +1 -0
  79. package/dist/extensions/mcp/abort.js +41 -0
  80. package/dist/extensions/mcp/abort.js.map +1 -0
  81. package/dist/extensions/mcp/agent-dir.d.ts +6 -0
  82. package/dist/extensions/mcp/agent-dir.d.ts.map +1 -0
  83. package/dist/extensions/mcp/agent-dir.js +18 -0
  84. package/dist/extensions/mcp/agent-dir.js.map +1 -0
  85. package/dist/extensions/mcp/agent-plugin-loader.d.ts +9 -0
  86. package/dist/extensions/mcp/agent-plugin-loader.d.ts.map +1 -0
  87. package/dist/extensions/mcp/agent-plugin-loader.js +384 -0
  88. package/dist/extensions/mcp/agent-plugin-loader.js.map +1 -0
  89. package/dist/extensions/mcp/app-bridge.bundle.js +67 -0
  90. package/dist/extensions/mcp/commands.d.ts +47 -0
  91. package/dist/extensions/mcp/commands.d.ts.map +1 -0
  92. package/dist/extensions/mcp/commands.js +821 -0
  93. package/dist/extensions/mcp/commands.js.map +1 -0
  94. package/dist/extensions/mcp/config.d.ts +123 -38
  95. package/dist/extensions/mcp/config.d.ts.map +1 -1
  96. package/dist/extensions/mcp/config.js +1035 -70
  97. package/dist/extensions/mcp/config.js.map +1 -1
  98. package/dist/extensions/mcp/consent-manager.d.ts +14 -0
  99. package/dist/extensions/mcp/consent-manager.d.ts.map +1 -0
  100. package/dist/extensions/mcp/consent-manager.js +60 -0
  101. package/dist/extensions/mcp/consent-manager.js.map +1 -0
  102. package/dist/extensions/mcp/direct-tools.d.ts +11 -0
  103. package/dist/extensions/mcp/direct-tools.d.ts.map +1 -0
  104. package/dist/extensions/mcp/direct-tools.js +562 -0
  105. package/dist/extensions/mcp/direct-tools.js.map +1 -0
  106. package/dist/extensions/mcp/elicitation-handler.d.ts +18 -0
  107. package/dist/extensions/mcp/elicitation-handler.d.ts.map +1 -0
  108. package/dist/extensions/mcp/elicitation-handler.js +320 -0
  109. package/dist/extensions/mcp/elicitation-handler.js.map +1 -0
  110. package/dist/extensions/mcp/error-signal.d.ts +16 -0
  111. package/dist/extensions/mcp/error-signal.d.ts.map +1 -0
  112. package/dist/extensions/mcp/error-signal.js +22 -0
  113. package/dist/extensions/mcp/error-signal.js.map +1 -0
  114. package/dist/extensions/mcp/errors.d.ts +104 -0
  115. package/dist/extensions/mcp/errors.d.ts.map +1 -0
  116. package/dist/extensions/mcp/errors.js +171 -0
  117. package/dist/extensions/mcp/errors.js.map +1 -0
  118. package/dist/extensions/mcp/glimpse-ui.d.ts +10 -0
  119. package/dist/extensions/mcp/glimpse-ui.d.ts.map +1 -0
  120. package/dist/extensions/mcp/glimpse-ui.js +67 -0
  121. package/dist/extensions/mcp/glimpse-ui.js.map +1 -0
  122. package/dist/extensions/mcp/host-html-template.d.ts +17 -0
  123. package/dist/extensions/mcp/host-html-template.d.ts.map +1 -0
  124. package/dist/extensions/mcp/host-html-template.js +442 -0
  125. package/dist/extensions/mcp/host-html-template.js.map +1 -0
  126. package/dist/extensions/mcp/index.d.ts +20 -15
  127. package/dist/extensions/mcp/index.d.ts.map +1 -1
  128. package/dist/extensions/mcp/index.js +1113 -82
  129. package/dist/extensions/mcp/index.js.map +1 -1
  130. package/dist/extensions/mcp/init.d.ts +28 -0
  131. package/dist/extensions/mcp/init.d.ts.map +1 -0
  132. package/dist/extensions/mcp/init.js +631 -0
  133. package/dist/extensions/mcp/init.js.map +1 -0
  134. package/dist/extensions/mcp/json-schema-validator.d.ts +3 -0
  135. package/dist/extensions/mcp/json-schema-validator.d.ts.map +1 -0
  136. package/dist/extensions/mcp/json-schema-validator.js +53 -0
  137. package/dist/extensions/mcp/json-schema-validator.js.map +1 -0
  138. package/dist/extensions/mcp/lifecycle.d.ts +56 -0
  139. package/dist/extensions/mcp/lifecycle.d.ts.map +1 -0
  140. package/dist/extensions/mcp/lifecycle.js +395 -0
  141. package/dist/extensions/mcp/lifecycle.js.map +1 -0
  142. package/dist/extensions/mcp/logger.d.ts +52 -0
  143. package/dist/extensions/mcp/logger.d.ts.map +1 -0
  144. package/dist/extensions/mcp/logger.js +134 -0
  145. package/dist/extensions/mcp/logger.js.map +1 -0
  146. package/dist/extensions/mcp/mcp-auth-flow.d.ts +117 -0
  147. package/dist/extensions/mcp/mcp-auth-flow.d.ts.map +1 -0
  148. package/dist/extensions/mcp/mcp-auth-flow.js +869 -0
  149. package/dist/extensions/mcp/mcp-auth-flow.js.map +1 -0
  150. package/dist/extensions/mcp/mcp-auth.d.ts +162 -0
  151. package/dist/extensions/mcp/mcp-auth.d.ts.map +1 -0
  152. package/dist/extensions/mcp/mcp-auth.js +897 -0
  153. package/dist/extensions/mcp/mcp-auth.js.map +1 -0
  154. package/dist/extensions/mcp/mcp-bearer-store.d.ts +25 -0
  155. package/dist/extensions/mcp/mcp-bearer-store.d.ts.map +1 -0
  156. package/dist/extensions/mcp/mcp-bearer-store.js +350 -0
  157. package/dist/extensions/mcp/mcp-bearer-store.js.map +1 -0
  158. package/dist/extensions/mcp/mcp-callback-server.d.ts +54 -0
  159. package/dist/extensions/mcp/mcp-callback-server.d.ts.map +1 -0
  160. package/dist/extensions/mcp/mcp-callback-server.js +454 -0
  161. package/dist/extensions/mcp/mcp-callback-server.js.map +1 -0
  162. package/dist/extensions/mcp/mcp-code.d.ts +48 -0
  163. package/dist/extensions/mcp/mcp-code.d.ts.map +1 -0
  164. package/dist/extensions/mcp/mcp-code.js +358 -0
  165. package/dist/extensions/mcp/mcp-code.js.map +1 -0
  166. package/dist/extensions/mcp/mcp-keyring-helper.cjs +89 -0
  167. package/dist/extensions/mcp/mcp-oauth-provider.d.ts +135 -0
  168. package/dist/extensions/mcp/mcp-oauth-provider.d.ts.map +1 -0
  169. package/dist/extensions/mcp/mcp-oauth-provider.js +491 -0
  170. package/dist/extensions/mcp/mcp-oauth-provider.js.map +1 -0
  171. package/dist/extensions/mcp/mcp-output-guard.d.ts +59 -0
  172. package/dist/extensions/mcp/mcp-output-guard.d.ts.map +1 -0
  173. package/dist/extensions/mcp/mcp-output-guard.js +343 -0
  174. package/dist/extensions/mcp/mcp-output-guard.js.map +1 -0
  175. package/dist/extensions/mcp/mcp-panel.d.ts +71 -0
  176. package/dist/extensions/mcp/mcp-panel.d.ts.map +1 -0
  177. package/dist/extensions/mcp/mcp-panel.js +973 -0
  178. package/dist/extensions/mcp/mcp-panel.js.map +1 -0
  179. package/dist/extensions/mcp/mcp-probe.d.ts +7 -0
  180. package/dist/extensions/mcp/mcp-probe.d.ts.map +1 -0
  181. package/dist/extensions/mcp/mcp-probe.js +155 -0
  182. package/dist/extensions/mcp/mcp-probe.js.map +1 -0
  183. package/dist/extensions/mcp/mcp-script-worker.mjs +130 -0
  184. package/dist/extensions/mcp/mcp-setup-panel.d.ts +146 -0
  185. package/dist/extensions/mcp/mcp-setup-panel.d.ts.map +1 -0
  186. package/dist/extensions/mcp/mcp-setup-panel.js +1104 -0
  187. package/dist/extensions/mcp/mcp-setup-panel.js.map +1 -0
  188. package/dist/extensions/mcp/mcp-status.d.ts +12 -0
  189. package/dist/extensions/mcp/mcp-status.d.ts.map +1 -0
  190. package/dist/extensions/mcp/mcp-status.js +98 -0
  191. package/dist/extensions/mcp/mcp-status.js.map +1 -0
  192. package/dist/extensions/mcp/mcp-trace.d.ts +95 -0
  193. package/dist/extensions/mcp/mcp-trace.d.ts.map +1 -0
  194. package/dist/extensions/mcp/mcp-trace.js +252 -0
  195. package/dist/extensions/mcp/mcp-trace.js.map +1 -0
  196. package/dist/extensions/mcp/metadata-cache.d.ts +20 -0
  197. package/dist/extensions/mcp/metadata-cache.d.ts.map +1 -0
  198. package/dist/extensions/mcp/metadata-cache.js +318 -0
  199. package/dist/extensions/mcp/metadata-cache.js.map +1 -0
  200. package/dist/extensions/mcp/npx-resolver.d.ts +7 -0
  201. package/dist/extensions/mcp/npx-resolver.d.ts.map +1 -0
  202. package/dist/extensions/mcp/npx-resolver.js +505 -0
  203. package/dist/extensions/mcp/npx-resolver.js.map +1 -0
  204. package/dist/extensions/mcp/oauth.d.ts +21 -0
  205. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  206. package/dist/extensions/mcp/oauth.js +15 -0
  207. package/dist/extensions/mcp/oauth.js.map +1 -0
  208. package/dist/extensions/mcp/onboarding-state.d.ts +13 -0
  209. package/dist/extensions/mcp/onboarding-state.d.ts.map +1 -0
  210. package/dist/extensions/mcp/onboarding-state.js +65 -0
  211. package/dist/extensions/mcp/onboarding-state.js.map +1 -0
  212. package/dist/extensions/mcp/package-mcp-loader.d.ts +3 -0
  213. package/dist/extensions/mcp/package-mcp-loader.d.ts.map +1 -0
  214. package/dist/extensions/mcp/package-mcp-loader.js +170 -0
  215. package/dist/extensions/mcp/package-mcp-loader.js.map +1 -0
  216. package/dist/extensions/mcp/panel-keys.d.ts +21 -0
  217. package/dist/extensions/mcp/panel-keys.d.ts.map +1 -0
  218. package/dist/extensions/mcp/panel-keys.js +29 -0
  219. package/dist/extensions/mcp/panel-keys.js.map +1 -0
  220. package/dist/extensions/mcp/prompts.d.ts +63 -0
  221. package/dist/extensions/mcp/prompts.d.ts.map +1 -0
  222. package/dist/extensions/mcp/prompts.js +297 -0
  223. package/dist/extensions/mcp/prompts.js.map +1 -0
  224. package/dist/extensions/mcp/proxy-modes.d.ts +15 -0
  225. package/dist/extensions/mcp/proxy-modes.d.ts.map +1 -0
  226. package/dist/extensions/mcp/proxy-modes.js +1421 -0
  227. package/dist/extensions/mcp/proxy-modes.js.map +1 -0
  228. package/dist/extensions/mcp/request-headers-command.d.ts +11 -0
  229. package/dist/extensions/mcp/request-headers-command.d.ts.map +1 -0
  230. package/dist/extensions/mcp/request-headers-command.js +334 -0
  231. package/dist/extensions/mcp/request-headers-command.js.map +1 -0
  232. package/dist/extensions/mcp/resource-tools.d.ts +2 -0
  233. package/dist/extensions/mcp/resource-tools.d.ts.map +1 -0
  234. package/dist/extensions/mcp/resource-tools.js +15 -0
  235. package/dist/extensions/mcp/resource-tools.js.map +1 -0
  236. package/dist/extensions/mcp/runtime-owner.d.ts +14 -0
  237. package/dist/extensions/mcp/runtime-owner.d.ts.map +1 -0
  238. package/dist/extensions/mcp/runtime-owner.js +84 -0
  239. package/dist/extensions/mcp/runtime-owner.js.map +1 -0
  240. package/dist/extensions/mcp/sampling-handler.d.ts +18 -0
  241. package/dist/extensions/mcp/sampling-handler.d.ts.map +1 -0
  242. package/dist/extensions/mcp/sampling-handler.js +229 -0
  243. package/dist/extensions/mcp/sampling-handler.js.map +1 -0
  244. package/dist/extensions/mcp/search-ranking.d.ts +25 -0
  245. package/dist/extensions/mcp/search-ranking.d.ts.map +1 -0
  246. package/dist/extensions/mcp/search-ranking.js +234 -0
  247. package/dist/extensions/mcp/search-ranking.js.map +1 -0
  248. package/dist/extensions/mcp/server-manager.d.ts +116 -0
  249. package/dist/extensions/mcp/server-manager.d.ts.map +1 -0
  250. package/dist/extensions/mcp/server-manager.js +1052 -0
  251. package/dist/extensions/mcp/server-manager.js.map +1 -0
  252. package/dist/extensions/mcp/session-recovery.d.ts +27 -0
  253. package/dist/extensions/mcp/session-recovery.d.ts.map +1 -0
  254. package/dist/extensions/mcp/session-recovery.js +140 -0
  255. package/dist/extensions/mcp/session-recovery.js.map +1 -0
  256. package/dist/extensions/mcp/skills/mcp-scripting/SKILL.md +38 -0
  257. package/dist/extensions/mcp/state.d.ts +62 -0
  258. package/dist/extensions/mcp/state.d.ts.map +1 -0
  259. package/dist/extensions/mcp/state.js +2 -0
  260. package/dist/extensions/mcp/state.js.map +1 -0
  261. package/dist/extensions/mcp/tool-approval.d.ts +11 -0
  262. package/dist/extensions/mcp/tool-approval.d.ts.map +1 -0
  263. package/dist/extensions/mcp/tool-approval.js +156 -0
  264. package/dist/extensions/mcp/tool-approval.js.map +1 -0
  265. package/dist/extensions/mcp/tool-metadata.d.ts +11 -0
  266. package/dist/extensions/mcp/tool-metadata.d.ts.map +1 -0
  267. package/dist/extensions/mcp/tool-metadata.js +264 -0
  268. package/dist/extensions/mcp/tool-metadata.js.map +1 -0
  269. package/dist/extensions/mcp/tool-registrar.d.ts +21 -0
  270. package/dist/extensions/mcp/tool-registrar.d.ts.map +1 -0
  271. package/dist/extensions/mcp/tool-registrar.js +229 -0
  272. package/dist/extensions/mcp/tool-registrar.js.map +1 -0
  273. package/dist/extensions/mcp/tool-result-renderer.d.ts +83 -0
  274. package/dist/extensions/mcp/tool-result-renderer.d.ts.map +1 -0
  275. package/dist/extensions/mcp/tool-result-renderer.js +345 -0
  276. package/dist/extensions/mcp/tool-result-renderer.js.map +1 -0
  277. package/dist/extensions/mcp/ts-shape.d.ts +3 -0
  278. package/dist/extensions/mcp/ts-shape.d.ts.map +1 -0
  279. package/dist/extensions/mcp/ts-shape.js +160 -0
  280. package/dist/extensions/mcp/ts-shape.js.map +1 -0
  281. package/dist/extensions/mcp/types.d.ts +521 -0
  282. package/dist/extensions/mcp/types.d.ts.map +1 -0
  283. package/dist/extensions/mcp/types.js +294 -0
  284. package/dist/extensions/mcp/types.js.map +1 -0
  285. package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts +7 -0
  286. package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts.map +1 -0
  287. package/dist/extensions/mcp/ui-app-bridge-helpers.js +37 -0
  288. package/dist/extensions/mcp/ui-app-bridge-helpers.js.map +1 -0
  289. package/dist/extensions/mcp/ui-resource-handler.d.ts +18 -0
  290. package/dist/extensions/mcp/ui-resource-handler.d.ts.map +1 -0
  291. package/dist/extensions/mcp/ui-resource-handler.js +210 -0
  292. package/dist/extensions/mcp/ui-resource-handler.js.map +1 -0
  293. package/dist/extensions/mcp/ui-server.d.ts +52 -0
  294. package/dist/extensions/mcp/ui-server.d.ts.map +1 -0
  295. package/dist/extensions/mcp/ui-server.js +740 -0
  296. package/dist/extensions/mcp/ui-server.js.map +1 -0
  297. package/dist/extensions/mcp/ui-session.d.ts +40 -0
  298. package/dist/extensions/mcp/ui-session.d.ts.map +1 -0
  299. package/dist/extensions/mcp/ui-session.js +477 -0
  300. package/dist/extensions/mcp/ui-session.js.map +1 -0
  301. package/dist/extensions/mcp/ui-stream-types.d.ts +105 -0
  302. package/dist/extensions/mcp/ui-stream-types.d.ts.map +1 -0
  303. package/dist/extensions/mcp/ui-stream-types.js +61 -0
  304. package/dist/extensions/mcp/ui-stream-types.js.map +1 -0
  305. package/dist/extensions/mcp/ui-tool-visibility.d.ts +5 -0
  306. package/dist/extensions/mcp/ui-tool-visibility.d.ts.map +1 -0
  307. package/dist/extensions/mcp/ui-tool-visibility.js +27 -0
  308. package/dist/extensions/mcp/ui-tool-visibility.js.map +1 -0
  309. package/dist/extensions/mcp/unix-socket-transport.d.ts +15 -0
  310. package/dist/extensions/mcp/unix-socket-transport.d.ts.map +1 -0
  311. package/dist/extensions/mcp/unix-socket-transport.js +85 -0
  312. package/dist/extensions/mcp/unix-socket-transport.js.map +1 -0
  313. package/dist/extensions/mcp/utils.d.ts +32 -0
  314. package/dist/extensions/mcp/utils.d.ts.map +1 -0
  315. package/dist/extensions/mcp/utils.js +336 -0
  316. package/dist/extensions/mcp/utils.js.map +1 -0
  317. package/dist/extensions/subagent/index.d.ts +62 -1
  318. package/dist/extensions/subagent/index.d.ts.map +1 -1
  319. package/dist/extensions/subagent/index.js +195 -9
  320. package/dist/extensions/subagent/index.js.map +1 -1
  321. package/dist/extensions/subagent-render.d.ts +3 -0
  322. package/dist/extensions/subagent-render.d.ts.map +1 -0
  323. package/dist/extensions/subagent-render.js +39 -0
  324. package/dist/extensions/subagent-render.js.map +1 -0
  325. package/dist/extensions/web-access.d.ts.map +1 -1
  326. package/dist/extensions/web-access.js +1 -1
  327. package/dist/extensions/web-access.js.map +1 -1
  328. package/dist/index.d.ts +2 -0
  329. package/dist/index.d.ts.map +1 -1
  330. package/dist/index.js +20992 -2003
  331. package/dist/index.js.map +1 -1
  332. package/dist/mcp-keyring-helper.cjs +89 -0
  333. package/dist/mcp-script-worker.mjs +130 -0
  334. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  335. package/dist/modes/interactive/components/model-selector.js +1 -1
  336. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  337. package/dist/modes/interactive/components/response-separator.d.ts +1 -1
  338. package/dist/modes/interactive/components/response-separator.d.ts.map +1 -1
  339. package/dist/modes/interactive/components/response-separator.js +1 -1
  340. package/dist/modes/interactive/components/response-separator.js.map +1 -1
  341. package/dist/modes/interactive/components/tool-execution.d.ts +3 -2
  342. package/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  343. package/dist/modes/interactive/components/tool-execution.js +12 -2
  344. package/dist/modes/interactive/components/tool-execution.js.map +1 -1
  345. package/dist/modes/interactive/interactive-mode.d.ts +2 -0
  346. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  347. package/dist/modes/interactive/interactive-mode.js +14 -8
  348. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  349. package/dist/rpc-entry.js +20866 -1882
  350. package/dist/skills/mcp-scripting/SKILL.md +38 -0
  351. package/dist/utils/hidden-spawn.d.ts +29 -0
  352. package/dist/utils/hidden-spawn.d.ts.map +1 -0
  353. package/dist/utils/hidden-spawn.js +101 -0
  354. package/dist/utils/hidden-spawn.js.map +1 -0
  355. package/dist/vendor/ai.js +110 -35
  356. package/docs/mcp.md +178 -0
  357. package/docs/pi-subagents.md +75 -0
  358. package/docs/quickstart.md +1 -1
  359. package/docs/usage.md +2 -1
  360. package/examples/extensions/pi-subagents-worker-policy.ts +86 -0
  361. package/native/win32/build.mjs +95 -0
  362. package/native/win32/prebuilds/win32-x64/hidden-spawn.exe +0 -0
  363. package/native/win32/src/hidden-spawn.c +157 -0
  364. package/npm-shrinkwrap.json +728 -6
  365. package/package.json +21 -6
  366. package/dist/extensions/mcp/client.d.ts +0 -86
  367. package/dist/extensions/mcp/client.d.ts.map +0 -1
  368. package/dist/extensions/mcp/client.js +0 -275
  369. package/dist/extensions/mcp/client.js.map +0 -1
@@ -0,0 +1,821 @@
1
+ import { ensureCompatibilityImports, getMcpDiscoverySummary, getMcpStandardConfigSummary, getProjectConfigPath, getServerProvenance, previewCompatibilityImports, previewSharedServerEntry, previewStarterProjectConfig, writeDirectToolsConfig, writeProjectServerDisabledOverride, writeSharedServerEntry, writeStarterProjectConfig, } from "./config.js";
2
+ import { clearFailure, getFailureAgeSeconds, getFailureMessage, markKeepAliveAfterConnect, notifyToolMetadataUpdated, recordFailure, updateMetadataCache, updateStatusBar, } from "./init.js";
3
+ import { getAuthStorageOptions, inspectAuthForUrl } from "./mcp-auth.js";
4
+ import { authenticate, removeAuth, supportsOAuth } from "./mcp-auth-flow.js";
5
+ import { inspectBearerTokenForUrl, removeBearerToken } from "./mcp-bearer-store.js";
6
+ import { createMcpPanel } from "./mcp-panel.js";
7
+ import { createMcpSetupPanel } from "./mcp-setup-panel.js";
8
+ import { loadMetadataCache, reconstructPromptMetadata } from "./metadata-cache.js";
9
+ import { loadOnboardingState, markSharedConfigHintShown, markSetupCompleted as persistSetupCompleted, } from "./onboarding-state.js";
10
+ import { isAbortError } from "./runtime-owner.js";
11
+ import { buildToolMetadata } from "./tool-metadata.js";
12
+ import { isServerDisabled, } from "./types.js";
13
+ import { openPath, resolveServerUrl, sanitizeTerminalText } from "./utils.js";
14
+ function terminalHyperlink(label, url) {
15
+ return `\u001B]8;;${sanitizeTerminalText(url)}\u001B\\${sanitizeTerminalText(label)}\u001B]8;;\u001B\\`;
16
+ }
17
+ /**
18
+ * True when this run mode can display a `ctx.ui.custom()` overlay.
19
+ *
20
+ * `ctx.hasUI` only reports that *some* UI context is bound. In rpc/print mode
21
+ * that context is a headless stub whose `custom()` returns immediately without
22
+ * ever invoking the factory or the `done` callback, so a panel awaited through
23
+ * `new Promise(resolve => ctx.ui.custom(...))` never settles and the command
24
+ * hangs. Overlay panels therefore additionally require `ctx.mode === "tui"`.
25
+ */
26
+ function canRenderPanel(ctx) {
27
+ return ctx.hasUI && ctx.mode === "tui";
28
+ }
29
+ export async function showStatus(state, ctx) {
30
+ if (!ctx.hasUI)
31
+ return;
32
+ const lines = ["MCP Server Status:", ""];
33
+ for (const name of Object.keys(state.config.mcpServers)) {
34
+ const definition = state.config.mcpServers[name];
35
+ if (isServerDisabled(definition)) {
36
+ lines.push(`⊘ ${name}: disabled (run /mcp enable ${name}, then /reload)`);
37
+ continue;
38
+ }
39
+ const connection = state.manager.getConnection(name);
40
+ const metadata = state.toolMetadata.get(name);
41
+ const toolCount = metadata?.length ?? 0;
42
+ const failedAgo = getFailureAgeSeconds(state, name);
43
+ let status = "not connected";
44
+ let statusIcon = "○";
45
+ let failed = false;
46
+ if (connection?.status === "connected") {
47
+ status = "connected";
48
+ statusIcon = "✓";
49
+ }
50
+ else if (connection?.status === "needs-auth") {
51
+ status = "needs auth";
52
+ statusIcon = "⚠";
53
+ }
54
+ else if (failedAgo !== null) {
55
+ const reason = sanitizeTerminalText(getFailureMessage(state, name) ?? "");
56
+ status = reason ? `failed ${failedAgo}s ago — ${reason}` : `failed ${failedAgo}s ago`;
57
+ statusIcon = "✗";
58
+ failed = true;
59
+ }
60
+ else if (metadata !== undefined) {
61
+ status = "cached";
62
+ }
63
+ const toolSuffix = failed ? "" : ` (${toolCount} tools${status === "cached" ? ", cached" : ""})`;
64
+ lines.push(`${statusIcon} ${name}: ${status}${toolSuffix}`);
65
+ }
66
+ if (Object.keys(state.config.mcpServers).length === 0) {
67
+ lines.push("No MCP servers configured");
68
+ lines.push("Run /mcp setup to adopt imports or scaffold .nexus/mcp.json");
69
+ }
70
+ ctx.ui.notify(lines.join("\n"), "info");
71
+ }
72
+ export async function showPrompts(state, ctx) {
73
+ if (!ctx.hasUI)
74
+ return;
75
+ const allPrompts = [...(state.promptMetadata?.values() ?? [])].flat();
76
+ const failedPromptServers = [...(state.manager.getAllConnections?.() ?? [])]
77
+ .filter(([, connection]) => connection.status === "connected" && connection.promptDiscoveryFailed)
78
+ .map(([serverName]) => serverName)
79
+ .sort();
80
+ if (allPrompts.length === 0) {
81
+ const failureNote = failedPromptServers.length > 0 ? ` Prompt discovery failed for: ${failedPromptServers.join(", ")}.` : "";
82
+ ctx.ui.notify(`No MCP prompts available. Prompts are discovered when servers with the \`prompts\` capability connect.${failureNote}`, "info");
83
+ return;
84
+ }
85
+ const lines = ["MCP Prompts:", ""];
86
+ const grouped = new Map();
87
+ for (const prompt of allPrompts) {
88
+ const list = grouped.get(prompt.serverName) ?? [];
89
+ list.push(prompt);
90
+ grouped.set(prompt.serverName, list);
91
+ }
92
+ for (const [serverName, prompts] of [...grouped.entries()].sort(([a], [b]) => a.localeCompare(b))) {
93
+ lines.push(`${serverName}:`);
94
+ for (const prompt of prompts.sort((a, b) => a.commandName.localeCompare(b.commandName))) {
95
+ const args = prompt.arguments
96
+ .map((argument) => (argument.required ? `<${argument.name}>` : `[${argument.name}]`))
97
+ .join(" ");
98
+ lines.push(` /${prompt.commandName}${args ? ` ${args}` : ""}`);
99
+ if (prompt.description)
100
+ lines.push(` ${prompt.description}`);
101
+ }
102
+ lines.push("");
103
+ }
104
+ lines.push(`Total: ${allPrompts.length} prompt${allPrompts.length === 1 ? "" : "s"}`);
105
+ if (failedPromptServers.length > 0) {
106
+ lines.push(`Prompt discovery failed for: ${failedPromptServers.join(", ")}. Cached prompt metadata may be stale.`);
107
+ }
108
+ ctx.ui.notify(lines.join("\n"), "info");
109
+ }
110
+ export async function showTools(state, ctx) {
111
+ if (!ctx.hasUI)
112
+ return;
113
+ const allTools = [...state.toolMetadata.entries()]
114
+ .filter(([serverName]) => !isServerDisabled(state.config.mcpServers[serverName]))
115
+ .flatMap(([, metadata]) => metadata.map((m) => m.name));
116
+ if (allTools.length === 0) {
117
+ ctx.ui.notify("No MCP tools available", "info");
118
+ return;
119
+ }
120
+ const lines = ["MCP Tools:", "", ...allTools.map((t) => ` ${t}`), "", `Total: ${allTools.length} tools`];
121
+ ctx.ui.notify(lines.join("\n"), "info");
122
+ }
123
+ export async function reconnectServer(state, ctx, name) {
124
+ const definition = state.config.mcpServers[name];
125
+ const ui = ctx.hasUI ? ctx.ui : undefined;
126
+ const signal = state.owner?.signal;
127
+ if (!definition) {
128
+ if (ui) {
129
+ ui.notify(`Server "${name}" not found in config`, "error");
130
+ }
131
+ return false;
132
+ }
133
+ if (isServerDisabled(definition)) {
134
+ if (ui)
135
+ ui.notify(`MCP: ${name} is disabled. Run /mcp enable ${name}, then /reload.`, "warning");
136
+ return false;
137
+ }
138
+ try {
139
+ await state.manager.close(name);
140
+ state.owner?.throwIfInactive();
141
+ const connection = signal
142
+ ? await state.manager.connect(name, definition, signal)
143
+ : await state.manager.connect(name, definition);
144
+ state.owner?.throwIfInactive();
145
+ if (connection.status === "needs-auth") {
146
+ if (ui) {
147
+ ui.notify(`MCP: ${name} requires OAuth. Run /mcp-auth ${name} first.`, "warning");
148
+ }
149
+ updateStatusBar(state);
150
+ return false;
151
+ }
152
+ const prefix = state.config.settings?.toolPrefix ?? "server";
153
+ const { metadata, failedTools } = buildToolMetadata(connection.tools, connection.resources, definition, name, prefix, state.config.mcpServers, state.toolMetadata);
154
+ state.toolMetadata.set(name, metadata);
155
+ if (!connection.promptDiscoveryFailed) {
156
+ state.promptMetadata?.set(name, reconstructPromptMetadata(name, connection.prompts ?? [], prefix, definition));
157
+ state.promptMetadataLive?.add(name);
158
+ }
159
+ if (connection.instructions) {
160
+ state.serverInstructions.set(name, connection.instructions);
161
+ }
162
+ else {
163
+ state.serverInstructions.delete(name);
164
+ }
165
+ updateMetadataCache(state, name);
166
+ notifyToolMetadataUpdated(state, name, "command-reconnect");
167
+ markKeepAliveAfterConnect(state, name);
168
+ clearFailure(state, name);
169
+ if (ui) {
170
+ ui.notify(`MCP: Reconnected to ${name} (${connection.tools.length} tools, ${connection.resources.length} resources)`, "info");
171
+ if (failedTools.length > 0) {
172
+ ui.notify(`MCP: ${name} - ${failedTools.length} tools skipped`, "warning");
173
+ }
174
+ }
175
+ updateStatusBar(state);
176
+ return true;
177
+ }
178
+ catch (error) {
179
+ const message = error instanceof Error ? error.message : String(error);
180
+ if (isAbortError(error, signal))
181
+ throw error;
182
+ recordFailure(state, name, message);
183
+ if (ui) {
184
+ ui.notify(`MCP: Failed to reconnect to ${name}: ${sanitizeTerminalText(message)}`, "error");
185
+ }
186
+ updateStatusBar(state);
187
+ return false;
188
+ }
189
+ }
190
+ export async function reconnectServers(state, ctx, targetServer) {
191
+ if (targetServer && !state.config.mcpServers[targetServer]) {
192
+ if (ctx.hasUI) {
193
+ ctx.ui.notify(`Server "${targetServer}" not found in config`, "error");
194
+ }
195
+ return;
196
+ }
197
+ const names = targetServer ? [targetServer] : Object.keys(state.config.mcpServers);
198
+ for (const name of names) {
199
+ await reconnectServer(state, ctx, name);
200
+ }
201
+ updateStatusBar(state);
202
+ }
203
+ /** Whether stored OAuth tokens actually exist for a server — independent of whether it's currently connected. */
204
+ function isSignedInForOAuth(serverName, definition, state) {
205
+ try {
206
+ const serverUrl = resolveServerUrl(definition);
207
+ if (!serverUrl)
208
+ return false;
209
+ const authStatus = inspectAuthForUrl(serverName, serverUrl, state.authStorageOptions);
210
+ return authStatus.status !== "absent" && authStatus.status !== "unavailable" && !!authStatus.entry.tokens;
211
+ }
212
+ catch {
213
+ return false;
214
+ }
215
+ }
216
+ export async function authenticateServer(serverName, config, ctx, signal, runtime, nexus) {
217
+ const ui = ctx.hasUI ? ctx.ui : undefined;
218
+ const cwd = ctx.cwd;
219
+ signal ??= ctx.signal;
220
+ if (!ui)
221
+ return { ok: false, message: "OAuth authentication requires an interactive session." };
222
+ const definition = config.mcpServers[serverName];
223
+ if (!definition) {
224
+ const message = `Server "${serverName}" not found in config`;
225
+ ui.notify(message, "error");
226
+ return { ok: false, message };
227
+ }
228
+ if (isServerDisabled(definition)) {
229
+ const message = `Server "${serverName}" is disabled. Run /mcp enable ${serverName}, then /reload.`;
230
+ ui.notify(message, "warning");
231
+ return { ok: false, message };
232
+ }
233
+ if (!supportsOAuth(definition)) {
234
+ const message = `Server "${serverName}" does not use OAuth authentication. Set "auth": "oauth" or omit auth for auto-detection.`;
235
+ ui.notify(`Server "${serverName}" does not use OAuth authentication.\n` +
236
+ `Set "auth": "oauth" or omit auth for auto-detection.`, "error");
237
+ return { ok: false, message };
238
+ }
239
+ try {
240
+ const serverUrl = resolveServerUrl(definition);
241
+ if (!serverUrl) {
242
+ const message = `Server "${serverName}" has no URL configured (OAuth requires HTTP transport)`;
243
+ ui.notify(message, "error");
244
+ return { ok: false, message };
245
+ }
246
+ ui.setStatus("mcp-auth", `Authenticating ${serverName}...`);
247
+ const authStorageOptions = getAuthStorageOptions(config.settings?.oauthDir, cwd);
248
+ const status = await authenticate(serverName, serverUrl, definition, {
249
+ ...(authStorageOptions.baseDir ? { authStorageOptions } : {}),
250
+ onAuthorizationUrl: async (authorizationUrl) => {
251
+ // Best-effort: launch the user's browser straight to the authorization page
252
+ // instead of relying on them to click (or copy) the link printed below.
253
+ if (!nexus)
254
+ return;
255
+ try {
256
+ await openPath(nexus, authorizationUrl);
257
+ }
258
+ catch {
259
+ // The link is still shown in the prompt text below; nothing else to do here.
260
+ }
261
+ },
262
+ onAuthorizationInput: async (authorizationUrl, inputSignal) => {
263
+ if (inputSignal.aborted)
264
+ return undefined;
265
+ return ui.input(`Complete ${serverName} OAuth\n\n` +
266
+ `${terminalHyperlink("Open authorization page", authorizationUrl)}\n${authorizationUrl}\n\n` +
267
+ "Approve access, then paste the full localhost callback URL below.", undefined, { signal: inputSignal });
268
+ },
269
+ ...(signal ? { signal } : {}),
270
+ ...(runtime ? { runtime } : {}),
271
+ });
272
+ if (signal?.aborted)
273
+ signal.throwIfAborted();
274
+ if (status === "authenticated") {
275
+ const message = `OAuth authentication successful for "${serverName}".`;
276
+ ui.notify(message, "info");
277
+ return { ok: true, message };
278
+ }
279
+ const message = `OAuth authentication failed for "${serverName}".`;
280
+ ui.notify(message, "error");
281
+ return { ok: false, message };
282
+ }
283
+ catch (error) {
284
+ if (signal?.aborted)
285
+ throw error;
286
+ const message = error instanceof Error ? error.message : String(error);
287
+ ui.notify(`Failed to authenticate "${serverName}": ${message}`, "error");
288
+ return { ok: false, message };
289
+ }
290
+ finally {
291
+ if (!signal?.aborted)
292
+ ui.setStatus("mcp-auth", undefined);
293
+ }
294
+ }
295
+ export async function logoutServer(serverName, state, ctx) {
296
+ const definition = state.config.mcpServers[serverName];
297
+ const ui = ctx.hasUI ? ctx.ui : undefined;
298
+ if (!definition) {
299
+ const message = `Server "${serverName}" not found in config`;
300
+ if (ui)
301
+ ui.notify(message, "error");
302
+ return { ok: false, message };
303
+ }
304
+ const signal = state.owner?.signal;
305
+ try {
306
+ await removeAuth(serverName, {
307
+ authStorageOptions: state.authStorageOptions,
308
+ signal,
309
+ runtime: state.oauthRuntime,
310
+ });
311
+ }
312
+ catch (error) {
313
+ if (isAbortError(error, signal))
314
+ throw error;
315
+ const message = error instanceof Error ? error.message : String(error);
316
+ if (ui) {
317
+ ui.notify(`Failed to clear OAuth credentials for "${serverName}": ${sanitizeTerminalText(message)}`, "error");
318
+ }
319
+ return { ok: false, message };
320
+ }
321
+ state.owner?.throwIfInactive();
322
+ try {
323
+ await state.manager.close(serverName);
324
+ }
325
+ catch (error) {
326
+ if (isAbortError(error, signal))
327
+ throw error;
328
+ const message = error instanceof Error ? error.message : String(error);
329
+ if (ui) {
330
+ ui.notify(`OAuth credentials were cleared for "${serverName}", but its connection could not be closed: ${sanitizeTerminalText(message)}`, "error");
331
+ }
332
+ return { ok: false, message };
333
+ }
334
+ state.owner?.throwIfInactive();
335
+ updateStatusBar(state);
336
+ const message = `OAuth credentials cleared for "${serverName}". Run /mcp-auth ${serverName} to authenticate again.`;
337
+ if (ui)
338
+ ui.notify(message, "info");
339
+ return { ok: true, message };
340
+ }
341
+ function validateBearerTokenStoreServer(serverName, state) {
342
+ const safeName = sanitizeTerminalText(serverName);
343
+ const definition = state.config.mcpServers[serverName];
344
+ if (!definition)
345
+ return { ok: false, message: `Server "${safeName}" not found in config`, type: "error" };
346
+ if (isServerDisabled(definition))
347
+ return {
348
+ ok: false,
349
+ message: `Server "${safeName}" is disabled. Run /mcp enable ${safeName}, then /reload.`,
350
+ type: "warning",
351
+ };
352
+ if (definition.auth !== "bearer" || definition.bearerTokenStore !== true) {
353
+ return { ok: false, message: `Server "${safeName}" is not configured for bearerTokenStore.`, type: "error" };
354
+ }
355
+ // resolveServerUrl embeds the interpolated URL in its exceptions; redact it
356
+ // because the URL can carry userinfo or interpolated secrets.
357
+ let serverUrl;
358
+ try {
359
+ serverUrl = resolveServerUrl(definition);
360
+ }
361
+ catch {
362
+ return { ok: false, message: `Server "${safeName}" has an invalid or unresolvable URL.`, type: "error" };
363
+ }
364
+ if (!serverUrl)
365
+ return { ok: false, message: `Server "${safeName}" has no URL configured.`, type: "error" };
366
+ return { ok: true, serverUrl };
367
+ }
368
+ export async function manageBearerToken(action, serverName, state, ctx) {
369
+ const ui = ctx.hasUI ? ctx.ui : undefined;
370
+ const safeName = sanitizeTerminalText(serverName);
371
+ const validation = validateBearerTokenStoreServer(serverName, state);
372
+ if (!validation.ok) {
373
+ if (ui)
374
+ ui.notify(validation.message, validation.type);
375
+ return { ok: false, message: validation.message };
376
+ }
377
+ if (action === "set") {
378
+ const message = `Nexus will not collect bearer tokens through an unmasked prompt. Configure bearerTokenEnv for "${safeName}" in MCP config, then reload.`;
379
+ if (ui)
380
+ ui.notify(message, "error");
381
+ return { ok: false, message };
382
+ }
383
+ if (action === "status") {
384
+ const status = inspectBearerTokenForUrl(serverName, validation.serverUrl);
385
+ const message = status.status === "present"
386
+ ? `Bearer token is stored for "${safeName}".`
387
+ : status.status === "url-mismatch"
388
+ ? `Bearer token is stored for "${safeName}", but its URL does not match the current server URL.`
389
+ : status.status === "unavailable"
390
+ ? status.message
391
+ : `No bearer token is stored for "${safeName}".`;
392
+ if (ui)
393
+ ui.notify(message, status.status === "unavailable" ? "error" : "info");
394
+ return { ok: status.status !== "unavailable", message };
395
+ }
396
+ try {
397
+ removeBearerToken(serverName);
398
+ }
399
+ catch (error) {
400
+ const message = error instanceof Error ? error.message : String(error);
401
+ if (ui)
402
+ ui.notify(`Failed to remove bearer token for "${safeName}": ${sanitizeTerminalText(message)}`, "error");
403
+ return { ok: false, message };
404
+ }
405
+ const message = `Bearer token removed for "${safeName}".`;
406
+ if (ui)
407
+ ui.notify(message, "info");
408
+ return { ok: true, message };
409
+ }
410
+ const ADD_SERVER_NAME_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
411
+ function parseKeyValueFlag(flag, raw) {
412
+ const eq = raw?.indexOf("=") ?? -1;
413
+ if (!raw || eq <= 0)
414
+ return { ok: false, error: `${flag} expects KEY=VALUE, got "${raw ?? ""}".` };
415
+ return { ok: true, key: raw.slice(0, eq), value: raw.slice(eq + 1) };
416
+ }
417
+ /**
418
+ * Parses `/mcp add <name> ...` arguments. Mirrors the rest of /mcp's naive
419
+ * whitespace-split argument handling (no quoting support) rather than
420
+ * inventing a shell-quote parser just for this subcommand.
421
+ */
422
+ export function parseAddServerArgs(argv) {
423
+ const name = argv[0];
424
+ if (!name)
425
+ return { ok: false, error: "Missing server name." };
426
+ if (!ADD_SERVER_NAME_PATTERN.test(name)) {
427
+ return { ok: false, error: `Invalid server name "${name}" — use letters, digits, ".", "_", "-".` };
428
+ }
429
+ const rest = argv.slice(1);
430
+ const env = {};
431
+ const headers = {};
432
+ let cwd;
433
+ let url;
434
+ let auth;
435
+ let bearerTokenEnv;
436
+ let commandArgv;
437
+ let i = 0;
438
+ while (i < rest.length) {
439
+ const token = rest[i];
440
+ if (token === "--") {
441
+ commandArgv = rest.slice(i + 1);
442
+ break;
443
+ }
444
+ if (token === "--url") {
445
+ url = rest[i + 1];
446
+ i += 2;
447
+ continue;
448
+ }
449
+ if (token === "--env" || token === "--header") {
450
+ const parsed = parseKeyValueFlag(token, rest[i + 1]);
451
+ if (!parsed.ok)
452
+ return parsed;
453
+ (token === "--env" ? env : headers)[parsed.key] = parsed.value;
454
+ i += 2;
455
+ continue;
456
+ }
457
+ if (token === "--cwd") {
458
+ cwd = rest[i + 1];
459
+ i += 2;
460
+ continue;
461
+ }
462
+ if (token === "--auth") {
463
+ const value = rest[i + 1];
464
+ if (value !== "oauth" && value !== "bearer") {
465
+ return { ok: false, error: `--auth expects "oauth" or "bearer", got "${value ?? ""}".` };
466
+ }
467
+ auth = value;
468
+ i += 2;
469
+ continue;
470
+ }
471
+ if (token === "--bearer-env") {
472
+ bearerTokenEnv = rest[i + 1];
473
+ i += 2;
474
+ continue;
475
+ }
476
+ return { ok: false, error: `Unrecognized argument "${token}".` };
477
+ }
478
+ if (url && commandArgv) {
479
+ return { ok: false, error: "Use either --url (remote server) or -- <command> (local server), not both." };
480
+ }
481
+ if (!url && !commandArgv) {
482
+ return { ok: false, error: "Specify a server type: --url <url> (remote), or -- <command> [args...] (local)." };
483
+ }
484
+ if (commandArgv) {
485
+ const [command, ...args] = commandArgv;
486
+ if (!command)
487
+ return { ok: false, error: "Missing command after --." };
488
+ const entry = { command, ...(args.length ? { args } : {}) };
489
+ if (Object.keys(env).length)
490
+ entry.env = env;
491
+ if (cwd)
492
+ entry.cwd = cwd;
493
+ return { ok: true, name, entry };
494
+ }
495
+ const entry = { url: url };
496
+ if (Object.keys(headers).length)
497
+ entry.headers = headers;
498
+ if (bearerTokenEnv) {
499
+ entry.bearerTokenEnv = bearerTokenEnv;
500
+ entry.auth = auth ?? "bearer";
501
+ }
502
+ else if (auth) {
503
+ entry.auth = auth;
504
+ }
505
+ return { ok: true, name, entry };
506
+ }
507
+ export const ADD_SERVER_USAGE = [
508
+ "Usage:",
509
+ " /mcp add <name> -- <command> [args...] local server, runs over stdio",
510
+ " /mcp add <name> --url <url> remote server over HTTP",
511
+ "",
512
+ "Flags:",
513
+ " --env KEY=VALUE extra environment variable (local, repeatable)",
514
+ " --cwd <path> working directory (local)",
515
+ " --header KEY=VALUE extra HTTP header (remote, repeatable)",
516
+ " --auth oauth|bearer auth mode (remote; default is OAuth auto-detection)",
517
+ " --bearer-env <VAR> read a bearer token from this env var (remote)",
518
+ "",
519
+ "For fields not covered here (lifecycle, includeTools, ...), edit the config",
520
+ 'file directly — /mcp setup, then "Open detected config paths".',
521
+ ].join("\n");
522
+ /** Adds a server to the project's shared MCP config. Reused by both `/mcp add` and any UI entry point. */
523
+ export function addCustomServer(cwd, name, entry) {
524
+ const path = writeSharedServerEntry(getProjectConfigPath(cwd), name, entry);
525
+ return { path };
526
+ }
527
+ function buildSharedConfigNoticeLines(configOverridePath, cwd) {
528
+ const discovery = getMcpStandardConfigSummary(configOverridePath, cwd);
529
+ const onboardingState = loadOnboardingState();
530
+ if (!discovery.hasSharedServers || onboardingState.sharedConfigHintShown) {
531
+ return { lines: [], fingerprint: null };
532
+ }
533
+ const sharedSources = discovery.sources.filter((source) => source.kind === "shared" && source.serverCount > 0);
534
+ const sourceList = sharedSources.map((source) => source.path).join(", ");
535
+ return {
536
+ lines: [
537
+ `Using MCP configuration from ${sourceList}.`,
538
+ "Nexus writes compatibility imports and MCP-specific overrides only to Nexus configuration files.",
539
+ ],
540
+ fingerprint: discovery.fingerprint,
541
+ };
542
+ }
543
+ export async function openMcpSetup(state, nexus, ctx, configOverridePath, mode = "setup", options = {}) {
544
+ if (!ctx.hasUI)
545
+ return { configChanged: false };
546
+ if (!canRenderPanel(ctx)) {
547
+ ctx.ui.notify(`The interactive MCP setup panel is only available in the terminal UI (current mode: ${ctx.mode}). Edit .nexus/mcp.json directly, or run /mcp status to review servers.`, "info");
548
+ return { configChanged: false };
549
+ }
550
+ if (state.programmaticConfig) {
551
+ ctx.ui.notify("MCP setup is unavailable when config is supplied by createMcpAdapter().", "info");
552
+ return { configChanged: false };
553
+ }
554
+ const discovery = getMcpDiscoverySummary(configOverridePath, ctx.cwd, options);
555
+ const onboardingState = loadOnboardingState();
556
+ const installedServers = Object.entries(state.config.mcpServers).map(([name, definition]) => {
557
+ const authCapable = supportsOAuth(definition);
558
+ return {
559
+ name,
560
+ disabled: isServerDisabled(definition),
561
+ kind: (definition.command ? "stdio" : "http"),
562
+ authCapable,
563
+ signedIn: authCapable ? isSignedInForOAuth(name, definition, state) : false,
564
+ };
565
+ });
566
+ let configChanged = false;
567
+ let overlayHandle;
568
+ const callbacks = {
569
+ previewImports: (imports) => previewCompatibilityImports(imports, configOverridePath),
570
+ previewStarterProject: () => previewStarterProjectConfig(ctx.cwd),
571
+ previewRepoPrompt: () => {
572
+ const repoPrompt = getMcpDiscoverySummary(configOverridePath, ctx.cwd, options).repoPrompt;
573
+ if (!repoPrompt.entry || !repoPrompt.targetPath || !repoPrompt.serverName)
574
+ return null;
575
+ return previewSharedServerEntry(repoPrompt.targetPath, repoPrompt.serverName, repoPrompt.entry);
576
+ },
577
+ previewKnownServer: (preset) => previewSharedServerEntry(getProjectConfigPath(ctx.cwd), preset.id, preset.entry),
578
+ adoptImports: async (imports) => {
579
+ const result = ensureCompatibilityImports(imports, configOverridePath);
580
+ if (result.added.length > 0)
581
+ configChanged = true;
582
+ return result;
583
+ },
584
+ scaffoldProjectConfig: async () => {
585
+ const path = writeStarterProjectConfig(ctx.cwd);
586
+ configChanged = true;
587
+ return { path };
588
+ },
589
+ addRepoPrompt: async () => {
590
+ const repoPrompt = getMcpDiscoverySummary(configOverridePath, ctx.cwd, options).repoPrompt;
591
+ if (!repoPrompt.entry || !repoPrompt.targetPath || !repoPrompt.serverName) {
592
+ throw new Error("RepoPrompt is not available to add from this setup screen.");
593
+ }
594
+ const path = writeSharedServerEntry(repoPrompt.targetPath, repoPrompt.serverName, repoPrompt.entry);
595
+ configChanged = true;
596
+ return { path, serverName: repoPrompt.serverName };
597
+ },
598
+ addKnownServer: async (preset) => {
599
+ const path = writeSharedServerEntry(getProjectConfigPath(ctx.cwd), preset.id, preset.entry);
600
+ configChanged = true;
601
+ return { path, serverName: preset.name };
602
+ },
603
+ openPath: async (targetPath) => {
604
+ await openPath(nexus, targetPath);
605
+ },
606
+ markSetupCompleted: () => {
607
+ persistSetupCompleted(discovery.fingerprint);
608
+ },
609
+ seedEditor: (text) => {
610
+ if (ctx.hasUI)
611
+ ctx.ui.setEditorText(text);
612
+ },
613
+ toggleServerDisabled: async (serverName, disabled) => {
614
+ const result = writeProjectServerDisabledOverride(configOverridePath, ctx.cwd, serverName, disabled);
615
+ if (result.changed)
616
+ configChanged = true;
617
+ return { path: result.path, changed: result.changed };
618
+ },
619
+ authenticateServer: async (serverName, fallbackEntry) => {
620
+ // A server added this session isn't in the live config until /reload —
621
+ // hand authenticateServer a synthetic config with just that one entry
622
+ // merged in, rather than making the user reload first.
623
+ const effectiveConfig = state.config.mcpServers[serverName] || !fallbackEntry
624
+ ? state.config
625
+ : { ...state.config, mcpServers: { ...state.config.mcpServers, [serverName]: fallbackEntry } };
626
+ // The auth prompt (the actual link, and the "paste the callback URL"
627
+ // input) renders as a *separate* overlay. Without hiding this one first,
628
+ // it stays drawn on top and the auth prompt is invisible underneath it.
629
+ overlayHandle?.setHidden(true);
630
+ try {
631
+ const result = await authenticateServer(serverName, effectiveConfig, ctx, ctx.signal, state.oauthRuntime, nexus);
632
+ return {
633
+ ok: result.ok,
634
+ message: result.message ??
635
+ (result.ok ? `Signed in to "${serverName}".` : `Sign-in failed for "${serverName}".`),
636
+ };
637
+ }
638
+ finally {
639
+ overlayHandle?.setHidden(false);
640
+ overlayHandle?.focus();
641
+ }
642
+ },
643
+ };
644
+ return new Promise((resolve) => {
645
+ ctx.ui.custom((tui, _theme, keybindings, done) => {
646
+ return createMcpSetupPanel(discovery, callbacks, { mode, onboardingState, keybindings, installedServers }, tui, () => {
647
+ done(undefined);
648
+ resolve({ configChanged });
649
+ });
650
+ }, {
651
+ overlay: true,
652
+ overlayOptions: { anchor: "center", width: 92, maxHeight: "90%" },
653
+ onHandle: (handle) => {
654
+ overlayHandle = handle;
655
+ },
656
+ });
657
+ });
658
+ }
659
+ function buildMcpPanelCallbacks(state, config, ctx, nexus, getOverlayHandle) {
660
+ // Panel-only diagnostics keep status inspection from mutating connection
661
+ // failure state while allowing the existing panel failure UI to show why the
662
+ // credential store could not be inspected.
663
+ const authStatusFailures = new Map();
664
+ return {
665
+ reconnect: (serverName) => reconnectServer(state, ctx, serverName),
666
+ canAuthenticate: (serverName) => {
667
+ const definition = config.mcpServers[serverName];
668
+ return definition ? !isServerDisabled(definition) && supportsOAuth(definition) : false;
669
+ },
670
+ authenticate: async (serverName) => {
671
+ const overlay = getOverlayHandle?.();
672
+ overlay?.setHidden(true);
673
+ try {
674
+ return await authenticateServer(serverName, config, ctx, state.owner?.signal, state.oauthRuntime, nexus);
675
+ }
676
+ finally {
677
+ overlay?.setHidden(false);
678
+ overlay?.focus();
679
+ }
680
+ },
681
+ getConnectionStatus: (serverName) => {
682
+ authStatusFailures.delete(serverName);
683
+ const definition = config.mcpServers[serverName];
684
+ if (isServerDisabled(definition))
685
+ return "disabled";
686
+ const connection = state.manager.getConnection(serverName);
687
+ let serverUrl;
688
+ try {
689
+ serverUrl = definition ? resolveServerUrl(definition) : undefined;
690
+ }
691
+ catch {
692
+ return "failed";
693
+ }
694
+ if (definition?.auth === "oauth" &&
695
+ serverUrl &&
696
+ definition.oauth !== false &&
697
+ definition.oauth?.grantType !== "client_credentials") {
698
+ const authStatus = inspectAuthForUrl(serverName, serverUrl, state.authStorageOptions);
699
+ if (authStatus.status === "unavailable") {
700
+ authStatusFailures.set(serverName, authStatus.message);
701
+ return "failed";
702
+ }
703
+ if (authStatus.status === "absent" || !authStatus.entry.tokens) {
704
+ return "needs-auth";
705
+ }
706
+ }
707
+ if (connection?.status === "needs-auth")
708
+ return "needs-auth";
709
+ if (connection?.status === "connected")
710
+ return "connected";
711
+ if (getFailureAgeSeconds(state, serverName) !== null)
712
+ return "failed";
713
+ return "idle";
714
+ },
715
+ getFailureMessage: (serverName) => authStatusFailures.get(serverName) ?? getFailureMessage(state, serverName),
716
+ refreshCacheAfterReconnect: (serverName) => {
717
+ const freshCache = loadMetadataCache();
718
+ return freshCache?.servers?.[serverName] ?? null;
719
+ },
720
+ };
721
+ }
722
+ export async function openMcpPanel(state, nexus, ctx, configOverridePath, onDirectToolsConfigChanged) {
723
+ if (state.programmaticConfig) {
724
+ if (ctx.hasUI) {
725
+ ctx.ui.notify("MCP status is shown from the in-memory SDK config; configuration discovery is unavailable.", "info");
726
+ await showStatus(state, ctx);
727
+ }
728
+ return { configChanged: false };
729
+ }
730
+ if (!canRenderPanel(ctx)) {
731
+ // No overlay here, but the same information is available as text.
732
+ await showStatus(state, ctx);
733
+ return { configChanged: false };
734
+ }
735
+ if (Object.keys(state.config.mcpServers).length === 0) {
736
+ return openMcpSetup(state, nexus, ctx, configOverridePath, "empty", { includeHostConfigs: false });
737
+ }
738
+ const config = state.config;
739
+ const cache = loadMetadataCache();
740
+ const configPath = nexus.getFlag("mcp-config") ?? configOverridePath;
741
+ const provenanceMap = getServerProvenance(configPath, ctx.cwd);
742
+ const { lines: noticeLines, fingerprint } = buildSharedConfigNoticeLines(configPath, ctx.cwd);
743
+ let overlayHandle;
744
+ const callbacks = buildMcpPanelCallbacks(state, config, ctx, nexus, () => overlayHandle);
745
+ let configChanged = false;
746
+ await new Promise((resolve) => {
747
+ ctx.ui.custom((tui, _theme, keybindings, done) => {
748
+ return createMcpPanel(config, cache, provenanceMap, callbacks, tui, (result) => {
749
+ void (async () => {
750
+ if (!result.cancelled && result.changes.size > 0) {
751
+ writeDirectToolsConfig(result.changes, provenanceMap);
752
+ configChanged = true;
753
+ await onDirectToolsConfigChanged?.(result.changes);
754
+ ctx.ui.notify("Direct tools updated for this session.", "info");
755
+ }
756
+ done(undefined);
757
+ resolve();
758
+ })().catch((error) => {
759
+ const message = error instanceof Error ? error.message : String(error);
760
+ ctx.ui.notify(`Direct tools updated, but live refresh failed: ${message}`, "error");
761
+ configChanged = true;
762
+ done(undefined);
763
+ resolve();
764
+ });
765
+ }, { noticeLines, keybindings });
766
+ }, {
767
+ overlay: true,
768
+ overlayOptions: { anchor: "center", width: 82 },
769
+ onHandle: (handle) => {
770
+ overlayHandle = handle;
771
+ },
772
+ });
773
+ });
774
+ if (noticeLines.length > 0 && fingerprint) {
775
+ markSharedConfigHintShown(fingerprint);
776
+ }
777
+ return { configChanged };
778
+ }
779
+ export async function openMcpAuthPanel(state, nexus, ctx, configOverridePath) {
780
+ if (!ctx.hasUI)
781
+ return { configChanged: false };
782
+ if (!canRenderPanel(ctx)) {
783
+ ctx.ui.notify(`The interactive MCP auth panel is only available in the terminal UI (current mode: ${ctx.mode}). Use /mcp-auth <server> to authenticate a specific server.`, "info");
784
+ return { configChanged: false };
785
+ }
786
+ if (state.programmaticConfig) {
787
+ ctx.ui.notify("Use /mcp-auth <server> to authenticate a server from the in-memory SDK config.", "info");
788
+ return { configChanged: false };
789
+ }
790
+ const config = state.config;
791
+ const oauthServers = Object.entries(config.mcpServers).filter(([, definition]) => !isServerDisabled(definition) && supportsOAuth(definition));
792
+ if (oauthServers.length === 0) {
793
+ ctx.ui.notify("No OAuth-capable MCP servers are configured.", "warning");
794
+ return { configChanged: false };
795
+ }
796
+ const cache = loadMetadataCache();
797
+ const configPath = nexus.getFlag("mcp-config") ?? configOverridePath;
798
+ const provenanceMap = getServerProvenance(configPath, ctx.cwd);
799
+ let overlayHandle;
800
+ const callbacks = buildMcpPanelCallbacks(state, config, ctx, nexus, () => overlayHandle);
801
+ await new Promise((resolve) => {
802
+ ctx.ui.custom((tui, _theme, keybindings, done) => {
803
+ return createMcpPanel(config, cache, provenanceMap, callbacks, tui, () => {
804
+ done(undefined);
805
+ resolve();
806
+ }, {
807
+ authOnly: true,
808
+ keybindings,
809
+ noticeLines: ["Select an OAuth MCP server and press Enter or ctrl+a to authenticate."],
810
+ });
811
+ }, {
812
+ overlay: true,
813
+ overlayOptions: { anchor: "center", width: 82 },
814
+ onHandle: (handle) => {
815
+ overlayHandle = handle;
816
+ },
817
+ });
818
+ });
819
+ return { configChanged: false };
820
+ }
821
+ //# sourceMappingURL=commands.js.map