xaq-cli 0.0.0 → 0.1.0-nightly.72

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 (227) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +79 -0
  3. package/dist/admin-5gThRwgj.js +162 -0
  4. package/dist/admin-5gThRwgj.js.map +1 -0
  5. package/dist/admin-Btrm8mCd.js +218 -0
  6. package/dist/admin-Btrm8mCd.js.map +1 -0
  7. package/dist/admin-CWofnT_Q.js +2 -0
  8. package/dist/api-BFpElwqK.js +89 -0
  9. package/dist/api-BFpElwqK.js.map +1 -0
  10. package/dist/audit-BB7jK9Z5.js +2 -0
  11. package/dist/audit-BVYknW2i.js +79 -0
  12. package/dist/audit-BVYknW2i.js.map +1 -0
  13. package/dist/auth-CXmBdMqw.js +2 -0
  14. package/dist/auth-D-GmwNv-.js +550 -0
  15. package/dist/auth-D-GmwNv-.js.map +1 -0
  16. package/dist/brand--ZB8jTn1.js +32 -0
  17. package/dist/brand--ZB8jTn1.js.map +1 -0
  18. package/dist/bus-Cz0flS37.js +12 -0
  19. package/dist/bus-Cz0flS37.js.map +1 -0
  20. package/dist/bus-OKIGut72.js +2 -0
  21. package/dist/cli.js +234 -0
  22. package/dist/cli.js.map +1 -0
  23. package/dist/commands-BNVLjYXA.js +167 -0
  24. package/dist/commands-BNVLjYXA.js.map +1 -0
  25. package/dist/commands-CdA6-WE7.js +112 -0
  26. package/dist/commands-CdA6-WE7.js.map +1 -0
  27. package/dist/config-C9XmYZWO.js +94 -0
  28. package/dist/config-C9XmYZWO.js.map +1 -0
  29. package/dist/config-CNVi0v5t.js +2 -0
  30. package/dist/connect-TtJ9n0Rw.js +362 -0
  31. package/dist/connect-TtJ9n0Rw.js.map +1 -0
  32. package/dist/content-C1lKMxFS.js +1170 -0
  33. package/dist/content-C1lKMxFS.js.map +1 -0
  34. package/dist/content-worker.js +28 -0
  35. package/dist/content-worker.js.map +1 -0
  36. package/dist/crypto-fv2fj3S8.js +75 -0
  37. package/dist/crypto-fv2fj3S8.js.map +1 -0
  38. package/dist/db-BEUEUPyP.js +561 -0
  39. package/dist/db-BEUEUPyP.js.map +1 -0
  40. package/dist/db-Q5BQuwga.js +2 -0
  41. package/dist/errors-FbMS3QBo.js +39 -0
  42. package/dist/errors-FbMS3QBo.js.map +1 -0
  43. package/dist/filter-Ck6OMxvu.js +158 -0
  44. package/dist/filter-Ck6OMxvu.js.map +1 -0
  45. package/dist/hermes-CKyzt1mH.js +3 -0
  46. package/dist/hermes-DHnDTYJp.js +1023 -0
  47. package/dist/hermes-DHnDTYJp.js.map +1 -0
  48. package/dist/import-DsN5NZT3.js +910 -0
  49. package/dist/import-DsN5NZT3.js.map +1 -0
  50. package/dist/instance-CwWbFbJ8.js +2 -0
  51. package/dist/instance-Dj9TpJB2.js +195 -0
  52. package/dist/instance-Dj9TpJB2.js.map +1 -0
  53. package/dist/listen-B9iO7HgQ.js +1568 -0
  54. package/dist/listen-B9iO7HgQ.js.map +1 -0
  55. package/dist/listen-CXVKG9XD.js +2 -0
  56. package/dist/manage-Bo6COB4p.js +477 -0
  57. package/dist/manage-Bo6COB4p.js.map +1 -0
  58. package/dist/manage-DoXqvjnU.js +2 -0
  59. package/dist/mcpheader-B8c5YO1B.js +2 -0
  60. package/dist/mcpheader-C9H4vudu.js +185 -0
  61. package/dist/mcpheader-C9H4vudu.js.map +1 -0
  62. package/dist/mcpsetup-BnHudwpq.js +2 -0
  63. package/dist/mcpsetup-DXXo2qjf.js +1053 -0
  64. package/dist/mcpsetup-DXXo2qjf.js.map +1 -0
  65. package/dist/node-check-CjTk6VNL.js +24 -0
  66. package/dist/node-check-CjTk6VNL.js.map +1 -0
  67. package/dist/paths-d-C2kdjo.js +2 -0
  68. package/dist/paths-yzOKD6ow.js +46 -0
  69. package/dist/paths-yzOKD6ow.js.map +1 -0
  70. package/dist/profile-CcMZ4hn7.js +2 -0
  71. package/dist/profile-NmMKAczz.js +222 -0
  72. package/dist/profile-NmMKAczz.js.map +1 -0
  73. package/dist/prompt-CKMQx_MJ.js +114 -0
  74. package/dist/prompt-CKMQx_MJ.js.map +1 -0
  75. package/dist/recipes-C7TIDlRj.js +3 -0
  76. package/dist/recipes-DG_-doGq.js +314 -0
  77. package/dist/recipes-DG_-doGq.js.map +1 -0
  78. package/dist/send-Dk-t8ia-.js +108 -0
  79. package/dist/send-Dk-t8ia-.js.map +1 -0
  80. package/dist/server-CDqDp1q3.js +20640 -0
  81. package/dist/server-CDqDp1q3.js.map +1 -0
  82. package/dist/service-BVn3soZZ.js +766 -0
  83. package/dist/service-BVn3soZZ.js.map +1 -0
  84. package/dist/service-BaWGPmSd.js +2 -0
  85. package/dist/service-C7jfo-Ex.js +457 -0
  86. package/dist/service-C7jfo-Ex.js.map +1 -0
  87. package/dist/service-DxDyKDQ-.js +2 -0
  88. package/dist/settings-B5qSHxRM.js +134 -0
  89. package/dist/settings-B5qSHxRM.js.map +1 -0
  90. package/dist/settings-DQvZaMN1.js +2 -0
  91. package/dist/setup-token-CwuSzfLK.js +48 -0
  92. package/dist/setup-token-CwuSzfLK.js.map +1 -0
  93. package/dist/skill/SKILL.md +445 -0
  94. package/dist/skill-1UQj3qgW.js +69 -0
  95. package/dist/skill-1UQj3qgW.js.map +1 -0
  96. package/dist/skill-pelq18JQ.js +2 -0
  97. package/dist/ssrf-BlVpGZ7C.js +181 -0
  98. package/dist/ssrf-BlVpGZ7C.js.map +1 -0
  99. package/dist/types-BhJDbSzE.js +135 -0
  100. package/dist/types-BhJDbSzE.js.map +1 -0
  101. package/dist/ui-B8Sd4Y7Y.js +81 -0
  102. package/dist/ui-B8Sd4Y7Y.js.map +1 -0
  103. package/dist/urls-Dp8pBGMU.js +2 -0
  104. package/dist/urls-U_LfYV61.js +27 -0
  105. package/dist/urls-U_LfYV61.js.map +1 -0
  106. package/dist/version-BxH7OuWD.js +20 -0
  107. package/dist/version-BxH7OuWD.js.map +1 -0
  108. package/dist/web/assets/_agentId-DonOCOlC.js +1 -0
  109. package/dist/web/assets/_app-B7t5lEia.js +1 -0
  110. package/dist/web/assets/_app-DMTGqYpM.js +65 -0
  111. package/dist/web/assets/_connectionId-DR5vFXOg.js +1 -0
  112. package/dist/web/assets/_webhookId-LfUlsULp.js +1 -0
  113. package/dist/web/assets/account-status-CEszs13C.js +1 -0
  114. package/dist/web/assets/accounts-5m7aiXuZ.js +1 -0
  115. package/dist/web/assets/accounts-list-YfJzThZa.js +1 -0
  116. package/dist/web/assets/activity-DOIe7SAg.js +1 -0
  117. package/dist/web/assets/add-connection-C8JR-13R.js +1 -0
  118. package/dist/web/assets/agent-create-form-CPxnPYH4.js +1 -0
  119. package/dist/web/assets/agents-B2Qj5KxT.js +1 -0
  120. package/dist/web/assets/approvals-BGaVaoFy.js +1 -0
  121. package/dist/web/assets/approve._id-BLrQnzPM.js +1 -0
  122. package/dist/web/assets/arrow-left-DZVAXoKj.js +1 -0
  123. package/dist/web/assets/arrow-right-C2zcqRr2.js +1 -0
  124. package/dist/web/assets/attention-gO9Nw5uW.js +1 -0
  125. package/dist/web/assets/audit-BPXXre8S.js +1 -0
  126. package/dist/web/assets/audit-bits-CGyIprzK.js +1 -0
  127. package/dist/web/assets/bell-ring-ig3zn1iS.js +1 -0
  128. package/dist/web/assets/bot-Zk76q_39.js +1 -0
  129. package/dist/web/assets/calendar-notice-DsCfq3VJ.js +1 -0
  130. package/dist/web/assets/calendar-plus-Cycfkk0y.js +1 -0
  131. package/dist/web/assets/calendar-setup-Pn61Wj1n.js +2 -0
  132. package/dist/web/assets/card-GSO5o-Ug.js +1 -0
  133. package/dist/web/assets/check-check-Ds1bPIGv.js +1 -0
  134. package/dist/web/assets/checkbox-B937U-Fd.js +1 -0
  135. package/dist/web/assets/chevron-right-Cqh4mDk1.js +1 -0
  136. package/dist/web/assets/chips-input-2xWDofmE.js +1 -0
  137. package/dist/web/assets/choice-cards-CgAIqBGX.js +1 -0
  138. package/dist/web/assets/circle-x-DcU-0zVh.js +1 -0
  139. package/dist/web/assets/command-khhto70y.js +1 -0
  140. package/dist/web/assets/common-BPZV8TFb.js +1 -0
  141. package/dist/web/assets/connect-agent-guide-CJdw31p2.js +1 -0
  142. package/dist/web/assets/connect-host-lr2c3xWh.js +6 -0
  143. package/dist/web/assets/connection-row-DYx_5o0c.js +1 -0
  144. package/dist/web/assets/connections-C4NOFb5R.js +1 -0
  145. package/dist/web/assets/data-table-kW1pkRB5.js +1 -0
  146. package/dist/web/assets/empty-DzTDioBP.js +1 -0
  147. package/dist/web/assets/events-C9zJnPKK.js +1 -0
  148. package/dist/web/assets/eye-B9gT1QSq.js +1 -0
  149. package/dist/web/assets/eye-off-Diktqz_g.js +1 -0
  150. package/dist/web/assets/field-C6ejurju.js +1 -0
  151. package/dist/web/assets/geist-cyrillic-ext-wght-normal-DjL33-gN.woff2 +0 -0
  152. package/dist/web/assets/geist-cyrillic-wght-normal-BEAKL7Jp.woff2 +0 -0
  153. package/dist/web/assets/geist-latin-ext-wght-normal-DC-KSUi6.woff2 +0 -0
  154. package/dist/web/assets/geist-latin-wght-normal-BgDaEnEv.woff2 +0 -0
  155. package/dist/web/assets/geist-mono-cyrillic-ext-wght-normal-X_5orZeX.woff2 +0 -0
  156. package/dist/web/assets/geist-mono-cyrillic-wght-normal-DiZS0aHC.woff2 +0 -0
  157. package/dist/web/assets/geist-mono-latin-ext-wght-normal-Bwz-egvJ.woff2 +0 -0
  158. package/dist/web/assets/geist-mono-latin-wght-normal-XN7g48iV.woff2 +0 -0
  159. package/dist/web/assets/geist-mono-symbols2-wght-normal-CO5SzqOn.woff2 +0 -0
  160. package/dist/web/assets/geist-mono-vietnamese-wght-normal-DadHysG0.woff2 +0 -0
  161. package/dist/web/assets/geist-vietnamese-wght-normal-6IgcOCM7.woff2 +0 -0
  162. package/dist/web/assets/get-started-C38bq1gZ.js +2 -0
  163. package/dist/web/assets/hidden-chars-Dr9TxfvF.js +1 -0
  164. package/dist/web/assets/index-DGzo3kGh.js +11 -0
  165. package/dist/web/assets/index-zKOCQLGX.css +2 -0
  166. package/dist/web/assets/input-CWwJgozn.js +1 -0
  167. package/dist/web/assets/input-group-HG8OXcJ4.js +1 -0
  168. package/dist/web/assets/label-multi-select-sH8mllw8.js +1 -0
  169. package/dist/web/assets/labels-B5UqVwFo.js +1 -0
  170. package/dist/web/assets/laptop-BxJ4Nbj7.js +1 -0
  171. package/dist/web/assets/last-call-D-O5O94z.js +1 -0
  172. package/dist/web/assets/listener-handled-HNCuVrQ7.js +1 -0
  173. package/dist/web/assets/login-DaeKclcf.js +1 -0
  174. package/dist/web/assets/mail-C5fm2pTC.js +1 -0
  175. package/dist/web/assets/mcp-call-UoOTPFyh.js +1 -0
  176. package/dist/web/assets/mcp-call-card-Cr-OEDX2.js +3 -0
  177. package/dist/web/assets/message-square-quote-se8Bf3RP.js +1 -0
  178. package/dist/web/assets/mutations-CLPqJ6cj.js +1 -0
  179. package/dist/web/assets/network-igNw0VVx.js +1 -0
  180. package/dist/web/assets/pairing-XjuaVr2u.js +1 -0
  181. package/dist/web/assets/pairing-notifier-KPzOEZSO.js +1 -0
  182. package/dist/web/assets/paperclip-znS4iTrg.js +1 -0
  183. package/dist/web/assets/password-input-DV3aqcNf.js +1 -0
  184. package/dist/web/assets/pause-o-dK3khK.js +1 -0
  185. package/dist/web/assets/pencil-DkPFAhEq.js +1 -0
  186. package/dist/web/assets/play-DvCHND93.js +1 -0
  187. package/dist/web/assets/plug-CXAniEiR.js +1 -0
  188. package/dist/web/assets/plug-zap-BwR-l5wb.js +1 -0
  189. package/dist/web/assets/plus-B_TUslu3.js +1 -0
  190. package/dist/web/assets/preload-helper-Cc_aKyUb.js +1 -0
  191. package/dist/web/assets/public-url-rF2Xjyel.js +1 -0
  192. package/dist/web/assets/queries-Cv3nXx0U.js +42 -0
  193. package/dist/web/assets/refresh-cw-Ch5FNrby.js +1 -0
  194. package/dist/web/assets/revealed-keys-C_9NtJPY.js +1 -0
  195. package/dist/web/assets/rolldown-runtime-XKyaHtl9.js +1 -0
  196. package/dist/web/assets/rotate-ccw-B-mzPDk0.js +1 -0
  197. package/dist/web/assets/search-CTVKGomS.js +1 -0
  198. package/dist/web/assets/select-Bb806bpq.js +1 -0
  199. package/dist/web/assets/send-DuMVuYs1.js +1 -0
  200. package/dist/web/assets/settings-BWauhfFf.js +1 -0
  201. package/dist/web/assets/setup-B7bNKQOp.js +1 -0
  202. package/dist/web/assets/sheet-CYPwpUsH.js +1 -0
  203. package/dist/web/assets/shield-alert-CSYB-ThV.js +1 -0
  204. package/dist/web/assets/shield-check-BulpsYqK.js +1 -0
  205. package/dist/web/assets/sparkles-CUTiob4K.js +1 -0
  206. package/dist/web/assets/stamp-BNXUGNa3.js +1 -0
  207. package/dist/web/assets/step-url-51aMNak-.js +1 -0
  208. package/dist/web/assets/stream-Du7fY5_Y.js +1 -0
  209. package/dist/web/assets/tag-I5_-1jFL.js +1 -0
  210. package/dist/web/assets/terminal-BvxDFTJc.js +1 -0
  211. package/dist/web/assets/test-email-button-DYi7V_6X.js +1 -0
  212. package/dist/web/assets/toggle-group-Bdo1gmQ1.js +1 -0
  213. package/dist/web/assets/trash-Ci0aICEl.js +1 -0
  214. package/dist/web/assets/use-delivery-speed-BBh7W2q6.js +1 -0
  215. package/dist/web/assets/use-label-names-BXicesnP.js +1 -0
  216. package/dist/web/assets/use-sign-out-CPrY_oVO.js +1 -0
  217. package/dist/web/assets/useInfiniteQuery-DJLIM8yJ.js +1 -0
  218. package/dist/web/assets/useQuery-MrTwwNy5.js +1 -0
  219. package/dist/web/assets/useRouterState-D4OBK8l5.js +1 -0
  220. package/dist/web/assets/webhook-DjeeZiNC.js +1 -0
  221. package/dist/web/assets/webhook-bits-jw-y2D3u.js +1 -0
  222. package/dist/web/assets/webhook-sheet-B8h0skDe.js +34 -0
  223. package/dist/web/assets/webhooks-Cfsdpoyd.js +1 -0
  224. package/dist/web/assets/x-MF2TZ9aG.js +1 -0
  225. package/dist/web/favicon.svg +1 -0
  226. package/dist/web/index.html +27 -0
  227. package/package.json +98 -1
