openmeld 0.3.124 → 0.3.127

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 (24) hide show
  1. package/dist/{add-me-membership-NHxQFPU0.js → add-me-membership-CSOBspmn.js} +2 -2
  2. package/dist/{add-me-membership-NHxQFPU0.js.map → add-me-membership-CSOBspmn.js.map} +1 -1
  3. package/dist/{api-client-foundation-w4Oa06t4.js → api-client-foundation-eG7A-GEB.js} +84 -25
  4. package/dist/api-client-foundation-eG7A-GEB.js.map +1 -0
  5. package/dist/auth-session-B1jSy0ws.js +1905 -0
  6. package/dist/auth-session-B1jSy0ws.js.map +1 -0
  7. package/dist/{base-url-PkgATS5u.js → base-url-BtqW4aLS.js} +73 -8
  8. package/dist/base-url-BtqW4aLS.js.map +1 -0
  9. package/dist/{command-Cp18onuk.js → command-Dk3z-M2K.js} +1059 -592
  10. package/dist/{command-Cp18onuk.js.map → command-Dk3z-M2K.js.map} +1 -1
  11. package/dist/{daemon-runtime-lease-Cvo63MGd.js → daemon-runtime-lease-D82uDZ5s.js} +2 -2
  12. package/dist/{daemon-runtime-lease-Cvo63MGd.js.map → daemon-runtime-lease-D82uDZ5s.js.map} +1 -1
  13. package/dist/{dist-DYE9Q3T4.js → dist-BnHChh7U.js} +3 -3
  14. package/dist/{dist-DYE9Q3T4.js.map → dist-BnHChh7U.js.map} +1 -1
  15. package/dist/openmeld-dev.js +1 -1
  16. package/dist/openmeld.js +504 -101
  17. package/dist/openmeld.js.map +1 -1
  18. package/dist/{runtime-transport-CWWB2Ily.js → runtime-transport-CHbXitKu.js} +2 -2
  19. package/dist/{runtime-transport-CWWB2Ily.js.map → runtime-transport-CHbXitKu.js.map} +1 -1
  20. package/package.json +1 -1
  21. package/dist/api-client-foundation-w4Oa06t4.js.map +0 -1
  22. package/dist/auth-session-qk94UQqs.js +0 -1146
  23. package/dist/auth-session-qk94UQqs.js.map +0 -1
  24. package/dist/base-url-PkgATS5u.js.map +0 -1
