@wirecat/bitrix24-cli 0.0.0-stage → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (245) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/LICENSE +204 -0
  3. package/README.md +17 -2
  4. package/dist/api-keys.d.ts +21 -0
  5. package/dist/api-keys.d.ts.map +1 -0
  6. package/dist/api-keys.js +58 -0
  7. package/dist/api-keys.js.map +1 -0
  8. package/dist/bin/b24.d.ts +3 -0
  9. package/dist/bin/b24.d.ts.map +1 -0
  10. package/dist/bin/b24.js +40 -0
  11. package/dist/bin/b24.js.map +1 -0
  12. package/dist/bitrix/errors.d.ts +22 -0
  13. package/dist/bitrix/errors.d.ts.map +1 -0
  14. package/dist/bitrix/errors.js +76 -0
  15. package/dist/bitrix/errors.js.map +1 -0
  16. package/dist/bitrix/methods.d.ts +13 -0
  17. package/dist/bitrix/methods.d.ts.map +1 -0
  18. package/dist/bitrix/methods.js +33 -0
  19. package/dist/bitrix/methods.js.map +1 -0
  20. package/dist/bitrix/transport.d.ts +50 -0
  21. package/dist/bitrix/transport.d.ts.map +1 -0
  22. package/dist/bitrix/transport.js +189 -0
  23. package/dist/bitrix/transport.js.map +1 -0
  24. package/dist/bitrix/webhook.d.ts +14 -0
  25. package/dist/bitrix/webhook.d.ts.map +1 -0
  26. package/dist/bitrix/webhook.js +29 -0
  27. package/dist/bitrix/webhook.js.map +1 -0
  28. package/dist/bundle/all-profiles-QJ444GSX.js +24 -0
  29. package/dist/bundle/anthropic-RHRAVHC2.js +70 -0
  30. package/dist/bundle/app-server-QIT6S7AZ.js +224 -0
  31. package/dist/bundle/b24.js +32 -0
  32. package/dist/bundle/bun-H6RSODZ3.js +169 -0
  33. package/dist/bundle/bun-sqlite-BO4LTQHX.js +69 -0
  34. package/dist/bundle/chunk-2KCZ7BKW.js +215 -0
  35. package/dist/bundle/chunk-2SNUMZ7S.js +1028 -0
  36. package/dist/bundle/chunk-45AKJVKV.js +24 -0
  37. package/dist/bundle/chunk-4PDYYS5K.js +2 -0
  38. package/dist/bundle/chunk-5D4AEUVA.js +24783 -0
  39. package/dist/bundle/chunk-6WY72XVQ.js +216 -0
  40. package/dist/bundle/chunk-7GRZAKBB.js +639 -0
  41. package/dist/bundle/chunk-ADLS6FVG.js +24600 -0
  42. package/dist/bundle/chunk-BCF7P4FZ.js +558 -0
  43. package/dist/bundle/chunk-CNNEA2M4.js +54 -0
  44. package/dist/bundle/chunk-CXL33BFL.js +570 -0
  45. package/dist/bundle/chunk-D5S6QV6R.js +95 -0
  46. package/dist/bundle/chunk-DFDN6AUB.js +21 -0
  47. package/dist/bundle/chunk-DTXERR44.js +35 -0
  48. package/dist/bundle/chunk-EVYSBZ3I.js +153 -0
  49. package/dist/bundle/chunk-EXOOKUEA.js +82 -0
  50. package/dist/bundle/chunk-FLUEXJ4X.js +53 -0
  51. package/dist/bundle/chunk-FOTREPNS.js +366 -0
  52. package/dist/bundle/chunk-FZL7F5NR.js +2022 -0
  53. package/dist/bundle/chunk-GDFNH33E.js +1691 -0
  54. package/dist/bundle/chunk-H2ADPPSH.js +50910 -0
  55. package/dist/bundle/chunk-HAXNUIGQ.js +1245 -0
  56. package/dist/bundle/chunk-HGL63O5V.js +288 -0
  57. package/dist/bundle/chunk-INFYLWUA.js +929 -0
  58. package/dist/bundle/chunk-IRV2PCQ2.js +5213 -0
  59. package/dist/bundle/chunk-K3UIB6ZF.js +45 -0
  60. package/dist/bundle/chunk-LRGYKOCP.js +91 -0
  61. package/dist/bundle/chunk-LSPIOT6Z.js +459 -0
  62. package/dist/bundle/chunk-MBDK4YXG.js +34 -0
  63. package/dist/bundle/chunk-N6FLBXZS.js +73 -0
  64. package/dist/bundle/chunk-OTD2ZRXD.js +161 -0
  65. package/dist/bundle/chunk-P33NDCDI.js +78 -0
  66. package/dist/bundle/chunk-P364PLIK.js +257 -0
  67. package/dist/bundle/chunk-PH5FZX6E.js +193 -0
  68. package/dist/bundle/chunk-POC3V3AO.js +36616 -0
  69. package/dist/bundle/chunk-QC53QBNC.js +143 -0
  70. package/dist/bundle/chunk-QGMDQ2PM.js +122 -0
  71. package/dist/bundle/chunk-QIPTIUMJ.js +281 -0
  72. package/dist/bundle/chunk-QMPN6WKD.js +3512 -0
  73. package/dist/bundle/chunk-QQXH2OPB.js +594 -0
  74. package/dist/bundle/chunk-QSNROIJL.js +413 -0
  75. package/dist/bundle/chunk-RRJNNPR4.js +76 -0
  76. package/dist/bundle/chunk-SFRNX2TI.js +6848 -0
  77. package/dist/bundle/chunk-SGRYYE4X.js +266 -0
  78. package/dist/bundle/chunk-TE3FR6MI.js +884 -0
  79. package/dist/bundle/chunk-U5ACMCAQ.js +12049 -0
  80. package/dist/bundle/chunk-VEWWAGTD.js +2315 -0
  81. package/dist/bundle/chunk-VL6SPMZV.js +194 -0
  82. package/dist/bundle/chunk-WII44RXN.js +58 -0
  83. package/dist/bundle/chunk-WKRQ44EH.js +528 -0
  84. package/dist/bundle/chunk-WTPMJYMD.js +8308 -0
  85. package/dist/bundle/chunk-XD4FRDSL.js +565 -0
  86. package/dist/bundle/chunk-XJXONOB5.js +63 -0
  87. package/dist/bundle/chunk-XNHSPHUN.js +48 -0
  88. package/dist/bundle/chunk-XRFJWHY5.js +131 -0
  89. package/dist/bundle/chunk-Y5E2WNWB.js +35 -0
  90. package/dist/bundle/chunk-YYO7D2MO.js +783 -0
  91. package/dist/bundle/chunk-YZ5LHE5Q.js +31 -0
  92. package/dist/bundle/chunk-ZDQQCXFG.js +392 -0
  93. package/dist/bundle/chunk-ZEW4P6AH.js +158 -0
  94. package/dist/bundle/chunk-ZGZT5S6B.js +3480 -0
  95. package/dist/bundle/chunk-ZIAQPTUS.js +82 -0
  96. package/dist/bundle/chunk-ZVVMGPBJ.js +50 -0
  97. package/dist/bundle/command-contract-OKQOE6G4.js +30 -0
  98. package/dist/bundle/decode-5ZPLTYV6.js +160 -0
  99. package/dist/bundle/dist-6Y64DTOE.js +7577 -0
  100. package/dist/bundle/echarts-J6LAPIX7.js +42501 -0
  101. package/dist/bundle/embed-YG5LDHME.js +35 -0
  102. package/dist/bundle/embedder-7FNUA5OZ.js +108 -0
  103. package/dist/bundle/first-run-JPZNWIJN.js +23 -0
  104. package/dist/bundle/first-screen-VQM4MTS7.js +28 -0
  105. package/dist/bundle/instructions-AXWTQHMR.js +11 -0
  106. package/dist/bundle/mcp-7F46P6AM.js +165 -0
  107. package/dist/bundle/mcp-HUD6UH5X.js +160 -0
  108. package/dist/bundle/mcp-J5R5A65I.js +87 -0
  109. package/dist/bundle/node-CWKAIOEM.js +176 -0
  110. package/dist/bundle/node-P4E63KXA.js +2340 -0
  111. package/dist/bundle/node-TLZSIHIJ.js +21 -0
  112. package/dist/bundle/node-sqlite-LSEKVRDA.js +67 -0
  113. package/dist/bundle/oauth-THYNLRLD.js +17 -0
  114. package/dist/bundle/open-E47QYKFC.js +20 -0
  115. package/dist/bundle/openai-EWSGC3BC.js +227 -0
  116. package/dist/bundle/process-WKTEA3WE.js +91 -0
  117. package/dist/bundle/program-UYX5362I.js +20851 -0
  118. package/dist/bundle/prompt-CAQ7QR3U.js +12 -0
  119. package/dist/bundle/recognize-6KGHNZC3.js +23 -0
  120. package/dist/bundle/remote-3UO2WDC3.js +26 -0
  121. package/dist/bundle/rerank-2JVDPZBX.js +49 -0
  122. package/dist/bundle/serve-ES7AG5IK.js +19 -0
  123. package/dist/bundle/server-5LE5LNUQ.js +45 -0
  124. package/dist/bundle/server-BU4VBM6S.js +58 -0
  125. package/dist/bundle/state-7NH5G4XJ.js +33 -0
  126. package/dist/bundle/store-7O4JQD2Z.js +127 -0
  127. package/dist/bundle/store-maintenance-command-UDVGEY2D.js +47 -0
  128. package/dist/commands/api.d.ts +3 -0
  129. package/dist/commands/api.d.ts.map +1 -0
  130. package/dist/commands/api.js +131 -0
  131. package/dist/commands/api.js.map +1 -0
  132. package/dist/commands/crm-writes.d.ts +4 -0
  133. package/dist/commands/crm-writes.d.ts.map +1 -0
  134. package/dist/commands/crm-writes.js +182 -0
  135. package/dist/commands/crm-writes.js.map +1 -0
  136. package/dist/commands/crm.d.ts +3 -0
  137. package/dist/commands/crm.d.ts.map +1 -0
  138. package/dist/commands/crm.js +144 -0
  139. package/dist/commands/crm.js.map +1 -0
  140. package/dist/commands/doctor.d.ts +77 -0
  141. package/dist/commands/doctor.d.ts.map +1 -0
  142. package/dist/commands/doctor.js +74 -0
  143. package/dist/commands/doctor.js.map +1 -0
  144. package/dist/commands/mcp.d.ts +3 -0
  145. package/dist/commands/mcp.d.ts.map +1 -0
  146. package/dist/commands/mcp.js +97 -0
  147. package/dist/commands/mcp.js.map +1 -0
  148. package/dist/commands/session.d.ts +3 -0
  149. package/dist/commands/session.d.ts.map +1 -0
  150. package/dist/commands/session.js +101 -0
  151. package/dist/commands/session.js.map +1 -0
  152. package/dist/commands/write.d.ts +21 -0
  153. package/dist/commands/write.d.ts.map +1 -0
  154. package/dist/commands/write.js +47 -0
  155. package/dist/commands/write.js.map +1 -0
  156. package/dist/config.d.ts +9 -0
  157. package/dist/config.d.ts.map +1 -0
  158. package/dist/config.js +17 -0
  159. package/dist/config.js.map +1 -0
  160. package/dist/crm/conditions.d.ts +25 -0
  161. package/dist/crm/conditions.d.ts.map +1 -0
  162. package/dist/crm/conditions.js +78 -0
  163. package/dist/crm/conditions.js.map +1 -0
  164. package/dist/crm/deal.d.ts +27 -0
  165. package/dist/crm/deal.d.ts.map +1 -0
  166. package/dist/crm/deal.js +74 -0
  167. package/dist/crm/deal.js.map +1 -0
  168. package/dist/crm/items.d.ts +30 -0
  169. package/dist/crm/items.d.ts.map +1 -0
  170. package/dist/crm/items.js +76 -0
  171. package/dist/crm/items.js.map +1 -0
  172. package/dist/crm/lead.d.ts +36 -0
  173. package/dist/crm/lead.d.ts.map +1 -0
  174. package/dist/crm/lead.js +85 -0
  175. package/dist/crm/lead.js.map +1 -0
  176. package/dist/crm/organization.d.ts +32 -0
  177. package/dist/crm/organization.d.ts.map +1 -0
  178. package/dist/crm/organization.js +67 -0
  179. package/dist/crm/organization.js.map +1 -0
  180. package/dist/crm/person.d.ts +31 -0
  181. package/dist/crm/person.d.ts.map +1 -0
  182. package/dist/crm/person.js +67 -0
  183. package/dist/crm/person.js.map +1 -0
  184. package/dist/crm/pipeline.d.ts +17 -0
  185. package/dist/crm/pipeline.d.ts.map +1 -0
  186. package/dist/crm/pipeline.js +42 -0
  187. package/dist/crm/pipeline.js.map +1 -0
  188. package/dist/crm/product.d.ts +43 -0
  189. package/dist/crm/product.d.ts.map +1 -0
  190. package/dist/crm/product.js +42 -0
  191. package/dist/crm/product.js.map +1 -0
  192. package/dist/crm/stage.d.ts +20 -0
  193. package/dist/crm/stage.d.ts.map +1 -0
  194. package/dist/crm/stage.js +65 -0
  195. package/dist/crm/stage.js.map +1 -0
  196. package/dist/crm/user.d.ts +39 -0
  197. package/dist/crm/user.d.ts.map +1 -0
  198. package/dist/crm/user.js +54 -0
  199. package/dist/crm/user.js.map +1 -0
  200. package/dist/crm/values.d.ts +33 -0
  201. package/dist/crm/values.d.ts.map +1 -0
  202. package/dist/crm/values.js +54 -0
  203. package/dist/crm/values.js.map +1 -0
  204. package/dist/crm/walk.d.ts +19 -0
  205. package/dist/crm/walk.d.ts.map +1 -0
  206. package/dist/crm/walk.js +22 -0
  207. package/dist/crm/walk.js.map +1 -0
  208. package/dist/identity.d.ts +5 -0
  209. package/dist/identity.d.ts.map +1 -0
  210. package/dist/identity.js +18 -0
  211. package/dist/identity.js.map +1 -0
  212. package/dist/index.d.ts +3 -0
  213. package/dist/index.d.ts.map +1 -0
  214. package/dist/index.js +3 -0
  215. package/dist/index.js.map +1 -0
  216. package/dist/mcp.d.ts +29 -0
  217. package/dist/mcp.d.ts.map +1 -0
  218. package/dist/mcp.js +99 -0
  219. package/dist/mcp.js.map +1 -0
  220. package/dist/portal.d.ts +47 -0
  221. package/dist/portal.d.ts.map +1 -0
  222. package/dist/portal.js +52 -0
  223. package/dist/portal.js.map +1 -0
  224. package/dist/program.d.ts +6 -0
  225. package/dist/program.d.ts.map +1 -0
  226. package/dist/program.js +45 -0
  227. package/dist/program.js.map +1 -0
  228. package/dist/reasons.d.ts +10 -0
  229. package/dist/reasons.d.ts.map +1 -0
  230. package/dist/reasons.js +28 -0
  231. package/dist/reasons.js.map +1 -0
  232. package/dist/token.d.ts +12 -0
  233. package/dist/token.d.ts.map +1 -0
  234. package/dist/token.js +41 -0
  235. package/dist/token.js.map +1 -0
  236. package/dist/version.d.ts +2 -0
  237. package/dist/version.d.ts.map +1 -0
  238. package/dist/version.js +2 -0
  239. package/dist/version.js.map +1 -0
  240. package/dist/whoami.d.ts +8 -0
  241. package/dist/whoami.d.ts.map +1 -0
  242. package/dist/whoami.js +9 -0
  243. package/dist/whoami.js.map +1 -0
  244. package/package.json +83 -4
  245. package/skills/bitrix24-cli/SKILL.md +41 -0
