nolo-cli 0.7.0 → 0.8.0-alpha.11

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 (175) hide show
  1. package/_executeModel-GPU2276G.js +198 -0
  2. package/action-PAXRPJJF.js +27 -0
  3. package/addContentAction-CZVWF3QZ.js +25 -0
  4. package/addDialogAgentAction-CCIDTPHC.js +67 -0
  5. package/agentDeleteCommand-4ZZFM6AT.js +323 -0
  6. package/agentEmailCommands-C4FIVQYV.js +621 -0
  7. package/agentListCommands-VQAKVNEX.js +219 -0
  8. package/agentMachineCommands-ONFDXZUQ.js +421 -0
  9. package/agentPullCommand-O2MTUAFR.js +122 -0
  10. package/agentRecordCommands-QANUGHLK.js +89 -0
  11. package/agentRunCommand-A3OSRB5Q.js +102 -0
  12. package/agentRunControl-K4VKNEHF.js +57 -0
  13. package/agentRuntimeLocal-62ZB2ODP.js +99 -0
  14. package/agentSlice-GCGLVR2N.js +41 -0
  15. package/authCommand-WXMD3IPR.js +574 -0
  16. package/authCommands-X74AFDTC.js +26 -0
  17. package/chunk-2EISRLRC.js +238 -0
  18. package/chunk-2FTTDCD4.js +675 -0
  19. package/chunk-2MALU52L.js +51 -0
  20. package/chunk-2UZXR7WO.js +3631 -0
  21. package/chunk-3ASDTTEI.js +1774 -0
  22. package/chunk-3EUW3WEO.js +8 -0
  23. package/chunk-3LY4F7SV.js +9293 -0
  24. package/chunk-4CQLVGRV.js +50 -0
  25. package/chunk-4IJYA27C.js +342 -0
  26. package/chunk-4SN6J65J.js +38 -0
  27. package/chunk-4VNS5WPM.js +42 -0
  28. package/chunk-53DNV5AT.js +421 -0
  29. package/chunk-572EKYLF.js +792 -0
  30. package/chunk-5MIDPSSK.js +206 -0
  31. package/chunk-5MMAK75Q.js +15 -0
  32. package/chunk-63W5N6P3.js +150 -0
  33. package/chunk-6B7G54GE.js +1078 -0
  34. package/chunk-6HYVJV7B.js +102 -0
  35. package/chunk-6WD3OOJS.js +20 -0
  36. package/chunk-7OC5VCLW.js +929 -0
  37. package/chunk-7YLKNMOM.js +562 -0
  38. package/chunk-ATNTHIZI.js +13 -0
  39. package/chunk-AUGHVUFE.js +69 -0
  40. package/chunk-AVMKZHBC.js +85 -0
  41. package/chunk-AZPCASRE.js +36 -0
  42. package/chunk-BR2WP3DF.js +548 -0
  43. package/chunk-BSTNFPHD.js +231 -0
  44. package/chunk-CF2WZF4N.js +134 -0
  45. package/chunk-CF7PE763.js +10 -0
  46. package/chunk-CJH2VTEU.js +360 -0
  47. package/chunk-CKOJQDKR.js +198 -0
  48. package/chunk-CM54RSSA.js +206 -0
  49. package/chunk-CQAHS7YO.js +4300 -0
  50. package/chunk-CWMSB67P.js +34 -0
  51. package/chunk-DFFIZ25G.js +30 -0
  52. package/chunk-DWLEOOGR.js +8 -0
  53. package/chunk-DZ3XJVET.js +231 -0
  54. package/chunk-EHLHSX7R.js +1433 -0
  55. package/chunk-ELRRLDWI.js +478 -0
  56. package/chunk-EYEEHCU4.js +3066 -0
  57. package/chunk-F6QQI5YI.js +19 -0
  58. package/chunk-G3SUCT4W.js +8 -0
  59. package/chunk-G5H7RNFL.js +807 -0
  60. package/chunk-GAKEBQD6.js +30 -0
  61. package/chunk-GBRG75BQ.js +86 -0
  62. package/chunk-GCMRDRCQ.js +190 -0
  63. package/chunk-GGUO4FKF.js +27158 -0
  64. package/chunk-GGXABIPP.js +628 -0
  65. package/chunk-H2RMRZJE.js +113 -0
  66. package/chunk-H33743XH.js +25 -0
  67. package/chunk-HEIIIZBX.js +104 -0
  68. package/chunk-HNMXYYJR.js +12 -0
  69. package/chunk-I3D64LRJ.js +1447 -0
  70. package/chunk-IAXBCTTE.js +175 -0
  71. package/chunk-IDZTNRP2.js +85 -0
  72. package/chunk-ISNCLGUZ.js +146 -0
  73. package/chunk-IYQV26RA.js +138 -0
  74. package/chunk-J4576WMJ.js +91 -0
  75. package/chunk-J5KV47ZW.js +222 -0
  76. package/chunk-JBTJAPUF.js +35 -0
  77. package/chunk-JZPBVBIY.js +94 -0
  78. package/chunk-KB7YFGL6.js +34 -0
  79. package/chunk-KKY4B2Q2.js +21 -0
  80. package/chunk-KQHGZWSV.js +63 -0
  81. package/chunk-KUG52IAP.js +8 -0
  82. package/chunk-KX6YBIHG.js +8 -0
  83. package/chunk-LAWBMYBC.js +171 -0
  84. package/chunk-LCBAMY2M.js +60 -0
  85. package/chunk-LM25IZBJ.js +902 -0
  86. package/chunk-LM6IYQ3F.js +16 -0
  87. package/chunk-M76ECQRD.js +13658 -0
  88. package/chunk-MRC4Q34M.js +188 -0
  89. package/chunk-NXZGF7F7.js +2878 -0
  90. package/chunk-OF5H3QWS.js +300 -0
  91. package/chunk-OLZBQWZU.js +6 -0
  92. package/chunk-OWOHNGCN.js +50 -0
  93. package/chunk-PN7AFLOK.js +3401 -0
  94. package/chunk-QR5IPGT3.js +24674 -0
  95. package/chunk-QSJ3HFEF.js +8 -0
  96. package/chunk-QYXLLLGL.js +4519 -0
  97. package/chunk-R2HXWML7.js +1949 -0
  98. package/chunk-ROWQEJRP.js +139 -0
  99. package/chunk-S7Z2HMCN.js +25 -0
  100. package/chunk-SYOF5TAS.js +962 -0
  101. package/chunk-TDIQFT2F.js +301 -0
  102. package/chunk-TILFE6LV.js +381 -0
  103. package/chunk-TZNCFAUP.js +2157 -0
  104. package/chunk-U4TRT5V4.js +246 -0
  105. package/chunk-U6VC4MU4.js +8 -0
  106. package/chunk-UAD2WT54.js +64 -0
  107. package/chunk-USZMK5UT.js +105 -0
  108. package/chunk-VEJLAVTC.js +2052 -0
  109. package/chunk-VF4K2QE6.js +21 -0
  110. package/chunk-VHBWHNVT.js +59 -0
  111. package/chunk-VIDPVFP3.js +20 -0
  112. package/chunk-VP4WJWKW.js +8882 -0
  113. package/chunk-VQ2AJRGD.js +148 -0
  114. package/chunk-W4NVOSFF.js +37 -0
  115. package/chunk-WWC7I6TA.js +8 -0
  116. package/chunk-X7W4TNB4.js +1550 -0
  117. package/chunk-XBIUN5CR.js +191 -0
  118. package/chunk-XDVAYP26.js +537 -0
  119. package/chunk-XKIMRZO2.js +221 -0
  120. package/chunk-Y5GCAMGP.js +9 -0
  121. package/chunk-YOUZDXU7.js +9013 -0
  122. package/chunk-Z4NR32XR.js +50 -0
  123. package/chunk-ZNFJWEN4.js +56 -0
  124. package/cliExecutor-DNE7TCC4.js +36 -0
  125. package/clipboardy-BVE3LVEH.js +12001 -0
  126. package/createAgentAutomationAction-537X433B.js +864 -0
  127. package/createDialogAction-YUD4RKBS.js +52 -0
  128. package/createPageAction-KJMFHL4C.js +169 -0
  129. package/db-HCJ5PRB5.js +271 -0
  130. package/dbSlice-C4UJLRZP.js +59 -0
  131. package/deleteFile-4SKGPHOZ.js +41 -0
  132. package/dialogCommands-H74KJKHC.js +59 -0
  133. package/dialogSlice-ETSD4YWS.js +146 -0
  134. package/docCreateCommands-ADUSU34K.js +215 -0
  135. package/docDeleteCommands-ZXV3S5OS.js +176 -0
  136. package/docReadCommands-YYYI6LT7.js +129 -0
  137. package/docStore-ZBF5DDKR.js +96 -0
  138. package/docUpdateCommands-7MGJ3BYA.js +313 -0
  139. package/fetchMessages-JOCYIFKL.js +16 -0
  140. package/getPricing-PWPJ6MNV.js +30 -0
  141. package/handleSendMessageAction-MGKI62Y6.js +183 -0
  142. package/index.js +184 -112288
  143. package/lib-FYYBQIXS.js +19839 -0
  144. package/localDialogRead-D3BELSTF.js +26 -0
  145. package/localFirstLog-DHNOY2NA.js +19 -0
  146. package/localRuntimeAuthority-TEGCOWX4.js +471 -0
  147. package/localRuntimeDb-LGDF6FQP.js +12 -0
  148. package/machineCommands-RMTMN7VQ.js +774 -0
  149. package/machineInfo-M6KB6HZN.js +10 -0
  150. package/machineWsRunDispatch-UIP355FN.js +105 -0
  151. package/memoryCommands-O4MIPIWQ.js +476 -0
  152. package/models-XLEOET3E.js +9 -0
  153. package/offlineMarxistsAgentCommand-BCPJITJL.js +242 -0
  154. package/package.json +3 -25
  155. package/read-RIJCIVKX.js +17 -0
  156. package/readDocTool-GZD2N3LO.js +16 -0
  157. package/readlineWorkspace-CRNQRZ6D.js +5374 -0
  158. package/removeDialogAgentAction-CXLST3N6.js +72 -0
  159. package/runAgentClientLoop-2S334SGA.js +288 -0
  160. package/runtimeDoctorCommands-LRHLPDRC.js +289 -0
  161. package/setDialogExtraReferencesAction-LP6VYGU7.js +59 -0
  162. package/setPrimaryDialogAgentAction-D3GGH23T.js +79 -0
  163. package/settingSlice-J4I3Z5H7.js +198 -0
  164. package/skillSummaryMarker-42HKSXYY.js +9 -0
  165. package/slateToRenderMarkdown-Y5IYN73U.js +7 -0
  166. package/slateUtils-2M7MUTWX.js +19 -0
  167. package/spaceCommands-NDEWMFZJ.js +450 -0
  168. package/spaceSlice-RLB6RTHO.js +145 -0
  169. package/streamAgentChatTurn-Y2TTYPBD.js +4503 -0
  170. package/tableCommands-GOFP7QKA.js +1286 -0
  171. package/toolApiClient-QI3YBNWB.js +26 -0
  172. package/tools-YZYLY2ZQ.js +83 -0
  173. package/understanding-HCSFPE7R.js +318 -0
  174. package/updateCommands-VOSPKXFF.js +31 -0
  175. package/updateDialogTitleAction-LQV6QLBW.js +185 -0
