codexuse-cli 5.0.9 → 5.1.1

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.
package/dist/index.js CHANGED
@@ -2022,7 +2022,7 @@ var require_toml = __commonJS({
2022
2022
  });
2023
2023
 
2024
2024
  // src/commands/accountPool.ts
2025
- var import_node_crypto4 = require("crypto");
2025
+ var import_node_crypto7 = require("crypto");
2026
2026
  var import_node_path7 = __toESM(require("path"));
2027
2027
 
2028
2028
  // ../../packages/contracts/src/settings/types.ts
@@ -2366,7 +2366,7 @@ async function withDatabase(dbPath, task) {
2366
2366
  function resolveAppStorageDbPath(userDataDir) {
2367
2367
  return import_node_path.default.join(userDataDir, APP_STORAGE_DB_DIR, APP_STORAGE_DB_NAME);
2368
2368
  }
2369
- async function readDocument(dbPath, namespace, normalize) {
2369
+ async function readDocument(dbPath, namespace, normalize2) {
2370
2370
  return withDatabase(dbPath, (db) => {
2371
2371
  const row = useStatement(
2372
2372
  db,
@@ -2377,10 +2377,10 @@ async function readDocument(dbPath, namespace, normalize) {
2377
2377
  if (parsed === null) {
2378
2378
  return null;
2379
2379
  }
2380
- return normalize(parsed);
2380
+ return normalize2(parsed);
2381
2381
  });
2382
2382
  }
2383
- async function readDocumentStrict(dbPath, namespace, normalize) {
2383
+ async function readDocumentStrict(dbPath, namespace, normalize2) {
2384
2384
  return withDatabase(dbPath, (db) => {
2385
2385
  const row = useStatement(
2386
2386
  db,
@@ -2401,7 +2401,7 @@ async function readDocumentStrict(dbPath, namespace, normalize) {
2401
2401
  );
2402
2402
  }
2403
2403
  try {
2404
- return normalize(parsed);
2404
+ return normalize2(parsed);
2405
2405
  } catch (error) {
2406
2406
  throw new AppStorageCorruptionError(
2407
2407
  `App storage document ${namespace} failed normalization.`,
@@ -2480,6 +2480,25 @@ async function updateDocument(input) {
2480
2480
  })
2481
2481
  );
2482
2482
  }
2483
+ async function deleteDocument(dbPath, namespace) {
2484
+ await withWriteQueue(
2485
+ dbPath,
2486
+ async () => withDatabase(dbPath, (db) => {
2487
+ beginImmediate(db);
2488
+ try {
2489
+ useStatement(
2490
+ db,
2491
+ `DELETE FROM ${APP_STORAGE_TABLE} WHERE namespace = ?`,
2492
+ (statement) => statement.run(namespace)
2493
+ );
2494
+ commit(db);
2495
+ } catch (error) {
2496
+ rollback(db);
2497
+ throw error;
2498
+ }
2499
+ })
2500
+ );
2501
+ }
2483
2502
 
2484
2503
  // ../../packages/runtime-app-state/src/app/state.ts
2485
2504
  var APP_STATE_DOCUMENT = "desktop.app-state";
@@ -2564,6 +2583,16 @@ function createDefaultAppState() {
2564
2583
  status: "inactive",
2565
2584
  signature: null
2566
2585
  },
2586
+ trial: {
2587
+ deviceId: null,
2588
+ startedAt: null,
2589
+ expiresAt: null,
2590
+ lastServerCheckAt: null,
2591
+ lastLocalSeenAt: null,
2592
+ offlineGraceUntil: null,
2593
+ serverExpired: false,
2594
+ signature: null
2595
+ },
2567
2596
  preferences: {
2568
2597
  excludeFolders: [],
2569
2598
  enableTaskCompleteBeep: true,
@@ -3011,6 +3040,25 @@ function normalizeAppState(raw) {
3011
3040
  if (!["inactive", "active", "grace", "error"].includes(merged.license.status)) {
3012
3041
  merged.license.status = "inactive";
3013
3042
  }
3043
+ if (!isRecord2(merged.trial)) {
3044
+ merged.trial = clone2(defaults.trial);
3045
+ }
3046
+ merged.trial.deviceId = asString(merged.trial.deviceId);
3047
+ merged.trial.startedAt = asString(merged.trial.startedAt);
3048
+ merged.trial.expiresAt = asString(merged.trial.expiresAt);
3049
+ merged.trial.lastServerCheckAt = asString(merged.trial.lastServerCheckAt);
3050
+ merged.trial.lastLocalSeenAt = asString(merged.trial.lastLocalSeenAt);
3051
+ merged.trial.offlineGraceUntil = asString(merged.trial.offlineGraceUntil);
3052
+ merged.trial.serverExpired = merged.trial.serverExpired === true;
3053
+ merged.trial.signature = asString(merged.trial.signature);
3054
+ {
3055
+ const allowedTrialKeys = new Set(Object.keys(defaults.trial));
3056
+ for (const key of Object.keys(merged.trial)) {
3057
+ if (!allowedTrialKeys.has(key)) {
3058
+ delete merged.trial[key];
3059
+ }
3060
+ }
3061
+ }
3014
3062
  if (!Array.isArray(merged.preferences.excludeFolders)) {
3015
3063
  merged.preferences.excludeFolders = [];
3016
3064
  }
@@ -3416,7 +3464,7 @@ async function writeAppSettings(settings, onUpdated) {
3416
3464
  }
3417
3465
 
3418
3466
  // ../../packages/runtime-profiles/src/license/service.ts
3419
- var import_node_crypto2 = __toESM(require("crypto"), 1);
3467
+ var import_node_crypto5 = __toESM(require("crypto"), 1);
3420
3468
 
3421
3469
  // ../../packages/runtime-codex/src/codex/settings.ts
3422
3470
  function asString2(value) {
@@ -3459,6 +3507,53 @@ function parseStoredLicense(raw) {
3459
3507
  );
3460
3508
  return hasValue ? license : null;
3461
3509
  }
3510
+ function parseStoredTrial(raw) {
3511
+ if (!isRecord3(raw)) {
3512
+ return null;
3513
+ }
3514
+ const trial = {
3515
+ deviceId: asString2(raw.deviceId ?? raw.device_id),
3516
+ startedAt: asString2(raw.startedAt ?? raw.started_at),
3517
+ expiresAt: asString2(raw.expiresAt ?? raw.expires_at),
3518
+ lastServerCheckAt: asString2(raw.lastServerCheckAt ?? raw.last_server_check_at),
3519
+ lastLocalSeenAt: asString2(raw.lastLocalSeenAt ?? raw.last_local_seen_at),
3520
+ offlineGraceUntil: asString2(raw.offlineGraceUntil ?? raw.offline_grace_until),
3521
+ serverExpired: raw.serverExpired === true || raw.server_expired === true,
3522
+ signature: asString2(raw.signature)
3523
+ };
3524
+ const hasValue = Boolean(
3525
+ trial.deviceId || trial.startedAt || trial.expiresAt || trial.lastServerCheckAt || trial.lastLocalSeenAt || trial.serverExpired || trial.signature
3526
+ );
3527
+ return hasValue ? trial : null;
3528
+ }
3529
+ async function getStoredTrial() {
3530
+ const state = await getAppState();
3531
+ return parseStoredTrial(state.trial);
3532
+ }
3533
+ async function persistTrial(trial) {
3534
+ const parsed = parseStoredTrial(trial);
3535
+ await patchAppState({
3536
+ trial: parsed ? {
3537
+ deviceId: parsed.deviceId ?? null,
3538
+ startedAt: parsed.startedAt ?? null,
3539
+ expiresAt: parsed.expiresAt ?? null,
3540
+ lastServerCheckAt: parsed.lastServerCheckAt ?? null,
3541
+ lastLocalSeenAt: parsed.lastLocalSeenAt ?? null,
3542
+ offlineGraceUntil: parsed.offlineGraceUntil ?? null,
3543
+ serverExpired: parsed.serverExpired === true,
3544
+ signature: parsed.signature ?? null
3545
+ } : {
3546
+ deviceId: null,
3547
+ startedAt: null,
3548
+ expiresAt: null,
3549
+ lastServerCheckAt: null,
3550
+ lastLocalSeenAt: null,
3551
+ offlineGraceUntil: null,
3552
+ serverExpired: false,
3553
+ signature: null
3554
+ }
3555
+ });
3556
+ }
3462
3557
  async function getStoredLicense() {
3463
3558
  const state = await getAppState();
3464
3559
  return parseStoredLicense(state.license);
@@ -3590,7 +3685,9 @@ function getActiveOffer() {
3590
3685
  isActive: true,
3591
3686
  campaign: "summer-2026",
3592
3687
  productPermalink: "codex-use",
3593
- checkoutBaseUrl: "https://hweihwang.gumroad.com/l/codex-use"
3688
+ checkoutBaseUrl: "https://hweihwang.gumroad.com/l/codex-use",
3689
+ trialEnabled: true,
3690
+ trialDays: 7
3594
3691
  };
3595
3692
  }
3596
3693
  function buildCheckoutUrl(offer2, options) {
@@ -3613,6 +3710,504 @@ function buildCheckoutUrl(offer2, options) {
3613
3710
  return url.toString();
3614
3711
  }
3615
3712
 
3713
+ // ../../packages/runtime-profiles/src/license/trial.ts
3714
+ var import_node_crypto4 = __toESM(require("crypto"), 1);
3715
+
3716
+ // ../../packages/runtime-profiles/src/license/device-id.ts
3717
+ var import_node_crypto2 = __toESM(require("crypto"), 1);
3718
+ var import_promises = require("fs/promises");
3719
+ var import_node_child_process = require("child_process");
3720
+ var import_node_util = require("util");
3721
+ var DEVICE_ID_DOCUMENT = "desktop.device-id";
3722
+ var SHA256_HEX_PATTERN = /^[0-9a-f]{64}$/i;
3723
+ var execFileAsync = (0, import_node_util.promisify)(import_node_child_process.execFile);
3724
+ var memoizedDeviceId = null;
3725
+ function normalize(value) {
3726
+ return typeof value === "string" ? value.trim() : "";
3727
+ }
3728
+ async function readHardwareUuid() {
3729
+ if (process.platform !== "darwin") {
3730
+ return null;
3731
+ }
3732
+ try {
3733
+ const { stdout } = await execFileAsync(
3734
+ "ioreg",
3735
+ ["-rd1", "-c", "IOPlatformExpertDevice"],
3736
+ { timeout: 4e3 }
3737
+ );
3738
+ const match = stdout.match(/"IOPlatformUUID"\s*=\s*"([^"]+)"/);
3739
+ return normalize(match?.[1]) || null;
3740
+ } catch {
3741
+ return null;
3742
+ }
3743
+ }
3744
+ async function readLinuxMachineId() {
3745
+ if (process.platform !== "linux") {
3746
+ return null;
3747
+ }
3748
+ for (const file of ["/etc/machine-id", "/var/lib/dbus/machine-id"]) {
3749
+ try {
3750
+ const value = normalize(await (0, import_promises.readFile)(file, "utf8"));
3751
+ if (value) {
3752
+ return value;
3753
+ }
3754
+ } catch {
3755
+ }
3756
+ }
3757
+ return null;
3758
+ }
3759
+ function hashDeviceComponent(value) {
3760
+ return import_node_crypto2.default.createHash("sha256").update(`codexuse-device:${value}`).digest("hex");
3761
+ }
3762
+ async function getDeviceId() {
3763
+ if (memoizedDeviceId) {
3764
+ return memoizedDeviceId;
3765
+ }
3766
+ const dbPath = resolveAppStorageDbPath(getUserDataDir());
3767
+ const cached = normalize(await readDocument(dbPath, DEVICE_ID_DOCUMENT, normalize));
3768
+ const stableDeviceSource = await readHardwareUuid() ?? await readLinuxMachineId();
3769
+ if (stableDeviceSource) {
3770
+ const deviceId2 = hashDeviceComponent(stableDeviceSource);
3771
+ if (cached !== deviceId2) {
3772
+ await writeDocument(dbPath, DEVICE_ID_DOCUMENT, deviceId2);
3773
+ }
3774
+ memoizedDeviceId = deviceId2;
3775
+ return deviceId2;
3776
+ }
3777
+ if (SHA256_HEX_PATTERN.test(cached)) {
3778
+ memoizedDeviceId = cached;
3779
+ return cached;
3780
+ }
3781
+ const seed = import_node_crypto2.default.randomBytes(32).toString("hex");
3782
+ const deviceId = hashDeviceComponent(seed);
3783
+ await writeDocument(dbPath, DEVICE_ID_DOCUMENT, deviceId);
3784
+ memoizedDeviceId = deviceId;
3785
+ return deviceId;
3786
+ }
3787
+ function hashEmail(email) {
3788
+ const normalized = typeof email === "string" ? email.trim().toLowerCase() : "";
3789
+ if (!normalized) {
3790
+ return null;
3791
+ }
3792
+ return import_node_crypto2.default.createHash("sha256").update(`codexuse-email:${normalized}`).digest("hex");
3793
+ }
3794
+
3795
+ // ../../packages/runtime-profiles/src/license/trial-client.ts
3796
+ var DEFAULT_API_BASE_URL = "https://api.codexuse.com";
3797
+ var TRIAL_REQUEST_TIMEOUT_MS = 1e4;
3798
+ function getApiBaseUrl() {
3799
+ return DEFAULT_API_BASE_URL;
3800
+ }
3801
+ function parseResponse(raw) {
3802
+ if (!raw || typeof raw !== "object") {
3803
+ return null;
3804
+ }
3805
+ const record = raw;
3806
+ const serverNow = typeof record.serverNow === "string" ? record.serverNow : null;
3807
+ if (!serverNow) {
3808
+ return null;
3809
+ }
3810
+ return {
3811
+ trialActive: record.trialActive === true,
3812
+ startedAt: typeof record.startedAt === "string" ? record.startedAt : null,
3813
+ expiresAt: typeof record.expiresAt === "string" ? record.expiresAt : null,
3814
+ trialToken: typeof record.trialToken === "string" ? record.trialToken : null,
3815
+ serverNow,
3816
+ offlineGraceMs: typeof record.offlineGraceMs === "number" && Number.isFinite(record.offlineGraceMs) ? record.offlineGraceMs : 0
3817
+ };
3818
+ }
3819
+ async function registerTrialWithServer(input) {
3820
+ const controller = new AbortController();
3821
+ const timeout = setTimeout(() => controller.abort(), TRIAL_REQUEST_TIMEOUT_MS);
3822
+ try {
3823
+ const response = await fetch(`${getApiBaseUrl()}/v1/trial/register`, {
3824
+ method: "POST",
3825
+ headers: { "Content-Type": "application/json" },
3826
+ body: JSON.stringify({
3827
+ deviceId: input.deviceId,
3828
+ emailHash: input.emailHash ?? null,
3829
+ trialToken: input.trialToken ?? null
3830
+ }),
3831
+ signal: controller.signal
3832
+ });
3833
+ if (!response.ok) {
3834
+ throw new Error(`Trial registration failed (${response.status}).`);
3835
+ }
3836
+ const parsed = parseResponse(await response.json());
3837
+ if (!parsed) {
3838
+ throw new Error("Trial registration response was incomplete.");
3839
+ }
3840
+ return parsed;
3841
+ } finally {
3842
+ clearTimeout(timeout);
3843
+ }
3844
+ }
3845
+
3846
+ // ../../packages/runtime-profiles/src/license/trial-token-store.ts
3847
+ var import_node_crypto3 = require("crypto");
3848
+ var import_node_child_process2 = require("child_process");
3849
+ var KEYCHAIN_SERVICE = "CODEXUSE_TRIAL_TOKEN";
3850
+ var KEYCHAIN_ACCOUNT_PREFIX = "device-sha256:";
3851
+ var FALLBACK_DOCUMENT_PREFIX = "desktop.trial-token.";
3852
+ function keychainAccountForDevice(deviceId) {
3853
+ const digest = (0, import_node_crypto3.createHash)("sha256").update(deviceId).digest("hex");
3854
+ return KEYCHAIN_ACCOUNT_PREFIX + digest;
3855
+ }
3856
+ function fallbackDocumentForDevice(deviceId) {
3857
+ const digest = (0, import_node_crypto3.createHash)("sha256").update(deviceId).digest("hex");
3858
+ return FALLBACK_DOCUMENT_PREFIX + digest;
3859
+ }
3860
+ function normalizeToken(value) {
3861
+ const trimmed = typeof value === "string" ? value.trim() : "";
3862
+ return trimmed.length > 0 ? trimmed : null;
3863
+ }
3864
+ function runSecurityCommand(args) {
3865
+ return new Promise((resolve, reject) => {
3866
+ const child = (0, import_node_child_process2.spawn)("security", args, { stdio: ["ignore", "pipe", "ignore"] });
3867
+ let stdout = "";
3868
+ child.stdout?.on("data", (chunk) => {
3869
+ stdout += String(chunk);
3870
+ });
3871
+ child.on("error", () => {
3872
+ reject(new Error("keychain-command-failed"));
3873
+ });
3874
+ child.on("close", (code) => {
3875
+ resolve({ code, stdout });
3876
+ });
3877
+ });
3878
+ }
3879
+ async function readStoredTrialToken(deviceId) {
3880
+ if (process.platform !== "darwin") {
3881
+ const dbPath = resolveAppStorageDbPath(getUserDataDir());
3882
+ return readDocument(
3883
+ dbPath,
3884
+ fallbackDocumentForDevice(deviceId),
3885
+ normalizeToken
3886
+ );
3887
+ }
3888
+ const result = await runSecurityCommand([
3889
+ "find-generic-password",
3890
+ "-a",
3891
+ keychainAccountForDevice(deviceId),
3892
+ "-s",
3893
+ KEYCHAIN_SERVICE,
3894
+ "-w"
3895
+ ]).catch(() => null);
3896
+ await deleteDocument(
3897
+ resolveAppStorageDbPath(getUserDataDir()),
3898
+ fallbackDocumentForDevice(deviceId)
3899
+ ).catch(() => void 0);
3900
+ if (!result || result.code !== 0) {
3901
+ return null;
3902
+ }
3903
+ return result.stdout.length > 0 ? result.stdout.replace(/\n$/, "") : null;
3904
+ }
3905
+ async function writeStoredTrialToken(deviceId, token) {
3906
+ const value = typeof token === "string" ? token.trim() : "";
3907
+ if (!value) {
3908
+ return;
3909
+ }
3910
+ if (process.platform !== "darwin") {
3911
+ const dbPath = resolveAppStorageDbPath(getUserDataDir());
3912
+ await writeDocument(
3913
+ dbPath,
3914
+ fallbackDocumentForDevice(deviceId),
3915
+ value
3916
+ );
3917
+ return;
3918
+ }
3919
+ const result = await runSecurityCommand([
3920
+ "add-generic-password",
3921
+ "-U",
3922
+ "-a",
3923
+ keychainAccountForDevice(deviceId),
3924
+ "-s",
3925
+ KEYCHAIN_SERVICE,
3926
+ "-w",
3927
+ value
3928
+ ]).catch(() => null);
3929
+ await deleteDocument(
3930
+ resolveAppStorageDbPath(getUserDataDir()),
3931
+ fallbackDocumentForDevice(deviceId)
3932
+ ).catch(() => void 0);
3933
+ if (!result || result.code !== 0) {
3934
+ throw new Error("trial-token-keychain-write-failed");
3935
+ }
3936
+ }
3937
+
3938
+ // ../../packages/runtime-profiles/src/license/trial.ts
3939
+ var DAY_MS = 24 * 60 * 60 * 1e3;
3940
+ var TRIAL_SERVER_REFRESH_MS = 15 * 60 * 1e3;
3941
+ var TRIAL_BACKGROUND_RETRY_MS = 60 * 1e3;
3942
+ var CLOCK_ROLLBACK_TOLERANCE_MS = 5 * 60 * 1e3;
3943
+ var verifiedTrialCache = null;
3944
+ var backgroundTrialSyncPromise = null;
3945
+ var nextBackgroundTrialSyncAtMs = 0;
3946
+ function isTrialEnforcementEnabled() {
3947
+ return true;
3948
+ }
3949
+ function trialSignaturePayload(trial) {
3950
+ return JSON.stringify({
3951
+ deviceId: trial.deviceId ?? null,
3952
+ startedAt: trial.startedAt ?? null,
3953
+ expiresAt: trial.expiresAt ?? null,
3954
+ lastServerCheckAt: trial.lastServerCheckAt ?? null,
3955
+ lastLocalSeenAt: trial.lastLocalSeenAt ?? null,
3956
+ offlineGraceUntil: trial.offlineGraceUntil ?? null,
3957
+ serverExpired: trial.serverExpired === true
3958
+ });
3959
+ }
3960
+ function signTrial(trial, secret) {
3961
+ return import_node_crypto4.default.createHmac("sha256", secret).update(trialSignaturePayload(trial)).digest("hex");
3962
+ }
3963
+ function withTrialSignature(trial, secret) {
3964
+ return { ...trial, signature: signTrial(trial, secret) };
3965
+ }
3966
+ function isSignatureValid(trial, secret) {
3967
+ return Boolean(trial.signature) && signTrial(trial, secret) === trial.signature;
3968
+ }
3969
+ function parseTs(value) {
3970
+ if (typeof value !== "string" || value.trim() === "") {
3971
+ return null;
3972
+ }
3973
+ const parsed = Date.parse(value);
3974
+ return Number.isNaN(parsed) ? null : parsed;
3975
+ }
3976
+ function buildTrialInfo(stored, now) {
3977
+ const expiresAtMs = parseTs(stored?.expiresAt);
3978
+ const expired = stored?.serverExpired === true || expiresAtMs === null || expiresAtMs <= now;
3979
+ const daysLeft = expired || expiresAtMs === null ? 0 : Math.max(0, Math.ceil((expiresAtMs - now) / DAY_MS));
3980
+ return {
3981
+ active: !expired,
3982
+ expired,
3983
+ expiresAt: stored?.expiresAt ?? null,
3984
+ daysLeft
3985
+ };
3986
+ }
3987
+ function buildLockedTrialInfo(stored) {
3988
+ return {
3989
+ active: false,
3990
+ expired: true,
3991
+ expiresAt: stored?.expiresAt ?? null,
3992
+ daysLeft: 0
3993
+ };
3994
+ }
3995
+ function hasTrustedServerRecord(stored, secret, deviceId) {
3996
+ return Boolean(
3997
+ stored && stored.deviceId === deviceId && stored.startedAt && stored.lastServerCheckAt && isSignatureValid(stored, secret)
3998
+ );
3999
+ }
4000
+ function shouldRefreshInBackground(stored, now) {
4001
+ const lastServerCheckMs = parseTs(stored.lastServerCheckAt);
4002
+ return lastServerCheckMs !== null && now - lastServerCheckMs >= TRIAL_SERVER_REFRESH_MS;
4003
+ }
4004
+ function hasLocalClockRollback(stored, now) {
4005
+ const lastTrustedMs = Math.max(
4006
+ parseTs(stored.lastLocalSeenAt) ?? 0,
4007
+ parseTs(stored.lastServerCheckAt) ?? 0
4008
+ );
4009
+ return lastTrustedMs > 0 && now + CLOCK_ROLLBACK_TOLERANCE_MS < lastTrustedMs;
4010
+ }
4011
+ function canUseOfflineTrial(stored, now) {
4012
+ if (stored.serverExpired === true || hasLocalClockRollback(stored, now)) {
4013
+ return false;
4014
+ }
4015
+ const expiresAtMs = parseTs(stored.expiresAt);
4016
+ const offlineGraceUntilMs = parseTs(stored.offlineGraceUntil);
4017
+ const effectiveNow = trustedTrialNow(stored, now);
4018
+ if (expiresAtMs === null || offlineGraceUntilMs === null) {
4019
+ return false;
4020
+ }
4021
+ return effectiveNow < expiresAtMs && effectiveNow <= offlineGraceUntilMs;
4022
+ }
4023
+ function trustedTrialNow(stored, now) {
4024
+ return Math.max(now, parseTs(stored.lastServerCheckAt) ?? now);
4025
+ }
4026
+ async function persistLocalSeenIfNeeded(stored, secret, now) {
4027
+ const lastLocalSeenMs = parseTs(stored.lastLocalSeenAt);
4028
+ if (lastLocalSeenMs !== null && now - lastLocalSeenMs < TRIAL_SERVER_REFRESH_MS) {
4029
+ return stored;
4030
+ }
4031
+ const next = withTrialSignature(
4032
+ {
4033
+ ...stored,
4034
+ lastLocalSeenAt: new Date(Math.max(now, lastLocalSeenMs ?? 0)).toISOString()
4035
+ },
4036
+ secret
4037
+ );
4038
+ await persistTrial(next);
4039
+ return next;
4040
+ }
4041
+ function startTrialSyncInBackground() {
4042
+ const now = Date.now();
4043
+ if (backgroundTrialSyncPromise || now < nextBackgroundTrialSyncAtMs) {
4044
+ return;
4045
+ }
4046
+ nextBackgroundTrialSyncAtMs = now + TRIAL_BACKGROUND_RETRY_MS;
4047
+ backgroundTrialSyncPromise = syncTrialWithServer({ force: true }).catch(() => false).finally(() => {
4048
+ backgroundTrialSyncPromise = null;
4049
+ });
4050
+ }
4051
+ async function resolveFirstProfileEmailHash() {
4052
+ try {
4053
+ const state = await getAppState();
4054
+ for (const record of Object.values(state.profilesByName ?? {})) {
4055
+ const hashed = hashEmail(record.email ?? null);
4056
+ if (hashed) {
4057
+ return hashed;
4058
+ }
4059
+ }
4060
+ } catch {
4061
+ }
4062
+ return null;
4063
+ }
4064
+ function signedServerTrial(input) {
4065
+ const serverNowMs = parseTs(input.response.serverNow) ?? input.now;
4066
+ return withTrialSignature(
4067
+ {
4068
+ deviceId: input.deviceId,
4069
+ startedAt: input.response.startedAt ?? input.stored?.startedAt ?? new Date(serverNowMs).toISOString(),
4070
+ expiresAt: input.response.expiresAt ?? input.stored?.expiresAt ?? null,
4071
+ lastServerCheckAt: input.response.serverNow,
4072
+ lastLocalSeenAt: new Date(input.now).toISOString(),
4073
+ offlineGraceUntil: new Date(serverNowMs + input.response.offlineGraceMs).toISOString(),
4074
+ serverExpired: input.response.trialActive === false
4075
+ },
4076
+ input.secret
4077
+ );
4078
+ }
4079
+ async function syncAndPersistTrial(input) {
4080
+ let deviceId;
4081
+ try {
4082
+ deviceId = await getDeviceId();
4083
+ } catch {
4084
+ return null;
4085
+ }
4086
+ const emailHash = input.emailHash ?? await resolveFirstProfileEmailHash();
4087
+ try {
4088
+ const trialToken = await readStoredTrialToken(deviceId).catch(() => null);
4089
+ const response = await registerTrialWithServer({ deviceId, emailHash, trialToken });
4090
+ if (response.trialToken) {
4091
+ try {
4092
+ await writeStoredTrialToken(deviceId, response.trialToken);
4093
+ } catch {
4094
+ if (!trialToken) {
4095
+ return null;
4096
+ }
4097
+ }
4098
+ }
4099
+ const next = signedServerTrial({
4100
+ response,
4101
+ secret: input.secret,
4102
+ stored: input.stored,
4103
+ now: input.now,
4104
+ deviceId
4105
+ });
4106
+ await persistTrial(next);
4107
+ rememberServerVerifiedTrial(next, input.now);
4108
+ return next;
4109
+ } catch {
4110
+ return null;
4111
+ }
4112
+ }
4113
+ function rememberServerVerifiedTrial(stored, now) {
4114
+ const refreshAtMs = now + TRIAL_SERVER_REFRESH_MS;
4115
+ const expiresAtMs = stored.serverExpired === true ? refreshAtMs : parseTs(stored.expiresAt) ?? now;
4116
+ verifiedTrialCache = {
4117
+ stored,
4118
+ usableUntilMs: Math.max(now, Math.min(expiresAtMs, refreshAtMs))
4119
+ };
4120
+ }
4121
+ function readServerVerifiedTrial(now) {
4122
+ if (!verifiedTrialCache || verifiedTrialCache.usableUntilMs <= now) {
4123
+ verifiedTrialCache = null;
4124
+ return null;
4125
+ }
4126
+ return verifiedTrialCache.stored;
4127
+ }
4128
+ async function resolveTrialState(now = Date.now(), options = {}) {
4129
+ if (!isTrialEnforcementEnabled()) {
4130
+ return { info: null, locked: false };
4131
+ }
4132
+ const allowNetwork = options.allowNetwork !== false;
4133
+ const secret = await getLicenseSecret();
4134
+ let stored = await getStoredTrial();
4135
+ const hadStoredTrial = stored !== null;
4136
+ const currentDeviceId = await getDeviceId().catch(() => null);
4137
+ const cached = readServerVerifiedTrial(now);
4138
+ if (cached) {
4139
+ if (!currentDeviceId || !hasTrustedServerRecord(cached, secret, currentDeviceId)) {
4140
+ verifiedTrialCache = null;
4141
+ } else {
4142
+ if (hasLocalClockRollback(cached, now)) {
4143
+ const refreshed2 = allowNetwork ? await syncAndPersistTrial({ stored: cached, secret, now }) : null;
4144
+ if (!refreshed2) {
4145
+ return { info: buildLockedTrialInfo(cached), locked: true };
4146
+ }
4147
+ const info3 = buildTrialInfo(refreshed2, trustedTrialNow(refreshed2, now));
4148
+ return { info: info3, locked: info3.expired };
4149
+ }
4150
+ if (shouldRefreshInBackground(cached, now)) {
4151
+ void syncTrialWithServer({ force: true }).catch(() => void 0);
4152
+ }
4153
+ const info2 = buildTrialInfo(cached, trustedTrialNow(cached, now));
4154
+ return { info: info2, locked: info2.expired };
4155
+ }
4156
+ }
4157
+ if (stored && (!currentDeviceId || !hasTrustedServerRecord(stored, secret, currentDeviceId))) {
4158
+ stored = null;
4159
+ }
4160
+ if (!allowNetwork) {
4161
+ if (stored && canUseOfflineTrial(stored, now)) {
4162
+ const next = await persistLocalSeenIfNeeded(stored, secret, now).catch(() => stored);
4163
+ rememberServerVerifiedTrial(next, now);
4164
+ if (options.refreshInBackground === true && shouldRefreshInBackground(next, now)) {
4165
+ startTrialSyncInBackground();
4166
+ }
4167
+ const info2 = buildTrialInfo(next, trustedTrialNow(next, now));
4168
+ return { info: info2, locked: info2.expired };
4169
+ }
4170
+ if (options.refreshInBackground === true) {
4171
+ startTrialSyncInBackground();
4172
+ }
4173
+ if (!hadStoredTrial && options.refreshInBackground === true) {
4174
+ return { info: null, locked: false };
4175
+ }
4176
+ return { info: buildLockedTrialInfo(stored), locked: true };
4177
+ }
4178
+ const refreshed = await syncAndPersistTrial({ stored, secret, now });
4179
+ if (!refreshed) {
4180
+ if (stored && canUseOfflineTrial(stored, now)) {
4181
+ const next = await persistLocalSeenIfNeeded(stored, secret, now).catch(() => stored);
4182
+ rememberServerVerifiedTrial(next, now);
4183
+ const info2 = buildTrialInfo(next, trustedTrialNow(next, now));
4184
+ return { info: info2, locked: info2.expired };
4185
+ }
4186
+ return { info: buildLockedTrialInfo(stored), locked: true };
4187
+ }
4188
+ const info = buildTrialInfo(refreshed, trustedTrialNow(refreshed, now));
4189
+ return { info, locked: info.expired };
4190
+ }
4191
+ async function syncTrialWithServer(opts = {}) {
4192
+ if (!isTrialEnforcementEnabled()) {
4193
+ return true;
4194
+ }
4195
+ const now = Date.now();
4196
+ const secret = await getLicenseSecret();
4197
+ const stored = await getStoredTrial();
4198
+ const explicitEmailHash = opts.emailHash ?? null;
4199
+ if (!opts.force && !explicitEmailHash && readServerVerifiedTrial(now)) {
4200
+ return true;
4201
+ }
4202
+ const next = await syncAndPersistTrial({
4203
+ stored,
4204
+ secret,
4205
+ now,
4206
+ emailHash: explicitEmailHash
4207
+ });
4208
+ return next !== null;
4209
+ }
4210
+
3616
4211
  // ../../packages/runtime-profiles/src/license/service.ts
3617
4212
  var offer = getActiveOffer();
3618
4213
  var PRODUCT_PERMALINK = offer.productPermalink;
@@ -3677,7 +4272,7 @@ function licenseSignaturePayload(license) {
3677
4272
  return JSON.stringify(payload);
3678
4273
  }
3679
4274
  function signLicense(license, secret) {
3680
- return import_node_crypto2.default.createHmac("sha256", secret).update(licenseSignaturePayload(license)).digest("hex");
4275
+ return import_node_crypto5.default.createHmac("sha256", secret).update(licenseSignaturePayload(license)).digest("hex");
3681
4276
  }
3682
4277
  function withSignature(license, secret) {
3683
4278
  return {
@@ -3685,7 +4280,7 @@ function withSignature(license, secret) {
3685
4280
  signature: signLicense(license, secret)
3686
4281
  };
3687
4282
  }
3688
- function isSignatureValid(license, secret) {
4283
+ function isSignatureValid2(license, secret) {
3689
4284
  if (!license.signature) {
3690
4285
  return false;
3691
4286
  }
@@ -3763,6 +4358,47 @@ function ensureWithinUseLimit(response) {
3763
4358
  );
3764
4359
  }
3765
4360
  }
4361
+ function computeCapabilities(opts) {
4362
+ return {
4363
+ unlimitedProfiles: opts.entitled,
4364
+ accountPool: opts.entitled,
4365
+ telegram: opts.entitled,
4366
+ autoRoll: opts.entitled,
4367
+ cloudSync: opts.licensed || opts.entitled
4368
+ };
4369
+ }
4370
+ function applyTrial(base, trial) {
4371
+ if (base.isPro) {
4372
+ return { ...base, trial: null };
4373
+ }
4374
+ const { info, locked } = trial;
4375
+ if (!info) {
4376
+ return base;
4377
+ }
4378
+ if (info.active) {
4379
+ return {
4380
+ ...base,
4381
+ tier: "trial",
4382
+ state: "trial",
4383
+ capabilities: computeCapabilities({ licensed: false, entitled: true }),
4384
+ profileLimit: null,
4385
+ profilesRemaining: null,
4386
+ trial: info
4387
+ };
4388
+ }
4389
+ if (locked) {
4390
+ return {
4391
+ ...base,
4392
+ tier: "free",
4393
+ state: "locked",
4394
+ capabilities: computeCapabilities({ licensed: false, entitled: false }),
4395
+ profileLimit: 0,
4396
+ profilesRemaining: 0,
4397
+ trial: info
4398
+ };
4399
+ }
4400
+ return { ...base, trial: info };
4401
+ }
3766
4402
  function toLicenseStatus(stored, overrides = {}) {
3767
4403
  const tier = determineTierFromStored(stored);
3768
4404
  const isPro = tier === "pro";
@@ -3771,6 +4407,8 @@ function toLicenseStatus(stored, overrides = {}) {
3771
4407
  tier,
3772
4408
  state,
3773
4409
  isPro,
4410
+ capabilities: computeCapabilities({ licensed: isPro, entitled: isPro }),
4411
+ trial: null,
3774
4412
  profileLimit: isPro ? null : FREE_PROFILE_LIMIT,
3775
4413
  profilesRemaining: null,
3776
4414
  purchaseEmail: stored?.purchaseEmail ?? null,
@@ -3812,15 +4450,27 @@ var LicenseService = class {
3812
4450
  const refreshInBackground = Boolean(options.refreshInBackground);
3813
4451
  const secret = await getLicenseSecret();
3814
4452
  const stored = await getStoredLicense();
4453
+ const finalize = async (status) => {
4454
+ if (status.isPro) {
4455
+ return { ...status, trial: null };
4456
+ }
4457
+ return applyTrial(
4458
+ status,
4459
+ await resolveTrialState(Date.now(), {
4460
+ allowNetwork: !allowStale || forceRefresh,
4461
+ refreshInBackground
4462
+ })
4463
+ );
4464
+ };
3815
4465
  if (!stored?.licenseKey) {
3816
- return toLicenseStatus(null);
4466
+ return finalize(toLicenseStatus(null));
3817
4467
  }
3818
4468
  const now = Date.now();
3819
4469
  const nextCheckTs = parseTimestamp(stored.nextCheckAt);
3820
4470
  const lastVerifiedTs = parseTimestamp(stored.lastVerifiedAt);
3821
4471
  const graceStale = (stored.status === "grace" || stored.status === "error") && (lastVerifiedTs === null || lastVerifiedTs + GRACE_MAX_AGE_MS < now);
3822
4472
  let workingStored = { ...stored };
3823
- const signatureValid = isSignatureValid(workingStored, secret);
4473
+ const signatureValid = isSignatureValid2(workingStored, secret);
3824
4474
  let cappedNextCheckTs = nextCheckTs;
3825
4475
  if (nextCheckTs !== null && nextCheckTs > now + MAX_NEXT_CHECK_MS) {
3826
4476
  cappedNextCheckTs = now;
@@ -3843,7 +4493,7 @@ var LicenseService = class {
3843
4493
  if (allowStale && shouldRefresh && refreshInBackground) {
3844
4494
  this.refreshStatusInBackground({ force: forceRefresh });
3845
4495
  }
3846
- return cached;
4496
+ return finalize(cached);
3847
4497
  }
3848
4498
  if (this.verificationPromise && !forceRefresh) {
3849
4499
  return this.verificationPromise;
@@ -3863,7 +4513,7 @@ var LicenseService = class {
3863
4513
  };
3864
4514
  const signed = withSignature(updated, secret);
3865
4515
  await persistLicense(signed);
3866
- return toLicenseStatus(signed);
4516
+ return finalize(toLicenseStatus(signed));
3867
4517
  } catch (error) {
3868
4518
  const message = error instanceof Error ? error.message : "License verification failed.";
3869
4519
  if (error instanceof LicenseError && error.code === "network") {
@@ -3881,7 +4531,7 @@ var LicenseService = class {
3881
4531
  state: fallbackStored2.status ?? "grace",
3882
4532
  error: message
3883
4533
  });
3884
- return fallback;
4534
+ return finalize(fallback);
3885
4535
  }
3886
4536
  const fallbackStored = withSignature({
3887
4537
  licenseKey: workingStored.licenseKey,
@@ -3892,7 +4542,7 @@ var LicenseService = class {
3892
4542
  lastVerificationError: message
3893
4543
  }, secret);
3894
4544
  await persistLicense(fallbackStored);
3895
- return toLicenseStatus(fallbackStored, { error: message });
4545
+ return finalize(toLicenseStatus(fallbackStored, { error: message }));
3896
4546
  }
3897
4547
  };
3898
4548
  this.verificationPromise = verify();
@@ -3908,7 +4558,7 @@ var LicenseService = class {
3908
4558
  throw new Error("License key is required.");
3909
4559
  }
3910
4560
  const secret = await getLicenseSecret();
3911
- const digest = import_node_crypto2.default.createHash("sha256").update(trimmed).digest("hex");
4561
+ const digest = import_node_crypto5.default.createHash("sha256").update(trimmed).digest("hex");
3912
4562
  const result = await requestGumroadVerify(trimmed, "activation");
3913
4563
  ensureWithinUseLimit(result);
3914
4564
  const normalized = normalizeVerificationResult(result);
@@ -3950,9 +4600,28 @@ var LicenseService = class {
3950
4600
  }
3951
4601
  };
3952
4602
  var licenseService = new LicenseService();
4603
+ function isExplicitInvalidation(message) {
4604
+ if (!message) {
4605
+ return false;
4606
+ }
4607
+ const normalized = message.toLowerCase();
4608
+ return normalized.includes("revoked") || normalized.includes("refunded") || normalized.includes("invalid") || normalized.includes("no longer active");
4609
+ }
4610
+ function shouldEnforceProfileLimit(status) {
4611
+ if (status.capabilities.unlimitedProfiles) {
4612
+ return false;
4613
+ }
4614
+ if (status.state === "grace" || status.state === "verifying" || status.state === "error") {
4615
+ return false;
4616
+ }
4617
+ if (isExplicitInvalidation(status.error)) {
4618
+ return true;
4619
+ }
4620
+ return status.state === "inactive" || status.state === "locked";
4621
+ }
3953
4622
 
3954
4623
  // ../../packages/runtime-profiles/src/profiles/profile-manager.ts
3955
- var import_node_crypto3 = require("crypto");
4624
+ var import_node_crypto6 = require("crypto");
3956
4625
  var import_fs = require("fs");
3957
4626
  var import_path = __toESM(require("path"), 1);
3958
4627
  var import_path2 = require("path");
@@ -4005,7 +4674,7 @@ function resolveProfileIdentityKeyFromProfile(profile) {
4005
4674
  }
4006
4675
 
4007
4676
  // ../../packages/runtime-codex/src/codex/rpc.ts
4008
- var import_node_child_process2 = require("child_process");
4677
+ var import_node_child_process4 = require("child_process");
4009
4678
  var import_node_readline = __toESM(require("readline"), 1);
4010
4679
  var import_node_fs3 = require("fs");
4011
4680
  var import_node_os2 = __toESM(require("os"), 1);
@@ -4137,7 +4806,7 @@ async function requireCodexCli() {
4137
4806
  }
4138
4807
 
4139
4808
  // ../../packages/runtime-codex/src/codex/command.ts
4140
- var import_node_child_process = require("child_process");
4809
+ var import_node_child_process3 = require("child_process");
4141
4810
  var import_node_path4 = __toESM(require("path"), 1);
4142
4811
  var cachedNodeRuntime = null;
4143
4812
  function isJavaScriptEntrypoint(binaryPath) {
@@ -4180,7 +4849,7 @@ function resolveNodeRuntime(env) {
4180
4849
  )
4181
4850
  );
4182
4851
  for (const candidate of candidates) {
4183
- const probe = (0, import_node_child_process.spawnSync)(candidate, ["-v"], { env: runtimeEnv, stdio: "ignore" });
4852
+ const probe = (0, import_node_child_process3.spawnSync)(candidate, ["-v"], { env: runtimeEnv, stdio: "ignore" });
4184
4853
  if (!probe.error && probe.status === 0) {
4185
4854
  cachedNodeRuntime = candidate;
4186
4855
  return candidate;
@@ -4862,7 +5531,7 @@ function parseRateLimitSnapshotFromOAuthUsage(value) {
4862
5531
  }
4863
5532
  return {
4864
5533
  lastUpdated: (/* @__PURE__ */ new Date()).toISOString(),
4865
- source: "codex-oauth",
5534
+ source: "codex-oauth-estimate",
4866
5535
  ...primary ? { primary } : {},
4867
5536
  ...secondary ? { secondary } : {},
4868
5537
  ...extraWindows.length > 0 ? { extraWindows } : {}
@@ -5059,7 +5728,7 @@ async function fetchRateLimitsViaRpc(envOverride, options = {}) {
5059
5728
  ["-s", "read-only", "-a", "untrusted", "app-server"],
5060
5729
  childEnv
5061
5730
  );
5062
- const child = (0, import_node_child_process2.spawn)(command.command, command.args, {
5731
+ const child = (0, import_node_child_process4.spawn)(command.command, command.args, {
5063
5732
  stdio: ["pipe", "pipe", "pipe"],
5064
5733
  env: childEnv,
5065
5734
  shell: command.shell
@@ -5169,7 +5838,7 @@ async function activateResetWindowViaRpc(envOverride, options = {}) {
5169
5838
  ["-s", "read-only", "-a", "untrusted", "app-server"],
5170
5839
  childEnv
5171
5840
  );
5172
- const child = (0, import_node_child_process2.spawn)(command.command, command.args, {
5841
+ const child = (0, import_node_child_process4.spawn)(command.command, command.args, {
5173
5842
  stdio: ["pipe", "pipe", "pipe"],
5174
5843
  env: childEnv,
5175
5844
  shell: command.shell
@@ -5633,7 +6302,7 @@ var ProfileManager = class {
5633
6302
  if (!trimmed) {
5634
6303
  return this.emptyAuthSnapshot();
5635
6304
  }
5636
- const fingerprint = (0, import_node_crypto3.createHash)("sha256").update(trimmed).digest("hex");
6305
+ const fingerprint = (0, import_node_crypto6.createHash)("sha256").update(trimmed).digest("hex");
5637
6306
  try {
5638
6307
  const parsed = JSON.parse(trimmed);
5639
6308
  const normalized = this.normalizeProfileData(parsed);
@@ -7048,6 +7717,25 @@ var ProfileManager = class {
7048
7717
  });
7049
7718
  }
7050
7719
  }
7720
+ async readConfirmedRateLimits(name, options = {}) {
7721
+ const profileName = this.normalizeProfileName(name);
7722
+ try {
7723
+ return await this.enqueueProfileOperation(
7724
+ profileName,
7725
+ () => this.runWithPreparedProfileHome(
7726
+ profileName,
7727
+ (env) => fetchRateLimitsViaRpc(env, { codexPath: options.codexPath }),
7728
+ { syncFromActiveAuthBeforeAction: false }
7729
+ )
7730
+ );
7731
+ } finally {
7732
+ await this.enqueueAuthSwap(async () => {
7733
+ await this.syncActiveAuthFromProfileIfCurrent(profileName);
7734
+ }).catch((error) => {
7735
+ logWarn(`Failed to sync active auth after rate-limit confirmation for '${profileName}':`, error);
7736
+ });
7737
+ }
7738
+ }
7051
7739
  async activateResetWindow(name, options = {}) {
7052
7740
  const profileName = this.normalizeProfileName(name);
7053
7741
  try {
@@ -7266,7 +7954,7 @@ var ProfileManager = class {
7266
7954
  }
7267
7955
  if (options.canAutoImport === false) {
7268
7956
  return this.buildActiveCodexAuthStatus("unmanaged", description, {
7269
- importBlockedReason: options.importBlockedReason ?? "Profile limit reached. Upgrade to CodexUse Pro or remove a profile before importing this Codex login."
7957
+ importBlockedReason: options.importBlockedReason ?? "Your CodexUse trial has ended. Upgrade to Pro before importing this Codex login."
7270
7958
  });
7271
7959
  }
7272
7960
  const records = await this.listProfileRecords();
@@ -7454,7 +8142,7 @@ Flags:
7454
8142
  --runtime=NAME Accounts Pool runtime store: desktop
7455
8143
  --state-dir=PATH Override the runtime state dir for Accounts Pool inspection
7456
8144
  --passphrase-stdin Read Cloud Sync passphrase from stdin
7457
- Note: profile autoroll requires Pro.
8145
+ Note: profile autoroll requires Pro or an active trial.
7458
8146
  Cloud Sync: set CODEXUSE_SYNC_PASSPHRASE or use --passphrase-stdin unless the passphrase is saved in Keychain.
7459
8147
  `);
7460
8148
  }
@@ -7506,7 +8194,7 @@ function parseStringFlag(flags, name) {
7506
8194
 
7507
8195
  // src/commands/accountPool.ts
7508
8196
  var ACCOUNT_POOL_DOCUMENT = "desktop.account-pool.v2";
7509
- var ACCOUNT_POOL_PRO_REQUIRED_MESSAGE = "Accounts Pool requires a Pro license.";
8197
+ var ACCOUNT_POOL_PRO_REQUIRED_MESSAGE = "Accounts Pool requires a Pro license or an active trial.";
7510
8198
  var DESKTOP_RPC_STATE_DIR = "desktop-rpc";
7511
8199
  var ACCOUNT_POOL_STORE_VERSION = 3;
7512
8200
  var MAX_RESPONSE_IDS_PER_SESSION = 64;
@@ -7894,13 +8582,13 @@ async function listApiKeys(stateDir) {
7894
8582
  return Object.values(store.apiKeysById).filter((key) => key.revokedAt === null).sort((left, right) => right.createdAt.localeCompare(left.createdAt)).map(accountPoolApiKeyView);
7895
8583
  }
7896
8584
  function hashToken(token) {
7897
- return (0, import_node_crypto4.createHash)("sha256").update(token).digest("hex");
8585
+ return (0, import_node_crypto7.createHash)("sha256").update(token).digest("hex");
7898
8586
  }
7899
8587
  async function createApiKey(stateDir) {
7900
- const plaintextToken = `cux_pool_${(0, import_node_crypto4.randomBytes)(24).toString("hex")}`;
8588
+ const plaintextToken = `cux_pool_${(0, import_node_crypto7.randomBytes)(24).toString("hex")}`;
7901
8589
  const now = (/* @__PURE__ */ new Date()).toISOString();
7902
8590
  const keyRecord = {
7903
- id: (0, import_node_crypto4.randomUUID)(),
8591
+ id: (0, import_node_crypto7.randomUUID)(),
7904
8592
  tokenHash: hashToken(plaintextToken),
7905
8593
  tokenPreview: `${plaintextToken.slice(0, 8)}...${plaintextToken.slice(-6)}`,
7906
8594
  createdAt: now,
@@ -7994,7 +8682,7 @@ async function readAccountPoolRuntimeSummary(input = {}) {
7994
8682
  stateDir,
7995
8683
  baseUrl: resolveBaseUrlFromPort(runtime, input.port ?? null),
7996
8684
  enabled: normalized.accountPoolEnabled,
7997
- hasProLicense: license?.isPro === true,
8685
+ hasAccountPoolAccess: license?.capabilities.accountPool === true,
7998
8686
  routingStrategy: normalized.accountPoolRoutingStrategy,
7999
8687
  activeApiKeyCount: apiKeys.length,
8000
8688
  activeSessionCount: sessions.length
@@ -8011,7 +8699,7 @@ async function updateSettings(transform) {
8011
8699
  const { raw, normalized } = await readSettingsSnapshot();
8012
8700
  const nextSettings = transform(normalized);
8013
8701
  const license = await licenseService.getStatus().catch(() => null);
8014
- const forcedDisabledByLicense = !license?.isPro && nextSettings.accountPoolEnabled === true;
8702
+ const forcedDisabledByLicense = license?.capabilities.accountPool !== true && nextSettings.accountPoolEnabled === true;
8015
8703
  const sanitizedSettings = {
8016
8704
  ...nextSettings,
8017
8705
  accountPoolEnabled: forcedDisabledByLicense ? false : nextSettings.accountPoolEnabled,
@@ -8038,7 +8726,7 @@ async function updateSettings(transform) {
8038
8726
  }
8039
8727
  async function requireProAccess() {
8040
8728
  const license = await licenseService.getStatus();
8041
- if (!license.isPro) {
8729
+ if (!license.capabilities.accountPool) {
8042
8730
  throw new Error(ACCOUNT_POOL_PRO_REQUIRED_MESSAGE);
8043
8731
  }
8044
8732
  }
@@ -8100,7 +8788,7 @@ async function handleStatus(flags) {
8100
8788
  console.log(`Runtime: ${runtime}`);
8101
8789
  console.log(`State dir: ${stateDir}`);
8102
8790
  console.log(`Routing: ${formatRoutingStrategy(normalized.accountPoolRoutingStrategy)}`);
8103
- console.log(`Public API ready: ${normalized.accountPoolEnabled && license?.isPro === true && apiKeys.length > 0 ? "yes" : "no"}`);
8791
+ console.log(`Public API ready: ${normalized.accountPoolEnabled && license?.capabilities.accountPool === true && apiKeys.length > 0 ? "yes" : "no"}`);
8104
8792
  console.log(`API keys: ${apiKeys.length}`);
8105
8793
  console.log(`Sessions: ${sessions.length}`);
8106
8794
  console.log(`Selection mode: ${explicitSelection.length > 0 ? "explicit" : "all saved profiles"}`);
@@ -8116,7 +8804,7 @@ async function handleStatus(flags) {
8116
8804
  printStringList("Published models", normalized.accountPoolExposedModels);
8117
8805
  printStringList("Reasoning aliases", normalized.accountPoolExposedReasoningEfforts);
8118
8806
  printStringList("Fast-mode aliases", normalized.accountPoolExposedFastModeReasoningEfforts);
8119
- if (normalized.accountPoolEnabled && license?.isPro !== true) {
8807
+ if (normalized.accountPoolEnabled && license?.capabilities.accountPool !== true) {
8120
8808
  console.log(ACCOUNT_POOL_PRO_REQUIRED_MESSAGE);
8121
8809
  }
8122
8810
  }
@@ -8321,7 +9009,7 @@ async function handleQuickstart(flags) {
8321
9009
  console.log("Accounts Pool quickstart");
8322
9010
  console.log(`Runtime: ${summary.runtime}`);
8323
9011
  console.log(`Enabled: ${summary.enabled ? "yes" : "no"}`);
8324
- console.log(`Pro: ${summary.hasProLicense ? "yes" : "no"}`);
9012
+ console.log(`Access: ${summary.hasAccountPoolAccess ? "yes" : "no"}`);
8325
9013
  console.log(`API keys: ${summary.activeApiKeyCount}`);
8326
9014
  console.log(`Base URL: ${baseUrl}`);
8327
9015
  console.log("");
@@ -8405,7 +9093,7 @@ async function handleAccountPoolCommand(args, version) {
8405
9093
  }
8406
9094
 
8407
9095
  // src/commands/codex.ts
8408
- var import_node_child_process4 = require("child_process");
9096
+ var import_node_child_process6 = require("child_process");
8409
9097
 
8410
9098
  // ../../packages/runtime-profiles/src/profiles/rate-limit-notifier.ts
8411
9099
  function maxUsedPercent(snapshot) {
@@ -8414,8 +9102,7 @@ function maxUsedPercent(snapshot) {
8414
9102
  }
8415
9103
  const candidates = [
8416
9104
  snapshot.primary?.usedPercent,
8417
- snapshot.secondary?.usedPercent,
8418
- ...(snapshot.extraWindows ?? []).map((window) => window.usedPercent)
9105
+ snapshot.secondary?.usedPercent
8419
9106
  ].filter((value) => typeof value === "number" && Number.isFinite(value));
8420
9107
  if (candidates.length === 0) {
8421
9108
  return null;
@@ -8423,8 +9110,108 @@ function maxUsedPercent(snapshot) {
8423
9110
  return Math.max(...candidates);
8424
9111
  }
8425
9112
 
9113
+ // ../../packages/runtime-profiles/src/profiles/profile-visibility.ts
9114
+ function resolveLicenseVisibleProfiles(args) {
9115
+ const { profiles, license, currentProfile } = args;
9116
+ const licenseWithCounts = licenseService.applyProfileCount(license, profiles.length);
9117
+ const enforceProfileLimit = shouldEnforceProfileLimit(licenseWithCounts);
9118
+ const visibleProfiles = enforceProfileLimit ? resolveVisibleProfiles(profiles, licenseWithCounts, currentProfile) : profiles;
9119
+ return {
9120
+ allProfiles: profiles,
9121
+ profiles: licenseWithCounts.capabilities.unlimitedProfiles ? profiles : visibleProfiles,
9122
+ license,
9123
+ licenseWithCounts,
9124
+ enforceProfileLimit
9125
+ };
9126
+ }
9127
+ async function loadLicenseVisibleProfiles(profileManager, options = {}) {
9128
+ await profileManager.initialize();
9129
+ const license = options.freshLicense ? await licenseService.getStatus() : await licenseService.getCachedStatus();
9130
+ const profiles = await profileManager.listProfiles();
9131
+ const currentProfile = options.currentProfile !== void 0 ? options.currentProfile : (await profileManager.getCurrentProfile()).name;
9132
+ return resolveLicenseVisibleProfiles({
9133
+ profiles,
9134
+ license,
9135
+ currentProfile
9136
+ });
9137
+ }
9138
+ function resolveVisibleProfiles(profiles, license, currentProfile) {
9139
+ if (license.capabilities.unlimitedProfiles) {
9140
+ return profiles;
9141
+ }
9142
+ const limit = typeof license.profileLimit === "number" && license.profileLimit >= 0 ? license.profileLimit : FREE_PROFILE_LIMIT;
9143
+ if (profiles.length <= limit) {
9144
+ return profiles;
9145
+ }
9146
+ const normalizedCurrent = currentProfile ?? null;
9147
+ const sorted = profiles.slice().sort((a, b) => compareProfilesForLimit(a, b, normalizedCurrent));
9148
+ return sorted.slice(0, limit);
9149
+ }
9150
+ function compareProfilesForLimit(a, b, currentProfile) {
9151
+ if (currentProfile) {
9152
+ if (a.name === currentProfile && b.name !== currentProfile) {
9153
+ return -1;
9154
+ }
9155
+ if (b.name === currentProfile && a.name !== currentProfile) {
9156
+ return 1;
9157
+ }
9158
+ }
9159
+ if (Boolean(a.isValid) !== Boolean(b.isValid)) {
9160
+ return a.isValid ? -1 : 1;
9161
+ }
9162
+ const aTimestamp = parseTimestamp3(a.createdAt ?? null);
9163
+ const bTimestamp = parseTimestamp3(b.createdAt ?? null);
9164
+ if (aTimestamp !== null && bTimestamp !== null) {
9165
+ if (aTimestamp === bTimestamp) {
9166
+ return a.name.localeCompare(b.name);
9167
+ }
9168
+ return bTimestamp - aTimestamp;
9169
+ }
9170
+ if (aTimestamp !== null) {
9171
+ return -1;
9172
+ }
9173
+ if (bTimestamp !== null) {
9174
+ return 1;
9175
+ }
9176
+ return a.name.localeCompare(b.name);
9177
+ }
9178
+ function parseTimestamp3(value) {
9179
+ if (typeof value !== "string" || value.trim() === "") {
9180
+ return null;
9181
+ }
9182
+ const parsed = Date.parse(value);
9183
+ return Number.isNaN(parsed) ? null : parsed;
9184
+ }
9185
+
9186
+ // ../../packages/runtime-profiles/src/license/guard.ts
9187
+ var PROFILE_ACCESS_DENIED_MESSAGE = "Your CodexUse trial has ended. Upgrade to Pro to use saved profiles.";
9188
+ async function assertProfileCreationAllowed(profileManager) {
9189
+ const manager = profileManager ?? new ProfileManager();
9190
+ await manager.initialize();
9191
+ const license = await licenseService.getStatus();
9192
+ const profiles = await manager.listProfiles();
9193
+ const licenseWithCounts = licenseService.applyProfileCount(license, profiles.length);
9194
+ if (typeof licenseWithCounts.profileLimit === "number" && licenseWithCounts.profilesRemaining !== null && licenseWithCounts.profilesRemaining <= 0) {
9195
+ throw new Error("Your CodexUse trial has ended. Upgrade to Pro for unlimited profiles.");
9196
+ }
9197
+ }
9198
+ async function assertProfileAccessAllowed(profileManager, profileName) {
9199
+ const name = profileName.trim();
9200
+ if (!name) {
9201
+ throw new Error("Profile name is required.");
9202
+ }
9203
+ const visible = await loadLicenseVisibleProfiles(profileManager, {
9204
+ freshLicense: true
9205
+ });
9206
+ const exists = visible.allProfiles.some((profile) => profile.name === name);
9207
+ const allowed = visible.profiles.some((profile) => profile.name === name);
9208
+ if (exists && !allowed) {
9209
+ throw new Error(PROFILE_ACCESS_DENIED_MESSAGE);
9210
+ }
9211
+ }
9212
+
8426
9213
  // src/platform/codexCli.ts
8427
- var import_node_child_process3 = require("child_process");
9214
+ var import_node_child_process5 = require("child_process");
8428
9215
  var import_node_fs5 = require("fs");
8429
9216
  var import_node_path8 = __toESM(require("path"));
8430
9217
  var ENV_HINTS2 = ["CODEX_BINARY", "CODEX_CLI_PATH", "CODEX_PATH"];
@@ -8496,7 +9283,7 @@ async function runCodexLogin(mode) {
8496
9283
  const resolvedMode = resolveLoginMode(mode ?? null);
8497
9284
  const loginArgs = resolvedMode === "device" ? ["login", "--device-auth"] : ["login"];
8498
9285
  const { command, args, shell } = buildCodexCommand2(codexPath, loginArgs);
8499
- const child = (0, import_node_child_process3.spawn)(command, args, {
9286
+ const child = (0, import_node_child_process5.spawn)(command, args, {
8500
9287
  stdio: "inherit",
8501
9288
  env: process.env,
8502
9289
  shell
@@ -8544,8 +9331,7 @@ function formatUsagePercent(value) {
8544
9331
  function snapshotResetSeconds(snapshot) {
8545
9332
  const values = [
8546
9333
  snapshot?.primary?.resetsInSeconds,
8547
- snapshot?.secondary?.resetsInSeconds,
8548
- ...(snapshot?.extraWindows ?? []).map((window) => window.resetsInSeconds)
9334
+ snapshot?.secondary?.resetsInSeconds
8549
9335
  ].filter((value) => typeof value === "number" && Number.isFinite(value));
8550
9336
  return values.length > 0 ? Math.min(...values) : null;
8551
9337
  }
@@ -8569,7 +9355,7 @@ function compareCandidates(left, right) {
8569
9355
  async function runCommand(codexPath, args, timeoutMs) {
8570
9356
  const command = buildCodexCommand2(codexPath, args);
8571
9357
  return new Promise((resolve) => {
8572
- const child = (0, import_node_child_process4.spawn)(command.command, command.args, {
9358
+ const child = (0, import_node_child_process6.spawn)(command.command, command.args, {
8573
9359
  env: process.env,
8574
9360
  shell: command.shell,
8575
9361
  stdio: ["ignore", "pipe", "pipe"]
@@ -8630,12 +9416,13 @@ async function runCodexWithProfile(manager, profileName, codexArgs) {
8630
9416
  if (!codexPath) {
8631
9417
  throw new Error("Codex CLI not found. Install Codex CLI or set CODEX_BINARY.");
8632
9418
  }
9419
+ await assertProfileAccessAllowed(manager, profileName);
8633
9420
  const runtime = await manager.prepareProfileRuntime(profileName, {
8634
9421
  syncFromActiveAuthBeforeAction: false
8635
9422
  });
8636
9423
  const command = buildCodexCommand2(codexPath, codexArgs);
8637
9424
  try {
8638
- const child = (0, import_node_child_process4.spawn)(command.command, command.args, {
9425
+ const child = (0, import_node_child_process6.spawn)(command.command, command.args, {
8639
9426
  env: runtime.env,
8640
9427
  shell: command.shell,
8641
9428
  stdio: "inherit"
@@ -8736,7 +9523,7 @@ async function handleBestCommand(args) {
8736
9523
  console.log(`Usage:
8737
9524
  codexuse best -- <codex args>
8738
9525
 
8739
- Picks the healthiest saved profile, then runs Codex. Auto-run requires Pro.`);
9526
+ Picks the healthiest saved profile, then runs Codex. Auto-run requires Pro or an active trial.`);
8740
9527
  return;
8741
9528
  }
8742
9529
  const codexPath = resolveCodexBinary();
@@ -8744,20 +9531,17 @@ Picks the healthiest saved profile, then runs Codex. Auto-run requires Pro.`);
8744
9531
  throw new Error("Codex CLI not found. Install Codex CLI or set CODEX_BINARY.");
8745
9532
  }
8746
9533
  const manager = new ProfileManager();
8747
- const profiles = await manager.listProfiles();
9534
+ const visible = await loadLicenseVisibleProfiles(manager, { freshLicense: true });
9535
+ if (!visible.licenseWithCounts.capabilities.autoRoll) {
9536
+ throw new Error("Auto-run requires Pro or an active trial.");
9537
+ }
9538
+ const profiles = visible.profiles;
8748
9539
  const best = await selectBestProfile(manager, profiles, codexPath);
8749
9540
  if (!best) {
8750
9541
  throw new Error("No valid saved profiles found. Add one with `codexuse profile add <name>`.");
8751
9542
  }
8752
9543
  const dryRun = hasFlag(flags, "--dry-run");
8753
- const license = await licenseService.getStatus();
8754
9544
  const summary = `${best.profile.name} (${formatUsagePercent(best.usedPercent)} used)`;
8755
- if (!license.isPro) {
8756
- console.log(`Best profile: ${summary}`);
8757
- console.log("Auto-run is Pro. Free path:");
8758
- console.log(` codexuse run --profile ${best.profile.name} -- ${codexArgs.join(" ")}`.trimEnd());
8759
- return;
8760
- }
8761
9545
  if (dryRun) {
8762
9546
  console.log(`Would run with profile: ${summary}`);
8763
9547
  return;
@@ -8815,21 +9599,9 @@ async function handleLicense(args, version) {
8815
9599
  }
8816
9600
  }
8817
9601
 
8818
- // ../../packages/runtime-profiles/src/license/guard.ts
8819
- async function assertProfileCreationAllowed(profileManager) {
8820
- const manager = profileManager ?? new ProfileManager();
8821
- await manager.initialize();
8822
- const license = await licenseService.getStatus();
8823
- const profiles = await manager.listProfiles();
8824
- const licenseWithCounts = licenseService.applyProfileCount(license, profiles.length);
8825
- if (typeof licenseWithCounts.profileLimit === "number" && licenseWithCounts.profilesRemaining !== null && licenseWithCounts.profilesRemaining <= 0) {
8826
- throw new Error("CodexUse Free supports up to 2 profiles. Upgrade to CodexUse Pro for unlimited profiles.");
8827
- }
8828
- }
8829
-
8830
9602
  // ../../packages/runtime-codex/src/codex/officialAppRestart.ts
8831
- var import_node_child_process5 = require("child_process");
8832
- var import_node_crypto5 = require("crypto");
9603
+ var import_node_child_process7 = require("child_process");
9604
+ var import_node_crypto8 = require("crypto");
8833
9605
  var import_node_fs7 = require("fs");
8834
9606
  var import_node_os3 = require("os");
8835
9607
  var import_node_net = __toESM(require("net"), 1);
@@ -9104,7 +9876,7 @@ function hashProfileKey(profileKey) {
9104
9876
  if (!profileKey) {
9105
9877
  return null;
9106
9878
  }
9107
- return (0, import_node_crypto5.createHash)("sha256").update(profileKey).digest("hex").slice(0, 12);
9879
+ return (0, import_node_crypto8.createHash)("sha256").update(profileKey).digest("hex").slice(0, 12);
9108
9880
  }
9109
9881
  function sanitizeOfficialCodexOverlayActionTargetsForRenderer(targets) {
9110
9882
  const sanitized = [];
@@ -9727,6 +10499,7 @@ function buildInCodexStatusOverlayCssRules() {
9727
10499
  `${chip} .codexuse-handoff-main{display:inline-flex;align-items:center;padding:5px 8px 5px 10px;border-radius:999px;cursor:pointer;}`,
9728
10500
  `${chip} .codexuse-handoff-hide{display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;margin-right:3px;border-radius:50%;color:var(--cu-muted);cursor:pointer;font-size:12px;line-height:1;}`,
9729
10501
  `${chip} .codexuse-handoff-hide:hover{background:var(--cu-border);color:var(--cu-fg,#ececf1);}`,
10502
+ `body>[data-radix-popper-content-wrapper],body>[data-floating-ui-portal]{z-index:2147483004!important;}`,
9730
10503
  // Hand-off account picker is a standalone body child (not inside the pill),
9731
10504
  // so the pill-scoped popover rules don't reach it — give it its own palette
9732
10505
  // + popover styling, mirroring the chip.
@@ -12656,7 +13429,7 @@ async function runCdpCommandSequence(debuggerUrl, commands, timeoutMs = CODEX_CD
12656
13429
  });
12657
13430
  }
12658
13431
  async function verifyCdpBindingRoundTrip(debuggerUrl) {
12659
- const nonce = (0, import_node_crypto5.randomUUID)();
13432
+ const nonce = (0, import_node_crypto8.randomUUID)();
12660
13433
  const expression = `(() => {
12661
13434
  const binding = window[${JSON.stringify(CODEXUSE_BRIDGE_BINDING_NAME)}];
12662
13435
  if (typeof binding !== "function") return false;
@@ -13429,7 +14202,7 @@ async function recordOfficialCodexActivity(input) {
13429
14202
  }
13430
14203
  function runCommand2(command, args, timeoutMs = COMMAND_TIMEOUT_MS) {
13431
14204
  return new Promise((resolve) => {
13432
- const child = (0, import_node_child_process5.spawn)(command, args, {
14205
+ const child = (0, import_node_child_process7.spawn)(command, args, {
13433
14206
  stdio: ["ignore", "pipe", "pipe"]
13434
14207
  });
13435
14208
  let stdout = "";
@@ -13728,7 +14501,7 @@ async function openCodexWithProfileHome(candidate, profileHome, profileName, cdp
13728
14501
  if (appUserDataDir) {
13729
14502
  (0, import_node_fs7.mkdirSync)(appUserDataDir, { recursive: true });
13730
14503
  }
13731
- child = (0, import_node_child_process5.spawn)(
14504
+ child = (0, import_node_child_process7.spawn)(
13732
14505
  "/usr/bin/open",
13733
14506
  [
13734
14507
  "-n",
@@ -14507,6 +15280,13 @@ function formatProfileLabel(name, displayName) {
14507
15280
  }
14508
15281
  return name;
14509
15282
  }
15283
+ var AUTO_ROLL_ACCESS_REQUIRED_MESSAGE = "Auto-roll requires a Pro license or an active trial.";
15284
+ async function assertAutoRollAccess() {
15285
+ const license = await licenseService.getStatus();
15286
+ if (!license.capabilities.autoRoll) {
15287
+ throw new Error(AUTO_ROLL_ACCESS_REQUIRED_MESSAGE);
15288
+ }
15289
+ }
14510
15290
  function profileRateLimitKey(profile) {
14511
15291
  return resolveProfileIdentityKeyFromProfile(profile);
14512
15292
  }
@@ -15163,6 +15943,7 @@ async function collectUsageMap(manager, profiles, codexPath) {
15163
15943
  return usageMap;
15164
15944
  }
15165
15945
  async function runAutoRollPass(manager, options) {
15946
+ await assertAutoRollAccess();
15166
15947
  const profiles = await manager.listProfiles();
15167
15948
  if (!profiles.length) {
15168
15949
  return { switched: false, message: "No profiles found.", source: null, target: null };
@@ -15287,9 +16068,13 @@ async function handleProfileCommand(args, version) {
15287
16068
  const manager = new ProfileManager();
15288
16069
  switch (sub) {
15289
16070
  case "list": {
15290
- const profiles = await manager.listProfiles();
16071
+ const visible = await loadLicenseVisibleProfiles(manager, { freshLicense: true });
16072
+ const profiles = visible.profiles;
15291
16073
  const current = await manager.getCurrentProfile();
15292
16074
  if (!profiles.length) {
16075
+ if (visible.allProfiles.length) {
16076
+ throw new Error(PROFILE_ACCESS_DENIED_MESSAGE);
16077
+ }
15293
16078
  console.log("No profiles found.");
15294
16079
  return;
15295
16080
  }
@@ -15331,6 +16116,7 @@ async function handleProfileCommand(args, version) {
15331
16116
  console.log("No active profile.");
15332
16117
  return;
15333
16118
  }
16119
+ await assertProfileAccessAllowed(manager, current.name);
15334
16120
  console.log(current.name);
15335
16121
  return;
15336
16122
  }
@@ -15354,6 +16140,7 @@ async function handleProfileCommand(args, version) {
15354
16140
  if (!name) {
15355
16141
  throw new Error("Profile name is required.");
15356
16142
  }
16143
+ await assertProfileAccessAllowed(manager, name);
15357
16144
  if (!hasFlag(flags, "--skip-login")) {
15358
16145
  const loginMode = resolveLoginMode(parseLoginMode(flags));
15359
16146
  await runCodexLogin(loginMode);
@@ -15368,6 +16155,7 @@ async function handleProfileCommand(args, version) {
15368
16155
  if (!name) {
15369
16156
  throw new Error("Profile name is required.");
15370
16157
  }
16158
+ await assertProfileAccessAllowed(manager, name);
15371
16159
  const activateOfficialCodex = resolveActivateCodexFlag(flags, false);
15372
16160
  const profiles = await manager.listProfiles();
15373
16161
  const targetProfileKey = findProfileKey(profiles, name);
@@ -15387,10 +16175,7 @@ async function handleProfileCommand(args, version) {
15387
16175
  }
15388
16176
  case "autoroll":
15389
16177
  case "auto-roll": {
15390
- const license = await licenseService.getStatus();
15391
- if (!license.isPro) {
15392
- throw new Error("Auto-roll requires a Pro license.");
15393
- }
16178
+ await assertAutoRollAccess();
15394
16179
  const watch = hasFlag(flags, "--watch");
15395
16180
  const dryRun = hasFlag(flags, "--dry-run");
15396
16181
  const settings = await getStoredAutoRollSettings().catch(() => null);
@@ -15470,6 +16255,7 @@ async function handleProfileCommand(args, version) {
15470
16255
  if (!from || !to) {
15471
16256
  throw new Error("Old and new profile names are required.");
15472
16257
  }
16258
+ await assertProfileAccessAllowed(manager, from);
15473
16259
  await manager.renameProfile(from, to);
15474
16260
  console.log(`Profile renamed: ${from} -> ${to}`);
15475
16261
  return;
@@ -15598,7 +16384,7 @@ function normalizeSnapshot(value) {
15598
16384
  settingsJson
15599
16385
  };
15600
16386
  }
15601
- async function requestJson(method, pathname, licenseKey, body, rawBody) {
16387
+ async function requestJson(method, pathname, access, body, rawBody) {
15602
16388
  const controller = new AbortController();
15603
16389
  const timeout = setTimeout(() => controller.abort(), CLOUD_SYNC_TIMEOUT_MS);
15604
16390
  try {
@@ -15606,7 +16392,10 @@ async function requestJson(method, pathname, licenseKey, body, rawBody) {
15606
16392
  method,
15607
16393
  headers: {
15608
16394
  "Content-Type": "application/json",
15609
- "x-codexuse-license-key": licenseKey
16395
+ "x-codexuse-license-key": access.syncKey,
16396
+ ...access.trialDeviceId ? { "x-codexuse-trial-device-id": access.trialDeviceId } : {},
16397
+ ...access.trialToken ? { "x-codexuse-trial-token": access.trialToken } : {},
16398
+ ...access.trialMigration ? { "x-codexuse-sync-migrate-trial": "1" } : {}
15610
16399
  },
15611
16400
  body: typeof rawBody === "string" ? rawBody : body === void 0 ? void 0 : JSON.stringify(body),
15612
16401
  signal: controller.signal
@@ -15633,15 +16422,15 @@ async function requestJson(method, pathname, licenseKey, body, rawBody) {
15633
16422
  clearTimeout(timeout);
15634
16423
  }
15635
16424
  }
15636
- async function fetchRemoteSnapshot(licenseKey) {
15637
- const response = await requestJson("GET", "/v1/sync/snapshot", licenseKey);
16425
+ async function fetchRemoteSnapshot(access) {
16426
+ const response = await requestJson("GET", "/v1/sync/snapshot", access);
15638
16427
  return normalizeSnapshot(response.snapshot);
15639
16428
  }
15640
- async function fetchRemoteSnapshotMeta(licenseKey) {
16429
+ async function fetchRemoteSnapshotMeta(access) {
15641
16430
  const response = await requestJson(
15642
16431
  "GET",
15643
16432
  "/v1/sync/snapshot/meta",
15644
- licenseKey
16433
+ access
15645
16434
  );
15646
16435
  const updatedAt = toIsoOrNull(response.updatedAt);
15647
16436
  const snapshotKind = normalizeSnapshotKind(response.snapshotKind);
@@ -15650,12 +16439,12 @@ async function fetchRemoteSnapshotMeta(licenseKey) {
15650
16439
  snapshotKind: updatedAt && response.snapshotKind === void 0 ? "legacy-plaintext" : snapshotKind
15651
16440
  };
15652
16441
  }
15653
- async function pushRemoteSnapshot(licenseKey, snapshot, options) {
16442
+ async function pushRemoteSnapshot(access, snapshot, options) {
15654
16443
  const serializedSnapshot = typeof options?.serializedSnapshot === "string" ? options.serializedSnapshot : JSON.stringify(snapshot);
15655
16444
  const response = await requestJson(
15656
16445
  "PUT",
15657
16446
  "/v1/sync/snapshot",
15658
- licenseKey,
16447
+ access,
15659
16448
  void 0,
15660
16449
  `{"snapshot":${serializedSnapshot}}`
15661
16450
  );
@@ -15674,8 +16463,8 @@ async function pushRemoteSnapshot(licenseKey, snapshot, options) {
15674
16463
  var import_toml3 = __toESM(require_toml(), 1);
15675
16464
 
15676
16465
  // ../../packages/runtime-codex/src/codex/config-metadata.ts
15677
- var import_node_child_process6 = require("child_process");
15678
- var import_promises = require("fs/promises");
16466
+ var import_node_child_process8 = require("child_process");
16467
+ var import_promises2 = require("fs/promises");
15679
16468
  var import_node_path11 = __toESM(require("path"), 1);
15680
16469
  var CONFIG_SCHEMA_URL = "https://raw.githubusercontent.com/openai/codex/main/codex-rs/core/config.schema.json";
15681
16470
  var METADATA_CACHE_TTL_MS = 6e4;
@@ -15786,7 +16575,7 @@ function uniqueSorted(values) {
15786
16575
  }
15787
16576
  async function runCommand3(command, args, timeoutMs = 3e3) {
15788
16577
  return new Promise((resolve, reject) => {
15789
- const child = (0, import_node_child_process6.spawn)(command, args, {
16578
+ const child = (0, import_node_child_process8.spawn)(command, args, {
15790
16579
  stdio: ["ignore", "pipe", "pipe"],
15791
16580
  env: process.env
15792
16581
  });
@@ -15867,7 +16656,7 @@ async function readSchemaFromLocal() {
15867
16656
  ].filter((candidate) => Boolean(candidate));
15868
16657
  for (const candidate of candidates) {
15869
16658
  try {
15870
- return await (0, import_promises.readFile)(candidate, "utf8");
16659
+ return await (0, import_promises2.readFile)(candidate, "utf8");
15871
16660
  } catch {
15872
16661
  }
15873
16662
  }
@@ -15967,7 +16756,7 @@ async function getCodexConfigMetadata(forceRefresh = false) {
15967
16756
  }
15968
16757
 
15969
16758
  // ../../packages/runtime-codex/src/codex/config-io.ts
15970
- var import_promises2 = require("fs/promises");
16759
+ var import_promises3 = require("fs/promises");
15971
16760
  var import_node_path13 = __toESM(require("path"), 1);
15972
16761
 
15973
16762
  // ../../packages/runtime-codex/src/codex/home.ts
@@ -16077,7 +16866,7 @@ function getConfigPath(options) {
16077
16866
  }
16078
16867
  async function ensureConfigDirExists(filePath) {
16079
16868
  const dir = import_node_path13.default.dirname(filePath);
16080
- await (0, import_promises2.mkdir)(dir, { recursive: true });
16869
+ await (0, import_promises3.mkdir)(dir, { recursive: true });
16081
16870
  }
16082
16871
  function normalizeLineEndings(content) {
16083
16872
  return content.replace(/\r\n/g, "\n");
@@ -16089,7 +16878,7 @@ function ensureTrailingNewline(content) {
16089
16878
  async function readConfigContent(options) {
16090
16879
  const configPath = getConfigPath(options);
16091
16880
  try {
16092
- const content = await (0, import_promises2.readFile)(configPath, "utf8");
16881
+ const content = await (0, import_promises3.readFile)(configPath, "utf8");
16093
16882
  return {
16094
16883
  exists: true,
16095
16884
  content: normalizeLineEndings(content)
@@ -16109,14 +16898,14 @@ async function writeConfigContent(content, options) {
16109
16898
  const configPath = getConfigPath(options);
16110
16899
  await ensureConfigDirExists(configPath);
16111
16900
  const normalized = ensureTrailingNewline(normalizeLineEndings(content));
16112
- await (0, import_promises2.writeFile)(configPath, normalized, "utf8");
16901
+ await (0, import_promises3.writeFile)(configPath, normalized, "utf8");
16113
16902
  }
16114
16903
  async function getUpdatedAt(configPath, exists) {
16115
16904
  if (!exists) {
16116
16905
  return null;
16117
16906
  }
16118
16907
  try {
16119
- const stats = await (0, import_promises2.stat)(configPath);
16908
+ const stats = await (0, import_promises3.stat)(configPath);
16120
16909
  return stats.mtimeMs;
16121
16910
  } catch (error) {
16122
16911
  const nodeError = error;
@@ -16630,10 +17419,10 @@ async function saveCodexConfigContent(content, options) {
16630
17419
  }
16631
17420
 
16632
17421
  // ../../packages/runtime-profiles/src/cloud-sync/encryption.ts
16633
- var import_node_child_process7 = require("child_process");
16634
- var import_node_crypto6 = require("crypto");
16635
- var KEYCHAIN_SERVICE = "CODEXUSE_CLOUD_SYNC_PASSPHRASE";
16636
- var KEYCHAIN_ACCOUNT_PREFIX = "license-sha256:";
17422
+ var import_node_child_process9 = require("child_process");
17423
+ var import_node_crypto9 = require("crypto");
17424
+ var KEYCHAIN_SERVICE2 = "CODEXUSE_CLOUD_SYNC_PASSPHRASE";
17425
+ var KEYCHAIN_ACCOUNT_PREFIX2 = "license-sha256:";
16637
17426
  var ENCRYPTION_AAD = Buffer.from("codexuse-cloud-sync-v2", "utf8");
16638
17427
  var SCRYPT_PARAMS = {
16639
17428
  N: 32768,
@@ -16656,7 +17445,7 @@ function requireCloudSyncPassphrase(value) {
16656
17445
  }
16657
17446
  async function deriveKey(passphrase, salt, params = SCRYPT_PARAMS) {
16658
17447
  return new Promise((resolve, reject) => {
16659
- (0, import_node_crypto6.scrypt)(passphrase, salt, params.keyLength, {
17448
+ (0, import_node_crypto9.scrypt)(passphrase, salt, params.keyLength, {
16660
17449
  N: params.N,
16661
17450
  r: params.r,
16662
17451
  p: params.p,
@@ -16693,10 +17482,10 @@ function normalizeDecryptedSnapshot(value) {
16693
17482
  };
16694
17483
  }
16695
17484
  async function encryptCloudSyncSnapshot(snapshot, passphrase) {
16696
- const salt = (0, import_node_crypto6.randomBytes)(16);
16697
- const iv = (0, import_node_crypto6.randomBytes)(12);
17485
+ const salt = (0, import_node_crypto9.randomBytes)(16);
17486
+ const iv = (0, import_node_crypto9.randomBytes)(12);
16698
17487
  const key = await deriveKey(requireCloudSyncPassphrase(passphrase), salt);
16699
- const cipher = (0, import_node_crypto6.createCipheriv)("aes-256-gcm", key, iv);
17488
+ const cipher = (0, import_node_crypto9.createCipheriv)("aes-256-gcm", key, iv);
16700
17489
  cipher.setAAD(ENCRYPTION_AAD);
16701
17490
  const plaintext = Buffer.from(JSON.stringify(snapshot), "utf8");
16702
17491
  const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
@@ -16723,7 +17512,7 @@ async function decryptCloudSyncSnapshot(snapshot, passphrase) {
16723
17512
  const tag = fromBase64(snapshot.encryption.tag);
16724
17513
  const ciphertext = fromBase64(snapshot.encryption.ciphertext);
16725
17514
  const key = await deriveKey(requireCloudSyncPassphrase(passphrase), salt, snapshot.encryption.kdfParams);
16726
- const decipher = (0, import_node_crypto6.createDecipheriv)("aes-256-gcm", key, iv);
17515
+ const decipher = (0, import_node_crypto9.createDecipheriv)("aes-256-gcm", key, iv);
16727
17516
  decipher.setAAD(ENCRYPTION_AAD);
16728
17517
  decipher.setAuthTag(tag);
16729
17518
  const plaintext = Buffer.concat([decipher.update(ciphertext), decipher.final()]);
@@ -16738,12 +17527,12 @@ async function decryptCloudSyncSnapshot(snapshot, passphrase) {
16738
17527
  }
16739
17528
  }
16740
17529
  function keychainAccountForLicense(licenseKey) {
16741
- const digest = (0, import_node_crypto6.createHash)("sha256").update(licenseKey).digest("hex");
16742
- return KEYCHAIN_ACCOUNT_PREFIX + digest;
17530
+ const digest = (0, import_node_crypto9.createHash)("sha256").update(licenseKey).digest("hex");
17531
+ return KEYCHAIN_ACCOUNT_PREFIX2 + digest;
16743
17532
  }
16744
- function runSecurityCommand(args) {
17533
+ function runSecurityCommand2(args) {
16745
17534
  return new Promise((resolve, reject) => {
16746
- const child = (0, import_node_child_process7.spawn)("security", args, { stdio: ["ignore", "pipe", "ignore"] });
17535
+ const child = (0, import_node_child_process9.spawn)("security", args, { stdio: ["ignore", "pipe", "ignore"] });
16747
17536
  let stdout = "";
16748
17537
  child.stdout?.on("data", (chunk) => {
16749
17538
  stdout += String(chunk);
@@ -16760,12 +17549,12 @@ async function readRememberedCloudSyncPassphrase(licenseKey) {
16760
17549
  if (process.platform !== "darwin") {
16761
17550
  return null;
16762
17551
  }
16763
- const result = await runSecurityCommand([
17552
+ const result = await runSecurityCommand2([
16764
17553
  "find-generic-password",
16765
17554
  "-a",
16766
17555
  keychainAccountForLicense(licenseKey),
16767
17556
  "-s",
16768
- KEYCHAIN_SERVICE,
17557
+ KEYCHAIN_SERVICE2,
16769
17558
  "-w"
16770
17559
  ]);
16771
17560
  if (result.code !== 0) {
@@ -16778,13 +17567,13 @@ async function writeRememberedCloudSyncPassphrase(licenseKey, passphrase) {
16778
17567
  throw new Error("keychain-unsupported");
16779
17568
  }
16780
17569
  const value = requireCloudSyncPassphrase(passphrase);
16781
- const result = await runSecurityCommand([
17570
+ const result = await runSecurityCommand2([
16782
17571
  "add-generic-password",
16783
17572
  "-U",
16784
17573
  "-a",
16785
17574
  keychainAccountForLicense(licenseKey),
16786
17575
  "-s",
16787
- KEYCHAIN_SERVICE,
17576
+ KEYCHAIN_SERVICE2,
16788
17577
  "-w",
16789
17578
  value
16790
17579
  ]);
@@ -16863,31 +17652,144 @@ async function writeState(patch) {
16863
17652
  async function resolveEligibility() {
16864
17653
  const stored = await getStoredLicense();
16865
17654
  const licenseKey = typeof stored?.licenseKey === "string" ? stored.licenseKey.trim() : "";
16866
- if (!licenseKey) {
17655
+ const status = await licenseService.getStatus();
17656
+ if (licenseKey && status.isPro) {
17657
+ const active = status.state === "active" || status.state === "grace";
17658
+ if (active) {
17659
+ await migrateTrialCloudSyncToPaidLicenseSafe(licenseKey);
17660
+ }
16867
17661
  return {
16868
- canSync: false,
16869
- reason: "License key is required for cloud sync.",
16870
- licenseKey: null,
16871
- licenseState: null
17662
+ canSync: active,
17663
+ canDelete: active,
17664
+ reason: active ? null : "Cloud sync requires an active Pro license.",
17665
+ access: active ? { syncKey: licenseKey } : null,
17666
+ hasPaidLicenseKey: true,
17667
+ licenseState: status.state
16872
17668
  };
16873
17669
  }
16874
- const status = await licenseService.getStatus();
16875
- const active = status.state === "active" || status.state === "grace";
16876
- if (!active) {
17670
+ if (status.trial?.active && status.capabilities.cloudSync) {
17671
+ const trialAccess = await resolveTrialCloudSyncAccess();
17672
+ if (trialAccess) {
17673
+ return {
17674
+ canSync: true,
17675
+ canDelete: true,
17676
+ reason: null,
17677
+ access: trialAccess,
17678
+ hasPaidLicenseKey: false,
17679
+ licenseState: status.state
17680
+ };
17681
+ }
16877
17682
  return {
16878
17683
  canSync: false,
16879
- reason: "Cloud sync requires an active Pro license.",
16880
- licenseKey,
17684
+ canDelete: false,
17685
+ reason: "Cloud sync trial identity is unavailable.",
17686
+ access: null,
17687
+ hasPaidLicenseKey: false,
16881
17688
  licenseState: status.state
16882
17689
  };
16883
17690
  }
17691
+ if (status.trial?.expired) {
17692
+ const trialAccess = await resolveTrialCloudSyncAccess();
17693
+ if (trialAccess) {
17694
+ return {
17695
+ canSync: false,
17696
+ canDelete: true,
17697
+ reason: "Cloud sync requires an active trial or Pro license.",
17698
+ access: trialAccess,
17699
+ hasPaidLicenseKey: false,
17700
+ licenseState: status.state
17701
+ };
17702
+ }
17703
+ }
16884
17704
  return {
16885
- canSync: true,
16886
- reason: null,
16887
- licenseKey,
17705
+ canSync: false,
17706
+ canDelete: false,
17707
+ reason: "Cloud sync requires an active trial or Pro license.",
17708
+ access: null,
17709
+ hasPaidLicenseKey: false,
16888
17710
  licenseState: status.state
16889
17711
  };
16890
17712
  }
17713
+ async function hasRemoteSnapshot(access) {
17714
+ const meta = await fetchRemoteSnapshotMeta(access);
17715
+ return meta.snapshotKind !== "none" || Boolean(meta.updatedAt);
17716
+ }
17717
+ async function readRemoteSnapshotOrNull(access) {
17718
+ try {
17719
+ return await fetchRemoteSnapshot(access);
17720
+ } catch (error) {
17721
+ if (error instanceof CloudSyncClientError && (error.status === 403 || error.status === 404)) {
17722
+ return null;
17723
+ }
17724
+ throw error;
17725
+ }
17726
+ }
17727
+ async function migrateTrialPassphraseToPaidLicense(trialKey, licenseKey) {
17728
+ const paidPassphrase = await readRememberedCloudSyncPassphrase(licenseKey).catch(() => null);
17729
+ if (paidPassphrase) {
17730
+ return;
17731
+ }
17732
+ const trialPassphrase = await readRememberedCloudSyncPassphrase(trialKey).catch(() => null);
17733
+ if (!trialPassphrase) {
17734
+ return;
17735
+ }
17736
+ await writeRememberedCloudSyncPassphrase(licenseKey, trialPassphrase);
17737
+ }
17738
+ async function migrateTrialCloudSyncToPaidLicense(licenseKey) {
17739
+ const paidLicenseKey = licenseKey.trim();
17740
+ if (!paidLicenseKey) {
17741
+ return;
17742
+ }
17743
+ const trialAccess = await resolveTrialCloudSyncAccess();
17744
+ if (!trialAccess || trialAccess.syncKey === paidLicenseKey) {
17745
+ return;
17746
+ }
17747
+ if (await hasRemoteSnapshot({ syncKey: paidLicenseKey })) {
17748
+ await migrateTrialPassphraseToPaidLicense(trialAccess.syncKey, paidLicenseKey).catch((error) => {
17749
+ logWarn("[cloud-sync] failed to migrate remembered trial passphrase", {
17750
+ error: error instanceof Error ? error.message : String(error)
17751
+ });
17752
+ });
17753
+ return;
17754
+ }
17755
+ const trialSnapshot = await readRemoteSnapshotOrNull({
17756
+ ...trialAccess,
17757
+ syncKey: paidLicenseKey,
17758
+ trialMigration: true
17759
+ });
17760
+ if (trialSnapshot) {
17761
+ await pushRemoteSnapshot({ syncKey: paidLicenseKey }, trialSnapshot, {
17762
+ serializedSnapshot: JSON.stringify(trialSnapshot)
17763
+ });
17764
+ }
17765
+ await migrateTrialPassphraseToPaidLicense(trialAccess.syncKey, paidLicenseKey);
17766
+ }
17767
+ async function migrateTrialCloudSyncToPaidLicenseSafe(licenseKey) {
17768
+ try {
17769
+ await migrateTrialCloudSyncToPaidLicense(licenseKey);
17770
+ } catch (error) {
17771
+ logWarn("[cloud-sync] trial snapshot migration to paid license failed", {
17772
+ error: error instanceof Error ? error.message : String(error)
17773
+ });
17774
+ }
17775
+ }
17776
+ async function resolveTrialCloudSyncAccess() {
17777
+ let deviceId;
17778
+ try {
17779
+ deviceId = await getDeviceId();
17780
+ } catch {
17781
+ return null;
17782
+ }
17783
+ const trialToken = await readStoredTrialToken(deviceId).catch(() => null);
17784
+ if (!trialToken) {
17785
+ return null;
17786
+ }
17787
+ return {
17788
+ syncKey: `trial:${deviceId}`,
17789
+ trialDeviceId: deviceId,
17790
+ trialToken
17791
+ };
17792
+ }
16891
17793
  function formatMegabytes(bytes) {
16892
17794
  return (bytes / MB_DIVISOR).toFixed(2);
16893
17795
  }
@@ -16980,19 +17882,19 @@ async function getCloudSyncStatus() {
16980
17882
  let remoteUpdatedAt = state.remoteUpdatedAt ?? null;
16981
17883
  let remoteKind = state.remoteKind ?? "none";
16982
17884
  let hasRememberedPassphrase = false;
16983
- if (eligibility.canSync && eligibility.licenseKey) {
17885
+ if (eligibility.canSync && eligibility.access) {
16984
17886
  hasRememberedPassphrase = Boolean(
16985
- await readRememberedCloudSyncPassphrase(eligibility.licenseKey).catch(() => null)
17887
+ await readRememberedCloudSyncPassphrase(eligibility.access.syncKey).catch(() => null)
16986
17888
  );
16987
17889
  try {
16988
- const remoteMeta = await fetchRemoteSnapshotMeta(eligibility.licenseKey);
17890
+ const remoteMeta = await fetchRemoteSnapshotMeta(eligibility.access);
16989
17891
  remoteUpdatedAt = remoteMeta.updatedAt;
16990
17892
  remoteKind = remoteMeta.snapshotKind;
16991
17893
  await writeState({ remoteUpdatedAt, remoteKind });
16992
17894
  } catch (error) {
16993
17895
  if (error instanceof CloudSyncClientError && error.status === 404) {
16994
17896
  try {
16995
- const remote = await fetchRemoteSnapshot(eligibility.licenseKey);
17897
+ const remote = await fetchRemoteSnapshot(eligibility.access);
16996
17898
  remoteUpdatedAt = remote?.updatedAt ?? null;
16997
17899
  remoteKind = getSnapshotKind(remote);
16998
17900
  } catch {
@@ -17002,9 +17904,10 @@ async function getCloudSyncStatus() {
17002
17904
  }
17003
17905
  return {
17004
17906
  canSync: eligibility.canSync,
17907
+ canDelete: eligibility.canDelete,
17005
17908
  reason: eligibility.reason,
17006
17909
  licenseState: eligibility.licenseState,
17007
- hasLicenseKey: Boolean(eligibility.licenseKey),
17910
+ hasLicenseKey: eligibility.hasPaidLicenseKey,
17008
17911
  hasRememberedPassphrase,
17009
17912
  lastPushAt: state.lastPushAt ?? null,
17010
17913
  lastPullAt: state.lastPullAt ?? null,
@@ -17015,7 +17918,7 @@ async function getCloudSyncStatus() {
17015
17918
  }
17016
17919
  async function pushCloudSync(options = {}) {
17017
17920
  const eligibility = await resolveEligibility();
17018
- if (!eligibility.canSync || !eligibility.licenseKey) {
17921
+ if (!eligibility.canSync || !eligibility.access) {
17019
17922
  return {
17020
17923
  mode: "push",
17021
17924
  status: "skipped",
@@ -17028,7 +17931,7 @@ async function pushCloudSync(options = {}) {
17028
17931
  try {
17029
17932
  await profileManager.initialize();
17030
17933
  const localSnapshot = await buildLocalSnapshot(profileManager, { enforcePushGuards: true });
17031
- const passphrase = await resolvePassphrase(eligibility.licenseKey, options);
17934
+ const passphrase = await resolvePassphrase(eligibility.access.syncKey, options);
17032
17935
  const encryptedSnapshot = await encryptCloudSyncSnapshot(localSnapshot, passphrase.value);
17033
17936
  const serializedSnapshot = JSON.stringify(encryptedSnapshot);
17034
17937
  const snapshotBytes = Buffer.byteLength(serializedSnapshot, "utf8");
@@ -17046,7 +17949,7 @@ async function pushCloudSync(options = {}) {
17046
17949
  if (process.env.NODE_ENV !== "production") {
17047
17950
  logInfo("[cloud-sync] push snapshot summary", summarizeSnapshot(localSnapshot));
17048
17951
  }
17049
- const remote = await pushRemoteSnapshot(eligibility.licenseKey, encryptedSnapshot, {
17952
+ const remote = await pushRemoteSnapshot(eligibility.access, encryptedSnapshot, {
17050
17953
  serializedSnapshot
17051
17954
  });
17052
17955
  const remoteKind = getSnapshotKind(remote.snapshot);
@@ -17065,7 +17968,7 @@ async function pushCloudSync(options = {}) {
17065
17968
  remoteUpdatedAt: remote.snapshot.updatedAt
17066
17969
  };
17067
17970
  }
17068
- await rememberPassphraseIfRequested(eligibility.licenseKey, options, passphrase);
17971
+ await rememberPassphraseIfRequested(eligibility.access.syncKey, options, passphrase);
17069
17972
  return {
17070
17973
  mode: "push",
17071
17974
  status: "applied",
@@ -17082,7 +17985,7 @@ async function pushCloudSync(options = {}) {
17082
17985
  }
17083
17986
  async function pullCloudSync(options = {}) {
17084
17987
  const eligibility = await resolveEligibility();
17085
- if (!eligibility.canSync || !eligibility.licenseKey) {
17988
+ if (!eligibility.canSync || !eligibility.access) {
17086
17989
  return {
17087
17990
  mode: "pull",
17088
17991
  status: "skipped",
@@ -17094,7 +17997,7 @@ async function pullCloudSync(options = {}) {
17094
17997
  const profileManager = new ProfileManager();
17095
17998
  try {
17096
17999
  await profileManager.initialize();
17097
- const remote = await fetchRemoteSnapshot(eligibility.licenseKey);
18000
+ const remote = await fetchRemoteSnapshot(eligibility.access);
17098
18001
  if (!remote) {
17099
18002
  await writeState({ remoteUpdatedAt: null, remoteKind: "none" });
17100
18003
  return {
@@ -17109,7 +18012,7 @@ async function pullCloudSync(options = {}) {
17109
18012
  let passphrase = null;
17110
18013
  let plainSnapshot;
17111
18014
  if (remote.schemaVersion === CLOUD_SYNC_ENCRYPTED_SCHEMA_VERSION) {
17112
- passphrase = await resolvePassphrase(eligibility.licenseKey, options);
18015
+ passphrase = await resolvePassphrase(eligibility.access.syncKey, options);
17113
18016
  plainSnapshot = await decryptCloudSyncSnapshot(remote, passphrase.value);
17114
18017
  } else {
17115
18018
  plainSnapshot = remote;
@@ -17122,7 +18025,7 @@ async function pullCloudSync(options = {}) {
17122
18025
  lastError: void 0
17123
18026
  });
17124
18027
  if (passphrase) {
17125
- await rememberPassphraseIfRequested(eligibility.licenseKey, options, passphrase);
18028
+ await rememberPassphraseIfRequested(eligibility.access.syncKey, options, passphrase);
17126
18029
  }
17127
18030
  return {
17128
18031
  mode: "pull",
@@ -17235,7 +18138,7 @@ async function ensureCliStorageReady() {
17235
18138
  }
17236
18139
 
17237
18140
  // src/app/main.ts
17238
- var VERSION = true ? "5.0.9" : "0.0.0";
18141
+ var VERSION = true ? "5.1.1" : "0.0.0";
17239
18142
  async function runCli() {
17240
18143
  const args = process.argv.slice(2);
17241
18144
  if (args.length === 0) {