@@ -0,0 +1,565 @@
1
+ import { createRequire as __bundleRequire } from "node:module";
2
+ const require = __bundleRequire(import.meta.url);
3
+ import {
4
+ COMPACT_FLAG,
5
+ CliError,
6
+ createRenderer,
7
+ fieldsOf,
8
+ processStreams,
9
+ projectFields,
10
+ singleLine
11
+ } from "./chunk-IRV2PCQ2.js";
12
+ import {
13
+ __name
14
+ } from "./chunk-ZVVMGPBJ.js";
15
+
16
+ // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/sends/permissions.js
17
+ var LEVELS = ["deny", "readonly", "ask", "allow"];
18
+ var DANGEROUS = /* @__PURE__ */ new Set(["messages.delete", "bot.messages.delete", "topics.delete", "chats.delete", "chats.clear"]);
19
+ var skipFlagFor = /* @__PURE__ */ __name((key) => DANGEROUS.has(key) ? "--allow-dangerous" : "--yes", "skipFlagFor");
20
+ var DEFAULT_PERMISSIONS = {
21
+ "messages.delete": "ask",
22
+ "account.sessions.end": "ask",
23
+ "bot.messages.delete": "ask",
24
+ "topics.enable": "ask",
25
+ "topics.delete": "ask",
26
+ "chats.delete": "ask",
27
+ "chats.clear": "ask",
28
+ // NEED-568: a rule writes to people with nobody typing a command; it waits for the owner's own allow.
29
+ "replies.send": "deny",
30
+ // NEED-1662: an agent that changes settings, schedules or recipients could lift its own limits; the owner opts in.
31
+ "mcp.authority": "deny",
32
+ // NEED-1663: writes no level stopped before, so MCP could not offer them; over MCP `ask` goes ahead.
33
+ "store.backup": "ask",
34
+ "store.restore": "ask",
35
+ "store.migrate": "ask",
36
+ "store.repair": "ask",
37
+ "store.reset": "ask",
38
+ "store.clear": "ask",
39
+ "store.decrypt": "ask",
40
+ "store.copies.delete": "ask",
41
+ "server.start": "ask",
42
+ "server.stop": "ask",
43
+ "server.restart": "ask",
44
+ "models.download": "ask",
45
+ "images.models.download": "ask",
46
+ "schedule.run": "ask",
47
+ "schedule.exec": "ask",
48
+ "doctor.reports.create": "ask"
49
+ };
50
+ var KEYED_UNDER_HOUSEKEEPING = new Set(Object.keys(DEFAULT_PERMISSIONS).filter((key) => /^(store|server|models|images|schedule|doctor)\./.test(key)));
51
+ var AUTHORITY_KEY = "mcp.authority";
52
+ var authorityAllowed = /* @__PURE__ */ __name((levels) => {
53
+ const { level } = levelFor(levels, AUTHORITY_KEY);
54
+ return level === "allow" || level === "ask";
55
+ }, "authorityAllowed");
56
+ var BOT_API_KEY = "bot.api";
57
+ var isBotApi = /* @__PURE__ */ __name((path) => path[0] === "bot" && path[1] === "api", "isBotApi");
58
+ var botApiAllowed = /* @__PURE__ */ __name((levels) => {
59
+ const { level } = levelFor(levels, BOT_API_KEY, { ...DEFAULT_PERMISSIONS, [BOT_API_KEY]: "deny" });
60
+ return level === "allow" || level === "ask";
61
+ }, "botApiAllowed");
62
+ var RESOURCES = [
63
+ "messages",
64
+ "drafts",
65
+ "reactions",
66
+ "polls",
67
+ "topics",
68
+ "chats",
69
+ "contacts",
70
+ "account",
71
+ "bot",
72
+ "conversations",
73
+ "tags",
74
+ "mentions",
75
+ "search",
76
+ "searches",
77
+ "tasks",
78
+ "replies",
79
+ "attachments",
80
+ "stats",
81
+ "store",
82
+ "metadata",
83
+ "mcp",
84
+ "server",
85
+ "models",
86
+ "schedule",
87
+ "doctor",
88
+ "images"
89
+ ];
90
+ var layerPermissions = /* @__PURE__ */ __name((layers) => {
91
+ const levels = {};
92
+ const sources = {};
93
+ for (const [from, layer] of layers) {
94
+ const nearer = Object.keys(levels);
95
+ for (const [key, level] of Object.entries(layer ?? {})) {
96
+ if (nearer.some((named2) => key === named2 || key.startsWith(`${named2}.`)))
97
+ continue;
98
+ levels[key] = level;
99
+ sources[key] = from;
100
+ }
101
+ }
102
+ return { levels, sources };
103
+ }, "layerPermissions");
104
+ var CEILING_KEY = "*";
105
+ var ALLOWED = { level: "allow", key: null };
106
+ var ORDER = { deny: 0, readonly: 1, ask: 2, allow: 3 };
107
+ var nearest = /* @__PURE__ */ __name((levels, key) => {
108
+ for (let parts = key.split("."); parts.length > 0; parts = parts.slice(0, -1)) {
109
+ const named2 = parts.join(".");
110
+ const level = levels[named2];
111
+ if (level)
112
+ return { level, key: named2, depth: parts.length };
113
+ }
114
+ return void 0;
115
+ }, "nearest");
116
+ var levelFor = /* @__PURE__ */ __name((permissions, key, defaults = DEFAULT_PERMISSIONS) => {
117
+ const found = profileLevel(permissions, key, defaults);
118
+ const ceiling = permissions[CEILING_KEY];
119
+ return ceiling && ORDER[ceiling] < ORDER[found.level] ? { level: ceiling, key: CEILING_KEY } : found;
120
+ }, "levelFor");
121
+ var profileLevel = /* @__PURE__ */ __name((permissions, key, defaults) => {
122
+ const own = nearest(permissions, key);
123
+ const builtIn = nearest(defaults, key);
124
+ if (!builtIn || own && own.depth >= builtIn.depth)
125
+ return own ? { level: own.level, key: own.key } : ALLOWED;
126
+ if (!own || ORDER[builtIn.level] <= ORDER[own.level])
127
+ return { level: builtIn.level, key: builtIn.key };
128
+ return { level: own.level, key: own.key };
129
+ }, "profileLevel");
130
+ var CHAT_KEYS = {
131
+ settings: "chats.update",
132
+ "requests.accept": "chats.requests.confirm",
133
+ "requests.decline": "chats.requests.reject",
134
+ "link.create": "chats.links.create",
135
+ "link.reset": "chats.links.reset",
136
+ "link.revoke": "chats.links.remove",
137
+ "link.update": "chats.links.update"
138
+ };
139
+ var ACCOUNT_KEYS = {
140
+ "contact-add": "contacts.add",
141
+ "contact-remove": "contacts.remove",
142
+ "contact-import": "contacts.import",
143
+ "contact-rename": "contacts.rename",
144
+ "contact-block": "contacts.block",
145
+ "contact-unblock": "contacts.unblock",
146
+ profile: "account.update",
147
+ "folder-create": "chats.folders.create",
148
+ "folder-update": "chats.folders.update",
149
+ "folder-delete": "chats.folders.delete",
150
+ "folder-order": "chats.folders.order",
151
+ "folder-join": "chats.folders.join",
152
+ "sessions-end": "account.sessions.end",
153
+ "chat-mute": "chats.mute",
154
+ "chat-unmute": "chats.unmute",
155
+ "chat-archive": "chats.archive",
156
+ "chat-unarchive": "chats.unarchive",
157
+ "chat-pin": "chats.pin",
158
+ "chat-unpin": "chats.unpin",
159
+ "chat-mark-unread": "chats.mark-unread",
160
+ "message-star": "messages.star",
161
+ "message-unstar": "messages.unstar",
162
+ // A mail CLI names its own key on every write; these only answer `keyForWrite` when one is left out.
163
+ "message-flag": "messages.update",
164
+ "message-move": "messages.move",
165
+ "message-copy": "messages.copy",
166
+ "message-delete": "messages.trash",
167
+ "message-restore": "messages.restore",
168
+ privacy: "account.privacy.set"
169
+ };
170
+ var KIND_KEYS = {
171
+ message: "messages.send",
172
+ forward: "messages.forward",
173
+ edit: "messages.edit",
174
+ pin: "messages.pin",
175
+ reaction: "reactions",
176
+ read: "chats.mark-read",
177
+ delete: "messages.delete"
178
+ };
179
+ var keyForWrite = /* @__PURE__ */ __name((kind, action) => {
180
+ if (kind === "chat")
181
+ return CHAT_KEYS[action] ?? `chats.${action ?? "update"}`;
182
+ if (kind === "account") {
183
+ const key = ACCOUNT_KEYS[action];
184
+ if (!key)
185
+ throw new Error(`an account change without a known action: ${action}`);
186
+ return key;
187
+ }
188
+ return KIND_KEYS[kind];
189
+ }, "keyForWrite");
190
+ var writeOfKey = /* @__PURE__ */ __name((key) => {
191
+ const account = Object.entries(ACCOUNT_KEYS).find(([, named2]) => named2 === key)?.[0];
192
+ if (account)
193
+ return { kind: "account", action: account };
194
+ const kind = Object.entries(KIND_KEYS).find(([, named2]) => named2 === key || key.startsWith(`${named2}.`))?.[0];
195
+ if (kind)
196
+ return { kind };
197
+ if (key === "messages.unpin")
198
+ return { kind: "pin" };
199
+ if (key.startsWith("chats.")) {
200
+ const action = Object.entries(CHAT_KEYS).find(([, named2]) => named2 === key)?.[0] ?? key.slice("chats.".length);
201
+ return { kind: "chat", action };
202
+ }
203
+ return {};
204
+ }, "writeOfKey");
205
+ var NAMED_WRITE_KEYS = [
206
+ "drafts",
207
+ "store.gaps.repair",
208
+ "messages.sync-first",
209
+ "messages.server-search",
210
+ "messages.press",
211
+ "chats.start",
212
+ "chats.app",
213
+ "stats.messages.counters.sync",
214
+ "stats.messages.show.sync-first",
215
+ "stats.messages.top.sync-first",
216
+ "stats.contacts.top.sync-first",
217
+ "account.sessions.list",
218
+ "attachments.extract",
219
+ "attachments.move",
220
+ "attachments.update",
221
+ "bot.callbacks.answer",
222
+ "bot.chats.action",
223
+ "bot.chats.admins.add",
224
+ "bot.chats.admins.remove",
225
+ "bot.chats.leave",
226
+ "bot.chats.members.remove",
227
+ "bot.chats.moderate",
228
+ "bot.messages.delete",
229
+ "bot.messages.edit",
230
+ "bot.messages.pin",
231
+ "bot.messages.send",
232
+ "bot.messages.unpin",
233
+ "chats.admins.add",
234
+ "chats.admins.remove",
235
+ "chats.links.create",
236
+ "chats.links.reset",
237
+ "chats.links.remove",
238
+ "chats.links.update",
239
+ "chats.members.add",
240
+ "chats.members.remove",
241
+ "chats.moderate",
242
+ "conversations.embeddings",
243
+ "conversations.links",
244
+ "polls.close",
245
+ "polls.create",
246
+ "polls.vote",
247
+ "searches.clear",
248
+ "searches.create",
249
+ "searches.delete",
250
+ "contacts.aliases.set",
251
+ "contacts.aliases.remove",
252
+ "contacts.notes.add",
253
+ "contacts.notes.edit",
254
+ "contacts.notes.remove",
255
+ "tags.rebuild",
256
+ "metadata.sync",
257
+ "mentions.rebuild",
258
+ "mentions.confirm",
259
+ "mentions.reject",
260
+ "tags.add",
261
+ "tags.remove",
262
+ "tasks.acknowledge",
263
+ "tasks.add",
264
+ "tasks.claim",
265
+ "tasks.close",
266
+ "tasks.duplicates.defer",
267
+ "tasks.duplicates.reject",
268
+ "tasks.link",
269
+ "tasks.merge",
270
+ "tasks.update",
271
+ "tasks.release",
272
+ "tasks.scan",
273
+ "tasks.unmerge",
274
+ "topics.create",
275
+ "topics.edit",
276
+ "topics.enable"
277
+ ];
278
+ var WRITE_KEYS = [
279
+ .../* @__PURE__ */ new Set([
280
+ ...NAMED_WRITE_KEYS,
281
+ ...Object.keys(DEFAULT_PERMISSIONS),
282
+ ...Object.values(KIND_KEYS),
283
+ ...Object.values(ACCOUNT_KEYS),
284
+ ...Object.values(CHAT_KEYS)
285
+ ])
286
+ ];
287
+ var HOUSEKEEPING = /* @__PURE__ */ new Set([
288
+ "help",
289
+ "guide",
290
+ "config",
291
+ "session",
292
+ "doctor",
293
+ "commands",
294
+ "complete",
295
+ "upgrade",
296
+ "skill",
297
+ "models",
298
+ "server",
299
+ // What a schedule runs is checked by its own key when it runs; an agent runs read-only.
300
+ "schedule",
301
+ "runs",
302
+ "sends",
303
+ "recipients",
304
+ "flood",
305
+ "mcp",
306
+ // Its commands read the rules or flip the pause switch; what a rule sends is checked as `replies.send`.
307
+ "replies"
308
+ ]);
309
+ var BOT_HOUSEKEEPING = /* @__PURE__ */ new Set(["auth", "list", "sends", "recipients", "mcp"]);
310
+ var STORE_MAINTENANCE = /* @__PURE__ */ new Set(["info", "check", "copies"]);
311
+ var SHOW_MESSAGES = /* @__PURE__ */ new Set(["inbox", "review", "watch", "serve", "store", "conversations", "projects"]);
312
+ var readKeysForCommand = /* @__PURE__ */ __name((path) => {
313
+ if (path[0] === "bot")
314
+ return readKeysForCommand(path.slice(1)).map((key2) => `bot.${key2}`);
315
+ const key = keyForCommand(path);
316
+ if (!key)
317
+ return [];
318
+ if (path[0] === "attachments" && path[1] === "download")
319
+ return [key, "messages", "chats"];
320
+ if (path[0] === "attachments" && (path[1] === "extract" || path[1] === "show"))
321
+ return [key, "messages"];
322
+ if (path[0] === "store" && path[1] === "gaps" && path[2] === "repair")
323
+ return [key, "messages"];
324
+ if (path[0] === "store" && ["reset", "clear", "decrypt"].includes(path[1] ?? ""))
325
+ return [key, "messages"];
326
+ if (path[0] === "search") {
327
+ if (path[1] === "notes")
328
+ return [key];
329
+ if (path[1] === "topics")
330
+ return [key, "topics"];
331
+ if (path[1] === "conversations")
332
+ return [key, "messages", "conversations"];
333
+ return [key, "messages"];
334
+ }
335
+ if (path[0] !== "stats")
336
+ return [key];
337
+ const resource = path[1] === "charts" ? "chats" : path[1];
338
+ return [
339
+ .../* @__PURE__ */ new Set([
340
+ key,
341
+ "messages",
342
+ ...["chats", "contacts", "tasks"].includes(resource ?? "") ? [resource] : []
343
+ ])
344
+ ];
345
+ }, "readKeysForCommand");
346
+ var keyForCommand = /* @__PURE__ */ __name((path) => {
347
+ if (path.length === 0)
348
+ return null;
349
+ const [top, next] = path;
350
+ if (top === "bot") {
351
+ if (next === void 0 || BOT_HOUSEKEEPING.has(next))
352
+ return null;
353
+ const inner = keyForCommand(path.slice(1));
354
+ return `bot.${inner ?? path.slice(1).join(".")}`;
355
+ }
356
+ if (KEYED_UNDER_HOUSEKEEPING.has(path.join(".")))
357
+ return path.join(".");
358
+ if (top === void 0 || HOUSEKEEPING.has(top) || top === "search" && next === "runs")
359
+ return null;
360
+ if (top === "images" && next === "models")
361
+ return null;
362
+ if (top === "attachments" && (next === "check" || next === "jobs"))
363
+ return null;
364
+ if (top === "attachments" && next === "download")
365
+ return "messages";
366
+ if (top === "store" && next !== void 0 && STORE_MAINTENANCE.has(next))
367
+ return null;
368
+ if (top === "conversations" && next === "links")
369
+ return path[2] === "rebuild" ? "conversations.links.rebuild" : "conversations.links";
370
+ if (top === "conversations" && (next === "embeddings" || next === "embed") || top === "images" && next === "embed" || top === "conversations" && next === "rebuild")
371
+ return "conversations.embeddings";
372
+ if (top === "attachments" && next === "list" || top === "chats" && next === "documents")
373
+ return "messages";
374
+ if (top === "mentions")
375
+ return next === "rebuild" || next === "confirm" || next === "reject" ? `mentions.${next}` : "messages";
376
+ if (top === "store" && (next === "gaps" || next === "jobs"))
377
+ return path.join(".");
378
+ if (SHOW_MESSAGES.has(top) || top === "contacts" && (next === "context" || next === "prepare" || next === "events"))
379
+ return "messages";
380
+ if (RESOURCES.includes(top))
381
+ return path.join(".");
382
+ return void 0;
383
+ }, "keyForCommand");
384
+ var RESOURCE_KEY = new RegExp(`^(${RESOURCES.join("|")})(\\.[a-z][a-z-]*)*$`);
385
+ var COMMAND_PATH_KEY = /^[a-z][a-z-]*(\.[a-zA-Z][a-zA-Z-]*)*$/;
386
+ var permissionOverrides = /* @__PURE__ */ __name((entries = [], shape = RESOURCE_KEY) => {
387
+ const levels = {};
388
+ const example = shape === RESOURCE_KEY ? "messages.send=allow" : "api=readonly";
389
+ for (const entry of entries) {
390
+ const [key = "", level = "", extra] = entry.split("=");
391
+ if (!shape.test(key) || !LEVELS.includes(level) || extra !== void 0)
392
+ throw new CliError("validation_error", `--permission takes a command path and level, e.g. ${example} (deny, readonly, ask, allow)`);
393
+ levels[key] = level;
394
+ }
395
+ return levels;
396
+ }, "permissionOverrides");
397
+ var assertOverridesTighten = /* @__PURE__ */ __name((overrides, profile, defaults = DEFAULT_PERMISSIONS) => {
398
+ for (const [key, level] of Object.entries(overrides)) {
399
+ const under = Object.keys(profile).filter((named2) => named2.startsWith(`${key}.`));
400
+ const lifted = [key, ...under].find((named2) => ORDER[level] > ORDER[levelFor(profile, named2, defaults).level]);
401
+ if (lifted !== void 0)
402
+ throw new CliError("validation_error", `--permission ${key}=${level} would loosen ${lifted} from ${levelFor(profile, lifted, defaults).level}; it only tightens \u2014 change the profile's permissions to loosen it`, { key, lifted });
403
+ }
404
+ }, "assertOverridesTighten");
405
+ var assertRetentionEvidenceRead = /* @__PURE__ */ __name((permissions) => {
406
+ for (const permission of ["stats.chats.retention", "chats"]) {
407
+ if (levelFor(permissions, permission).level === "deny")
408
+ throw new CliError("permission_error", `profile denies ${permission}`, { permission });
409
+ }
410
+ }, "assertRetentionEvidenceRead");
411
+
412
+ // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/cli/result-fields.js
413
+ var named = /* @__PURE__ */ __name((work) => {
414
+ try {
415
+ return work();
416
+ } catch (error) {
417
+ if (error instanceof CliError && error.code === "validation_error")
418
+ throw new CliError("validation_error", "--json takes comma-separated field paths, for example --json=id,text", {
419
+ param: "--json"
420
+ });
421
+ throw error;
422
+ }
423
+ }, "named");
424
+ var fieldsOf2 = /* @__PURE__ */ __name((value) => named(() => fieldsOf(value)), "fieldsOf");
425
+ var projectCommands = /* @__PURE__ */ __name((commands, fields) => commands.map((command) => ({
426
+ ...projectFields(command, fields),
427
+ path: command.path,
428
+ name: command.name,
429
+ origin: command.origin,
430
+ effects: command.effects,
431
+ commands: projectCommands(command.commands, fields)
432
+ })), "projectCommands");
433
+ var projectFields2 = /* @__PURE__ */ __name((value, fields) => named(() => {
434
+ if (value && typeof value === "object" && "cli" in value && typeof value.cli === "string" && "contract" in value && "commands" in value && Array.isArray(value.commands))
435
+ return { ...value, commands: projectCommands(value.commands, fields) };
436
+ return projectFields(value, fields);
437
+ }), "projectFields");
438
+
439
+ // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/output-detail.js
440
+ var RARELY_SET = ["editedAt", "replyTo", "forwardedFrom", "reactions"];
441
+ var BRIEF = ["locator", "chatTitle", "timestamp", "senderName", "excerpt", "score"];
442
+ var SNAKE_BRIEF = ["ref", "chat_title", "timestamp", "sender_name", "excerpt", "score"];
443
+ var isRecord = /* @__PURE__ */ __name((value) => typeof value === "object" && value !== null, "isRecord");
444
+ var isSnakeHit = /* @__PURE__ */ __name((value) => isRecord(value) && typeof value.ref === "string" && typeof value.excerpt === "string", "isSnakeHit");
445
+ var isHit = /* @__PURE__ */ __name((value) => isSnakeHit(value) || isRecord(value) && typeof value.locator === "string" && typeof value.text === "string", "isHit");
446
+ var picked = /* @__PURE__ */ __name((hit, keys) => Object.fromEntries(keys.flatMap((key) => hit[key] === void 0 || hit[key] === null ? [] : [[key, hit[key]]])), "picked");
447
+ var shaped = /* @__PURE__ */ __name((hit, detail) => {
448
+ if (isSnakeHit(hit))
449
+ return detail === "brief" ? picked(hit, SNAKE_BRIEF) : hit;
450
+ if (detail === "brief")
451
+ return picked(hit, BRIEF);
452
+ const { text, providerMetadata, ...rest } = hit;
453
+ for (const key of RARELY_SET)
454
+ if (rest[key] === null)
455
+ delete rest[key];
456
+ const metadata = rest.email ? void 0 : providerMetadata;
457
+ return {
458
+ ...rest,
459
+ ...typeof rest.excerpt === "string" ? {} : { text },
460
+ ...metadata === void 0 ? {} : { providerMetadata: metadata }
461
+ };
462
+ }, "shaped");
463
+ var atDetail = /* @__PURE__ */ __name((value, detail = "default") => {
464
+ if (detail === "full")
465
+ return value;
466
+ if (Array.isArray(value))
467
+ return value.map((item) => isHit(item) ? shaped(item, detail) : item);
468
+ if (isHit(value))
469
+ return shaped(value, detail);
470
+ if (typeof value === "object" && value !== null && Array.isArray(value.items))
471
+ return { ...value, items: atDetail(value.items, detail) };
472
+ return value;
473
+ }, "atDetail");
474
+
475
+ // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/output.js
476
+ var refuseCompact = /* @__PURE__ */ __name(({ json, jsonl, fields, hitDetail }) => {
477
+ const other = jsonl ? "--jsonl" : fields !== void 0 ? "--json=\u2026" : json ? "--json" : hitDetail === "brief" ? "--brief" : "";
478
+ if (other)
479
+ throw new CliError("validation_error", `${COMPACT_FLAG} and ${other} ask for different output \u2014 pick one`, {
480
+ reason: "output.conflict",
481
+ param: COMPACT_FLAG
482
+ });
483
+ }, "refuseCompact");
484
+ var resolveOutput = /* @__PURE__ */ __name(({ json, jsonl, quiet, streams = processStreams, tty, color, fields, hitDetail, env = process.env, capture, compact } = {}) => {
485
+ if (compact)
486
+ refuseCompact({ json, jsonl, fields, hitDetail });
487
+ const interactive = tty ?? process.stdout.isTTY === true;
488
+ const format = jsonl ? "jsonl" : json || compact || !interactive ? "json" : "pretty";
489
+ const painted = format === "pretty" && (color ?? (env.NO_COLOR === void 0 && env.TERM !== "dumb" && !env.CI));
490
+ const printing = createRenderer({ format, color: painted, streams });
491
+ const rendered = capture ? { ...printing, result: capture, stream: /* @__PURE__ */ __name((items) => capture([...items]), "stream") } : printing;
492
+ const level = hitDetail ?? (fields === void 0 ? "default" : "full");
493
+ const standard = format === "pretty" ? rendered : {
494
+ ...rendered,
495
+ result: /* @__PURE__ */ __name((value) => rendered.result(atDetail(value, level)), "result"),
496
+ stream: /* @__PURE__ */ __name((items) => rendered.stream(atDetail([...items], level)), "stream")
497
+ };
498
+ const created = standard;
499
+ const paths = fields === void 0 ? void 0 : fieldsOf2(fields);
500
+ const renderer = format === "pretty" ? oneLineFields(created) : paths ? {
501
+ ...created,
502
+ result: /* @__PURE__ */ __name((value) => created.result(projectFields2(value, paths)), "result"),
503
+ stream: /* @__PURE__ */ __name((items) => created.stream([...items].map((item) => projectFields2(item, paths))), "stream")
504
+ } : created;
505
+ return {
506
+ format,
507
+ color: painted,
508
+ streams,
509
+ renderer: quiet ? silence(renderer) : renderer,
510
+ ...compact ? { compact: true, full: hitDetail === "full" } : {}
511
+ };
512
+ }, "resolveOutput");
513
+ var MULTI_LINE = /* @__PURE__ */ new Set(["text", "description"]);
514
+ var oneLineFields = /* @__PURE__ */ __name((renderer) => ({
515
+ ...renderer,
516
+ result: /* @__PURE__ */ __name((value) => renderer.result(oneLine(value)), "result"),
517
+ stream: /* @__PURE__ */ __name((items) => renderer.stream([...items].map((item) => oneLine(item))), "stream")
518
+ }), "oneLineFields");
519
+ var oneLine = /* @__PURE__ */ __name((value, key) => {
520
+ if (typeof value === "string")
521
+ return key !== void 0 && MULTI_LINE.has(key) ? value : singleLine(value);
522
+ if (Array.isArray(value))
523
+ return value.map((item) => oneLine(item, key));
524
+ if (value !== null && typeof value === "object" && Object.getPrototypeOf(value) === Object.prototype) {
525
+ return Object.fromEntries(Object.entries(value).map(([field, item]) => [field, oneLine(item, field)]));
526
+ }
527
+ return value;
528
+ }, "oneLine");
529
+ var silence = /* @__PURE__ */ __name((renderer) => ({
530
+ ...renderer,
531
+ note: /* @__PURE__ */ __name(() => {
532
+ }, "note"),
533
+ success: /* @__PURE__ */ __name(() => {
534
+ }, "success"),
535
+ warn: /* @__PURE__ */ __name(() => {
536
+ }, "warn")
537
+ }), "silence");
538
+
539
+ export {
540
+ LEVELS,
541
+ skipFlagFor,
542
+ DEFAULT_PERMISSIONS,
543
+ AUTHORITY_KEY,
544
+ authorityAllowed,
545
+ BOT_API_KEY,
546
+ isBotApi,
547
+ botApiAllowed,
548
+ RESOURCES,
549
+ layerPermissions,
550
+ CEILING_KEY,
551
+ levelFor,
552
+ keyForWrite,
553
+ writeOfKey,
554
+ WRITE_KEYS,
555
+ readKeysForCommand,
556
+ keyForCommand,
557
+ RESOURCE_KEY,
558
+ COMMAND_PATH_KEY,
559
+ permissionOverrides,
560
+ assertOverridesTighten,
561
+ assertRetentionEvidenceRead,
562
+ fieldsOf2 as fieldsOf,
563
+ projectFields2 as projectFields,
564
+ resolveOutput
565
+ };
@@ -0,0 +1,63 @@
1
+ import { createRequire as __bundleRequire } from "node:module";
2
+ const require = __bundleRequire(import.meta.url);
3
+ import {
4
+ __name
5
+ } from "./chunk-ZVVMGPBJ.js";
6
+
7
+ // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/background/processes.js
8
+ import { execFileSync } from "node:child_process";
9
+ import { readdirSync, readFileSync, readlinkSync } from "node:fs";
10
+ var alive = /* @__PURE__ */ __name((pid) => {
11
+ try {
12
+ process.kill(pid, 0);
13
+ return true;
14
+ } catch (error) {
15
+ return error.code === "EPERM";
16
+ }
17
+ }, "alive");
18
+ var carries = /* @__PURE__ */ __name((pid, marker) => {
19
+ if (pid <= 0 || !alive(pid))
20
+ return false;
21
+ try {
22
+ if (process.platform === "linux") {
23
+ return readFileSync(`/proc/${pid}/environ`, "latin1").split("\0").some((entry) => entry.endsWith(marker));
24
+ }
25
+ if (process.platform === "darwin") {
26
+ return execFileSync("ps", ["eww", "-o", "command=", "-p", String(pid)], { encoding: "utf8" }).includes(marker);
27
+ }
28
+ } catch {
29
+ return false;
30
+ }
31
+ return false;
32
+ }, "carries");
33
+ var holdersOf = /* @__PURE__ */ __name((paths) => {
34
+ if (process.platform === "linux") {
35
+ const wanted = new Set(paths);
36
+ return readdirSync("/proc").filter((entry) => /^\d+$/.test(entry) && Number(entry) !== process.pid).filter((pid) => {
37
+ try {
38
+ return readdirSync(`/proc/${pid}/fd`).some((fd) => {
39
+ try {
40
+ return wanted.has(readlinkSync(`/proc/${pid}/fd/${fd}`));
41
+ } catch {
42
+ return false;
43
+ }
44
+ });
45
+ } catch {
46
+ return false;
47
+ }
48
+ }).map(Number);
49
+ }
50
+ const pids = /* @__PURE__ */ __name((listed) => listed.split("\n").filter(Boolean).map(Number).filter((pid) => pid !== process.pid), "pids");
51
+ try {
52
+ return pids(execFileSync("lsof", ["-t", "--", ...paths], { encoding: "utf8", stdio: ["ignore", "pipe", "ignore"] }));
53
+ } catch (error) {
54
+ const { status, stdout } = error;
55
+ return status === 1 ? pids(stdout ?? "") : void 0;
56
+ }
57
+ }, "holdersOf");
58
+
59
+ export {
60
+ alive,
61
+ carries,
62
+ holdersOf
63
+ };
@@ -0,0 +1,48 @@
1
+ import { createRequire as __bundleRequire } from "node:module";
2
+ const require = __bundleRequire(import.meta.url);
3
+ import {
4
+ CliError
5
+ } from "./chunk-IRV2PCQ2.js";
6
+ import {
7
+ __name
8
+ } from "./chunk-ZVVMGPBJ.js";
9
+
10
+ // node_modules/.pnpm/@wirecat+cli-core@0.586.0_@wirecat+cli-base@0.79.0_commander@15.0.0_esbuild@0.28.2_type_bdecddef0ae5a50ae90cab8b9e35c13b/node_modules/@wirecat/cli-core/dist/http/public-url.js
11
+ var EXAMPLE = "--public-url https://<name>.ts.net";
12
+ var publicUrlOf = /* @__PURE__ */ __name((given, { missing, reaches, path = false }) => {
13
+ if (!given)
14
+ throw new CliError("configuration_error", `${missing} needs the tunnel's address: ${EXAMPLE}`);
15
+ let url;
16
+ try {
17
+ url = new URL(given);
18
+ } catch {
19
+ throw new CliError("validation_error", `--public-url is not an address: ${EXAMPLE}`);
20
+ }
21
+ if (url.username || url.password)
22
+ throw new CliError("validation_error", "--public-url must not contain login credentials");
23
+ const local = url.protocol === "http:" && ["localhost", "127.0.0.1"].includes(url.hostname);
24
+ if (url.protocol !== "https:" && !local)
25
+ throw new CliError("validation_error", `--public-url must be https \u2014 ${reaches} through it`);
26
+ if (url.search || url.hash || !path && url.pathname !== "/")
27
+ throw new CliError("validation_error", path ? `--public-url is the tunnel's address, or a path of it, without a query: ${EXAMPLE}/tg` : `--public-url is the tunnel's address only, without a path: ${EXAMPLE}`);
28
+ if (path && !/^(\/[A-Za-z0-9_-][A-Za-z0-9._-]*)*\/?$/.test(url.pathname))
29
+ throw new CliError("validation_error", "--public-url's path takes letters, digits, dot, dash and underscore: /tg");
30
+ if (path)
31
+ url.pathname = url.pathname.replace(/\/+$/, "") || "/";
32
+ return url;
33
+ }, "publicUrlOf");
34
+ var portOf = /* @__PURE__ */ __name((given, fallback) => {
35
+ if (given === void 0)
36
+ return fallback;
37
+ const port = Number(given);
38
+ if (!Number.isInteger(port) || port < 1 || port > 65535)
39
+ throw new CliError("validation_error", "--port takes 1\u201365535");
40
+ return port;
41
+ }, "portOf");
42
+ var mcpUrlOf = /* @__PURE__ */ __name((publicUrl) => new URL(`${publicUrl.pathname.replace(/\/+$/, "")}/mcp`, publicUrl.origin), "mcpUrlOf");
43
+
44
+ export {
45
+ publicUrlOf,
46
+ portOf,
47
+ mcpUrlOf
48
+ };