@@ -0,0 +1,50 @@
1
+ import {
2
+ asOptionalTrimmedString
3
+ } from "./chunk-G3SUCT4W.js";
4
+ import {
5
+ isRecord
6
+ } from "./chunk-KUG52IAP.js";
7
+
8
+ // packages/cli/cliSpaceHelpers.ts
9
+ function normalizeSpaceIdInput(rawInput) {
10
+ const raw = rawInput.trim();
11
+ if (!raw) return "";
12
+ let candidate = raw;
13
+ if (raw.startsWith("http://") || raw.startsWith("https://")) {
14
+ const match = new URL(raw).pathname.match(/^\/space\/([^/?#]+)/);
15
+ if (!match?.[1]) return "";
16
+ candidate = decodeURIComponent(match[1]);
17
+ }
18
+ return candidate.startsWith("space-") ? candidate.slice("space-".length) : candidate;
19
+ }
20
+ function buildSpaceLookup(rawInput) {
21
+ const spaceId = normalizeSpaceIdInput(rawInput);
22
+ return {
23
+ spaceId,
24
+ spaceKey: spaceId ? `space-${spaceId}` : ""
25
+ };
26
+ }
27
+ function getSpaceContentKeys(spaceRecord) {
28
+ const keys = /* @__PURE__ */ new Set();
29
+ const contents = spaceRecord?.contents;
30
+ if (!contents || typeof contents !== "object") return keys;
31
+ for (const [entryKey, value] of Object.entries(contents)) {
32
+ const trimmedEntryKey = asOptionalTrimmedString(entryKey);
33
+ if (trimmedEntryKey) {
34
+ keys.add(trimmedEntryKey);
35
+ }
36
+ if (isRecord(value)) {
37
+ const contentKey = asOptionalTrimmedString(value.contentKey);
38
+ if (contentKey) {
39
+ keys.add(contentKey);
40
+ }
41
+ }
42
+ }
43
+ return keys;
44
+ }
45
+
46
+ export {
47
+ normalizeSpaceIdInput,
48
+ buildSpaceLookup,
49
+ getSpaceContentKeys
50
+ };
@@ -0,0 +1,342 @@
1
+ import {
2
+ generatePkcePair,
3
+ startCallbackServer
4
+ } from "./chunk-EHLHSX7R.js";
5
+ import {
6
+ toErrorMessage
7
+ } from "./chunk-HNMXYYJR.js";
8
+ import {
9
+ asOptionalFiniteNumber
10
+ } from "./chunk-WWC7I6TA.js";
11
+
12
+ // packages/cli/oauth/flows/cloudflare.ts
13
+ var CLOUDFLARE_OAUTH_AUTH_ENDPOINT = "https://dash.cloudflare.com/oauth2/auth";
14
+ var CLOUDFLARE_OAUTH_TOKEN_ENDPOINT = "https://dash.cloudflare.com/oauth2/token";
15
+ var CLOUDFLARE_API_BASE = "https://api.cloudflare.com/client/v4";
16
+ var CLOUDFLARE_OAUTH_REDIRECT_HOST = "127.0.0.1";
17
+ var CLOUDFLARE_OAUTH_REDIRECT_PORT = 56122;
18
+ var CLOUDFLARE_OAUTH_REDIRECT_PATH = "/callback";
19
+ var ACCESS_TOKEN_CLIENT_SKEW_MS = 5 * 60 * 1e3;
20
+ var TOKEN_REQUEST_TIMEOUT_MS = 2e4;
21
+ var DEFAULT_SCOPE = "account:read zone:read zone:edit user:read user:edit";
22
+ function generateState() {
23
+ const bytes = new Uint8Array(16);
24
+ crypto.getRandomValues(bytes);
25
+ return Array.from(bytes).map((value) => value.toString(16).padStart(2, "0")).join("");
26
+ }
27
+ function getClientId(args) {
28
+ const value = args?.clientId?.trim() || process.env.CLOUDFLARE_OAUTH_CLIENT_ID?.trim();
29
+ if (!value) {
30
+ throw new Error(
31
+ "Cloudflare OAuth client ID is required. Set CLOUDFLARE_OAUTH_CLIENT_ID or pass --client-id."
32
+ );
33
+ }
34
+ return value;
35
+ }
36
+ function getScope(args) {
37
+ return args?.scope?.trim() || process.env.CLOUDFLARE_OAUTH_SCOPE?.trim() || DEFAULT_SCOPE;
38
+ }
39
+ function buildCloudflareAuthorizeUrl(opts) {
40
+ const params = new URLSearchParams({
41
+ response_type: "code",
42
+ client_id: opts.clientId,
43
+ redirect_uri: opts.redirectUri,
44
+ scope: opts.scope,
45
+ code_challenge: opts.codeChallenge,
46
+ code_challenge_method: "S256",
47
+ state: opts.state
48
+ });
49
+ return `${CLOUDFLARE_OAUTH_AUTH_ENDPOINT}?${params.toString()}`;
50
+ }
51
+ async function exchangeCloudflareToken(fetchImpl, code, redirectUri, verifier, clientId) {
52
+ const body = new URLSearchParams({
53
+ grant_type: "authorization_code",
54
+ client_id: clientId,
55
+ code,
56
+ redirect_uri: redirectUri,
57
+ code_verifier: verifier
58
+ });
59
+ const response = await fetchImpl(CLOUDFLARE_OAUTH_TOKEN_ENDPOINT, {
60
+ method: "POST",
61
+ headers: {
62
+ "Content-Type": "application/x-www-form-urlencoded",
63
+ Accept: "application/json"
64
+ },
65
+ body,
66
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
67
+ });
68
+ if (!response.ok) {
69
+ let detail = "";
70
+ try {
71
+ detail = (await response.text()).trim();
72
+ } catch {
73
+ }
74
+ throw new Error(
75
+ `Cloudflare token exchange failed: ${response.status}${detail ? ` ${detail}` : ""}`
76
+ );
77
+ }
78
+ const data = await response.json();
79
+ if (typeof data.access_token !== "string" || !data.access_token) {
80
+ throw new Error("Cloudflare token exchange response missing access_token");
81
+ }
82
+ return {
83
+ accessToken: data.access_token,
84
+ refreshToken: typeof data.refresh_token === "string" ? data.refresh_token : void 0,
85
+ expiresIn: asOptionalFiniteNumber(data.expires_in),
86
+ scope: typeof data.scope === "string" ? data.scope : void 0,
87
+ idToken: typeof data.id_token === "string" ? data.id_token : void 0
88
+ };
89
+ }
90
+ async function runCloudflareOAuthLogin(deps = {}) {
91
+ const fetchImpl = deps.fetchImpl ?? fetch;
92
+ const output = deps.output ?? console;
93
+ const error = deps.error ?? console;
94
+ const clientId = getClientId(deps);
95
+ const scope = getScope(deps);
96
+ const redirectUri = `http://${CLOUDFLARE_OAUTH_REDIRECT_HOST}:${CLOUDFLARE_OAUTH_REDIRECT_PORT}${CLOUDFLARE_OAUTH_REDIRECT_PATH}`;
97
+ let handle;
98
+ try {
99
+ handle = await startCallbackServer({
100
+ port: CLOUDFLARE_OAUTH_REDIRECT_PORT,
101
+ hostname: CLOUDFLARE_OAUTH_REDIRECT_HOST,
102
+ timeoutMs: 5 * 6e4
103
+ });
104
+ } catch (err) {
105
+ throw new Error(
106
+ `Failed to start Cloudflare OAuth callback server on ${CLOUDFLARE_OAUTH_REDIRECT_PORT}: ${toErrorMessage(err)}`
107
+ );
108
+ }
109
+ try {
110
+ const state = generateState();
111
+ const pkce = await generatePkcePair();
112
+ const authUrl = buildCloudflareAuthorizeUrl({
113
+ redirectUri,
114
+ codeChallenge: pkce.challenge,
115
+ state,
116
+ clientId,
117
+ scope
118
+ });
119
+ output.log(
120
+ `Open the following URL in your browser to authorize Cloudflare access:
121
+ ${authUrl}
122
+
123
+ Requested scopes: ${scope}`
124
+ );
125
+ if (deps.openBrowser) {
126
+ try {
127
+ await deps.openBrowser(authUrl);
128
+ } catch (err) {
129
+ error.error(
130
+ `Failed to open browser automatically: ${toErrorMessage(err)}`
131
+ );
132
+ }
133
+ }
134
+ const callback = await handle.waitForCode();
135
+ const token = await exchangeCloudflareToken(
136
+ fetchImpl,
137
+ callback.code,
138
+ redirectUri,
139
+ pkce.verifier,
140
+ clientId
141
+ );
142
+ const now = (deps.now ?? Date.now)();
143
+ const expiresIn = token.expiresIn;
144
+ return {
145
+ provider: "cloudflare",
146
+ accessToken: token.accessToken,
147
+ refreshToken: token.refreshToken,
148
+ expiresAt: typeof expiresIn === "number" ? now + expiresIn * 1e3 - ACCESS_TOKEN_CLIENT_SKEW_MS : void 0,
149
+ scope: token.scope,
150
+ idToken: token.idToken,
151
+ obtainedAt: now
152
+ };
153
+ } finally {
154
+ await handle.close();
155
+ }
156
+ }
157
+ async function createCloudflareApiToken(input) {
158
+ const fetchImpl = input.fetchImpl ?? fetch;
159
+ const response = await fetchImpl(`${CLOUDFLARE_API_BASE}/user/tokens`, {
160
+ method: "POST",
161
+ headers: {
162
+ "Content-Type": "application/json",
163
+ Authorization: `Bearer ${input.accessToken}`
164
+ },
165
+ body: JSON.stringify({
166
+ name: input.name,
167
+ policies: input.policies
168
+ }),
169
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
170
+ });
171
+ if (!response.ok) {
172
+ let detail = "";
173
+ try {
174
+ detail = (await response.text()).trim();
175
+ } catch {
176
+ }
177
+ throw new Error(
178
+ `Cloudflare API token creation failed: ${response.status}${detail ? ` ${detail}` : ""}`
179
+ );
180
+ }
181
+ const data = await response.json();
182
+ const tokenValue = data.result?.value;
183
+ if (typeof tokenValue !== "string" || !tokenValue) {
184
+ throw new Error(
185
+ "Cloudflare API token creation response did not contain a token value"
186
+ );
187
+ }
188
+ return tokenValue;
189
+ }
190
+ async function listCloudflarePermissionGroups(accessToken, fetchImpl = fetch) {
191
+ const response = await fetchImpl(
192
+ `${CLOUDFLARE_API_BASE}/user/tokens/permission_groups`,
193
+ {
194
+ method: "GET",
195
+ headers: {
196
+ Authorization: `Bearer ${accessToken}`,
197
+ Accept: "application/json"
198
+ },
199
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
200
+ }
201
+ );
202
+ if (!response.ok) {
203
+ let detail = "";
204
+ try {
205
+ detail = (await response.text()).trim();
206
+ } catch {
207
+ }
208
+ throw new Error(
209
+ `Cloudflare permission groups lookup failed: ${response.status}${detail ? ` ${detail}` : ""}`
210
+ );
211
+ }
212
+ const data = await response.json();
213
+ if (!Array.isArray(data.result)) {
214
+ throw new Error("Cloudflare permission groups response missing result array");
215
+ }
216
+ return data.result.filter(
217
+ (group) => typeof group.id === "string" && typeof group.name === "string" && Array.isArray(group.permissions)
218
+ ).map((group) => ({
219
+ id: group.id,
220
+ name: group.name,
221
+ permissions: group.permissions
222
+ }));
223
+ }
224
+ async function findCloudflareZoneIdByName(accessToken, zoneName, fetchImpl = fetch) {
225
+ const response = await fetchImpl(
226
+ `${CLOUDFLARE_API_BASE}/zones?name=${encodeURIComponent(zoneName)}`,
227
+ {
228
+ method: "GET",
229
+ headers: {
230
+ Authorization: `Bearer ${accessToken}`,
231
+ Accept: "application/json"
232
+ },
233
+ signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS)
234
+ }
235
+ );
236
+ if (!response.ok) {
237
+ let detail = "";
238
+ try {
239
+ detail = (await response.text()).trim();
240
+ } catch {
241
+ }
242
+ throw new Error(
243
+ `Cloudflare zone lookup failed: ${response.status}${detail ? ` ${detail}` : ""}`
244
+ );
245
+ }
246
+ const data = await response.json();
247
+ if (!Array.isArray(data.result)) {
248
+ throw new Error("Cloudflare zone lookup response missing result array");
249
+ }
250
+ const zone = data.result.find((z) => z.name === zoneName);
251
+ return zone?.id ?? null;
252
+ }
253
+ async function generateCloudflareEmailRoutingToken(input) {
254
+ const fetchImpl = input.fetchImpl ?? fetch;
255
+ const zoneId = await findCloudflareZoneIdByName(
256
+ input.accessToken,
257
+ input.zoneName,
258
+ fetchImpl
259
+ );
260
+ if (!zoneId) {
261
+ throw new Error(`Cloudflare zone "${input.zoneName}" not found`);
262
+ }
263
+ const groups = await listCloudflarePermissionGroups(
264
+ input.accessToken,
265
+ fetchImpl
266
+ );
267
+ const emailRoutingGroup = groups.find(
268
+ (g) => g.name.toLowerCase().includes("email routing")
269
+ );
270
+ if (!emailRoutingGroup) {
271
+ throw new Error(
272
+ "Cloudflare Email Routing Edit permission group not found for this account."
273
+ );
274
+ }
275
+ const token = await createCloudflareApiToken({
276
+ name: input.tokenName ?? `nolo-email-routing-${input.zoneName}-${Date.now()}`,
277
+ policies: [buildEmailRoutingPolicy(zoneId, [emailRoutingGroup.id])],
278
+ accessToken: input.accessToken,
279
+ fetchImpl
280
+ });
281
+ return { token, zoneId };
282
+ }
283
+ function buildEmailRoutingPolicy(zoneId, emailRoutingPermissionGroupIds) {
284
+ if (emailRoutingPermissionGroupIds.length === 0) {
285
+ throw new Error(
286
+ "Email routing permission group IDs are required. Resolve them with listCloudflarePermissionGroups."
287
+ );
288
+ }
289
+ return {
290
+ effect: "allow",
291
+ resources: {
292
+ "com.cloudflare.api.account": "*",
293
+ "com.cloudflare.api.zone": zoneId
294
+ },
295
+ permission_groups: emailRoutingPermissionGroupIds.map((id) => ({ id }))
296
+ };
297
+ }
298
+
299
+ // packages/cli/oauth/envFile.ts
300
+ import { readFileSync, writeFileSync, existsSync } from "node:fs";
301
+ import { resolve } from "node:path";
302
+ function upsertEnvVariable(filePath, key, value) {
303
+ const normalizedPath = resolve(filePath);
304
+ let content = "";
305
+ if (existsSync(normalizedPath)) {
306
+ content = readFileSync(normalizedPath, "utf8");
307
+ }
308
+ const lines = content.length > 0 ? content.split("\n") : [];
309
+ const keyPrefix = `${key}=`;
310
+ let replaced = false;
311
+ const newLines = lines.map((line) => {
312
+ const trimmed = line.trim();
313
+ if (trimmed.startsWith(keyPrefix) || trimmed.startsWith(`${key} =`)) {
314
+ replaced = true;
315
+ return `${key}=${value}`;
316
+ }
317
+ return line;
318
+ });
319
+ if (!replaced) {
320
+ if (newLines.length > 0 && newLines[newLines.length - 1] !== "") {
321
+ newLines.push("");
322
+ }
323
+ newLines.push(`${key}=${value}`);
324
+ }
325
+ writeFileSync(normalizedPath, newLines.join("\n"), "utf8");
326
+ }
327
+ function parseFlagWithOptionalValue(args, flag) {
328
+ const index = args.indexOf(flag);
329
+ if (index === -1) return void 0;
330
+ const next = args[index + 1];
331
+ if (next && !next.startsWith("--")) {
332
+ return next;
333
+ }
334
+ return true;
335
+ }
336
+
337
+ export {
338
+ runCloudflareOAuthLogin,
339
+ generateCloudflareEmailRoutingToken,
340
+ upsertEnvVariable,
341
+ parseFlagWithOptionalValue
342
+ };
@@ -0,0 +1,38 @@
1
+ // packages/core/localOrigins.ts
2
+ var DEFAULT_LOCAL_HOST = "127.0.0.1";
3
+ var DEFAULT_LOCAL_API_PORT = "38123";
4
+ var DEFAULT_LOCAL_API_ORIGIN = `http://${DEFAULT_LOCAL_HOST}:${DEFAULT_LOCAL_API_PORT}`;
5
+ var LOOPBACK_HOSTNAMES = /* @__PURE__ */ new Set([
6
+ "127.0.0.1",
7
+ "localhost",
8
+ "::1"
9
+ ]);
10
+ function isLoopbackHostname(hostname) {
11
+ if (typeof hostname !== "string") return false;
12
+ let normalized = hostname.trim().toLowerCase();
13
+ if (!normalized) return false;
14
+ if (normalized.startsWith("[") && normalized.endsWith("]")) {
15
+ normalized = normalized.slice(1, -1);
16
+ }
17
+ return LOOPBACK_HOSTNAMES.has(normalized);
18
+ }
19
+ function isLoopbackUrl(value) {
20
+ if (typeof value !== "string" || !value.trim()) return false;
21
+ try {
22
+ return isLoopbackHostname(new URL(value).hostname);
23
+ } catch {
24
+ return false;
25
+ }
26
+ }
27
+ var LOCAL_SERVER_URL_PATTERN = /^https?:\/\/(?:(?:\d{1,3}\.){3}\d{1,3}|localhost|nolotus\.local)(?::\d+)?$/i;
28
+ function isLocalServerUrl(value) {
29
+ if (typeof value !== "string") return false;
30
+ return LOCAL_SERVER_URL_PATTERN.test(value.trim());
31
+ }
32
+
33
+ export {
34
+ DEFAULT_LOCAL_API_ORIGIN,
35
+ isLoopbackHostname,
36
+ isLoopbackUrl,
37
+ isLocalServerUrl
38
+ };
@@ -0,0 +1,42 @@
1
+ var __create = Object.create;
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __getProtoOf = Object.getPrototypeOf;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
+ }) : x)(function(x) {
10
+ if (typeof require !== "undefined") return require.apply(this, arguments);
11
+ throw Error('Dynamic require of "' + x + '" is not supported');
12
+ });
13
+ var __commonJS = (cb, mod) => function __require2() {
14
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
15
+ };
16
+ var __export = (target, all) => {
17
+ for (var name in all)
18
+ __defProp(target, name, { get: all[name], enumerable: true });
19
+ };
20
+ var __copyProps = (to, from, except, desc) => {
21
+ if (from && typeof from === "object" || typeof from === "function") {
22
+ for (let key of __getOwnPropNames(from))
23
+ if (!__hasOwnProp.call(to, key) && key !== except)
24
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
25
+ }
26
+ return to;
27
+ };
28
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
29
+ // If the importer is in node compatibility mode or this is not an ESM
30
+ // file that has been converted to a CommonJS file using a Babel-
31
+ // compatible transform (i.e. "__esModule" has not been set), then set
32
+ // "default" to the CommonJS "module.exports" for node compatibility.
33
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
34
+ mod
35
+ ));
36
+
37
+ export {
38
+ __require,
39
+ __commonJS,
40
+ __export,
41
+ __toESM
42
+ };