@@ -1,1146 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- import { Ft as openMeldRootDir, yn as __exportAll } from "./base-url-PkgATS5u.js";
4
- import { t as CURRENT_DAEMON_EXECUTION_CONTRACT_EPOCH } from "./runtime-transport-CWWB2Ily.js";
5
- import { createRequire } from "node:module";
6
- import * as z$1 from "zod/v4";
7
- import { join, resolve } from "node:path";
8
- import { createHash, randomUUID } from "node:crypto";
9
- import { chmod, mkdir, open, readFile, rename, rm, writeFile } from "node:fs/promises";
10
- import { spawn } from "node:child_process";
11
- import { fileURLToPath } from "node:url";
12
- //#region ../../packages/schemas/dist/schemas/local-machine/macos-keychain-helper.js
13
- const MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION = "disallow";
14
- const macOsKeychainServiceSchema = z$1.string().trim().min(1).max(512);
15
- const macOsKeychainAccountSchema = z$1.string().trim().min(1).max(512);
16
- const macOsKeychainAccessTokenSchema = z$1.string().min(1).max(65536);
17
- const macOsKeychainHelperOperationSchema = z$1.enum([
18
- "store",
19
- "read",
20
- "delete"
21
- ]);
22
- const macOsKeychainHelperRequestSchema = z$1.discriminatedUnion("operation", [
23
- z$1.strictObject({
24
- schemaVersion: z$1.literal(2),
25
- operation: z$1.literal("store"),
26
- service: macOsKeychainServiceSchema,
27
- account: macOsKeychainAccountSchema,
28
- accessToken: macOsKeychainAccessTokenSchema,
29
- authenticationInteraction: z$1.literal(MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION)
30
- }),
31
- z$1.strictObject({
32
- schemaVersion: z$1.literal(2),
33
- operation: z$1.literal("read"),
34
- service: macOsKeychainServiceSchema,
35
- account: macOsKeychainAccountSchema,
36
- authenticationInteraction: z$1.literal(MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION)
37
- }),
38
- z$1.strictObject({
39
- schemaVersion: z$1.literal(2),
40
- operation: z$1.literal("delete"),
41
- service: macOsKeychainServiceSchema,
42
- account: macOsKeychainAccountSchema,
43
- authenticationInteraction: z$1.literal(MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION)
44
- })
45
- ]);
46
- const macOsKeychainHelperMutationSuccessSchema = z$1.strictObject({
47
- schemaVersion: z$1.literal(2),
48
- ok: z$1.literal(true),
49
- operation: z$1.enum(["store", "delete"])
50
- });
51
- const macOsKeychainHelperReadSuccessSchema = z$1.strictObject({
52
- schemaVersion: z$1.literal(2),
53
- ok: z$1.literal(true),
54
- operation: z$1.literal("read"),
55
- accessToken: z$1.union([macOsKeychainAccessTokenSchema, z$1.null()])
56
- });
57
- const macOsKeychainHelperErrorSchema = z$1.strictObject({
58
- schemaVersion: z$1.literal(2),
59
- ok: z$1.literal(false),
60
- operation: macOsKeychainHelperOperationSchema,
61
- errorMessage: z$1.string().trim().min(1).max(2048)
62
- });
63
- const macOsKeychainHelperResponseSchema = z$1.union([
64
- macOsKeychainHelperMutationSuccessSchema,
65
- macOsKeychainHelperReadSuccessSchema,
66
- macOsKeychainHelperErrorSchema
67
- ]);
68
- //#endregion
69
- //#region src/strategy-constants.ts
70
- const DEFAULT_GATEWAY_CHAIN_TIMEOUT_MS = 3e4;
71
- const DEFAULT_REMOTE_SESSION_TIMEOUT_MS = 8e3;
72
- const LOOPBACK_REMOTE_SESSION_TIMEOUT_MS = 1500;
73
- const DEFAULT_SPACE_REQUEST_TIMEOUT_MS = 1e4;
74
- const MIN_SPACE_REQUEST_TIMEOUT_MS = 1e3;
75
- const MAX_SPACE_REQUEST_TIMEOUT_MS = 12e4;
76
- const DEFAULT_HEARTBEAT_INTERVAL_MS = 25e3;
77
- const MIN_HEARTBEAT_INTERVAL_MS = 5e3;
78
- const MAX_HEARTBEAT_INTERVAL_MS = 6e4;
79
- const DAEMON_STREAM_KEEPALIVE_INTERVAL_MS = 2e4;
80
- const DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS = 1e4;
81
- const CATALOG_SYNC_RETRY_INTERVAL_MS = 5e3;
82
- const CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS = 1e3;
83
- const ROUTE_CATALOG_LOAD_TIMEOUT_MS = 15e3;
84
- const RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS = 5 * 6e4;
85
- const RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS = 6e4;
86
- const PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS = 5 * 6e4;
87
- const PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS = 6e4;
88
- const RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS = 6e4;
89
- const DAEMON_STREAM_CONNECT_TIMEOUT_MS = 15e3;
90
- const REGISTER_RESPONSE_TIMEOUT_MS = 1e4;
91
- const HEARTBEAT_RESPONSE_TIMEOUT_MS = 15e3;
92
- const DAEMON_RUNTIME_CONTRACT_EPOCH = CURRENT_DAEMON_EXECUTION_CONTRACT_EPOCH;
93
- const OPENCLAW_CLI_TIMEOUT_MS = 3e4;
94
- //#endregion
95
- //#region src/runtime/distribution.ts
96
- const BINARY_DISTRIBUTION = "binary";
97
- const NPM_DISTRIBUTION = "npm";
98
- /**
99
- * The distribution form this CLI build was compiled for. Falls back to `npm`
100
- * when the marker is absent (e.g. under Vitest, where no build-time define
101
- * runs), which keeps the safe, path-independent default.
102
- */
103
- function resolveOpenMeldDistribution() {
104
- return NPM_DISTRIBUTION;
105
- }
106
- function isBinaryDistribution() {
107
- return resolveOpenMeldDistribution() === BINARY_DISTRIBUTION;
108
- }
109
- //#endregion
110
- //#region src/config/macos-native-keychain.ts
111
- const MAC_OS_KEYCHAIN_HELPER_ARG = "__openmeld_macos_keychain_helper";
112
- const HELPER_OUTPUT_MAX_BYTES = 128 * 1024;
113
- let loadedAddon = null;
114
- let unresponsiveKeychainError = null;
115
- async function storeMacOsNativeKeychainToken(input) {
116
- if (isBinaryDistribution()) {
117
- await runBoundedMacOsNativeKeychainRequest({
118
- operation: "store",
119
- service: input.service,
120
- account: input.account,
121
- accessToken: input.accessToken
122
- });
123
- return;
124
- }
125
- (await loadAddon()).store(input.service, input.account, input.accessToken);
126
- }
127
- async function readMacOsNativeKeychainToken(input) {
128
- if (isBinaryDistribution()) return await runBoundedMacOsNativeKeychainRequest({
129
- operation: "read",
130
- service: input.service,
131
- account: input.account
132
- });
133
- return (await loadAddon()).read(input.service, input.account);
134
- }
135
- async function deleteMacOsNativeKeychainToken(input) {
136
- if (isBinaryDistribution()) {
137
- await runBoundedMacOsNativeKeychainRequest({
138
- operation: "delete",
139
- service: input.service,
140
- account: input.account
141
- });
142
- return;
143
- }
144
- (await loadAddon()).remove(input.service, input.account);
145
- }
146
- async function runMacOsNativeKeychainRequestInChild(input, options = {}) {
147
- const request = macOsKeychainHelperRequestSchema.parse({
148
- schemaVersion: 2,
149
- authenticationInteraction: MAC_OS_KEYCHAIN_AUTHENTICATION_INTERACTION,
150
- ...input
151
- });
152
- const timeoutMs = options.timeoutMs ?? 5e3;
153
- if (!(Number.isSafeInteger(timeoutMs) && timeoutMs > 0)) throw new Error("macOS Keychain helper timeout must be a positive integer");
154
- return await new Promise((resolve, reject) => {
155
- const child = spawn(process.execPath, [MAC_OS_KEYCHAIN_HELPER_ARG], {
156
- env: process.env,
157
- shell: false,
158
- stdio: [
159
- "pipe",
160
- "pipe",
161
- "pipe"
162
- ],
163
- windowsHide: true
164
- });
165
- let settled = false;
166
- let stdout = "";
167
- let stderr = "";
168
- const clearDeadline = () => {
169
- clearTimeout(deadline);
170
- };
171
- const rejectOnce = (error) => {
172
- if (settled) return;
173
- settled = true;
174
- clearDeadline();
175
- reject(error);
176
- };
177
- const deadline = setTimeout(() => {
178
- if (settled) return;
179
- settled = true;
180
- child.kill("SIGKILL");
181
- reject(new MacOsNativeKeychainTimeoutError(`macOS Keychain did not respond within ${formatTimeout(timeoutMs)}`));
182
- }, timeoutMs);
183
- child.stdout.setEncoding("utf8");
184
- child.stderr.setEncoding("utf8");
185
- child.stdout.on("data", (chunk) => {
186
- stdout += String(chunk);
187
- if (Buffer.byteLength(stdout, "utf8") > HELPER_OUTPUT_MAX_BYTES) {
188
- child.kill("SIGKILL");
189
- rejectOnce(/* @__PURE__ */ new Error("macOS Keychain helper output was too large"));
190
- }
191
- });
192
- child.stderr.on("data", (chunk) => {
193
- stderr += String(chunk);
194
- if (Buffer.byteLength(stderr, "utf8") > HELPER_OUTPUT_MAX_BYTES) stderr = stderr.slice(-131072);
195
- });
196
- child.once("error", (error) => {
197
- rejectOnce(/* @__PURE__ */ new Error(`macOS Keychain helper could not start: ${toErrorMessage$1(error)}`));
198
- });
199
- child.stdin.once("error", (error) => {
200
- rejectOnce(/* @__PURE__ */ new Error(`macOS Keychain helper input failed: ${toErrorMessage$1(error)}`));
201
- });
202
- child.once("close", (code) => {
203
- if (settled) return;
204
- clearDeadline();
205
- settled = true;
206
- try {
207
- resolve(parseMacOsKeychainHelperResult({
208
- code,
209
- operation: request.operation,
210
- stderr,
211
- stdout
212
- }));
213
- } catch (error) {
214
- reject(toError(error));
215
- }
216
- });
217
- child.stdin.end(JSON.stringify(request), "utf8");
218
- });
219
- }
220
- async function runMacOsNativeKeychainHelperIfRequested(argv = process.argv) {
221
- if (!argv.includes(MAC_OS_KEYCHAIN_HELPER_ARG)) return false;
222
- if (!(isBinaryDistribution() && process.platform === "darwin")) throw new Error("the internal macOS Keychain helper is only available in the macOS binary");
223
- if (!(await loadAddon()).isParentSameExecutable()) throw new Error("the internal macOS Keychain helper is reserved for an OpenMeld child process");
224
- const rawRequest = await readHelperStdin();
225
- let json;
226
- try {
227
- json = JSON.parse(rawRequest);
228
- } catch {
229
- throw new Error("invalid macOS Keychain helper request");
230
- }
231
- const request = macOsKeychainHelperRequestSchema.safeParse(json);
232
- if (!request.success) throw new Error("invalid macOS Keychain helper request");
233
- const response = await executeHelperRequest(request.data).catch((error) => ({
234
- schemaVersion: 2,
235
- ok: false,
236
- operation: request.data.operation,
237
- errorMessage: truncateErrorMessage(toErrorMessage$1(error))
238
- }));
239
- process.stdout.write(JSON.stringify(response));
240
- return true;
241
- }
242
- async function runBoundedMacOsNativeKeychainRequest(input) {
243
- if (unresponsiveKeychainError) throw unresponsiveKeychainError;
244
- try {
245
- if (input.operation === "read") return await runMacOsNativeKeychainRequestInChild(input);
246
- await runMacOsNativeKeychainRequestInChild(input);
247
- } catch (error) {
248
- if (error instanceof MacOsNativeKeychainTimeoutError) unresponsiveKeychainError = error;
249
- throw error;
250
- }
251
- }
252
- function parseMacOsKeychainHelperResult(input) {
253
- if (input.code !== 0) throw new Error(`macOS Keychain helper exited with code ${input.code ?? "unknown"}${input.stderr.trim() ? `: ${input.stderr.trim()}` : ""}`);
254
- let rawResponse;
255
- try {
256
- rawResponse = JSON.parse(input.stdout);
257
- } catch {
258
- throw new Error("macOS Keychain helper returned an invalid response");
259
- }
260
- const parsed = macOsKeychainHelperResponseSchema.safeParse(rawResponse);
261
- if (!(parsed.success && parsed.data.operation === input.operation)) throw new Error("macOS Keychain helper returned an invalid response");
262
- if (!parsed.data.ok) throw new Error(parsed.data.errorMessage);
263
- return parsed.data.operation === "read" ? parsed.data.accessToken : void 0;
264
- }
265
- async function executeHelperRequest(input) {
266
- const addon = await loadAddon();
267
- if (input.operation === "store") {
268
- addon.store(input.service, input.account, input.accessToken);
269
- return {
270
- schemaVersion: 2,
271
- ok: true,
272
- operation: "store"
273
- };
274
- }
275
- if (input.operation === "delete") {
276
- addon.remove(input.service, input.account);
277
- return {
278
- schemaVersion: 2,
279
- ok: true,
280
- operation: "delete"
281
- };
282
- }
283
- return {
284
- schemaVersion: 2,
285
- ok: true,
286
- operation: "read",
287
- accessToken: addon.read(input.service, input.account)
288
- };
289
- }
290
- async function readHelperStdin() {
291
- let raw = "";
292
- process.stdin.setEncoding("utf8");
293
- for await (const chunk of process.stdin) {
294
- raw += String(chunk);
295
- if (Buffer.byteLength(raw, "utf8") > HELPER_OUTPUT_MAX_BYTES) throw new Error("macOS Keychain helper request was too large");
296
- }
297
- return raw;
298
- }
299
- function truncateErrorMessage(message) {
300
- return (message.trim() || "macOS Keychain operation failed").slice(0, 2048);
301
- }
302
- function formatTimeout(timeoutMs) {
303
- return timeoutMs % 1e3 === 0 ? `${timeoutMs / 1e3} seconds` : `${timeoutMs} ms`;
304
- }
305
- function toErrorMessage$1(error) {
306
- return error instanceof Error ? error.message : String(error);
307
- }
308
- function toError(error) {
309
- return error instanceof Error ? error : new Error(String(error));
310
- }
311
- var MacOsNativeKeychainTimeoutError = class extends Error {
312
- name = "MacOsNativeKeychainTimeoutError";
313
- };
314
- async function loadAddon() {
315
- if (loadedAddon) return loadedAddon;
316
- if (process.platform !== "darwin") throw new Error("macOS Keychain is only available on macOS");
317
- if (isBinaryDistribution()) {
318
- loadedAddon = (await import("./config/macos-native-keychain-embedded")).loadEmbeddedMacOsKeychainAddon();
319
- return loadedAddon;
320
- }
321
- loadedAddon = createRequire(import.meta.url)(fileURLToPath(new URL("./native/openmeld-keychain.node", import.meta.url)));
322
- return loadedAddon;
323
- }
324
- //#endregion
325
- //#region src/config/token-store.ts
326
- const TOKEN_STORE_KEYCHAIN_SERVICE = "sh.openmeld.auth.token";
327
- const INSECURE_FALLBACK_ENV_KEY = "OPENMELD_AUTH_ALLOW_INSECURE_FILE_TOKEN";
328
- const FORCE_INSECURE_STORE_ENV_KEY = "OPENMELD_AUTH_FORCE_INSECURE_FILE_TOKEN";
329
- const MAC_OS_KEYCHAIN_NONINTERACTIVE_UNAVAILABLE_MESSAGE = "macOS Keychain access is unavailable in this OpenMeld distribution. OpenMeld will not open an authorization window from an unattended process. Run setup or login with the current packaged OpenMeld CLI.";
330
- const COMMAND_MAX_BUFFER_BYTES = 1024 * 1024;
331
- const COMMAND_TIMEOUT_MS = 3e4;
332
- const TOKEN_FILE_KEY_PATTERN = /^[a-f0-9]{64}$/u;
333
- const EXEC_FILE_BASE_OPTIONS = {
334
- windowsHide: true,
335
- maxBuffer: COMMAND_MAX_BUFFER_BYTES,
336
- timeout: COMMAND_TIMEOUT_MS
337
- };
338
- let insecureFallbackWarningShown = false;
339
- let macOsPrivateStorageWarningShown = false;
340
- async function storeAccessToken(input) {
341
- const key = buildTokenKey({
342
- authBaseUrl: input.authBaseUrl,
343
- clientId: input.clientId
344
- });
345
- if (shouldForceInsecureStore()) {
346
- await setInsecureFileToken({
347
- key,
348
- accessToken: input.accessToken
349
- });
350
- return {
351
- provider: "insecure-file",
352
- key
353
- };
354
- }
355
- if (process.platform === "darwin") try {
356
- const account = buildUniqueMacOsAccount(key);
357
- if (shouldUseNativeMacOsKeychain()) await storeMacOsNativeKeychainToken({
358
- account,
359
- service: TOKEN_STORE_KEYCHAIN_SERVICE,
360
- accessToken: input.accessToken
361
- });
362
- else throw new Error(MAC_OS_KEYCHAIN_NONINTERACTIVE_UNAVAILABLE_MESSAGE);
363
- return {
364
- provider: "macos-keychain",
365
- service: TOKEN_STORE_KEYCHAIN_SERVICE,
366
- account
367
- };
368
- } catch (error) {
369
- if (allowInsecureFallback()) {
370
- await setInsecureFileToken({
371
- key,
372
- accessToken: input.accessToken
373
- });
374
- return {
375
- provider: "insecure-file",
376
- key
377
- };
378
- }
379
- const privateKey = buildUniqueTokenFileKey(key);
380
- await setInsecureFileToken({
381
- key: privateKey,
382
- accessToken: input.accessToken
383
- });
384
- warnMacOsPrivateStorageFallback(error);
385
- return {
386
- provider: "insecure-file",
387
- key: privateKey
388
- };
389
- }
390
- if (process.platform === "win32") try {
391
- await setWindowsDpapiToken({
392
- key,
393
- accessToken: input.accessToken
394
- });
395
- return {
396
- provider: "windows-dpapi",
397
- key
398
- };
399
- } catch (error) {
400
- if (allowInsecureFallback()) {
401
- await setInsecureFileToken({
402
- key,
403
- accessToken: input.accessToken
404
- });
405
- return {
406
- provider: "insecure-file",
407
- key
408
- };
409
- }
410
- throw new Error(`failed to store access token via Windows DPAPI: ${toErrorMessage(error)}`);
411
- }
412
- if (allowInsecureFallback()) {
413
- await setInsecureFileToken({
414
- key,
415
- accessToken: input.accessToken
416
- });
417
- return {
418
- provider: "insecure-file",
419
- key
420
- };
421
- }
422
- throw new Error(`secure token storage is unavailable on platform "${process.platform}". Use ${INSECURE_FALLBACK_ENV_KEY}=1 only for local testing fallback.`);
423
- }
424
- async function readAccessToken(ref) {
425
- try {
426
- if (ref.provider === "macos-keychain") {
427
- if (!shouldUseNativeMacOsKeychain()) throw new Error(MAC_OS_KEYCHAIN_NONINTERACTIVE_UNAVAILABLE_MESSAGE);
428
- return toAccessTokenReadResult(await readMacOsNativeKeychainToken(ref));
429
- }
430
- if (ref.provider === "windows-dpapi") return toAccessTokenReadResult(await getWindowsDpapiToken(ref));
431
- if (ref.provider === "insecure-file") return toAccessTokenReadResult(await getInsecureFileToken(ref));
432
- return { status: "missing" };
433
- } catch (error) {
434
- return {
435
- errorMessage: toErrorMessage(error),
436
- status: "unavailable"
437
- };
438
- }
439
- }
440
- async function deleteAccessToken(ref) {
441
- if (ref.provider === "macos-keychain") {
442
- if (!shouldUseNativeMacOsKeychain()) throw new Error(MAC_OS_KEYCHAIN_NONINTERACTIVE_UNAVAILABLE_MESSAGE);
443
- await deleteMacOsNativeKeychainToken(ref);
444
- return;
445
- }
446
- if (ref.provider === "windows-dpapi") {
447
- await deleteWindowsDpapiToken(ref);
448
- return;
449
- }
450
- if (ref.provider === "insecure-file") await deleteInsecureFileToken(ref);
451
- }
452
- function isStoredTokenRef(value) {
453
- if (!(value && typeof value === "object")) return false;
454
- const record = value;
455
- const provider = normalizeString(record.provider);
456
- if (provider === "macos-keychain") return Boolean(normalizeString(record.service) && normalizeString(record.account) && record.accessGroup === void 0);
457
- if (provider === "windows-dpapi" || provider === "insecure-file") return normalizeTokenFileKey(record.key) !== null;
458
- return false;
459
- }
460
- function buildTokenKey(input) {
461
- const rootDir = resolve(openMeldRootDir());
462
- return createHash("sha256").update(`${input.clientId}\n${input.authBaseUrl}\n${rootDir}`).digest("hex");
463
- }
464
- function buildUniqueMacOsAccount(key) {
465
- return `openmeld-auth-${key}-${randomUUID()}`;
466
- }
467
- function buildUniqueTokenFileKey(key) {
468
- return createHash("sha256").update(`${key}\n${randomUUID()}`).digest("hex");
469
- }
470
- function shouldUseNativeMacOsKeychain() {
471
- return isBinaryDistribution();
472
- }
473
- async function setWindowsDpapiToken(input) {
474
- const encrypted = await runPowerShellScript(WINDOWS_DPAPI_ENCRYPT_SCRIPT, input.accessToken, input.key);
475
- await mkdir(tokenDirectoryPath(), { recursive: true });
476
- await writeFile(windowsDpapiTokenPath(input.key), `${encrypted.trim()}\n`, {
477
- encoding: "utf8",
478
- mode: 384
479
- });
480
- }
481
- async function getWindowsDpapiToken(input) {
482
- const encrypted = await readFile(windowsDpapiTokenPath(input.key), "utf8").catch((error) => {
483
- if (isFileNotFoundError$1(error)) return null;
484
- throw error;
485
- });
486
- if (!encrypted) return null;
487
- return runPowerShellScript(WINDOWS_DPAPI_DECRYPT_SCRIPT, encrypted.trim(), input.key);
488
- }
489
- async function deleteWindowsDpapiToken(input) {
490
- await rm(windowsDpapiTokenPath(input.key), { force: true });
491
- }
492
- async function setInsecureFileToken(input) {
493
- await ensurePrivateTokenDirectory();
494
- const path = insecureTokenPath(input.key);
495
- await writeFile(path, `${input.accessToken}\n`, {
496
- encoding: "utf8",
497
- mode: 384
498
- });
499
- if (process.platform !== "win32") await chmod(path, 384);
500
- }
501
- async function getInsecureFileToken(input) {
502
- const raw = await readFile(insecureTokenPath(input.key), "utf8").catch((error) => {
503
- if (isFileNotFoundError$1(error)) return null;
504
- throw error;
505
- });
506
- return raw ? raw.trim() : null;
507
- }
508
- async function deleteInsecureFileToken(input) {
509
- await rm(insecureTokenPath(input.key), { force: true });
510
- }
511
- function tokenDirectoryPath() {
512
- return join(openMeldRootDir(), "auth", "tokens");
513
- }
514
- function windowsDpapiTokenPath(key) {
515
- return join(tokenDirectoryPath(), `${requireValidTokenFileKey(key)}.dpapi`);
516
- }
517
- function insecureTokenPath(key) {
518
- return join(tokenDirectoryPath(), `${requireValidTokenFileKey(key)}.token`);
519
- }
520
- function allowInsecureFallback() {
521
- if (process.env[INSECURE_FALLBACK_ENV_KEY] === "1") {
522
- warnInsecureFallback("env");
523
- return true;
524
- }
525
- const fallbackEnabled = !isNativeSecureStorePlatform();
526
- if (fallbackEnabled) warnInsecureFallback("platform");
527
- return fallbackEnabled;
528
- }
529
- function warnMacOsPrivateStorageFallback(error) {
530
- if (macOsPrivateStorageWarningShown) return;
531
- macOsPrivateStorageWarningShown = true;
532
- const storageExpectation = isBinaryDistribution() ? "This session stays in private local storage unless a later sign-in replaces it." : "This npm installation cannot use macOS Keychain. This session stays in private local storage.";
533
- console.warn(`[openmeld auth] macOS Keychain is unavailable. OpenMeld saved this session in a private file protected for your macOS user account, so setup can continue. ${storageExpectation} Details: ${toErrorMessage(error)}`);
534
- }
535
- function warnInsecureFallback(reason) {
536
- if (insecureFallbackWarningShown) return;
537
- insecureFallbackWarningShown = true;
538
- const reasonText = reason === "env" ? `enabled by ${INSECURE_FALLBACK_ENV_KEY}=1` : `enabled automatically on platform "${process.platform}"`;
539
- console.warn(`[openmeld auth] plaintext file token storage fallback is active (${reasonText}). Unset ${INSECURE_FALLBACK_ENV_KEY} to disable explicit opt-in, and prefer macOS or Windows for native secure token storage.`);
540
- }
541
- function shouldForceInsecureStore() {
542
- return process.env[FORCE_INSECURE_STORE_ENV_KEY] === "1";
543
- }
544
- function isNativeSecureStorePlatform() {
545
- return process.platform === "darwin" || process.platform === "win32";
546
- }
547
- async function ensurePrivateTokenDirectory() {
548
- const directory = tokenDirectoryPath();
549
- await mkdir(directory, {
550
- recursive: true,
551
- mode: 448
552
- });
553
- if (process.platform !== "win32") await chmod(directory, 448);
554
- }
555
- async function runPowerShellScript(script, token, entropy) {
556
- const payload = JSON.stringify({
557
- token,
558
- entropy
559
- });
560
- return (await runCommand("powershell.exe", [
561
- "-NoProfile",
562
- "-NonInteractive",
563
- "-ExecutionPolicy",
564
- "Bypass",
565
- "-Command",
566
- script
567
- ], payload)).stdout.trim();
568
- }
569
- async function runCommand(command, args, stdinPayload) {
570
- try {
571
- const { execFile } = await import("node:child_process");
572
- return await new Promise((resolve, reject) => {
573
- let stdout = "";
574
- let stderr = "";
575
- const child = execFile(command, args, { ...EXEC_FILE_BASE_OPTIONS });
576
- child.stdout?.setEncoding("utf8");
577
- child.stderr?.setEncoding("utf8");
578
- child.stdout?.on("data", (chunk) => {
579
- stdout += String(chunk);
580
- });
581
- child.stderr?.on("data", (chunk) => {
582
- stderr += String(chunk);
583
- });
584
- child.on("error", (error) => {
585
- reject(toCommandError(error, command));
586
- });
587
- child.on("close", (code) => {
588
- if (code === 0) {
589
- resolve({
590
- stdout,
591
- stderr
592
- });
593
- return;
594
- }
595
- reject(toCommandError({ message: `command failed (${command}) with exit code ${code}` }, command));
596
- });
597
- child.stdin?.write(stdinPayload);
598
- child.stdin?.end();
599
- });
600
- } catch (error) {
601
- throw toCommandError(error, command);
602
- }
603
- }
604
- function toCommandError(error, command) {
605
- if (!(error && typeof error === "object")) return /* @__PURE__ */ new Error(`command failed (${command}): ${String(error)}`);
606
- const e = error;
607
- const code = typeof e.code === "number" ? e.code : null;
608
- const messageParts = [`command failed (${command})`];
609
- if (typeof e.stderr === "string" && e.stderr.trim()) messageParts.push(`stderr: ${e.stderr.trim()}`);
610
- else if (e.message) messageParts.push(e.message);
611
- const wrapped = new Error(messageParts.join("; "));
612
- wrapped.code = code;
613
- wrapped.stdout = e.stdout;
614
- wrapped.stderr = e.stderr;
615
- return wrapped;
616
- }
617
- function normalizeString(value) {
618
- return String(value ?? "").trim();
619
- }
620
- function normalizeTokenFileKey(value) {
621
- const normalized = normalizeString(value);
622
- if (!TOKEN_FILE_KEY_PATTERN.test(normalized)) return null;
623
- return normalized;
624
- }
625
- function requireValidTokenFileKey(value) {
626
- const normalized = normalizeTokenFileKey(value);
627
- if (normalized === null) throw new Error("stored token key is invalid");
628
- return normalized;
629
- }
630
- function normalizeToken(value) {
631
- if (value === null) return null;
632
- const normalized = value.trim();
633
- return normalized.length > 0 ? normalized : null;
634
- }
635
- function toAccessTokenReadResult(value) {
636
- const accessToken = normalizeToken(value);
637
- if (!accessToken) return { status: "missing" };
638
- return {
639
- accessToken,
640
- status: "found"
641
- };
642
- }
643
- function toErrorMessage(error) {
644
- if (error instanceof Error) return error.message;
645
- return String(error);
646
- }
647
- function isFileNotFoundError$1(error) {
648
- return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
649
- }
650
- const WINDOWS_DPAPI_ENCRYPT_SCRIPT = [
651
- "$ErrorActionPreference='Stop'",
652
- "$rawInput = [Console]::In.ReadToEnd()",
653
- "$payload = $rawInput | ConvertFrom-Json",
654
- "$plain=[System.Text.Encoding]::UTF8.GetBytes($payload.token)",
655
- "$entropy=[System.Text.Encoding]::UTF8.GetBytes($payload.entropy)",
656
- "$cipher=[System.Security.Cryptography.ProtectedData]::Protect($plain,$entropy,[System.Security.Cryptography.DataProtectionScope]::CurrentUser)",
657
- "[System.Convert]::ToBase64String($cipher)"
658
- ].join(";");
659
- const WINDOWS_DPAPI_DECRYPT_SCRIPT = [
660
- "$ErrorActionPreference='Stop'",
661
- "$rawInput = [Console]::In.ReadToEnd()",
662
- "$payload = $rawInput | ConvertFrom-Json",
663
- "$cipher=[System.Convert]::FromBase64String($payload.token)",
664
- "$entropy=[System.Text.Encoding]::UTF8.GetBytes($payload.entropy)",
665
- "$plain=[System.Security.Cryptography.ProtectedData]::Unprotect($cipher,$entropy,[System.Security.Cryptography.DataProtectionScope]::CurrentUser)",
666
- "[System.Text.Encoding]::UTF8.GetString($plain)"
667
- ].join(";");
668
- //#endregion
669
- //#region src/config/auth-session.ts
670
- var auth_session_exports = /* @__PURE__ */ __exportAll({
671
- clearAuthSession: () => clearAuthSession,
672
- getAuthSessionMetadata: () => getAuthSessionMetadata,
673
- getAuthSessionState: () => getAuthSessionState,
674
- getCurrentAuthOwnerUserId: () => getCurrentAuthOwnerUserId,
675
- normalizeStoredActiveOrganization: () => normalizeStoredActiveOrganization,
676
- setAuthSession: () => setAuthSession,
677
- updateAuthSessionActiveOrganization: () => updateAuthSessionActiveOrganization
678
- });
679
- const TRAILING_SLASHES_RE = /\/+$/u;
680
- let cachedAuthSession = null;
681
- async function getAuthSessionState(options = {}) {
682
- const localState = await getLocalAuthSessionState();
683
- switch (localState.state) {
684
- case "missing":
685
- case "invalid":
686
- case "expired": return localState;
687
- case "valid": break;
688
- default: return localState;
689
- }
690
- if (!options.validateRemote) return localState;
691
- const remoteValidation = await getRemoteAuthSessionState(localState.session);
692
- if (remoteValidation.state === "valid") return localState;
693
- if (remoteValidation.state === "unknown") return localState;
694
- return {
695
- reasonCode: resolveRemoteAuthSessionReasonCode(remoteValidation.state),
696
- state: remoteValidation.state,
697
- session: null
698
- };
699
- }
700
- async function getCurrentAuthOwnerUserId() {
701
- const ownerUserId = (await getAuthSessionState({ validateRemote: false }).catch(() => null))?.session?.user?.id?.trim() ?? "";
702
- return ownerUserId.length > 0 ? ownerUserId : null;
703
- }
704
- async function setAuthSession(input) {
705
- const accessToken = String(input.accessToken ?? "").trim();
706
- if (!accessToken) throw new Error("access token is required");
707
- const authBaseUrl = String(input.authBaseUrl ?? "").trim();
708
- if (!authBaseUrl) throw new Error("auth base URL is required");
709
- const clientId = String(input.clientId ?? "").trim();
710
- if (!clientId) throw new Error("client_id is required");
711
- await retryPendingTokenCleanup();
712
- const previousTokenRef = normalizeTokenRef((await readSessionPayload())?.tokenRef);
713
- const tokenRef = await storeAccessToken({
714
- accessToken,
715
- authBaseUrl,
716
- clientId
717
- });
718
- const payload = {
719
- v: 1,
720
- tokenRef,
721
- tokenType: String(input.tokenType ?? "Bearer").trim() || "Bearer",
722
- authBaseUrl,
723
- clientId,
724
- createdAt: (/* @__PURE__ */ new Date()).toISOString(),
725
- ...input.expiresAt ? { expiresAt: input.expiresAt } : {},
726
- ...input.scope ? { scope: input.scope } : {},
727
- ...buildAuthUserPayload(input.user),
728
- ...buildActiveOrganizationPayload(input.activeOrganization)
729
- };
730
- const path = authSessionPath();
731
- await mkdir(join(openMeldRootDir(), "auth"), { recursive: true });
732
- try {
733
- await assertStoredAccessTokenReloads({
734
- accessToken,
735
- tokenRef
736
- });
737
- await writeSessionPayloadAtomically(path, payload);
738
- } catch (error) {
739
- await deleteAccessTokenOrRetainForCleanup(tokenRef);
740
- throw error;
741
- }
742
- cacheAuthSession({
743
- payload,
744
- session: buildStoredAuthSession({
745
- accessToken,
746
- payload
747
- })
748
- });
749
- if (previousTokenRef && !areStoredTokenRefsEqual(previousTokenRef, tokenRef)) await deleteAccessTokenOrRetainForCleanup(previousTokenRef);
750
- }
751
- async function getAuthSessionMetadata() {
752
- const payload = await readSessionPayload();
753
- if (payload?.v !== 1) return null;
754
- const authBaseUrl = normalizeOptionalString(payload.authBaseUrl);
755
- const clientId = normalizeOptionalString(payload.clientId);
756
- const createdAt = normalizeOptionalString(payload.createdAt);
757
- if (!(authBaseUrl && clientId && createdAt)) return null;
758
- return {
759
- authBaseUrl,
760
- clientId,
761
- createdAt,
762
- ...typeof payload.expiresAt === "string" && payload.expiresAt.trim() ? { expiresAt: payload.expiresAt.trim() } : {},
763
- ...typeof payload.scope === "string" && payload.scope.trim() ? { scope: payload.scope.trim() } : {},
764
- ...buildAuthUserPayload(payload.user),
765
- ...buildActiveOrganizationPayload(payload.activeOrganization)
766
- };
767
- }
768
- async function updateAuthSessionActiveOrganization(activeOrganization) {
769
- const payload = await readSessionPayload();
770
- if (payload?.v !== 1) throw new Error("cannot update active organization without auth session");
771
- const tokenRef = normalizeTokenRef(payload.tokenRef);
772
- const tokenType = normalizeOptionalString(payload.tokenType);
773
- const authBaseUrl = normalizeOptionalString(payload.authBaseUrl);
774
- const clientId = normalizeOptionalString(payload.clientId);
775
- const createdAt = normalizeOptionalString(payload.createdAt);
776
- if (!(tokenRef && tokenType && authBaseUrl && clientId && createdAt)) throw new Error("cannot update active organization for invalid auth session");
777
- const nextPayload = {
778
- v: 1,
779
- tokenRef,
780
- tokenType,
781
- authBaseUrl,
782
- clientId,
783
- createdAt,
784
- ...typeof payload.expiresAt === "string" && payload.expiresAt.trim() ? { expiresAt: payload.expiresAt.trim() } : {},
785
- ...typeof payload.scope === "string" && payload.scope.trim() ? { scope: payload.scope.trim() } : {},
786
- ...buildAuthUserPayload(payload.user),
787
- ...buildActiveOrganizationPayload(activeOrganization)
788
- };
789
- await writeSessionPayloadAtomically(authSessionPath(), nextPayload);
790
- const currentCachedSession = readCachedAuthSession(payload);
791
- if (currentCachedSession) cacheAuthSession({
792
- payload: nextPayload,
793
- session: buildStoredAuthSession({
794
- accessToken: currentCachedSession.accessToken,
795
- payload: nextPayload
796
- })
797
- });
798
- }
799
- async function clearAuthSession() {
800
- cachedAuthSession = null;
801
- await retryPendingTokenCleanup();
802
- const hadLocalSession = await authSessionFileExists();
803
- const payload = await readSessionPayload();
804
- if (payload?.v === 1 && isStoredTokenRef(payload.tokenRef)) await deleteAccessTokenOrRetainForCleanup(payload.tokenRef);
805
- await removeSessionFile();
806
- return { hadLocalSession };
807
- }
808
- async function retryPendingTokenCleanup() {
809
- const pending = await readPendingTokenCleanup();
810
- if (pending.tokenRefs.length === 0) return;
811
- const remaining = [];
812
- for (const tokenRef of pending.tokenRefs) try {
813
- await deleteAccessToken(tokenRef);
814
- } catch {
815
- remaining.push(tokenRef);
816
- }
817
- await persistPendingTokenCleanup(remaining);
818
- }
819
- async function deleteAccessTokenOrRetainForCleanup(tokenRef) {
820
- try {
821
- await deleteAccessToken(tokenRef);
822
- } catch {
823
- const pending = await readPendingTokenCleanup();
824
- if (pending.tokenRefs.some((ref) => areStoredTokenRefsEqual(ref, tokenRef))) return;
825
- await persistPendingTokenCleanup([...pending.tokenRefs, tokenRef]);
826
- }
827
- }
828
- async function readPendingTokenCleanup() {
829
- const raw = await readFile(pendingTokenCleanupPath(), "utf8").catch((error) => {
830
- if (isFileNotFoundError(error)) return null;
831
- throw error;
832
- });
833
- if (raw === null) return {
834
- v: 1,
835
- tokenRefs: []
836
- };
837
- let parsed;
838
- try {
839
- parsed = JSON.parse(raw);
840
- } catch {
841
- throw new Error("pending access-token cleanup state is invalid");
842
- }
843
- if (!(isRecord(parsed) && parsed.v === 1 && Array.isArray(parsed.tokenRefs))) throw new Error("pending access-token cleanup state is invalid");
844
- const tokenRefs = parsed.tokenRefs.filter(isStoredTokenRef);
845
- if (tokenRefs.length !== parsed.tokenRefs.length) throw new Error("pending access-token cleanup state is invalid");
846
- return {
847
- v: 1,
848
- tokenRefs
849
- };
850
- }
851
- async function persistPendingTokenCleanup(tokenRefs) {
852
- const path = pendingTokenCleanupPath();
853
- if (tokenRefs.length === 0) {
854
- await rm(path, { force: true });
855
- return;
856
- }
857
- await mkdir(join(openMeldRootDir(), "auth"), { recursive: true });
858
- await writeJsonAtomically(path, {
859
- v: 1,
860
- tokenRefs
861
- });
862
- }
863
- function pendingTokenCleanupPath() {
864
- return join(openMeldRootDir(), "auth", "pending-token-cleanup.json");
865
- }
866
- async function authSessionFileExists() {
867
- try {
868
- await readFile(authSessionPath(), "utf8");
869
- return true;
870
- } catch (error) {
871
- if (isFileNotFoundError(error)) return false;
872
- throw error;
873
- }
874
- }
875
- async function getLocalAuthSessionState() {
876
- const payload = await readSessionPayload();
877
- if (payload?.v !== 1) return {
878
- reasonCode: "session_missing",
879
- state: "missing",
880
- session: null
881
- };
882
- const tokenRef = normalizeTokenRef(payload.tokenRef);
883
- if (!tokenRef) return {
884
- reasonCode: "session_token_ref_invalid",
885
- state: "invalid",
886
- session: null
887
- };
888
- const tokenType = normalizeOptionalString(payload.tokenType);
889
- const authBaseUrl = normalizeOptionalString(payload.authBaseUrl);
890
- const clientId = normalizeOptionalString(payload.clientId);
891
- const createdAt = normalizeOptionalString(payload.createdAt);
892
- if (!(tokenType && authBaseUrl && clientId && createdAt)) return {
893
- reasonCode: "session_metadata_invalid",
894
- state: "invalid",
895
- session: null
896
- };
897
- let session = readCachedAuthSession(payload);
898
- if (!session) {
899
- const accessToken = await readAccessToken(tokenRef);
900
- if (accessToken.status === "missing") return {
901
- reasonCode: "session_token_missing",
902
- state: "invalid",
903
- session: null
904
- };
905
- if (accessToken.status === "unavailable") return {
906
- errorMessage: accessToken.errorMessage,
907
- reasonCode: "session_token_unavailable",
908
- state: "invalid",
909
- session: null
910
- };
911
- session = buildStoredAuthSession({
912
- accessToken: accessToken.accessToken,
913
- payload: {
914
- ...payload,
915
- v: 1,
916
- tokenRef,
917
- tokenType,
918
- authBaseUrl,
919
- clientId,
920
- createdAt
921
- }
922
- });
923
- cacheAuthSession({
924
- payload,
925
- session
926
- });
927
- }
928
- if (isExpired(session.expiresAt)) return {
929
- reasonCode: "session_expired",
930
- state: "expired",
931
- session
932
- };
933
- return {
934
- state: "valid",
935
- session
936
- };
937
- }
938
- async function assertStoredAccessTokenReloads(input) {
939
- const reloaded = await readAccessToken(input.tokenRef);
940
- if (reloaded.status === "found" && reloaded.accessToken === input.accessToken) return;
941
- if (reloaded.status === "unavailable") throw new Error(`stored access token could not be reloaded: ${reloaded.errorMessage}`);
942
- throw new Error("stored access token could not be reloaded");
943
- }
944
- function buildStoredAuthSession(input) {
945
- return {
946
- v: 1,
947
- accessToken: input.accessToken,
948
- tokenType: input.payload.tokenType,
949
- authBaseUrl: input.payload.authBaseUrl,
950
- clientId: input.payload.clientId,
951
- createdAt: input.payload.createdAt,
952
- ...typeof input.payload.expiresAt === "string" && input.payload.expiresAt.trim() ? { expiresAt: input.payload.expiresAt.trim() } : {},
953
- ...typeof input.payload.scope === "string" && input.payload.scope.trim() ? { scope: input.payload.scope.trim() } : {},
954
- ...buildAuthUserPayload(input.payload.user),
955
- ...buildActiveOrganizationPayload(input.payload.activeOrganization)
956
- };
957
- }
958
- function cacheAuthSession(input) {
959
- cachedAuthSession = {
960
- payloadKey: buildAuthSessionPayloadKey(input.payload),
961
- session: input.session
962
- };
963
- }
964
- function readCachedAuthSession(payload) {
965
- const payloadKey = buildAuthSessionPayloadKey(payload);
966
- return cachedAuthSession?.payloadKey === payloadKey ? cachedAuthSession.session : null;
967
- }
968
- function buildAuthSessionPayloadKey(payload) {
969
- return `${authSessionPath()}\n${JSON.stringify(payload)}`;
970
- }
971
- function areStoredTokenRefsEqual(left, right) {
972
- return JSON.stringify(left) === JSON.stringify(right);
973
- }
974
- function normalizeTokenRef(input) {
975
- if (!isStoredTokenRef(input)) return null;
976
- return input;
977
- }
978
- async function getRemoteAuthSessionState(session) {
979
- let endpoint = "";
980
- try {
981
- endpoint = toAuthEndpoint(session.authBaseUrl, "/api/auth/get-session");
982
- } catch {
983
- return { state: "invalid" };
984
- }
985
- try {
986
- const timeoutMs = resolveRemoteSessionTimeoutMs(endpoint);
987
- const response = await fetch(endpoint, {
988
- method: "GET",
989
- headers: { Authorization: `${normalizeTokenType(session.tokenType)} ${session.accessToken}` },
990
- signal: AbortSignal.timeout(timeoutMs)
991
- });
992
- if (response.status === 401 || response.status === 403) return { state: "revoked" };
993
- if (!response.ok) return { state: "unknown" };
994
- if (!hasActiveSessionPayload(await parseResponseJson(response))) return { state: "invalid" };
995
- return { state: "valid" };
996
- } catch {
997
- return { state: "unknown" };
998
- }
999
- }
1000
- function resolveRemoteSessionTimeoutMs(endpoint) {
1001
- const url = parseUrlOrNull(endpoint);
1002
- if (url && isLoopbackHostname(url.hostname)) return LOOPBACK_REMOTE_SESSION_TIMEOUT_MS;
1003
- return DEFAULT_REMOTE_SESSION_TIMEOUT_MS;
1004
- }
1005
- function parseUrlOrNull(value) {
1006
- try {
1007
- return new URL(value);
1008
- } catch {
1009
- return null;
1010
- }
1011
- }
1012
- function isLoopbackHostname(hostname) {
1013
- return hostname === "localhost" || hostname === "127.0.0.1" || hostname === "::1";
1014
- }
1015
- function hasActiveSessionPayload(payload) {
1016
- if (!isRecord(payload)) return false;
1017
- return isRecord(payload.session) && isRecord(payload.user);
1018
- }
1019
- function isExpired(expiresAt) {
1020
- if (!expiresAt) return false;
1021
- const expiresAtMs = Date.parse(expiresAt);
1022
- if (Number.isNaN(expiresAtMs)) return false;
1023
- return expiresAtMs <= Date.now();
1024
- }
1025
- function resolveRemoteAuthSessionReasonCode(state) {
1026
- switch (state) {
1027
- case "invalid": return "remote_session_invalid";
1028
- case "revoked": return "remote_session_revoked";
1029
- default: throw new Error(`unsupported remote auth session state: ${state}`);
1030
- }
1031
- }
1032
- async function readSessionPayload() {
1033
- const raw = await readFile(authSessionPath(), "utf8").catch(() => null);
1034
- if (!raw) return null;
1035
- try {
1036
- return JSON.parse(raw);
1037
- } catch {
1038
- return null;
1039
- }
1040
- }
1041
- function authSessionPath() {
1042
- return join(openMeldRootDir(), "auth", "session.json");
1043
- }
1044
- async function writeSessionPayloadAtomically(path, payload) {
1045
- await writeJsonAtomically(path, payload);
1046
- }
1047
- async function writeJsonAtomically(path, payload) {
1048
- const tempPath = `${path}.tmp-${process.pid}-${Date.now()}-${randomUUID()}`;
1049
- try {
1050
- const file = await open(tempPath, "wx", 384);
1051
- try {
1052
- await file.writeFile(`${JSON.stringify(payload, null, 2)}\n`, "utf8");
1053
- await file.sync();
1054
- } finally {
1055
- await file.close();
1056
- }
1057
- await rename(tempPath, path);
1058
- } catch (error) {
1059
- await rm(tempPath, { force: true }).catch(() => void 0);
1060
- throw error;
1061
- }
1062
- }
1063
- function isFileNotFoundError(error) {
1064
- return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
1065
- }
1066
- function buildAuthUserPayload(value) {
1067
- if (!(value && typeof value === "object")) return {};
1068
- const record = value;
1069
- const id = normalizeOptionalString(record.id);
1070
- const email = normalizeOptionalString(record.email);
1071
- const name = normalizeOptionalString(record.name);
1072
- if (!(id || email || name)) return {};
1073
- return { user: {
1074
- ...id ? { id } : {},
1075
- ...email ? { email } : {},
1076
- ...name ? { name } : {}
1077
- } };
1078
- }
1079
- function buildActiveOrganizationPayload(value) {
1080
- const activeOrganization = normalizeStoredActiveOrganization(value);
1081
- return activeOrganization ? { activeOrganization } : {};
1082
- }
1083
- function normalizeStoredActiveOrganization(value) {
1084
- if (!isRecord(value)) return null;
1085
- const id = normalizeOptionalString(value.id);
1086
- const slug = normalizeOptionalString(value.slug);
1087
- const name = normalizeOptionalString(value.name);
1088
- const role = normalizeOptionalString(value.role);
1089
- const personal = readOrganizationIsPersonal(value);
1090
- if (!(id && slug && name)) return null;
1091
- return {
1092
- id,
1093
- slug,
1094
- name,
1095
- ...role ? { role } : {},
1096
- ...personal ? { personal } : {}
1097
- };
1098
- }
1099
- function normalizeTokenType(value) {
1100
- const normalized = value.trim();
1101
- return normalized.length > 0 ? normalized : "Bearer";
1102
- }
1103
- function normalizeOptionalString(value) {
1104
- const normalized = String(value ?? "").trim();
1105
- return normalized.length > 0 ? normalized : null;
1106
- }
1107
- function readOrganizationIsPersonal(value) {
1108
- if (value.personal === true || value.isPersonal === true) return true;
1109
- return readOrganizationMetadata(value.metadata)?.personal === true;
1110
- }
1111
- function readOrganizationMetadata(metadata) {
1112
- if (metadata === null || metadata === void 0) return null;
1113
- if (typeof metadata === "string") try {
1114
- const parsed = JSON.parse(metadata);
1115
- return isRecord(parsed) ? parsed : null;
1116
- } catch {
1117
- return null;
1118
- }
1119
- return isRecord(metadata) ? metadata : null;
1120
- }
1121
- function toAuthEndpoint(baseUrl, pathname) {
1122
- const url = new URL(baseUrl);
1123
- url.pathname = `${url.pathname.replace(TRAILING_SLASHES_RE, "")}${pathname.startsWith("/") ? pathname : `/${pathname}`}` || "/";
1124
- url.search = "";
1125
- url.hash = "";
1126
- return url.toString();
1127
- }
1128
- function isRecord(value) {
1129
- return Boolean(value && typeof value === "object");
1130
- }
1131
- async function parseResponseJson(response) {
1132
- const raw = await response.text();
1133
- if (!raw) return null;
1134
- try {
1135
- return JSON.parse(raw);
1136
- } catch {
1137
- return { message: raw };
1138
- }
1139
- }
1140
- async function removeSessionFile() {
1141
- await rm(authSessionPath(), { force: true });
1142
- }
1143
- //#endregion
1144
- export { ROUTE_CATALOG_LOAD_TIMEOUT_MS as A, MAX_SPACE_REQUEST_TIMEOUT_MS as C, PROVIDER_CONVERSATION_PROOF_SYNC_INTERVAL_MS as D, OPENCLAW_CLI_TIMEOUT_MS as E, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_RETRY_INTERVAL_MS as M, RUNTIME_STATE_PERSIST_MIN_INTERVAL_MS as N, PROVIDER_CONVERSATION_PROOF_SYNC_RETRY_INTERVAL_MS as O, MAX_HEARTBEAT_INTERVAL_MS as S, MIN_SPACE_REQUEST_TIMEOUT_MS as T, DAEMON_STREAM_KEEPALIVE_PONG_TIMEOUT_MS as _, getCurrentAuthOwnerUserId as a, DEFAULT_SPACE_REQUEST_TIMEOUT_MS as b, updateAuthSessionActiveOrganization as c, resolveOpenMeldDistribution as d, CATALOG_SYNC_RETRY_INTERVAL_MS as f, DAEMON_STREAM_KEEPALIVE_INTERVAL_MS as g, DAEMON_STREAM_CONNECT_TIMEOUT_MS as h, getAuthSessionState as i, RUNTIME_AGENT_CONTROLLER_REPORT_SYNC_INTERVAL_MS as j, REGISTER_RESPONSE_TIMEOUT_MS as k, runMacOsNativeKeychainHelperIfRequested as l, DAEMON_RUNTIME_CONTRACT_EPOCH as m, clearAuthSession as n, normalizeStoredActiveOrganization as o, CATALOG_SYNC_SIGNAL_POLL_INTERVAL_MS as p, getAuthSessionMetadata as r, setAuthSession as s, auth_session_exports as t, isBinaryDistribution as u, DEFAULT_GATEWAY_CHAIN_TIMEOUT_MS as v, MIN_HEARTBEAT_INTERVAL_MS as w, HEARTBEAT_RESPONSE_TIMEOUT_MS as x, DEFAULT_HEARTBEAT_INTERVAL_MS as y };
1145
-
1146
- //# sourceMappingURL=auth-session-qk94UQqs.js.map