@@ -0,0 +1,477 @@
1
+ #!/usr/bin/env node
2
+ import { t as NPX } from "./version-BxH7OuWD.js";
3
+ import { i as safeText } from "./ui-B8Sd4Y7Y.js";
4
+ import { a as urlHost, r as normalizeIp } from "./ssrf-BlVpGZ7C.js";
5
+ import { BlockList, isIP } from "node:net";
6
+ import pc from "picocolors";
7
+ import { lookup } from "node:dns/promises";
8
+ //#region server/connections-cli/access.ts
9
+ /** The one access question (docs/MCP-BROKER.md "Access and approvals") and which agents get it. */
10
+ const ACCESS_LEVELS = [
11
+ {
12
+ value: "full",
13
+ label: "Full access: every tool, never asks",
14
+ short: "Full access"
15
+ },
16
+ {
17
+ value: "ask",
18
+ label: "Ask before risky actions: deleting, sending, publishing and payments wait for your approval",
19
+ short: "Ask before risky actions"
20
+ },
21
+ {
22
+ value: "read",
23
+ label: "Read only: only tools that read; the rest aren't listed",
24
+ short: "Read only"
25
+ }
26
+ ];
27
+ const accessLabel = (level) => ACCESS_LEVELS.find((l) => l.value === level)?.short ?? level;
28
+ function parseAccess(value) {
29
+ const v = value.trim().toLowerCase();
30
+ const map = {
31
+ full: "full",
32
+ ask: "ask",
33
+ risky: "ask",
34
+ read: "read",
35
+ "read-only": "read",
36
+ readonly: "read"
37
+ };
38
+ if (!map[v]) throw new Error(`Unknown --access "${value}". Use full, ask or read.`);
39
+ return map[v];
40
+ }
41
+ async function chooseAccess(p, flag) {
42
+ if (flag) return flag;
43
+ return p.choose("What can agents do with it?", ACCESS_LEVELS.map((l) => ({
44
+ value: l.value,
45
+ label: l.label
46
+ })), "ask");
47
+ }
48
+ /** Agent ids, or "all". `--agent` takes names or ids. */
49
+ async function chooseAgents(p, api, flags) {
50
+ const agents = (await api.agents()).filter((a) => !a.disabled);
51
+ if (flags?.length) {
52
+ if (flags.length === 1 && flags[0] === "all") return "all";
53
+ return flags.map((f) => {
54
+ const hit = agents.find((a) => a.id === f || a.name.toLowerCase() === f.toLowerCase());
55
+ if (!hit) throw new Error(`No agent "${f}". Agents: ${agents.map((a) => a.name).join(", ") || "none yet"}.`);
56
+ return hit.id;
57
+ });
58
+ }
59
+ if (agents.length <= 1 || p.assumeYes || !p.interactive) return "all";
60
+ if (await p.confirm(`Give it to all ${agents.length} agents (${agents.map((a) => safeText(a.name, 40)).join(", ")})?`, true)) return "all";
61
+ const picked = [];
62
+ for (const a of agents) if (await p.confirm(` ${safeText(a.name, 60)}?`, false)) picked.push(a.id);
63
+ if (!picked.length) p.print(pc.yellow("No agent gets it for now: give access on an agent's page in the console."));
64
+ return picked;
65
+ }
66
+ const agentsLabel = (agents) => agents === "all" ? "all agents" : `${agents.length} agent${agents.length === 1 ? "" : "s"}`;
67
+ //#endregion
68
+ //#region server/connections-cli/private.ts
69
+ /**
70
+ * Which upstream URLs need the private-target allow (docs/MCP-BROKER.md#private-targets), decided on the CLI side
71
+ * so the admin can confirm the exact origins before anything is created. The daemon's guard still decides; this
72
+ * only knows what to ask.
73
+ */
74
+ /** The ranges a private-target allow may cover: loopback, RFC 1918, CGNAT (Tailscale), ULA. */
75
+ const ALLOWABLE = new BlockList();
76
+ for (const [net, prefix] of [
77
+ ["127.0.0.0", 8],
78
+ ["10.0.0.0", 8],
79
+ ["172.16.0.0", 12],
80
+ ["192.168.0.0", 16],
81
+ ["100.64.0.0", 10]
82
+ ]) ALLOWABLE.addSubnet(net, prefix, "ipv4");
83
+ ALLOWABLE.addAddress("::1", "ipv6");
84
+ ALLOWABLE.addSubnet("fc00::", 7, "ipv6");
85
+ /** Never allowed, even by an admin: link-local and cloud metadata. */
86
+ const NEVER = new BlockList();
87
+ NEVER.addSubnet("169.254.0.0", 16, "ipv4");
88
+ NEVER.addSubnet("fe80::", 10, "ipv6");
89
+ NEVER.addAddress("fd00:ec2::254", "ipv6");
90
+ NEVER.addAddress("100.100.100.200", "ipv4");
91
+ function classifyAddress(ip) {
92
+ const a = normalizeIp(ip);
93
+ const family = isIP(a) === 6 ? "ipv6" : "ipv4";
94
+ if (NEVER.check(a, family)) return "never";
95
+ if (ALLOWABLE.check(a, family)) return "private";
96
+ return "public";
97
+ }
98
+ /** `scheme://host:port` with the port always spelled out: exactly what a private-target allow pins. */
99
+ function exactOrigin(url) {
100
+ const port = url.port || (url.protocol === "https:" ? "443" : "80");
101
+ return `${url.protocol}//${url.hostname}:${port}`;
102
+ }
103
+ const defaultLookup = (hostname) => lookup(hostname, {
104
+ all: true,
105
+ verbatim: true
106
+ });
107
+ /** Whether `url` is on this machine or a private network (resolving names the way the daemon on this host will). */
108
+ async function checkTarget(url, lookup = defaultLookup) {
109
+ const host = urlHost(url);
110
+ let addresses;
111
+ if (isIP(host)) addresses = [host];
112
+ else if (host === "localhost" || host.endsWith(".localhost")) addresses = ["127.0.0.1"];
113
+ else try {
114
+ addresses = (await lookup(host)).map((a) => a.address);
115
+ } catch {
116
+ return { kind: "public" };
117
+ }
118
+ const never = addresses.find((a) => classifyAddress(a) === "never");
119
+ if (never) return {
120
+ kind: "never",
121
+ address: never,
122
+ why: "link_local"
123
+ };
124
+ const priv = addresses.filter((a) => classifyAddress(a) === "private");
125
+ if (priv.length && isIP(host) === 6) return {
126
+ kind: "never",
127
+ address: host,
128
+ why: "ipv6_literal"
129
+ };
130
+ return priv.length ? {
131
+ kind: "private",
132
+ origin: exactOrigin(url),
133
+ addresses: priv
134
+ } : { kind: "public" };
135
+ }
136
+ //#endregion
137
+ //#region server/connections-cli/util.ts
138
+ /** A connection slug (`[a-z0-9-]{1,24}`, like the presets') from a client's server name or a host. */
139
+ function slugify(name) {
140
+ return name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "").slice(0, 24).replace(/-+$/, "") || "server";
141
+ }
142
+ const validSlug = (s) => /^[a-z0-9-]{1,24}$/.test(s);
143
+ /** How to reconnect it later. */
144
+ function reconnectHint(c) {
145
+ return `Reconnect: ${NPX} connections reconnect ${c.slug} (or Connections → Reconnect in the console)`;
146
+ }
147
+ //#endregion
148
+ //#region server/connections-cli/manage.ts
149
+ const isUrl = (s) => /^https?:\/\//i.test(s.trim());
150
+ /** Renders a preset's setup step in the terminal (the console renders the same steps). */
151
+ function renderStep(step, n) {
152
+ const out = [pc.bold(`${n}. ${safeText(step.title, 120)}`)];
153
+ for (const para of step.body.split(/\n{2,}/)) out.push(` ${para.replace(/\s*\n\s*/g, " ").replace(/`([^`]+)`/g, (_m, c) => pc.cyan(c))}`);
154
+ if (step.link) out.push(` ${step.link.label}: ${pc.cyan(step.link.url)}`);
155
+ if (step.copy) out.push(` ${step.copy.label}: ${pc.cyan(step.copy.value)}`);
156
+ return out;
157
+ }
158
+ async function askInput(p, input) {
159
+ for (;;) {
160
+ const v = input.secret ? await p.secret(input.label) : await p.ask(input.label);
161
+ if (!v) {
162
+ p.print(pc.yellow(" This is needed to continue."));
163
+ continue;
164
+ }
165
+ if (input.pattern && !new RegExp(input.pattern).test(v)) {
166
+ p.print(pc.yellow(` That doesn't look right${input.placeholder ? ` (it looks like ${input.placeholder})` : ""}.`));
167
+ continue;
168
+ }
169
+ return v;
170
+ }
171
+ }
172
+ async function askSlug(p, flag, def, taken) {
173
+ if (flag) {
174
+ if (!validSlug(flag)) throw new Error(`--slug "${flag}": use 1-24 lowercase letters, digits and dashes.`);
175
+ if (taken.has(flag)) throw new Error(`There's already a connection "${flag}".`);
176
+ return flag;
177
+ }
178
+ let suggestion = def;
179
+ for (let n = 2; taken.has(suggestion); n++) suggestion = `${def.slice(0, 21)}-${n}`;
180
+ for (;;) {
181
+ const s = (await p.ask("Name it (agents see its tools as <name>__<tool>)", suggestion)).toLowerCase();
182
+ if (!validSlug(s)) p.print(pc.yellow(" Use 1-24 lowercase letters, digits and dashes."));
183
+ else if (taken.has(s)) p.print(pc.yellow(` There's already a connection "${s}".`));
184
+ else return s;
185
+ }
186
+ }
187
+ /** A slug from a URL: the host's first label that says something (mcp.notion.com → notion). */
188
+ function slugFromUrl(url) {
189
+ const labels = url.hostname.split(".").filter((l) => ![
190
+ "mcp",
191
+ "api",
192
+ "www"
193
+ ].includes(l));
194
+ return slugify(/^\d/.test(url.hostname) || url.hostname.includes(":") ? `${url.hostname}-${url.port || "mcp"}` : labels[0] ?? url.hostname);
195
+ }
196
+ const registrationWords = {
197
+ preregistered: "with a registered client",
198
+ metadata_document: "registers itself automatically (client metadata document)",
199
+ dcr: "registers itself automatically (dynamic client registration)",
200
+ manual: "needs a client ID you get from the provider"
201
+ };
202
+ const overSsh = (env) => !!(env.SSH_CONNECTION || env.SSH_TTY || env.SSH_CLIENT);
203
+ const isLoopbackHost = (h) => h === "localhost" || h === "127.0.0.1" || h === "[::1]" || h === "::1";
204
+ /** Where the provider sends the browser after consent: the authorize URL's redirect_uri. */
205
+ function redirectOf(authorizeUrl) {
206
+ try {
207
+ const r = new URL(authorizeUrl).searchParams.get("redirect_uri");
208
+ return r ? new URL(r) : null;
209
+ } catch {
210
+ return null;
211
+ }
212
+ }
213
+ /**
214
+ * OAuth: open the browser and wait for the callback, or paste the address the browser lands on: over SSH when the
215
+ * redirect goes to localhost (the browser isn't on this machine), and always for an https://localhost redirect
216
+ * (providers that refuse http, where nothing listens).
217
+ */
218
+ async function authorize(conn, start, deps, flags = {}) {
219
+ const { api, prompter: p } = deps;
220
+ const env = deps.env ?? process.env;
221
+ const authorizeUrl = start.authorizeUrl;
222
+ const redirect = (() => {
223
+ try {
224
+ return start.redirectUri ? new URL(start.redirectUri) : redirectOf(authorizeUrl);
225
+ } catch {
226
+ return redirectOf(authorizeUrl);
227
+ }
228
+ })();
229
+ const loopback = !!redirect && isLoopbackHost(redirect.hostname);
230
+ const paste = !!flags.paste || start.callbackMode === "paste" || loopback && (overSsh(env) || redirect.protocol === "https:");
231
+ const name = safeText(conn.name, 60);
232
+ if (paste) {
233
+ p.print(`Open this link in a browser where you can sign in to ${name}:`);
234
+ p.print(` ${pc.cyan(authorizeUrl)}`);
235
+ const start = redirect ? `${redirect.origin}${redirect.pathname}` : "the callback address";
236
+ p.print(pc.dim(`After you approve, the browser goes to an address starting with ${start} (it may say the page can't be reached). Copy that whole address.`));
237
+ for (;;) {
238
+ const pasted = await p.ask("Paste the address here");
239
+ if (!/[?&](code|error)=/.test(pasted)) {
240
+ p.print(pc.yellow(` That isn't the address after signing in: it starts with ${start} and has ?code=… in it.`));
241
+ continue;
242
+ }
243
+ const r = await api.finish(pasted.trim());
244
+ if (r.status === "connected") return r.connection;
245
+ throw new Error(r.status === "error" ? r.message : "The sign-in didn't finish.");
246
+ }
247
+ }
248
+ const stamp = () => api.channel.credentialStamp(conn.id);
249
+ const before = stamp();
250
+ const beforeView = await api.get(conn.id);
251
+ p.print(`Opening your browser to sign in to ${name}. If it doesn't open, use this link:`);
252
+ p.print(` ${pc.cyan(authorizeUrl)}`);
253
+ try {
254
+ await (deps.openBrowser ?? (async (u) => (await import("open")).default(u)))(authorizeUrl);
255
+ } catch {}
256
+ const pollMs = deps.pollMs ?? 2e3;
257
+ const deadline = Date.now() + (deps.timeoutMs ?? 9e5);
258
+ p.print(pc.dim("Waiting for you to approve in the browser… (Ctrl+C to stop)"));
259
+ while (Date.now() < deadline) {
260
+ await new Promise((r) => setTimeout(r, pollMs));
261
+ const now = await api.get(conn.id);
262
+ const after = stamp();
263
+ const changed = after !== null ? after !== before : now.expiresAt !== beforeView.expiresAt || now.updatedAt !== beforeView.updatedAt;
264
+ if (now.status === "active" && changed) return now;
265
+ }
266
+ throw new Error(`Timed out waiting for the sign-in. Try again with \`${NPX} connections reconnect ${conn.slug}\`${overSsh(env) ? "" : " (add --paste to paste the address instead)"}.`);
267
+ }
268
+ /** Working = active with at least one tool listed: a "connected" answer alone isn't proof (a header isn't tested). */
269
+ const isWorking = (c) => c.status === "active" && c.tools.total > 0;
270
+ /**
271
+ * Waits briefly for a just-connected connection's first tool sync: until it works, turns needs_reauth / error /
272
+ * disabled, or `ms` pass. Returns the last view.
273
+ */
274
+ async function waitWorking(api, c, opts = {}) {
275
+ let now = c;
276
+ const deadline = Date.now() + (opts.ms ?? 1e4);
277
+ while (!isWorking(now) && now.status === "active" && Date.now() < deadline) {
278
+ await new Promise((r) => setTimeout(r, opts.pollMs ?? 500));
279
+ now = await api.get(c.id);
280
+ }
281
+ return now;
282
+ }
283
+ /** Connects (header, setup inputs, or OAuth) and returns the connection as it ends up. */
284
+ async function connectNow(conn, input, deps, flags = {}) {
285
+ const r = await deps.api.connect(conn.id, input);
286
+ if (r.status === "connected") return waitWorking(deps.api, r.connection, {
287
+ pollMs: deps.pollMs,
288
+ ms: deps.timeoutMs === void 0 ? void 0 : Math.min(deps.timeoutMs, 1e4)
289
+ });
290
+ if (r.status === "authorize") return waitWorking(deps.api, await authorize(conn, r, deps, flags), {
291
+ pollMs: deps.pollMs,
292
+ ms: deps.timeoutMs === void 0 ? void 0 : Math.min(deps.timeoutMs, 1e4)
293
+ });
294
+ throw new Error(r.message);
295
+ }
296
+ function printResult(p, c) {
297
+ if (isWorking(c)) p.print(`${pc.green("✔")} Connected "${c.slug}": ${c.tools.total} tool${c.tools.total === 1 ? "" : "s"}, seen by agents as ${c.slug}__<tool> (${accessLabel(c.levelDefault)}).`);
298
+ else {
299
+ p.print(`${pc.yellow("○")} "${c.slug}" isn't working yet: ${c.status}${c.statusReason ? ` (${safeText(c.statusReason, 200)})` : ""}, ${c.tools.total} tools.`);
300
+ p.print(` ${reconnectHint(c)}`);
301
+ }
302
+ }
303
+ /** The access question, the agents, then create; `after` runs on the new connection (allow, connect). */
304
+ async function createThen(base, flags, deps, after) {
305
+ const { api, prompter: p } = deps;
306
+ const level = await chooseAccess(p, flags.access ? parseAccess(flags.access) : void 0);
307
+ const agents = await chooseAgents(p, api, flags.agent);
308
+ if (!await p.confirm(`Add "${base.slug}" (${accessLabel(level)}, ${agentsLabel(agents)})?`, true)) {
309
+ p.print("Nothing was added.");
310
+ return 0;
311
+ }
312
+ const created = await api.create({
313
+ ...base,
314
+ levelDefault: level,
315
+ ...agents === "all" ? {} : { agentIds: agents }
316
+ });
317
+ let conn;
318
+ try {
319
+ conn = await after(created);
320
+ } catch (err) {
321
+ p.print(pc.yellow(`"${created.slug}" was added but isn't connected: ${safeText(err instanceof Error ? err.message : String(err), 300)}`));
322
+ p.print(` ${reconnectHint(created)} (or remove it: ${NPX} connections remove ${created.slug})`);
323
+ return 1;
324
+ }
325
+ printResult(p, conn);
326
+ return isWorking(conn) ? 0 : 1;
327
+ }
328
+ async function addPreset(preset, flags, deps, taken) {
329
+ const p = deps.prompter;
330
+ p.print(pc.bold(`Connect ${safeText(preset.displayName, 60)}`));
331
+ preset.setupSteps.forEach((step, i) => {
332
+ for (const l of renderStep(step, i + 1)) p.print(l);
333
+ });
334
+ const inputs = {};
335
+ for (const step of preset.setupSteps) if (step.input) inputs[step.input.key] = await askInput(p, step.input);
336
+ let header;
337
+ if (preset.authType === "header") {
338
+ const name = flags.header ?? "Authorization";
339
+ header = {
340
+ name,
341
+ value: await askInput(p, {
342
+ key: "header",
343
+ label: `${name} value (not shown)`,
344
+ secret: true
345
+ })
346
+ };
347
+ }
348
+ const slug = await askSlug(p, flags.slug, preset.slug, taken);
349
+ const input = {
350
+ ...header ? { header } : {},
351
+ ...Object.keys(inputs).length ? { inputs } : {}
352
+ };
353
+ return createThen({
354
+ slug,
355
+ name: preset.displayName,
356
+ preset: preset.id
357
+ }, flags, deps, (c) => connectNow(c, input, deps, flags));
358
+ }
359
+ async function headerFor(p, flags) {
360
+ const name = flags.header ?? await p.ask("Header name", "Authorization");
361
+ const value = await askInput(p, {
362
+ key: "header",
363
+ label: `${name} value (not shown)`,
364
+ secret: true
365
+ });
366
+ return {
367
+ name,
368
+ value: /^authorization$/i.test(name) && !/\s/.test(value) ? `Bearer ${value}` : value
369
+ };
370
+ }
371
+ function describeProbe(p, probe) {
372
+ if (probe.auth === "oauth") p.print(`It signs in with OAuth${probe.issuer ? ` via ${safeText(probe.issuer, 120)}` : ""}${probe.registration ? `, and ${registrationWords[probe.registration] ?? probe.registration}` : ""}.`);
373
+ else if (probe.auth === "header") p.print(`It needs an API key or token. ${safeText(probe.message, 200)}`);
374
+ else if (probe.auth === "none") p.print("It doesn't need a sign-in.");
375
+ else p.print(safeText(probe.message, 200));
376
+ }
377
+ const MANUAL_CLIENT = "It needs a client ID from the provider; finish it in the console's Connections page.";
378
+ async function addUrl(raw, flags, deps, taken) {
379
+ const { api, prompter: p } = deps;
380
+ let url;
381
+ try {
382
+ url = new URL(raw.trim());
383
+ } catch {
384
+ throw new Error(`"${raw}" isn't a URL. Use the server's full MCP address, e.g. https://mcp.example.com/mcp.`);
385
+ }
386
+ p.print(`Checking ${pc.cyan(url.href)}…`);
387
+ const probe = await api.probe(url.href);
388
+ let allowPrivate = false;
389
+ let header;
390
+ if (probe.blocked === "private_target") {
391
+ const origin = exactOrigin(url);
392
+ p.print(pc.yellow(`${url.host} is on this machine or your private network.`));
393
+ p.print(`xaq blocks those by default: a connection to a server there can reach other services on the same machine or network. An allow covers exactly ${origin}, for this connection only (and plain http on that host).`);
394
+ if (!(flags.allowPrivate === origin || await p.confirmExplicit(`Allow this connection to reach ${origin}?`, `nothing was added (pass --allow-private ${origin} to allow it)`))) {
395
+ p.print("Nothing was added.");
396
+ return 0;
397
+ }
398
+ allowPrivate = true;
399
+ } else if (probe.blocked || !probe.reachable) throw new Error(probe.message);
400
+ else {
401
+ describeProbe(p, probe);
402
+ if (probe.auth === "oauth" && probe.registration === "manual") throw new Error(MANUAL_CLIENT);
403
+ if (probe.auth === "header") header = await headerFor(p, flags);
404
+ }
405
+ return createThen({
406
+ slug: await askSlug(p, flags.slug, slugFromUrl(url), taken),
407
+ name: url.hostname,
408
+ url: url.href
409
+ }, flags, deps, async (c) => {
410
+ if (allowPrivate) {
411
+ await api.allowPrivateTarget(c.id, true);
412
+ const again = await api.probe(url.href, c.id);
413
+ if (again.blocked || !again.reachable) throw new Error(again.message);
414
+ describeProbe(p, again);
415
+ if (again.auth === "oauth" && again.registration === "manual") throw new Error(MANUAL_CLIENT);
416
+ if (again.auth === "header") header = await headerFor(p, flags);
417
+ }
418
+ return connectNow(c, header ? { header } : {}, deps, flags);
419
+ });
420
+ }
421
+ async function addConnection(target, flags, deps) {
422
+ const existing = await deps.api.list();
423
+ const taken = new Set(existing.map((c) => c.slug));
424
+ if (isUrl(target)) return addUrl(target, flags, deps, taken);
425
+ const presets = await deps.api.presets();
426
+ const preset = presets.find((x) => x.id === target.trim().toLowerCase());
427
+ if (!preset) throw new Error(`Unknown integration "${target}". Use ${[...presets.map((x) => x.id), "<an MCP server URL>"].join(", ")}.`);
428
+ return addPreset(preset, flags, deps, taken);
429
+ }
430
+ async function listConnections(deps) {
431
+ const { api, prompter: p } = deps;
432
+ const all = await api.list();
433
+ if (!all.length) {
434
+ p.print(`No connections yet. Add one: ${NPX} connections add notion|whoop|<url>`);
435
+ return 0;
436
+ }
437
+ const w = Math.max(4, ...all.map((c) => c.slug.length));
438
+ p.print(pc.dim(`${"NAME".padEnd(w)} ${"STATUS".padEnd(12)} ${"ACCESS".padEnd(24)} ${"TOOLS".padEnd(5)} URL`));
439
+ for (const c of all) {
440
+ const status = c.status === "active" ? pc.green(c.status.padEnd(12)) : pc.yellow(c.status.padEnd(12));
441
+ const notes = [];
442
+ if (c.privateTarget) notes.push("private network");
443
+ const d = c.expiresInDays;
444
+ if (d !== null && d <= 7) notes.push(d <= 0 ? "expires today: Reconnect" : `expires in ${d} day${d === 1 ? "" : "s"}`);
445
+ if (c.tools.held) notes.push(`${c.tools.held} held`);
446
+ if (c.status === "needs_reauth") notes.push("Reconnect");
447
+ p.print(`${c.slug.padEnd(w)} ${status} ${accessLabel(c.levelDefault).padEnd(24)} ${String(c.tools.total).padEnd(5)} ${safeText(c.url ?? c.kind, 80)}${notes.length ? pc.yellow(` (${notes.join(", ")})`) : ""}`);
448
+ }
449
+ return 0;
450
+ }
451
+ async function reconnectConnection(slug, flags, deps) {
452
+ const { api, prompter: p } = deps;
453
+ const c = await api.bySlug(slug);
454
+ const after = await connectNow(c, c.authType === "header" ? { header: await headerFor(p, flags) } : {}, deps, flags);
455
+ printResult(p, after);
456
+ return isWorking(after) ? 0 : 1;
457
+ }
458
+ async function disableConnection(slug, deps) {
459
+ const { api, prompter: p } = deps;
460
+ const c = await api.bySlug(slug);
461
+ if (!await p.confirm(`Disable "${slug}"? Agents lose its tools at once, its pending approvals are cancelled and its stored credentials are deleted.`, false)) return 0;
462
+ await api.kill(c.id);
463
+ p.print(`${pc.green("✔")} Disabled "${slug}". To use it again, turn it on in the console's Connections page and reconnect.`);
464
+ return 0;
465
+ }
466
+ async function removeConnection(slug, deps) {
467
+ const { api, prompter: p } = deps;
468
+ const c = await api.bySlug(slug);
469
+ if (!await p.confirm(`Remove "${slug}" and delete its stored credentials? This can't be undone.`, false)) return 0;
470
+ await api.remove(c.id);
471
+ p.print(`${pc.green("✔")} Removed "${slug}".`);
472
+ return 0;
473
+ }
474
+ //#endregion
475
+ export { chooseAccess as _, isWorking as a, removeConnection as c, waitWorking as d, reconnectHint as f, agentsLabel as g, accessLabel as h, disableConnection as i, renderStep as l, checkTarget as m, authorize as n, listConnections as o, slugify as p, connectNow as r, reconnectConnection as s, addConnection as t, slugFromUrl as u, chooseAgents as v, parseAccess as y };
476
+
477
+ //# sourceMappingURL=manage-Bo6COB4p.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manage-Bo6COB4p.js","names":["dnsLookup"],"sources":["../server/connections-cli/access.ts","../server/connections-cli/private.ts","../server/connections-cli/util.ts","../server/connections-cli/manage.ts"],"sourcesContent":["import pc from \"picocolors\";\nimport type { AccessLevel } from \"../broker/types.ts\";\nimport type { ConnectionsApi } from \"./api.ts\";\nimport type { Prompter } from \"./prompt.ts\";\nimport { safeText } from \"../listen/ui.ts\";\n\n/** The one access question (docs/MCP-BROKER.md \"Access and approvals\") and which agents get it. */\n\nexport const ACCESS_LEVELS: { value: AccessLevel; label: string; short: string }[] = [\n { value: \"full\", label: \"Full access: every tool, never asks\", short: \"Full access\" },\n { value: \"ask\", label: \"Ask before risky actions: deleting, sending, publishing and payments wait for your approval\", short: \"Ask before risky actions\" },\n { value: \"read\", label: \"Read only: only tools that read; the rest aren't listed\", short: \"Read only\" },\n];\n\nexport const accessLabel = (level: AccessLevel) => ACCESS_LEVELS.find((l) => l.value === level)?.short ?? level;\n\nexport function parseAccess(value: string): AccessLevel {\n const v = value.trim().toLowerCase();\n const map: Record<string, AccessLevel> = { full: \"full\", ask: \"ask\", risky: \"ask\", read: \"read\", \"read-only\": \"read\", readonly: \"read\" };\n if (!map[v]) throw new Error(`Unknown --access \"${value}\". Use full, ask or read.`);\n return map[v];\n}\n\nexport async function chooseAccess(p: Prompter, flag: AccessLevel | undefined): Promise<AccessLevel> {\n if (flag) return flag;\n return p.choose(\n \"What can agents do with it?\",\n ACCESS_LEVELS.map((l) => ({ value: l.value, label: l.label })),\n \"ask\",\n );\n}\n\n/** Agent ids, or \"all\". `--agent` takes names or ids. */\nexport async function chooseAgents(p: Prompter, api: ConnectionsApi, flags: string[] | undefined): Promise<string[] | \"all\"> {\n const agents = (await api.agents()).filter((a) => !a.disabled);\n if (flags?.length) {\n if (flags.length === 1 && flags[0] === \"all\") return \"all\";\n return flags.map((f) => {\n const hit = agents.find((a) => a.id === f || a.name.toLowerCase() === f.toLowerCase());\n if (!hit) throw new Error(`No agent \"${f}\". Agents: ${agents.map((a) => a.name).join(\", \") || \"none yet\"}.`);\n return hit.id;\n });\n }\n if (agents.length <= 1 || p.assumeYes || !p.interactive) return \"all\";\n const all = await p.confirm(`Give it to all ${agents.length} agents (${agents.map((a) => safeText(a.name, 40)).join(\", \")})?`, true);\n if (all) return \"all\";\n const picked: string[] = [];\n for (const a of agents) if (await p.confirm(` ${safeText(a.name, 60)}?`, false)) picked.push(a.id);\n if (!picked.length) p.print(pc.yellow(\"No agent gets it for now: give access on an agent's page in the console.\"));\n return picked;\n}\n\nexport const agentsLabel = (agents: string[] | \"all\") => (agents === \"all\" ? \"all agents\" : `${agents.length} agent${agents.length === 1 ? \"\" : \"s\"}`);\n","import { lookup as dnsLookup } from \"node:dns/promises\";\nimport { BlockList, isIP } from \"node:net\";\nimport { type LookupFn, normalizeIp, urlHost } from \"../webhooks/ssrf.ts\";\n\n/**\n * Which upstream URLs need the private-target allow (docs/MCP-BROKER.md#private-targets), decided on the CLI side\n * so the admin can confirm the exact origins before anything is created. The daemon's guard still decides; this\n * only knows what to ask.\n */\n\n/** The ranges a private-target allow may cover: loopback, RFC 1918, CGNAT (Tailscale), ULA. */\nconst ALLOWABLE = new BlockList();\nfor (const [net, prefix] of [\n [\"127.0.0.0\", 8],\n [\"10.0.0.0\", 8],\n [\"172.16.0.0\", 12],\n [\"192.168.0.0\", 16],\n [\"100.64.0.0\", 10],\n] as const) {\n ALLOWABLE.addSubnet(net, prefix, \"ipv4\");\n}\nALLOWABLE.addAddress(\"::1\", \"ipv6\");\nALLOWABLE.addSubnet(\"fc00::\", 7, \"ipv6\");\n\n/** Never allowed, even by an admin: link-local and cloud metadata. */\nconst NEVER = new BlockList();\nNEVER.addSubnet(\"169.254.0.0\", 16, \"ipv4\");\nNEVER.addSubnet(\"fe80::\", 10, \"ipv6\");\nNEVER.addAddress(\"fd00:ec2::254\", \"ipv6\");\nNEVER.addAddress(\"100.100.100.200\", \"ipv4\");\n\nexport type AddressClass = \"public\" | \"private\" | \"never\";\n\nexport function classifyAddress(ip: string): AddressClass {\n const a = normalizeIp(ip);\n const family = isIP(a) === 6 ? \"ipv6\" : \"ipv4\";\n if (NEVER.check(a, family)) return \"never\";\n if (ALLOWABLE.check(a, family)) return \"private\";\n return \"public\";\n}\n\n/** `scheme://host:port` with the port always spelled out: exactly what a private-target allow pins. */\nexport function exactOrigin(url: URL): string {\n const port = url.port || (url.protocol === \"https:\" ? \"443\" : \"80\");\n return `${url.protocol}//${url.hostname}:${port}`;\n}\n\nexport type TargetCheck =\n | { kind: \"public\" }\n | { kind: \"private\"; origin: string; addresses: string[] }\n /** link_local: link-local or cloud metadata; ipv6_literal: the allow takes hostnames and IPv4 only. */\n | { kind: \"never\"; address: string; why: \"link_local\" | \"ipv6_literal\" };\n\nconst defaultLookup: LookupFn = (hostname) => dnsLookup(hostname, { all: true, verbatim: true });\n\n/** Whether `url` is on this machine or a private network (resolving names the way the daemon on this host will). */\nexport async function checkTarget(url: URL, lookup: LookupFn = defaultLookup): Promise<TargetCheck> {\n const host = urlHost(url);\n let addresses: string[];\n if (isIP(host)) addresses = [host];\n else if (host === \"localhost\" || host.endsWith(\".localhost\")) addresses = [\"127.0.0.1\"];\n else {\n try {\n addresses = (await lookup(host)).map((a) => a.address);\n } catch {\n // Unresolvable here: the daemon's probe reports it.\n return { kind: \"public\" };\n }\n }\n const never = addresses.find((a) => classifyAddress(a) === \"never\");\n if (never) return { kind: \"never\", address: never, why: \"link_local\" };\n const priv = addresses.filter((a) => classifyAddress(a) === \"private\");\n if (priv.length && isIP(host) === 6) return { kind: \"never\", address: host, why: \"ipv6_literal\" };\n return priv.length ? { kind: \"private\", origin: exactOrigin(url), addresses: priv } : { kind: \"public\" };\n}\n","import { NPX } from \"../listen/version.ts\";\n\n/** A connection slug (`[a-z0-9-]{1,24}`, like the presets') from a client's server name or a host. */\nexport function slugify(name: string): string {\n const s = name\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \"-\")\n .replace(/^-+|-+$/g, \"\")\n .slice(0, 24)\n .replace(/-+$/, \"\");\n return s || \"server\";\n}\n\nexport const validSlug = (s: string) => /^[a-z0-9-]{1,24}$/.test(s);\n\n/** How to reconnect it later. */\nexport function reconnectHint(c: { slug: string }): string {\n return `Reconnect: ${NPX} connections reconnect ${c.slug} (or Connections → Reconnect in the console)`;\n}\n","import pc from \"picocolors\";\nimport type { SetupStepView, StartConnectInput } from \"../../shared/types.ts\";\nimport { safeText } from \"../listen/ui.ts\";\nimport { NPX } from \"../listen/version.ts\";\nimport { accessLabel, agentsLabel, chooseAccess, chooseAgents, parseAccess } from \"./access.ts\";\nimport type { ConnectionProbe, ConnectionsApi, ConnectionView, PresetView } from \"./api.ts\";\nimport { exactOrigin } from \"./private.ts\";\nimport type { Prompter } from \"./prompt.ts\";\nimport { reconnectHint, slugify, validSlug } from \"./util.ts\";\n\n/** `connections add | list | reconnect | disable | remove`. */\n\nexport interface AddFlags {\n slug?: string;\n access?: string;\n agent?: string[];\n /** Header name for a server that wants a static key (default Authorization). */\n header?: string;\n /** Always paste the address the browser lands on, instead of waiting for the redirect. */\n paste?: boolean;\n /** The exact `scheme://host:port` to allow without asking (--yes never allows one). */\n allowPrivate?: string;\n yes?: boolean;\n}\n\nexport interface ManageDeps {\n prompter: Prompter;\n api: ConnectionsApi;\n openBrowser?: (url: string) => Promise<unknown>;\n env?: NodeJS.ProcessEnv;\n /** Tests: poll faster. */\n pollMs?: number;\n timeoutMs?: number;\n}\n\nconst isUrl = (s: string) => /^https?:\\/\\//i.test(s.trim());\n\n/** Renders a preset's setup step in the terminal (the console renders the same steps). */\nexport function renderStep(step: SetupStepView, n: number): string[] {\n const out = [pc.bold(`${n}. ${safeText(step.title, 120)}`)];\n for (const para of step.body.split(/\\n{2,}/)) out.push(` ${para.replace(/\\s*\\n\\s*/g, \" \").replace(/`([^`]+)`/g, (_m, c: string) => pc.cyan(c))}`);\n if (step.link) out.push(` ${step.link.label}: ${pc.cyan(step.link.url)}`);\n if (step.copy) out.push(` ${step.copy.label}: ${pc.cyan(step.copy.value)}`);\n return out;\n}\n\nasync function askInput(p: Prompter, input: NonNullable<SetupStepView[\"input\"]>): Promise<string> {\n for (;;) {\n const v = input.secret ? await p.secret(input.label) : await p.ask(input.label);\n if (!v) {\n p.print(pc.yellow(\" This is needed to continue.\"));\n continue;\n }\n if (input.pattern && !new RegExp(input.pattern).test(v)) {\n p.print(pc.yellow(` That doesn't look right${input.placeholder ? ` (it looks like ${input.placeholder})` : \"\"}.`));\n continue;\n }\n return v;\n }\n}\n\nasync function askSlug(p: Prompter, flag: string | undefined, def: string, taken: Set<string>): Promise<string> {\n if (flag) {\n if (!validSlug(flag)) throw new Error(`--slug \"${flag}\": use 1-24 lowercase letters, digits and dashes.`);\n if (taken.has(flag)) throw new Error(`There's already a connection \"${flag}\".`);\n return flag;\n }\n let suggestion = def;\n for (let n = 2; taken.has(suggestion); n++) suggestion = `${def.slice(0, 21)}-${n}`;\n for (;;) {\n const s = (await p.ask(\"Name it (agents see its tools as <name>__<tool>)\", suggestion)).toLowerCase();\n if (!validSlug(s)) p.print(pc.yellow(\" Use 1-24 lowercase letters, digits and dashes.\"));\n else if (taken.has(s)) p.print(pc.yellow(` There's already a connection \"${s}\".`));\n else return s;\n }\n}\n\n/** A slug from a URL: the host's first label that says something (mcp.notion.com → notion). */\nexport function slugFromUrl(url: URL): string {\n const labels = url.hostname.split(\".\").filter((l) => ![\"mcp\", \"api\", \"www\"].includes(l));\n const first = /^\\d/.test(url.hostname) || url.hostname.includes(\":\") ? `${url.hostname}-${url.port || \"mcp\"}` : (labels[0] ?? url.hostname);\n return slugify(first);\n}\n\nconst registrationWords: Record<string, string> = {\n preregistered: \"with a registered client\",\n metadata_document: \"registers itself automatically (client metadata document)\",\n dcr: \"registers itself automatically (dynamic client registration)\",\n manual: \"needs a client ID you get from the provider\",\n};\n\nconst overSsh = (env: NodeJS.ProcessEnv) => !!(env.SSH_CONNECTION || env.SSH_TTY || env.SSH_CLIENT);\nconst isLoopbackHost = (h: string) => h === \"localhost\" || h === \"127.0.0.1\" || h === \"[::1]\" || h === \"::1\";\n\n/** Where the provider sends the browser after consent: the authorize URL's redirect_uri. */\nfunction redirectOf(authorizeUrl: string): URL | null {\n try {\n const r = new URL(authorizeUrl).searchParams.get(\"redirect_uri\");\n return r ? new URL(r) : null;\n } catch {\n return null;\n }\n}\n\n/**\n * OAuth: open the browser and wait for the callback, or paste the address the browser lands on: over SSH when the\n * redirect goes to localhost (the browser isn't on this machine), and always for an https://localhost redirect\n * (providers that refuse http, where nothing listens).\n */\nexport async function authorize(\n conn: ConnectionView,\n start: { authorizeUrl: string; callbackMode?: \"direct\" | \"paste\"; redirectUri?: string },\n deps: ManageDeps,\n flags: { paste?: boolean } = {},\n): Promise<ConnectionView> {\n const { api, prompter: p } = deps;\n const env = deps.env ?? process.env;\n const authorizeUrl = start.authorizeUrl;\n const redirect = (() => {\n try {\n return start.redirectUri ? new URL(start.redirectUri) : redirectOf(authorizeUrl);\n } catch {\n return redirectOf(authorizeUrl);\n }\n })();\n const loopback = !!redirect && isLoopbackHost(redirect.hostname);\n const paste = !!flags.paste || start.callbackMode === \"paste\" || (loopback && (overSsh(env) || redirect!.protocol === \"https:\"));\n const name = safeText(conn.name, 60);\n if (paste) {\n p.print(`Open this link in a browser where you can sign in to ${name}:`);\n p.print(` ${pc.cyan(authorizeUrl)}`);\n const start = redirect ? `${redirect.origin}${redirect.pathname}` : \"the callback address\";\n p.print(pc.dim(`After you approve, the browser goes to an address starting with ${start} (it may say the page can't be reached). Copy that whole address.`));\n for (;;) {\n const pasted = await p.ask(\"Paste the address here\");\n if (!/[?&](code|error)=/.test(pasted)) {\n p.print(pc.yellow(` That isn't the address after signing in: it starts with ${start} and has ?code=… in it.`));\n continue;\n }\n const r = await api.finish(pasted.trim());\n if (r.status === \"connected\") return r.connection;\n throw new Error(r.status === \"error\" ? r.message : \"The sign-in didn't finish.\");\n }\n }\n // A sign-in that completes saves a new credential: its fingerprint changes even on an already-active\n // connection (a Reconnect), where status and updated_at can't tell.\n const stamp = () => api.channel.credentialStamp(conn.id);\n const before = stamp();\n const beforeView = await api.get(conn.id);\n p.print(`Opening your browser to sign in to ${name}. If it doesn't open, use this link:`);\n p.print(` ${pc.cyan(authorizeUrl)}`);\n try {\n await (deps.openBrowser ?? (async (u: string) => (await import(\"open\")).default(u)))(authorizeUrl);\n } catch {\n // The link is printed.\n }\n const pollMs = deps.pollMs ?? 2000;\n const deadline = Date.now() + (deps.timeoutMs ?? 15 * 60_000);\n p.print(pc.dim(\"Waiting for you to approve in the browser… (Ctrl+C to stop)\"));\n while (Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, pollMs));\n const now = await api.get(conn.id);\n const after = stamp();\n const changed = after !== null ? after !== before : now.expiresAt !== beforeView.expiresAt || now.updatedAt !== beforeView.updatedAt;\n // The sign-in page itself shows any error.\n if (now.status === \"active\" && changed) return now;\n }\n throw new Error(`Timed out waiting for the sign-in. Try again with \\`${NPX} connections reconnect ${conn.slug}\\`${overSsh(env) ? \"\" : \" (add --paste to paste the address instead)\"}.`);\n}\n\n/** Working = active with at least one tool listed: a \"connected\" answer alone isn't proof (a header isn't tested). */\nexport const isWorking = (c: ConnectionView) => c.status === \"active\" && c.tools.total > 0;\n\n/**\n * Waits briefly for a just-connected connection's first tool sync: until it works, turns needs_reauth / error /\n * disabled, or `ms` pass. Returns the last view.\n */\nexport async function waitWorking(api: ConnectionsApi, c: ConnectionView, opts: { pollMs?: number; ms?: number } = {}): Promise<ConnectionView> {\n let now = c;\n const deadline = Date.now() + (opts.ms ?? 10_000);\n while (!isWorking(now) && now.status === \"active\" && Date.now() < deadline) {\n await new Promise((r) => setTimeout(r, opts.pollMs ?? 500));\n now = await api.get(c.id);\n }\n return now;\n}\n\n/** Connects (header, setup inputs, or OAuth) and returns the connection as it ends up. */\nexport async function connectNow(conn: ConnectionView, input: StartConnectInput, deps: ManageDeps, flags: { paste?: boolean } = {}): Promise<ConnectionView> {\n const r = await deps.api.connect(conn.id, input);\n if (r.status === \"connected\") return waitWorking(deps.api, r.connection, { pollMs: deps.pollMs, ms: deps.timeoutMs === undefined ? undefined : Math.min(deps.timeoutMs, 10_000) });\n // A finished sign-in is the start, not proof: wait for the first tool sync, as for a header.\n if (r.status === \"authorize\") return waitWorking(deps.api, await authorize(conn, r, deps, flags), { pollMs: deps.pollMs, ms: deps.timeoutMs === undefined ? undefined : Math.min(deps.timeoutMs, 10_000) });\n throw new Error(r.message);\n}\n\nfunction printResult(p: Prompter, c: ConnectionView): void {\n if (isWorking(c)) {\n p.print(`${pc.green(\"✔\")} Connected \"${c.slug}\": ${c.tools.total} tool${c.tools.total === 1 ? \"\" : \"s\"}, seen by agents as ${c.slug}__<tool> (${accessLabel(c.levelDefault)}).`);\n } else {\n p.print(`${pc.yellow(\"○\")} \"${c.slug}\" isn't working yet: ${c.status}${c.statusReason ? ` (${safeText(c.statusReason, 200)})` : \"\"}, ${c.tools.total} tools.`);\n p.print(` ${reconnectHint(c)}`);\n }\n}\n\ninterface Pending {\n slug: string;\n name: string;\n preset?: string;\n url?: string;\n}\n\n/** The access question, the agents, then create; `after` runs on the new connection (allow, connect). */\nasync function createThen(base: Pending, flags: AddFlags, deps: ManageDeps, after: (c: ConnectionView) => Promise<ConnectionView>): Promise<number> {\n const { api, prompter: p } = deps;\n const level = await chooseAccess(p, flags.access ? parseAccess(flags.access) : undefined);\n const agents = await chooseAgents(p, api, flags.agent);\n if (!(await p.confirm(`Add \"${base.slug}\" (${accessLabel(level)}, ${agentsLabel(agents)})?`, true))) {\n p.print(\"Nothing was added.\");\n return 0;\n }\n const created = await api.create({ ...base, levelDefault: level, ...(agents === \"all\" ? {} : { agentIds: agents }) });\n let conn: ConnectionView;\n try {\n conn = await after(created);\n } catch (err) {\n p.print(pc.yellow(`\"${created.slug}\" was added but isn't connected: ${safeText(err instanceof Error ? err.message : String(err), 300)}`));\n p.print(` ${reconnectHint(created)} (or remove it: ${NPX} connections remove ${created.slug})`);\n return 1;\n }\n printResult(p, conn);\n return isWorking(conn) ? 0 : 1;\n}\n\nasync function addPreset(preset: PresetView, flags: AddFlags, deps: ManageDeps, taken: Set<string>): Promise<number> {\n const p = deps.prompter;\n p.print(pc.bold(`Connect ${safeText(preset.displayName, 60)}`));\n preset.setupSteps.forEach((step, i) => {\n for (const l of renderStep(step, i + 1)) p.print(l);\n });\n const inputs: Record<string, string> = {};\n for (const step of preset.setupSteps) if (step.input) inputs[step.input.key] = await askInput(p, step.input);\n let header: StartConnectInput[\"header\"];\n if (preset.authType === \"header\") {\n const name = flags.header ?? \"Authorization\";\n header = { name, value: await askInput(p, { key: \"header\", label: `${name} value (not shown)`, secret: true }) };\n }\n const slug = await askSlug(p, flags.slug, preset.slug, taken);\n const input: StartConnectInput = { ...(header ? { header } : {}), ...(Object.keys(inputs).length ? { inputs } : {}) };\n return createThen({ slug, name: preset.displayName, preset: preset.id }, flags, deps, (c) => connectNow(c, input, deps, flags));\n}\n\nasync function headerFor(p: Prompter, flags: { header?: string }): Promise<NonNullable<StartConnectInput[\"header\"]>> {\n const name = flags.header ?? (await p.ask(\"Header name\", \"Authorization\"));\n const value = await askInput(p, { key: \"header\", label: `${name} value (not shown)`, secret: true });\n return { name, value: /^authorization$/i.test(name) && !/\\s/.test(value) ? `Bearer ${value}` : value };\n}\n\nfunction describeProbe(p: Prompter, probe: ConnectionProbe): void {\n if (probe.auth === \"oauth\") {\n p.print(`It signs in with OAuth${probe.issuer ? ` via ${safeText(probe.issuer, 120)}` : \"\"}${probe.registration ? `, and ${registrationWords[probe.registration] ?? probe.registration}` : \"\"}.`);\n } else if (probe.auth === \"header\") p.print(`It needs an API key or token. ${safeText(probe.message, 200)}`);\n else if (probe.auth === \"none\") p.print(\"It doesn't need a sign-in.\");\n else p.print(safeText(probe.message, 200));\n}\n\nconst MANUAL_CLIENT = \"It needs a client ID from the provider; finish it in the console's Connections page.\";\n\nasync function addUrl(raw: string, flags: AddFlags, deps: ManageDeps, taken: Set<string>): Promise<number> {\n const { api, prompter: p } = deps;\n let url: URL;\n try {\n url = new URL(raw.trim());\n } catch {\n throw new Error(`\"${raw}\" isn't a URL. Use the server's full MCP address, e.g. https://mcp.example.com/mcp.`);\n }\n p.print(`Checking ${pc.cyan(url.href)}…`);\n const probe = await api.probe(url.href);\n let allowPrivate = false;\n let header: StartConnectInput[\"header\"];\n if (probe.blocked === \"private_target\") {\n const origin = exactOrigin(url);\n p.print(pc.yellow(`${url.host} is on this machine or your private network.`));\n p.print(\n \"xaq blocks those by default: a connection to a server there can reach other services on the same machine or network. \" +\n `An allow covers exactly ${origin}, for this connection only (and plain http on that host).`,\n );\n const allowed = flags.allowPrivate === origin || (await p.confirmExplicit(`Allow this connection to reach ${origin}?`, `nothing was added (pass --allow-private ${origin} to allow it)`));\n if (!allowed) {\n p.print(\"Nothing was added.\");\n return 0;\n }\n // Probed again once the connection (and its allow) exists.\n allowPrivate = true;\n } else if (probe.blocked || !probe.reachable) throw new Error(probe.message);\n else {\n describeProbe(p, probe);\n if (probe.auth === \"oauth\" && probe.registration === \"manual\") throw new Error(MANUAL_CLIENT);\n if (probe.auth === \"header\") header = await headerFor(p, flags);\n }\n const slug = await askSlug(p, flags.slug, slugFromUrl(url), taken);\n return createThen({ slug, name: url.hostname, url: url.href }, flags, deps, async (c) => {\n if (allowPrivate) {\n await api.allowPrivateTarget(c.id, true);\n const again = await api.probe(url.href, c.id);\n if (again.blocked || !again.reachable) throw new Error(again.message);\n describeProbe(p, again);\n if (again.auth === \"oauth\" && again.registration === \"manual\") throw new Error(MANUAL_CLIENT);\n if (again.auth === \"header\") header = await headerFor(p, flags);\n }\n return connectNow(c, header ? { header } : {}, deps, flags);\n });\n}\n\nexport async function addConnection(target: string, flags: AddFlags, deps: ManageDeps): Promise<number> {\n const existing = await deps.api.list();\n const taken = new Set(existing.map((c) => c.slug));\n if (isUrl(target)) return addUrl(target, flags, deps, taken);\n const presets = await deps.api.presets();\n const preset = presets.find((x) => x.id === target.trim().toLowerCase());\n if (!preset) throw new Error(`Unknown integration \"${target}\". Use ${[...presets.map((x) => x.id), \"<an MCP server URL>\"].join(\", \")}.`);\n return addPreset(preset, flags, deps, taken);\n}\n\nexport async function listConnections(deps: ManageDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const all = await api.list();\n if (!all.length) {\n p.print(`No connections yet. Add one: ${NPX} connections add notion|whoop|<url>`);\n return 0;\n }\n const w = Math.max(4, ...all.map((c) => c.slug.length));\n p.print(pc.dim(`${\"NAME\".padEnd(w)} ${\"STATUS\".padEnd(12)} ${\"ACCESS\".padEnd(24)} ${\"TOOLS\".padEnd(5)} URL`));\n for (const c of all) {\n const status = c.status === \"active\" ? pc.green(c.status.padEnd(12)) : pc.yellow(c.status.padEnd(12));\n const notes: string[] = [];\n if (c.privateTarget) notes.push(\"private network\");\n const d = c.expiresInDays;\n if (d !== null && d <= 7) notes.push(d <= 0 ? \"expires today: Reconnect\" : `expires in ${d} day${d === 1 ? \"\" : \"s\"}`);\n if (c.tools.held) notes.push(`${c.tools.held} held`);\n if (c.status === \"needs_reauth\") notes.push(\"Reconnect\");\n p.print(\n `${c.slug.padEnd(w)} ${status} ${accessLabel(c.levelDefault).padEnd(24)} ${String(c.tools.total).padEnd(5)} ${safeText(c.url ?? c.kind, 80)}${notes.length ? pc.yellow(` (${notes.join(\", \")})`) : \"\"}`,\n );\n }\n return 0;\n}\n\nexport async function reconnectConnection(slug: string, flags: { paste?: boolean; header?: string }, deps: ManageDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const c = await api.bySlug(slug);\n const after = await connectNow(c, c.authType === \"header\" ? { header: await headerFor(p, flags) } : {}, deps, flags);\n printResult(p, after);\n return isWorking(after) ? 0 : 1;\n}\n\nexport async function disableConnection(slug: string, deps: ManageDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const c = await api.bySlug(slug);\n if (!(await p.confirm(`Disable \"${slug}\"? Agents lose its tools at once, its pending approvals are cancelled and its stored credentials are deleted.`, false))) return 0;\n await api.kill(c.id);\n p.print(`${pc.green(\"✔\")} Disabled \"${slug}\". To use it again, turn it on in the console's Connections page and reconnect.`);\n return 0;\n}\n\nexport async function removeConnection(slug: string, deps: ManageDeps): Promise<number> {\n const { api, prompter: p } = deps;\n const c = await api.bySlug(slug);\n if (!(await p.confirm(`Remove \"${slug}\" and delete its stored credentials? This can't be undone.`, false))) return 0;\n await api.remove(c.id);\n p.print(`${pc.green(\"✔\")} Removed \"${slug}\".`);\n return 0;\n}\n"],"mappings":";;;;;;;;;AAQA,MAAa,gBAAwE;CACnF;EAAE,OAAO;EAAQ,OAAO;EAAuC,OAAO;CAAc;CACpF;EAAE,OAAO;EAAO,OAAO;EAA+F,OAAO;CAA2B;CACxJ;EAAE,OAAO;EAAQ,OAAO;EAA2D,OAAO;CAAY;AACxG;AAEA,MAAa,eAAe,UAAuB,cAAc,MAAM,MAAM,EAAE,UAAU,KAAK,CAAC,EAAE,SAAS;AAE1G,SAAgB,YAAY,OAA4B;CACtD,MAAM,IAAI,MAAM,KAAK,CAAC,CAAC,YAAY;CACnC,MAAM,MAAmC;EAAE,MAAM;EAAQ,KAAK;EAAO,OAAO;EAAO,MAAM;EAAQ,aAAa;EAAQ,UAAU;CAAO;CACvI,IAAI,CAAC,IAAI,IAAI,MAAM,IAAI,MAAM,qBAAqB,MAAM,0BAA0B;CAClF,OAAO,IAAI;AACb;AAEA,eAAsB,aAAa,GAAa,MAAqD;CACnG,IAAI,MAAM,OAAO;CACjB,OAAO,EAAE,OACP,+BACA,cAAc,KAAK,OAAO;EAAE,OAAO,EAAE;EAAO,OAAO,EAAE;CAAM,EAAE,GAC7D,KACF;AACF;;AAGA,eAAsB,aAAa,GAAa,KAAqB,OAAwD;CAC3H,MAAM,UAAU,MAAM,IAAI,OAAO,EAAA,CAAG,QAAQ,MAAM,CAAC,EAAE,QAAQ;CAC7D,IAAI,OAAO,QAAQ;EACjB,IAAI,MAAM,WAAW,KAAK,MAAM,OAAO,OAAO,OAAO;EACrD,OAAO,MAAM,KAAK,MAAM;GACtB,MAAM,MAAM,OAAO,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE,KAAK,YAAY,MAAM,EAAE,YAAY,CAAC;GACrF,IAAI,CAAC,KAAK,MAAM,IAAI,MAAM,aAAa,EAAE,aAAa,OAAO,KAAK,MAAM,EAAE,IAAI,CAAC,CAAC,KAAK,IAAI,KAAK,WAAW,EAAE;GAC3G,OAAO,IAAI;EACb,CAAC;CACH;CACA,IAAI,OAAO,UAAU,KAAK,EAAE,aAAa,CAAC,EAAE,aAAa,OAAO;CAEhE,IAAI,MADc,EAAE,QAAQ,kBAAkB,OAAO,OAAO,WAAW,OAAO,KAAK,MAAM,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,KAAK,IAAI,GAC1H,OAAO;CAChB,MAAM,SAAmB,CAAC;CAC1B,KAAK,MAAM,KAAK,QAAQ,IAAI,MAAM,EAAE,QAAQ,KAAK,SAAS,EAAE,MAAM,EAAE,EAAE,IAAI,KAAK,GAAG,OAAO,KAAK,EAAE,EAAE;CAClG,IAAI,CAAC,OAAO,QAAQ,EAAE,MAAM,GAAG,OAAO,0EAA0E,CAAC;CACjH,OAAO;AACT;AAEA,MAAa,eAAe,WAA8B,WAAW,QAAQ,eAAe,GAAG,OAAO,OAAO,QAAQ,OAAO,WAAW,IAAI,KAAK;;;;;;;;;ACzChJ,MAAM,YAAY,IAAI,UAAU;AAChC,KAAK,MAAM,CAAC,KAAK,WAAW;CAC1B,CAAC,aAAa,CAAC;CACf,CAAC,YAAY,CAAC;CACd,CAAC,cAAc,EAAE;CACjB,CAAC,eAAe,EAAE;CAClB,CAAC,cAAc,EAAE;AACnB,GACE,UAAU,UAAU,KAAK,QAAQ,MAAM;AAEzC,UAAU,WAAW,OAAO,MAAM;AAClC,UAAU,UAAU,UAAU,GAAG,MAAM;;AAGvC,MAAM,QAAQ,IAAI,UAAU;AAC5B,MAAM,UAAU,eAAe,IAAI,MAAM;AACzC,MAAM,UAAU,UAAU,IAAI,MAAM;AACpC,MAAM,WAAW,iBAAiB,MAAM;AACxC,MAAM,WAAW,mBAAmB,MAAM;AAI1C,SAAgB,gBAAgB,IAA0B;CACxD,MAAM,IAAI,YAAY,EAAE;CACxB,MAAM,SAAS,KAAK,CAAC,MAAM,IAAI,SAAS;CACxC,IAAI,MAAM,MAAM,GAAG,MAAM,GAAG,OAAO;CACnC,IAAI,UAAU,MAAM,GAAG,MAAM,GAAG,OAAO;CACvC,OAAO;AACT;;AAGA,SAAgB,YAAY,KAAkB;CAC5C,MAAM,OAAO,IAAI,SAAS,IAAI,aAAa,WAAW,QAAQ;CAC9D,OAAO,GAAG,IAAI,SAAS,IAAI,IAAI,SAAS,GAAG;AAC7C;AAQA,MAAM,iBAA2B,aAAaA,OAAU,UAAU;CAAE,KAAK;CAAM,UAAU;AAAK,CAAC;;AAG/F,eAAsB,YAAY,KAAU,SAAmB,eAAqC;CAClG,MAAM,OAAO,QAAQ,GAAG;CACxB,IAAI;CACJ,IAAI,KAAK,IAAI,GAAG,YAAY,CAAC,IAAI;MAC5B,IAAI,SAAS,eAAe,KAAK,SAAS,YAAY,GAAG,YAAY,CAAC,WAAW;MAEpF,IAAI;EACF,aAAa,MAAM,OAAO,IAAI,EAAA,CAAG,KAAK,MAAM,EAAE,OAAO;CACvD,QAAQ;EAEN,OAAO,EAAE,MAAM,SAAS;CAC1B;CAEF,MAAM,QAAQ,UAAU,MAAM,MAAM,gBAAgB,CAAC,MAAM,OAAO;CAClE,IAAI,OAAO,OAAO;EAAE,MAAM;EAAS,SAAS;EAAO,KAAK;CAAa;CACrE,MAAM,OAAO,UAAU,QAAQ,MAAM,gBAAgB,CAAC,MAAM,SAAS;CACrE,IAAI,KAAK,UAAU,KAAK,IAAI,MAAM,GAAG,OAAO;EAAE,MAAM;EAAS,SAAS;EAAM,KAAK;CAAe;CAChG,OAAO,KAAK,SAAS;EAAE,MAAM;EAAW,QAAQ,YAAY,GAAG;EAAG,WAAW;CAAK,IAAI,EAAE,MAAM,SAAS;AACzG;;;;ACvEA,SAAgB,QAAQ,MAAsB;CAO5C,OANU,KACP,YAAY,CAAC,CACb,QAAQ,eAAe,GAAG,CAAC,CAC3B,QAAQ,YAAY,EAAE,CAAC,CACvB,MAAM,GAAG,EAAE,CAAC,CACZ,QAAQ,OAAO,EACX,KAAK;AACd;AAEA,MAAa,aAAa,MAAc,oBAAoB,KAAK,CAAC;;AAGlE,SAAgB,cAAc,GAA6B;CACzD,OAAO,cAAc,IAAI,yBAAyB,EAAE,KAAK;AAC3D;;;ACiBA,MAAM,SAAS,MAAc,gBAAgB,KAAK,EAAE,KAAK,CAAC;;AAG1D,SAAgB,WAAW,MAAqB,GAAqB;CACnE,MAAM,MAAM,CAAC,GAAG,KAAK,GAAG,EAAE,IAAI,SAAS,KAAK,OAAO,GAAG,GAAG,CAAC;CAC1D,KAAK,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,GAAG,IAAI,KAAK,MAAM,KAAK,QAAQ,aAAa,GAAG,CAAC,CAAC,QAAQ,eAAe,IAAI,MAAc,GAAG,KAAK,CAAC,CAAC,GAAG;CAClJ,IAAI,KAAK,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,KAAK,GAAG,GAAG;CAC1E,IAAI,KAAK,MAAM,IAAI,KAAK,MAAM,KAAK,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,KAAK,KAAK,GAAG;CAC5E,OAAO;AACT;AAEA,eAAe,SAAS,GAAa,OAA6D;CAChG,SAAS;EACP,MAAM,IAAI,MAAM,SAAS,MAAM,EAAE,OAAO,MAAM,KAAK,IAAI,MAAM,EAAE,IAAI,MAAM,KAAK;EAC9E,IAAI,CAAC,GAAG;GACN,EAAE,MAAM,GAAG,OAAO,+BAA+B,CAAC;GAClD;EACF;EACA,IAAI,MAAM,WAAW,CAAC,IAAI,OAAO,MAAM,OAAO,CAAC,CAAC,KAAK,CAAC,GAAG;GACvD,EAAE,MAAM,GAAG,OAAO,4BAA4B,MAAM,cAAc,mBAAmB,MAAM,YAAY,KAAK,GAAG,EAAE,CAAC;GAClH;EACF;EACA,OAAO;CACT;AACF;AAEA,eAAe,QAAQ,GAAa,MAA0B,KAAa,OAAqC;CAC9G,IAAI,MAAM;EACR,IAAI,CAAC,UAAU,IAAI,GAAG,MAAM,IAAI,MAAM,WAAW,KAAK,kDAAkD;EACxG,IAAI,MAAM,IAAI,IAAI,GAAG,MAAM,IAAI,MAAM,iCAAiC,KAAK,GAAG;EAC9E,OAAO;CACT;CACA,IAAI,aAAa;CACjB,KAAK,IAAI,IAAI,GAAG,MAAM,IAAI,UAAU,GAAG,KAAK,aAAa,GAAG,IAAI,MAAM,GAAG,EAAE,EAAE,GAAG;CAChF,SAAS;EACP,MAAM,KAAK,MAAM,EAAE,IAAI,oDAAoD,UAAU,EAAA,CAAG,YAAY;EACpG,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,kDAAkD,CAAC;OACnF,IAAI,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,mCAAmC,EAAE,GAAG,CAAC;OAC7E,OAAO;CACd;AACF;;AAGA,SAAgB,YAAY,KAAkB;CAC5C,MAAM,SAAS,IAAI,SAAS,MAAM,GAAG,CAAC,CAAC,QAAQ,MAAM,CAAC;EAAC;EAAO;EAAO;CAAK,CAAC,CAAC,SAAS,CAAC,CAAC;CAEvF,OAAO,QADO,MAAM,KAAK,IAAI,QAAQ,KAAK,IAAI,SAAS,SAAS,GAAG,IAAI,GAAG,IAAI,SAAS,GAAG,IAAI,QAAQ,UAAW,OAAO,MAAM,IAAI,QAC9G;AACtB;AAEA,MAAM,oBAA4C;CAChD,eAAe;CACf,mBAAmB;CACnB,KAAK;CACL,QAAQ;AACV;AAEA,MAAM,WAAW,QAA2B,CAAC,EAAE,IAAI,kBAAkB,IAAI,WAAW,IAAI;AACxF,MAAM,kBAAkB,MAAc,MAAM,eAAe,MAAM,eAAe,MAAM,WAAW,MAAM;;AAGvG,SAAS,WAAW,cAAkC;CACpD,IAAI;EACF,MAAM,IAAI,IAAI,IAAI,YAAY,CAAC,CAAC,aAAa,IAAI,cAAc;EAC/D,OAAO,IAAI,IAAI,IAAI,CAAC,IAAI;CAC1B,QAAQ;EACN,OAAO;CACT;AACF;;;;;;AAOA,eAAsB,UACpB,MACA,OACA,MACA,QAA6B,CAAC,GACL;CACzB,MAAM,EAAE,KAAK,UAAU,MAAM;CAC7B,MAAM,MAAM,KAAK,OAAO,QAAQ;CAChC,MAAM,eAAe,MAAM;CAC3B,MAAM,kBAAkB;EACtB,IAAI;GACF,OAAO,MAAM,cAAc,IAAI,IAAI,MAAM,WAAW,IAAI,WAAW,YAAY;EACjF,QAAQ;GACN,OAAO,WAAW,YAAY;EAChC;CACF,EAAA,CAAG;CACH,MAAM,WAAW,CAAC,CAAC,YAAY,eAAe,SAAS,QAAQ;CAC/D,MAAM,QAAQ,CAAC,CAAC,MAAM,SAAS,MAAM,iBAAiB,WAAY,aAAa,QAAQ,GAAG,KAAK,SAAU,aAAa;CACtH,MAAM,OAAO,SAAS,KAAK,MAAM,EAAE;CACnC,IAAI,OAAO;EACT,EAAE,MAAM,wDAAwD,KAAK,EAAE;EACvE,EAAE,MAAM,KAAK,GAAG,KAAK,YAAY,GAAG;EACpC,MAAM,QAAQ,WAAW,GAAG,SAAS,SAAS,SAAS,aAAa;EACpE,EAAE,MAAM,GAAG,IAAI,mEAAmE,MAAM,kEAAkE,CAAC;EAC3J,SAAS;GACP,MAAM,SAAS,MAAM,EAAE,IAAI,wBAAwB;GACnD,IAAI,CAAC,oBAAoB,KAAK,MAAM,GAAG;IACrC,EAAE,MAAM,GAAG,OAAO,6DAA6D,MAAM,wBAAwB,CAAC;IAC9G;GACF;GACA,MAAM,IAAI,MAAM,IAAI,OAAO,OAAO,KAAK,CAAC;GACxC,IAAI,EAAE,WAAW,aAAa,OAAO,EAAE;GACvC,MAAM,IAAI,MAAM,EAAE,WAAW,UAAU,EAAE,UAAU,4BAA4B;EACjF;CACF;CAGA,MAAM,cAAc,IAAI,QAAQ,gBAAgB,KAAK,EAAE;CACvD,MAAM,SAAS,MAAM;CACrB,MAAM,aAAa,MAAM,IAAI,IAAI,KAAK,EAAE;CACxC,EAAE,MAAM,sCAAsC,KAAK,qCAAqC;CACxF,EAAE,MAAM,KAAK,GAAG,KAAK,YAAY,GAAG;CACpC,IAAI;EACF,OAAO,KAAK,gBAAgB,OAAO,OAAe,MAAM,OAAO,QAAA,CAAS,QAAQ,CAAC,GAAA,CAAI,YAAY;CACnG,QAAQ,CAER;CACA,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,WAAW,KAAK,IAAI,KAAK,KAAK,aAAa;CACjD,EAAE,MAAM,GAAG,IAAI,6DAA6D,CAAC;CAC7E,OAAO,KAAK,IAAI,IAAI,UAAU;EAC5B,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,MAAM,CAAC;EAC9C,MAAM,MAAM,MAAM,IAAI,IAAI,KAAK,EAAE;EACjC,MAAM,QAAQ,MAAM;EACpB,MAAM,UAAU,UAAU,OAAO,UAAU,SAAS,IAAI,cAAc,WAAW,aAAa,IAAI,cAAc,WAAW;EAE3H,IAAI,IAAI,WAAW,YAAY,SAAS,OAAO;CACjD;CACA,MAAM,IAAI,MAAM,uDAAuD,IAAI,yBAAyB,KAAK,KAAK,IAAI,QAAQ,GAAG,IAAI,KAAK,8CAA8C,EAAE;AACxL;;AAGA,MAAa,aAAa,MAAsB,EAAE,WAAW,YAAY,EAAE,MAAM,QAAQ;;;;;AAMzF,eAAsB,YAAY,KAAqB,GAAmB,OAAyC,CAAC,GAA4B;CAC9I,IAAI,MAAM;CACV,MAAM,WAAW,KAAK,IAAI,KAAK,KAAK,MAAM;CAC1C,OAAO,CAAC,UAAU,GAAG,KAAK,IAAI,WAAW,YAAY,KAAK,IAAI,IAAI,UAAU;EAC1E,MAAM,IAAI,SAAS,MAAM,WAAW,GAAG,KAAK,UAAU,GAAG,CAAC;EAC1D,MAAM,MAAM,IAAI,IAAI,EAAE,EAAE;CAC1B;CACA,OAAO;AACT;;AAGA,eAAsB,WAAW,MAAsB,OAA0B,MAAkB,QAA6B,CAAC,GAA4B;CAC3J,MAAM,IAAI,MAAM,KAAK,IAAI,QAAQ,KAAK,IAAI,KAAK;CAC/C,IAAI,EAAE,WAAW,aAAa,OAAO,YAAY,KAAK,KAAK,EAAE,YAAY;EAAE,QAAQ,KAAK;EAAQ,IAAI,KAAK,cAAc,KAAA,IAAY,KAAA,IAAY,KAAK,IAAI,KAAK,WAAW,GAAM;CAAE,CAAC;CAEjL,IAAI,EAAE,WAAW,aAAa,OAAO,YAAY,KAAK,KAAK,MAAM,UAAU,MAAM,GAAG,MAAM,KAAK,GAAG;EAAE,QAAQ,KAAK;EAAQ,IAAI,KAAK,cAAc,KAAA,IAAY,KAAA,IAAY,KAAK,IAAI,KAAK,WAAW,GAAM;CAAE,CAAC;CAC1M,MAAM,IAAI,MAAM,EAAE,OAAO;AAC3B;AAEA,SAAS,YAAY,GAAa,GAAyB;CACzD,IAAI,UAAU,CAAC,GACb,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,EAAE,cAAc,EAAE,KAAK,KAAK,EAAE,MAAM,MAAM,OAAO,EAAE,MAAM,UAAU,IAAI,KAAK,IAAI,sBAAsB,EAAE,KAAK,YAAY,YAAY,EAAE,YAAY,EAAE,GAAG;MAC1K;EACL,EAAE,MAAM,GAAG,GAAG,OAAO,GAAG,EAAE,IAAI,EAAE,KAAK,uBAAuB,EAAE,SAAS,EAAE,eAAe,KAAK,SAAS,EAAE,cAAc,GAAG,EAAE,KAAK,GAAG,IAAI,EAAE,MAAM,MAAM,QAAQ;EAC7J,EAAE,MAAM,KAAK,cAAc,CAAC,GAAG;CACjC;AACF;;AAUA,eAAe,WAAW,MAAe,OAAiB,MAAkB,OAAwE;CAClJ,MAAM,EAAE,KAAK,UAAU,MAAM;CAC7B,MAAM,QAAQ,MAAM,aAAa,GAAG,MAAM,SAAS,YAAY,MAAM,MAAM,IAAI,KAAA,CAAS;CACxF,MAAM,SAAS,MAAM,aAAa,GAAG,KAAK,MAAM,KAAK;CACrD,IAAI,CAAE,MAAM,EAAE,QAAQ,QAAQ,KAAK,KAAK,KAAK,YAAY,KAAK,EAAE,IAAI,YAAY,MAAM,EAAE,KAAK,IAAI,GAAI;EACnG,EAAE,MAAM,oBAAoB;EAC5B,OAAO;CACT;CACA,MAAM,UAAU,MAAM,IAAI,OAAO;EAAE,GAAG;EAAM,cAAc;EAAO,GAAI,WAAW,QAAQ,CAAC,IAAI,EAAE,UAAU,OAAO;CAAG,CAAC;CACpH,IAAI;CACJ,IAAI;EACF,OAAO,MAAM,MAAM,OAAO;CAC5B,SAAS,KAAK;EACZ,EAAE,MAAM,GAAG,OAAO,IAAI,QAAQ,KAAK,mCAAmC,SAAS,eAAe,QAAQ,IAAI,UAAU,OAAO,GAAG,GAAG,GAAG,GAAG,CAAC;EACxI,EAAE,MAAM,KAAK,cAAc,OAAO,EAAE,oBAAoB,IAAI,sBAAsB,QAAQ,KAAK,EAAE;EACjG,OAAO;CACT;CACA,YAAY,GAAG,IAAI;CACnB,OAAO,UAAU,IAAI,IAAI,IAAI;AAC/B;AAEA,eAAe,UAAU,QAAoB,OAAiB,MAAkB,OAAqC;CACnH,MAAM,IAAI,KAAK;CACf,EAAE,MAAM,GAAG,KAAK,WAAW,SAAS,OAAO,aAAa,EAAE,GAAG,CAAC;CAC9D,OAAO,WAAW,SAAS,MAAM,MAAM;EACrC,KAAK,MAAM,KAAK,WAAW,MAAM,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC;CACpD,CAAC;CACD,MAAM,SAAiC,CAAC;CACxC,KAAK,MAAM,QAAQ,OAAO,YAAY,IAAI,KAAK,OAAO,OAAO,KAAK,MAAM,OAAO,MAAM,SAAS,GAAG,KAAK,KAAK;CAC3G,IAAI;CACJ,IAAI,OAAO,aAAa,UAAU;EAChC,MAAM,OAAO,MAAM,UAAU;EAC7B,SAAS;GAAE;GAAM,OAAO,MAAM,SAAS,GAAG;IAAE,KAAK;IAAU,OAAO,GAAG,KAAK;IAAqB,QAAQ;GAAK,CAAC;EAAE;CACjH;CACA,MAAM,OAAO,MAAM,QAAQ,GAAG,MAAM,MAAM,OAAO,MAAM,KAAK;CAC5D,MAAM,QAA2B;EAAE,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;EAAI,GAAI,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,EAAE,OAAO,IAAI,CAAC;CAAG;CACpH,OAAO,WAAW;EAAE;EAAM,MAAM,OAAO;EAAa,QAAQ,OAAO;CAAG,GAAG,OAAO,OAAO,MAAM,WAAW,GAAG,OAAO,MAAM,KAAK,CAAC;AAChI;AAEA,eAAe,UAAU,GAAa,OAA+E;CACnH,MAAM,OAAO,MAAM,UAAW,MAAM,EAAE,IAAI,eAAe,eAAe;CACxE,MAAM,QAAQ,MAAM,SAAS,GAAG;EAAE,KAAK;EAAU,OAAO,GAAG,KAAK;EAAqB,QAAQ;CAAK,CAAC;CACnG,OAAO;EAAE;EAAM,OAAO,mBAAmB,KAAK,IAAI,KAAK,CAAC,KAAK,KAAK,KAAK,IAAI,UAAU,UAAU;CAAM;AACvG;AAEA,SAAS,cAAc,GAAa,OAA8B;CAChE,IAAI,MAAM,SAAS,SACjB,EAAE,MAAM,yBAAyB,MAAM,SAAS,QAAQ,SAAS,MAAM,QAAQ,GAAG,MAAM,KAAK,MAAM,eAAe,SAAS,kBAAkB,MAAM,iBAAiB,MAAM,iBAAiB,GAAG,EAAE;MAC3L,IAAI,MAAM,SAAS,UAAU,EAAE,MAAM,iCAAiC,SAAS,MAAM,SAAS,GAAG,GAAG;MACtG,IAAI,MAAM,SAAS,QAAQ,EAAE,MAAM,4BAA4B;MAC/D,EAAE,MAAM,SAAS,MAAM,SAAS,GAAG,CAAC;AAC3C;AAEA,MAAM,gBAAgB;AAEtB,eAAe,OAAO,KAAa,OAAiB,MAAkB,OAAqC;CACzG,MAAM,EAAE,KAAK,UAAU,MAAM;CAC7B,IAAI;CACJ,IAAI;EACF,MAAM,IAAI,IAAI,IAAI,KAAK,CAAC;CAC1B,QAAQ;EACN,MAAM,IAAI,MAAM,IAAI,IAAI,oFAAoF;CAC9G;CACA,EAAE,MAAM,YAAY,GAAG,KAAK,IAAI,IAAI,EAAE,EAAE;CACxC,MAAM,QAAQ,MAAM,IAAI,MAAM,IAAI,IAAI;CACtC,IAAI,eAAe;CACnB,IAAI;CACJ,IAAI,MAAM,YAAY,kBAAkB;EACtC,MAAM,SAAS,YAAY,GAAG;EAC9B,EAAE,MAAM,GAAG,OAAO,GAAG,IAAI,KAAK,6CAA6C,CAAC;EAC5E,EAAE,MACA,gJAC6B,OAAO,0DACtC;EAEA,IAAI,EADY,MAAM,iBAAiB,UAAW,MAAM,EAAE,gBAAgB,kCAAkC,OAAO,IAAI,2CAA2C,OAAO,cAAc,IACzK;GACZ,EAAE,MAAM,oBAAoB;GAC5B,OAAO;EACT;EAEA,eAAe;CACjB,OAAO,IAAI,MAAM,WAAW,CAAC,MAAM,WAAW,MAAM,IAAI,MAAM,MAAM,OAAO;MACtE;EACH,cAAc,GAAG,KAAK;EACtB,IAAI,MAAM,SAAS,WAAW,MAAM,iBAAiB,UAAU,MAAM,IAAI,MAAM,aAAa;EAC5F,IAAI,MAAM,SAAS,UAAU,SAAS,MAAM,UAAU,GAAG,KAAK;CAChE;CAEA,OAAO,WAAW;EAAE,MAAA,MADD,QAAQ,GAAG,MAAM,MAAM,YAAY,GAAG,GAAG,KAAK;EACvC,MAAM,IAAI;EAAU,KAAK,IAAI;CAAK,GAAG,OAAO,MAAM,OAAO,MAAM;EACvF,IAAI,cAAc;GAChB,MAAM,IAAI,mBAAmB,EAAE,IAAI,IAAI;GACvC,MAAM,QAAQ,MAAM,IAAI,MAAM,IAAI,MAAM,EAAE,EAAE;GAC5C,IAAI,MAAM,WAAW,CAAC,MAAM,WAAW,MAAM,IAAI,MAAM,MAAM,OAAO;GACpE,cAAc,GAAG,KAAK;GACtB,IAAI,MAAM,SAAS,WAAW,MAAM,iBAAiB,UAAU,MAAM,IAAI,MAAM,aAAa;GAC5F,IAAI,MAAM,SAAS,UAAU,SAAS,MAAM,UAAU,GAAG,KAAK;EAChE;EACA,OAAO,WAAW,GAAG,SAAS,EAAE,OAAO,IAAI,CAAC,GAAG,MAAM,KAAK;CAC5D,CAAC;AACH;AAEA,eAAsB,cAAc,QAAgB,OAAiB,MAAmC;CACtG,MAAM,WAAW,MAAM,KAAK,IAAI,KAAK;CACrC,MAAM,QAAQ,IAAI,IAAI,SAAS,KAAK,MAAM,EAAE,IAAI,CAAC;CACjD,IAAI,MAAM,MAAM,GAAG,OAAO,OAAO,QAAQ,OAAO,MAAM,KAAK;CAC3D,MAAM,UAAU,MAAM,KAAK,IAAI,QAAQ;CACvC,MAAM,SAAS,QAAQ,MAAM,MAAM,EAAE,OAAO,OAAO,KAAK,CAAC,CAAC,YAAY,CAAC;CACvE,IAAI,CAAC,QAAQ,MAAM,IAAI,MAAM,wBAAwB,OAAO,SAAS,CAAC,GAAG,QAAQ,KAAK,MAAM,EAAE,EAAE,GAAG,qBAAqB,CAAC,CAAC,KAAK,IAAI,EAAE,EAAE;CACvI,OAAO,UAAU,QAAQ,OAAO,MAAM,KAAK;AAC7C;AAEA,eAAsB,gBAAgB,MAAmC;CACvE,MAAM,EAAE,KAAK,UAAU,MAAM;CAC7B,MAAM,MAAM,MAAM,IAAI,KAAK;CAC3B,IAAI,CAAC,IAAI,QAAQ;EACf,EAAE,MAAM,gCAAgC,IAAI,oCAAoC;EAChF,OAAO;CACT;CACA,MAAM,IAAI,KAAK,IAAI,GAAG,GAAG,IAAI,KAAK,MAAM,EAAE,KAAK,MAAM,CAAC;CACtD,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,OAAO,CAAC,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,IAAI,SAAS,OAAO,EAAE,EAAE,IAAI,QAAQ,OAAO,CAAC,EAAE,MAAM,CAAC;CAChH,KAAK,MAAM,KAAK,KAAK;EACnB,MAAM,SAAS,EAAE,WAAW,WAAW,GAAG,MAAM,EAAE,OAAO,OAAO,EAAE,CAAC,IAAI,GAAG,OAAO,EAAE,OAAO,OAAO,EAAE,CAAC;EACpG,MAAM,QAAkB,CAAC;EACzB,IAAI,EAAE,eAAe,MAAM,KAAK,iBAAiB;EACjD,MAAM,IAAI,EAAE;EACZ,IAAI,MAAM,QAAQ,KAAK,GAAG,MAAM,KAAK,KAAK,IAAI,6BAA6B,cAAc,EAAE,MAAM,MAAM,IAAI,KAAK,KAAK;EACrH,IAAI,EAAE,MAAM,MAAM,MAAM,KAAK,GAAG,EAAE,MAAM,KAAK,MAAM;EACnD,IAAI,EAAE,WAAW,gBAAgB,MAAM,KAAK,WAAW;EACvD,EAAE,MACA,GAAG,EAAE,KAAK,OAAO,CAAC,EAAE,IAAI,OAAO,IAAI,YAAY,EAAE,YAAY,CAAC,CAAC,OAAO,EAAE,EAAE,IAAI,OAAO,EAAE,MAAM,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,IAAI,SAAS,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,MAAM,SAAS,GAAG,OAAO,MAAM,MAAM,KAAK,IAAI,EAAE,EAAE,IAAI,IAC1M;CACF;CACA,OAAO;AACT;AAEA,eAAsB,oBAAoB,MAAc,OAA6C,MAAmC;CACtI,MAAM,EAAE,KAAK,UAAU,MAAM;CAC7B,MAAM,IAAI,MAAM,IAAI,OAAO,IAAI;CAC/B,MAAM,QAAQ,MAAM,WAAW,GAAG,EAAE,aAAa,WAAW,EAAE,QAAQ,MAAM,UAAU,GAAG,KAAK,EAAE,IAAI,CAAC,GAAG,MAAM,KAAK;CACnH,YAAY,GAAG,KAAK;CACpB,OAAO,UAAU,KAAK,IAAI,IAAI;AAChC;AAEA,eAAsB,kBAAkB,MAAc,MAAmC;CACvF,MAAM,EAAE,KAAK,UAAU,MAAM;CAC7B,MAAM,IAAI,MAAM,IAAI,OAAO,IAAI;CAC/B,IAAI,CAAE,MAAM,EAAE,QAAQ,YAAY,KAAK,gHAAgH,KAAK,GAAI,OAAO;CACvK,MAAM,IAAI,KAAK,EAAE,EAAE;CACnB,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,EAAE,aAAa,KAAK,gFAAgF;CAC3H,OAAO;AACT;AAEA,eAAsB,iBAAiB,MAAc,MAAmC;CACtF,MAAM,EAAE,KAAK,UAAU,MAAM;CAC7B,MAAM,IAAI,MAAM,IAAI,OAAO,IAAI;CAC/B,IAAI,CAAE,MAAM,EAAE,QAAQ,WAAW,KAAK,6DAA6D,KAAK,GAAI,OAAO;CACnH,MAAM,IAAI,OAAO,EAAE,EAAE;CACrB,EAAE,MAAM,GAAG,GAAG,MAAM,GAAG,EAAE,YAAY,KAAK,GAAG;CAC7C,OAAO;AACT"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export { t as addConnection, i as disableConnection, o as listConnections, s as reconnectConnection, c as removeConnection } from "./manage-Bo6COB4p.js";
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export { t as claudeMcpConfigPath, d as printMcpHeader, m as writeClaudeMcpConfig } from "./mcpheader-C9H4vudu.js";