codexuse-cli 3.1.2 → 3.1.4

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.
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
- import { $ as encode, $a as CurrentLogAnnotations, $i as isDone, $n as all, $o as strictEqual, $r as runPromiseWith, $t as run$2, A as NonEmptyString, Aa as flatMap$1, Ai as clamp, An as publish, Ao as makeEquivalence, Ar as ignoreCause, At as FileSystem, B as Tuple, Ba as scope, Bi as provideMerge, Bn as transform$1, Bo as fromNullishOr, Br as matchCauseEffect, Bt as fail$5, C as Defect, Ca as andThen$1, Ci as void_$1, Cn as make$24, Co as fromIterable$2, Cr as forEach, Cs as constVoid, Ct as withConstructorDefault, D as Literal, Da as consolePretty$1, Di as zipWith, Dn as shutdown, Do as map$4, Dr as forkScoped, Ds as pipeArguments, Dt as Path$1, E as Int, Ea as causePretty, Ei as withSpan, En as offerUnsafe, Eo as makeEquivalence$1, Er as forkIn, Es as pipe, Et as omit, F as String$1, Fa as formatLogSpan, Fi as effectDiscard, Fo as failVoid, Fr as logError$1, Ft as callback$1, G as brand, Ga as succeed$3, Gi as addFinalizer, Gn as makeFormatterDefault, Go as isSome, Gr as orElseSucceed, Gt as fromPubSub, H as Union, Ha as servicesWith, Hi as sync$2, Hn as parseJson, Ho as getOrNull, Hr as never, Ht as fromChannel$1, I as Struct, Ia as gen$1, In as BadArgument, Io as getOrThrow, Ir as logInfo$1, It as concat, J as decodeExit, Ja as sync$1, Ji as provide$2, Jn as formatIso, Jo as none$3, Jr as provideService, Jt as isStream, K as declare, Ka as succeedNone, Ki as close, Kn as make$32, Ko as map$5, Kr as promise, Kt as fromQueue, L as TaggedErrorClass, La as ignore$1, Li as empty$6, Ln as badArgument, Lo as isFailure$1, Lr as logWarning$1, Lt as decodeText, M as NullOr, Ma as forever$1, Mi as Error$1, Mn as make$21, Mo as filterMap, Mr as isEffect, Mt as Size, N as Number$1, Na as forkDetach, Ni as TaggedError, Nn as set$4, No as makeEquivalence$2, Nr as log$1, Nt as WatchBackend, O as Literals, Oa as defaultLogger$1, Oi as catchDone, On as take, Oo as of, Or as gen, Ot as TypeId$17, P as Record, Pa as formatLabel, Pi as effect, Pn as makeUnsafe$1, Po as fail$3, Pr as logDebug, Pt as make$22, Q as decodeUnknownSync, Qa as void_$2, Qi as failCause$1, Qn as addFinalizer$1, Qo as make$33, Qr as runPromise, Qt as onExit$1, R as TemplateLiteral, Ra as loggerMake, Ri as mergeAll, Rn as systemError, Ro as succeed$4, Rr as map$3, S as DateValid, Sa as addFinalizer$2, Si as useSpan, Sn as failCauseUnsafe, So as flatMapNullishOr, Sr as fnUntraced, Ss as constTrue, St as toType, T as Finite, Ta as asSome, Ti as withParentSpan, Tn as offerAll, To as isReadonlyArrayNonEmpty, Tr as forkChild, Ts as identity, Tt as assign, U as Unknown, Ua as sleep, Ui as unwrap$1, Un as stringifyJson, Uo as getOrUndefined, Ur as onInterrupt, Ut as fromEffect, V as URLFromString, Va as scopeAddFinalizerExit, Vi as succeed$2, Vn as transformOrFail, Vo as getOrElse, Vr as matchEffect, Vt as flatMap$2, W as Void, Wa as structuredMessage, Wi as Scope, Wn as InvalidValue$1, Wo as isNone, Wr as orDie, Wt as fromIterable$1, X as decodeUnknownEffect, Xa as uninterruptibleMask, Xi as doneUnsafe, Xn as acquireRelease, Xo as Number$2, Xr as result, Xt as merge$1, Y as decodeTo, Ya as tracerLogger$1, Yi as _await, Yn as now, Yo as some, Yr as provideServices, Yt as make$31, Z as decodeUnknownExit, Za as updateServices, Zi as fail$4, Zn as acquireUseRelease, Zo as make$27, Zr as runFork, Zt as mkString, _a as squash, _i as tryPromise, _n as make$25, _o as toMillis, _r as fail$1, _s as isNotNull, _t as optional$2, aa as isFailure, ai as services, an as toReadableStreamEffect, ar as cached, as as BaseProto, at as isGreaterThan, b as Array$1, ba as CurrentLoggers$1, bi as uninterruptibleMask$1, bn as size, bo as ensure, br as flatMap, bs as isUndefined, bt as toCodecStringTree, c as FalseValues, ca as void_$3, ci as succeed, cn as get$2, cr as catchDefect, cs as format$1, ct as isMaxLength, d as boolean$3, da as UnknownError, di as sync, dn as fromChannel, do as fromInputUnsafe, dr as catchTags, ds as symbolRedactable, dt as isNonEmpty, ea as make$28, ei as runSync, en as runCollect, eo as CurrentLogSpans, er as andThen, es as PipeInspectableProto, et as encodeEffect, f as map$7, fa as done, fi as tap, fn as isSink, fo as infinity, fr as catch_, fs as symbol, ft as isPattern, g as string$3, ga as pretty, gi as timeoutOrElse, gn as get$3, go as seconds, gr as exit, gs as hasProperty, gt as mutable, h as port, ha as hasInterruptsOnly, hi as timeoutOption, hn as make$30, ho as minutes, hr as ensuring, hs as symbol$1, ht as makeFilter, ia as hasInterrupts$1, ii as serviceOption, in as suspend$3, io as Service, ir as asVoid, is as withFiber, it as isBetween, j as Null, ja as fnUntraced$1, ji as Class, jn as unbounded$1, jo as map$6, jr as interrupt, jt as FileTypeId, k as NonEmptyArray, ka as fiberInterrupt, ki as Random$1, kn as unbounded, ko as sort, kr as ignore, kt as FileDescriptor, l as TrueValues, la as Done, li as succeedNone$1, ln as make$23, lo as make$26, lr as catchFilter, ls as formatJson$1, lt as isMaxProperties, m as option, ma as hasInterrupts, mi as tapError, mn as mapDone, mo as isZero, mr as effectify, ms as structure, mt as link$1, n as SqlClient, na as succeed$5, ni as scoped, nn as runForEach, no as DisablePropagation, nr as as, ns as exitSucceed, nt as fromJsonString, oa as isSuccess, oi as servicesWith$1, on as transduce, oo as empty$5, or as callback, os as Class$1, ot as isGreaterThanOrEqualTo, p as number, pa as fail$2, pi as tapCause, pn as fromTransform, po as isFinite$1, pr as die, ps as array, pt as isSchemaError, q as decodeEffect, qa as suspend$1, qi as make$29, qn as encodeBase64Url, qo as match, qr as provide, qt as fromReadableStream, ra as fail, ri as service, rn as splitLines, ro as Reference, rr as asSome$1, rs as isEffect$1, rt as is, s as Boolean$1, sa as succeed$1, si as sleep$1, sn as unwrap, so as get$4, sr as catchCause, ss as NodeInspectSymbol, st as isLessThanOrEqualTo, ta as makeUnsafe$2, tn as runFold, to as MinimumLogLevel, tr as annotateLogs, ts as YieldableProto, tt as encodeUnknownEffect, u as all$1, ua as NoSuchElementError, ui as suspend, un as drain, uo as merge$2, ur as catchTag, us as redact$1, ut as isMinLength, v as url, va as ClockRef, vi as try_, vn as remove$2, vo as toSeconds, vr as failCause, vs as isNotUndefined, vt as suspend$2, w as ErrorClass, wa as as$1, wi as withFiber$1, wn as offer$1, wo as isArray, wr as forever, ws as dual, wt as withDecodingDefault, x as Boolean$2, xa as LogToStderr$1, xi as updateServices$1, xn as endUnsafe, xo as filter, xr as fn, xs as constFalse, xt as toJsonSchemaDocument, y as withDefault$2, ya as ConsoleRef, yi as uninterruptible, yn as set$3, yo as zero, yr as filterOrFail, ys as isNullish, yt as tag, z as Trim, za as onExit, zi as provide$1, zn as nominal, zo as filter$1, zr as mapError, zt as empty$4 } from "./SqlClient-CB8oPtuH.mjs";
3
+ import { $ as encode, $a as CurrentLogAnnotations, $i as isDone, $n as all, $o as strictEqual, $r as runPromiseWith, $t as run$2, A as NonEmptyString, Aa as flatMap$1, Ai as clamp, An as publish, Ao as makeEquivalence, Ar as ignoreCause, At as FileSystem, B as Tuple, Ba as scope, Bi as provideMerge, Bn as transform$1, Bo as fromNullishOr, Br as matchCauseEffect, Bt as fail$5, C as Defect, Ca as andThen$1, Ci as void_$1, Cn as make$24, Co as fromIterable$2, Cr as forEach, Cs as constVoid, Ct as withConstructorDefault, D as Literal, Da as consolePretty$1, Di as zipWith, Dn as shutdown, Do as map$4, Dr as forkScoped, Ds as pipeArguments, Dt as Path$1, E as Int, Ea as causePretty, Ei as withSpan, En as offerUnsafe, Eo as makeEquivalence$1, Er as forkIn, Es as pipe, Et as omit, F as String$1, Fa as formatLogSpan, Fi as effectDiscard, Fo as failVoid, Fr as logError$1, Ft as callback$1, G as brand, Ga as succeed$3, Gi as addFinalizer, Gn as makeFormatterDefault, Go as isSome, Gr as orElseSucceed, Gt as fromPubSub, H as Union, Ha as servicesWith, Hi as sync$2, Hn as parseJson, Ho as getOrNull, Hr as never, Ht as fromChannel$1, I as Struct, Ia as gen$1, In as BadArgument, Io as getOrThrow, Ir as logInfo$1, It as concat, J as decodeExit, Ja as sync$1, Ji as provide$2, Jn as formatIso, Jo as none$3, Jr as provideService, Jt as isStream, K as declare, Ka as succeedNone, Ki as close, Kn as make$32, Ko as map$5, Kr as promise, Kt as fromQueue, L as TaggedErrorClass, La as ignore$1, Li as empty$6, Ln as badArgument, Lo as isFailure$1, Lr as logWarning$1, Lt as decodeText, M as NullOr, Ma as forever$1, Mi as Error$1, Mn as make$21, Mo as filterMap, Mr as isEffect, Mt as Size, N as Number$1, Na as forkDetach, Ni as TaggedError, Nn as set$4, No as makeEquivalence$2, Nr as log$1, Nt as WatchBackend, O as Literals, Oa as defaultLogger$1, Oi as catchDone, On as take, Oo as of, Or as gen, Ot as TypeId$17, P as Record, Pa as formatLabel, Pi as effect, Pn as makeUnsafe$1, Po as fail$3, Pr as logDebug, Pt as make$22, Q as decodeUnknownSync, Qa as void_$2, Qi as failCause$1, Qn as addFinalizer$1, Qo as make$33, Qr as runPromise, Qt as onExit$1, R as TemplateLiteral, Ra as loggerMake, Ri as mergeAll, Rn as systemError, Ro as succeed$4, Rr as map$3, S as DateValid, Sa as addFinalizer$2, Si as useSpan, Sn as failCauseUnsafe, So as flatMapNullishOr, Sr as fnUntraced, Ss as constTrue, St as toType, T as Finite, Ta as asSome, Ti as withParentSpan, Tn as offerAll, To as isReadonlyArrayNonEmpty, Tr as forkChild, Ts as identity, Tt as assign, U as Unknown, Ua as sleep$1, Ui as unwrap$1, Un as stringifyJson, Uo as getOrUndefined, Ur as onInterrupt, Ut as fromEffect, V as URLFromString, Va as scopeAddFinalizerExit, Vi as succeed$2, Vn as transformOrFail, Vo as getOrElse, Vr as matchEffect, Vt as flatMap$2, W as Void, Wa as structuredMessage, Wi as Scope, Wn as InvalidValue$1, Wo as isNone, Wr as orDie, Wt as fromIterable$1, X as decodeUnknownEffect, Xa as uninterruptibleMask, Xi as doneUnsafe, Xn as acquireRelease, Xo as Number$2, Xr as result, Xt as merge$1, Y as decodeTo, Ya as tracerLogger$1, Yi as _await, Yn as now, Yo as some, Yr as provideServices, Yt as make$31, Z as decodeUnknownExit, Za as updateServices, Zi as fail$4, Zn as acquireUseRelease, Zo as make$27, Zr as runFork, Zt as mkString, _a as squash, _i as tryPromise, _n as make$25, _o as toMillis, _r as fail$1, _s as isNotNull, _t as optional$2, aa as isFailure, ai as services, an as toReadableStreamEffect, ar as cached, as as BaseProto, at as isGreaterThan, b as Array$1, ba as CurrentLoggers$1, bi as uninterruptibleMask$1, bn as size, bo as ensure, br as flatMap, bs as isUndefined, bt as toCodecStringTree, c as FalseValues, ca as void_$3, ci as succeed, cn as get$2, cr as catchDefect, cs as format$1, ct as isMaxLength, d as boolean$3, da as UnknownError, di as sync, dn as fromChannel, do as fromInputUnsafe, dr as catchTags, ds as symbolRedactable, dt as isNonEmpty, ea as make$28, ei as runSync, en as runCollect, eo as CurrentLogSpans, er as andThen, es as PipeInspectableProto, et as encodeEffect, f as map$7, fa as done, fi as tap, fn as isSink, fo as infinity, fr as catch_, fs as symbol, ft as isPattern, g as string$3, ga as pretty, gi as timeoutOrElse, gn as get$3, go as seconds, gr as exit, gs as hasProperty, gt as mutable, h as port, ha as hasInterruptsOnly, hi as timeoutOption, hn as make$30, ho as minutes, hr as ensuring, hs as symbol$1, ht as makeFilter, ia as hasInterrupts$1, ii as serviceOption, in as suspend$3, io as Service, ir as asVoid, is as withFiber, it as isBetween, j as Null, ja as fnUntraced$1, ji as Class, jn as unbounded$1, jo as map$6, jr as interrupt, jt as FileTypeId, k as NonEmptyArray, ka as fiberInterrupt, ki as Random$1, kn as unbounded, ko as sort, kr as ignore, kt as FileDescriptor, l as TrueValues, la as Done, li as succeedNone$1, ln as make$23, lo as make$26, lr as catchFilter, ls as formatJson$1, lt as isMaxProperties, m as option, ma as hasInterrupts, mi as tapError, mn as mapDone, mo as isZero, mr as effectify, ms as structure, mt as link$1, n as SqlClient, na as succeed$5, ni as scoped, nn as runForEach, no as DisablePropagation, nr as as, ns as exitSucceed, nt as fromJsonString, oa as isSuccess, oi as servicesWith$1, on as transduce, oo as empty$5, or as callback, os as Class$1, ot as isGreaterThanOrEqualTo, p as number, pa as fail$2, pi as tapCause, pn as fromTransform, po as isFinite$1, pr as die, ps as array, pt as isSchemaError, q as decodeEffect, qa as suspend$1, qi as make$29, qn as encodeBase64Url, qo as match, qr as provide, qt as fromReadableStream, ra as fail, ri as service, rn as splitLines, ro as Reference, rr as asSome$1, rs as isEffect$1, rt as is, s as Boolean$1, sa as succeed$1, si as sleep$2, sn as unwrap, so as get$4, sr as catchCause, ss as NodeInspectSymbol, st as isLessThanOrEqualTo, ta as makeUnsafe$2, tn as runFold, to as MinimumLogLevel, tr as annotateLogs, ts as YieldableProto, tt as encodeUnknownEffect, u as all$1, ua as NoSuchElementError, ui as suspend, un as drain, uo as merge$2, ur as catchTag, us as redact$1, ut as isMinLength, v as url, va as ClockRef, vi as try_, vn as remove$2, vo as toSeconds, vr as failCause, vs as isNotUndefined, vt as suspend$2, w as ErrorClass, wa as as$1, wi as withFiber$1, wn as offer$1, wo as isArray, wr as forever, ws as dual, wt as withDecodingDefault, x as Boolean$2, xa as LogToStderr$1, xi as updateServices$1, xn as endUnsafe, xo as filter, xr as fn, xs as constFalse, xt as toJsonSchemaDocument, y as withDefault$2, ya as ConsoleRef, yi as uninterruptible, yn as set$3, yo as zero, yr as filterOrFail, ys as isNullish, yt as tag, z as Trim, za as onExit, zi as provide$1, zn as nominal, zo as filter$1, zr as mapError, zt as empty$4 } from "./SqlClient-CB8oPtuH.mjs";
4
4
  import { createRequire } from "node:module";
5
5
  import * as NodeChildProcess from "node:child_process";
6
6
  import { execFileSync, spawn, spawnSync } from "node:child_process";
@@ -2754,7 +2754,7 @@ const batched = /* @__PURE__ */ dual(2, (self, options) => flatMap$1(scope, (sco
2754
2754
  buffer = [];
2755
2755
  return options.flush(arr);
2756
2756
  });
2757
- return uninterruptibleMask((restore) => restore(sleep(options.window).pipe(andThen$1(flush), forever$1)).pipe(forkDetach, flatMap$1((fiber) => scopeAddFinalizerExit(scope, () => fiberInterrupt(fiber))), andThen$1(addFinalizer$2(() => flush)), as$1(loggerMake((options) => {
2757
+ return uninterruptibleMask((restore) => restore(sleep$1(options.window).pipe(andThen$1(flush), forever$1)).pipe(forkDetach, flatMap$1((fiber) => scopeAddFinalizerExit(scope, () => fiberInterrupt(fiber))), andThen$1(addFinalizer$2(() => flush)), as$1(loggerMake((options) => {
2758
2758
  buffer.push(self.log(options));
2759
2759
  }))));
2760
2760
  }));
@@ -28589,6 +28589,9 @@ function normalizeCommitMessagePrompt(value) {
28589
28589
  const APP_STORAGE_TABLE = "app_storage_documents";
28590
28590
  const APP_STORAGE_DB_DIR = "t3-projects";
28591
28591
  const APP_STORAGE_DB_NAME = "state.sqlite";
28592
+ const SQLITE_BUSY_TIMEOUT_MS = 5e3;
28593
+ const SQLITE_BUSY_MAX_ATTEMPTS = 3;
28594
+ const SQLITE_BUSY_RETRY_DELAY_MS = 100;
28592
28595
  const initializedDbPaths = /* @__PURE__ */ new Set();
28593
28596
  function isRecord$9(value) {
28594
28597
  return Boolean(value) && typeof value === "object" && !Array.isArray(value);
@@ -28604,6 +28607,15 @@ function safeParseJson(raw) {
28604
28607
  return null;
28605
28608
  }
28606
28609
  }
28610
+ function sleep(ms) {
28611
+ return new Promise((resolve) => setTimeout(resolve, ms));
28612
+ }
28613
+ function isSqliteBusyError(error) {
28614
+ if (!error || typeof error !== "object") return false;
28615
+ const sqliteError = error;
28616
+ const message = typeof sqliteError.message === "string" ? sqliteError.message.toLowerCase() : "";
28617
+ return sqliteError.code === "SQLITE_BUSY" || sqliteError.errno === 5 || message.includes("sqlite_busy") || message.includes("database is locked");
28618
+ }
28607
28619
  function beginImmediate(db) {
28608
28620
  db.exec("BEGIN IMMEDIATE");
28609
28621
  }
@@ -28615,10 +28627,13 @@ function rollback(db) {
28615
28627
  db.exec("ROLLBACK");
28616
28628
  } catch {}
28617
28629
  }
28618
- function ensureSchema(db, dbPath) {
28619
- if (initializedDbPaths.has(dbPath)) return;
28630
+ function applyConnectionPragmas(db) {
28631
+ db.exec(`PRAGMA busy_timeout = ${SQLITE_BUSY_TIMEOUT_MS};`);
28620
28632
  db.exec("PRAGMA journal_mode = WAL;");
28621
28633
  db.exec("PRAGMA foreign_keys = ON;");
28634
+ }
28635
+ function ensureSchema(db, dbPath) {
28636
+ if (initializedDbPaths.has(dbPath)) return;
28622
28637
  db.exec(`
28623
28638
  CREATE TABLE IF NOT EXISTS ${APP_STORAGE_TABLE} (
28624
28639
  namespace TEXT PRIMARY KEY,
@@ -28638,7 +28653,7 @@ async function openDatabase(dbPath) {
28638
28653
  close: database.close.bind(database)
28639
28654
  };
28640
28655
  }
28641
- const database = new (await (import("node:sqlite"))).DatabaseSync(dbPath);
28656
+ const database = new (await (Function("return import('node:sqlite')")())).DatabaseSync(dbPath);
28642
28657
  return {
28643
28658
  exec: database.exec.bind(database),
28644
28659
  prepare: database.prepare.bind(database),
@@ -28646,13 +28661,20 @@ async function openDatabase(dbPath) {
28646
28661
  };
28647
28662
  }
28648
28663
  async function withDatabase(dbPath, task) {
28649
- const db = await openDatabase(dbPath);
28650
- try {
28651
- ensureSchema(db, dbPath);
28652
- return task(db);
28653
- } finally {
28654
- db.close();
28664
+ for (let attempt = 1; attempt <= SQLITE_BUSY_MAX_ATTEMPTS; attempt += 1) {
28665
+ const db = await openDatabase(dbPath);
28666
+ try {
28667
+ applyConnectionPragmas(db);
28668
+ ensureSchema(db, dbPath);
28669
+ return task(db);
28670
+ } catch (error) {
28671
+ if (!isSqliteBusyError(error) || attempt >= SQLITE_BUSY_MAX_ATTEMPTS) throw error;
28672
+ } finally {
28673
+ db.close();
28674
+ }
28675
+ await sleep(SQLITE_BUSY_RETRY_DELAY_MS * attempt);
28655
28676
  }
28677
+ throw new Error("App storage database remained busy after retrying.");
28656
28678
  }
28657
28679
  function resolveAppStorageDbPath(userDataDir) {
28658
28680
  return path.join(userDataDir, APP_STORAGE_DB_DIR, APP_STORAGE_DB_NAME);
@@ -32397,10 +32419,18 @@ const runExternalCodexThreadSync = gen(function* () {
32397
32419
  });
32398
32420
  }
32399
32421
  let bootstrappedProjectCount = 0;
32422
+ let remainingBootstrapProjects = (yield* promise(() => readProjectPolicy(readModel))).remainingProjects;
32400
32423
  for (const workspace of importableParityWorkspaces) {
32401
32424
  const workspaceRoot = workspace.path;
32402
32425
  const workspaceRootCanonicalKey = projectRootKey(workspaceRoot);
32403
32426
  if (projectIdByRootKey.has(workspaceRootCanonicalKey)) continue;
32427
+ if (remainingBootstrapProjects !== null && remainingBootstrapProjects <= 0) {
32428
+ yield* logInfo$1("skipping parity workspace bootstrap because free project limit is already reached", {
32429
+ workspaceId: workspace.id,
32430
+ workspaceRoot
32431
+ });
32432
+ continue;
32433
+ }
32404
32434
  const projectId = resolveBootstrapProjectId(workspace, state.projectIds);
32405
32435
  const projectScripts = buildProjectScripts(workspace);
32406
32436
  yield* orchestrationEngine.dispatch({
@@ -32431,6 +32461,7 @@ const runExternalCodexThreadSync = gen(function* () {
32431
32461
  }
32432
32462
  });
32433
32463
  bootstrappedProjectCount += 1;
32464
+ if (remainingBootstrapProjects !== null && remainingBootstrapProjects > 0) remainingBootstrapProjects -= 1;
32434
32465
  }
32435
32466
  if (syncTargets.length === 0) return;
32436
32467
  let createdThreadCount = 0;
@@ -43179,10 +43210,13 @@ function buildEnv() {
43179
43210
  const extra = [
43180
43211
  "/opt/homebrew/bin",
43181
43212
  "/usr/local/bin",
43182
- path.join(homeDir, ".local", "bin")
43213
+ path.join(homeDir, ".local", "bin"),
43214
+ path.join(homeDir, ".fnm", "aliases", "default", "bin"),
43215
+ path.join(homeDir, ".fnm", "current", "bin"),
43216
+ path.join(homeDir, ".volta", "bin"),
43217
+ path.join(homeDir, ".asdf", "shims")
43183
43218
  ];
43184
- const currentPath = env.PATH ?? "";
43185
- const segments = [...extra, ...currentPath.split(path.delimiter).filter(Boolean)];
43219
+ const segments = [...(env.PATH ?? "").split(path.delimiter).filter(Boolean), ...extra];
43186
43220
  env.PATH = Array.from(new Set(segments)).join(path.delimiter);
43187
43221
  return env;
43188
43222
  }
@@ -43192,6 +43226,12 @@ function runCommand$1(command, args, env) {
43192
43226
  encoding: "utf8"
43193
43227
  });
43194
43228
  }
43229
+ function resolveRunnableCommand(command, env, shellInfo) {
43230
+ const resolved = resolveCommandPath(command, env, shellInfo)?.trim();
43231
+ if (!resolved) return command;
43232
+ if (resolved.includes(path.sep) || resolved.includes("/")) return resolved;
43233
+ return command;
43234
+ }
43195
43235
  function resolveShell() {
43196
43236
  if (process.platform === "win32") return {
43197
43237
  shell: process.env.ComSpec ?? "cmd.exe",
@@ -43312,6 +43352,22 @@ function buildNpmInstallCommand(packageName) {
43312
43352
  function readCommandOutput(result) {
43313
43353
  return `${result.stderr ?? ""}\n${result.stdout ?? ""}`.trim();
43314
43354
  }
43355
+ function resolveInstalledPackageVersion(npmCommand, packageName, env) {
43356
+ const raw = (runCommand$1(npmCommand, [
43357
+ "ls",
43358
+ "-g",
43359
+ packageName,
43360
+ "--depth=0",
43361
+ "--json"
43362
+ ], env).stdout ?? "").trim();
43363
+ if (!raw) return null;
43364
+ try {
43365
+ const version = JSON.parse(raw).dependencies?.[packageName]?.version;
43366
+ return typeof version === "string" ? normalizeVersion(version) : null;
43367
+ } catch {
43368
+ return null;
43369
+ }
43370
+ }
43315
43371
  function isPackageNotFoundOutput(output, packageName) {
43316
43372
  const normalized = output.toLowerCase();
43317
43373
  if (!normalized.includes("e404") && !normalized.includes("404 not found")) return false;
@@ -43409,7 +43465,9 @@ async function getCliInstallStatusWithFreshness(options) {
43409
43465
  };
43410
43466
  }
43411
43467
  async function updateGlobalCliNow() {
43468
+ const previousStatus = await getCliInstallStatusWithFreshness({ forceFreshness: true });
43412
43469
  const env = buildEnv();
43470
+ const npmCommand = resolveRunnableCommand("npm", env, resolveShell());
43413
43471
  let packageNameUsed = null;
43414
43472
  let result = null;
43415
43473
  let recoveredBinConflict = false;
@@ -43419,11 +43477,11 @@ async function updateGlobalCliNow() {
43419
43477
  "-g",
43420
43478
  packageName
43421
43479
  ];
43422
- let nextResult = runCommand$1("npm", installArgs, env);
43480
+ let nextResult = runCommand$1(npmCommand, installArgs, env);
43423
43481
  let nextRecoveredBinConflict = false;
43424
43482
  if (!nextResult.error && nextResult.status !== 0) {
43425
43483
  if (isCodexuseBinConflict(readCommandOutput(nextResult))) {
43426
- nextResult = runCommand$1("npm", [...installArgs, "--force"], env);
43484
+ nextResult = runCommand$1(npmCommand, [...installArgs, "--force"], env);
43427
43485
  nextRecoveredBinConflict = nextResult.status === 0 && !nextResult.error;
43428
43486
  }
43429
43487
  }
@@ -43445,6 +43503,7 @@ async function updateGlobalCliNow() {
43445
43503
  const stderr = (result.stderr ?? "").trim();
43446
43504
  const stdout = (result.stdout ?? "").trim();
43447
43505
  const status = await getCliInstallStatusWithFreshness({ forceFreshness: true });
43506
+ const installedPackageVersion = resolveInstalledPackageVersion(npmCommand, packageNameUsed, env);
43448
43507
  if (result.error) return {
43449
43508
  ok: false,
43450
43509
  message: result.error.message || `Failed to run ${buildNpmInstallCommand(packageNameUsed)}.`,
@@ -43455,6 +43514,14 @@ async function updateGlobalCliNow() {
43455
43514
  message: stderr || stdout || `${buildNpmInstallCommand(packageNameUsed)} failed.`,
43456
43515
  status
43457
43516
  };
43517
+ if (status.latestVersion && status.installedVersion !== status.latestVersion) {
43518
+ const downgraded = previousStatus.installedVersion && status.installedVersion && isUpdateAvailable(status.installedVersion, previousStatus.installedVersion);
43519
+ return {
43520
+ ok: false,
43521
+ message: installedPackageVersion === status.latestVersion && status.installedVersion !== installedPackageVersion ? `${CLI_DISPLAY_NAME} npm package ${installedPackageVersion} installed, but \`codexuse --version\` still reports ${status.installedVersion}. The published npm bundle looks stale.` : downgraded ? `${CLI_DISPLAY_NAME} update regressed from ${previousStatus.installedVersion} to ${status.installedVersion}. npm latest is ${status.latestVersion}.` : `${CLI_DISPLAY_NAME} still reports ${status.installedVersion ?? "unknown"} after update. npm latest is ${status.latestVersion}.`,
43522
+ status
43523
+ };
43524
+ }
43458
43525
  const installSuffix = packageNameUsed === LEGACY_NPM_PACKAGE_NAME ? " using the current public npm package." : ".";
43459
43526
  return {
43460
43527
  ok: true,
@@ -45716,6 +45783,69 @@ var ProfileManager = class {
45716
45783
  return null;
45717
45784
  }
45718
45785
  }
45786
+ async captureActiveAuthSnapshot() {
45787
+ await this.initialize();
45788
+ let raw;
45789
+ try {
45790
+ raw = await promises$1.readFile(this.activeAuth, "utf8");
45791
+ } catch (error) {
45792
+ if (this.isNotFoundError(error)) return {
45793
+ fingerprint: null,
45794
+ email: null,
45795
+ accountId: null,
45796
+ userId: null,
45797
+ chatgptUserId: null,
45798
+ workspaceId: null
45799
+ };
45800
+ const message = error instanceof Error ? error.message : "unknown error";
45801
+ const signature = typeof message === "string" ? `${message}:${this.activeAuth}` : this.activeAuth;
45802
+ if (this.lastActiveAuthErrorSignature !== signature) {
45803
+ logWarn("Failed to snapshot active auth file:", error);
45804
+ this.lastActiveAuthErrorSignature = signature;
45805
+ }
45806
+ return {
45807
+ fingerprint: null,
45808
+ email: null,
45809
+ accountId: null,
45810
+ userId: null,
45811
+ chatgptUserId: null,
45812
+ workspaceId: null
45813
+ };
45814
+ }
45815
+ const trimmed = raw.trim();
45816
+ if (!trimmed) return {
45817
+ fingerprint: null,
45818
+ email: null,
45819
+ accountId: null,
45820
+ userId: null,
45821
+ chatgptUserId: null,
45822
+ workspaceId: null
45823
+ };
45824
+ const fingerprint = createHash("sha256").update(trimmed).digest("hex");
45825
+ try {
45826
+ const parsed = JSON.parse(trimmed);
45827
+ const normalized = this.normalizeProfileData(parsed);
45828
+ const metadata = this.extractProfileMetadata(normalized);
45829
+ const workspace = this.resolveWorkspaceIdentity(normalized, metadata);
45830
+ return {
45831
+ fingerprint,
45832
+ email: this.resolveProfileEmail(normalized, metadata) ?? null,
45833
+ accountId: this.getAccountIdFromData(normalized) ?? null,
45834
+ userId: metadata?.userId ?? null,
45835
+ chatgptUserId: metadata?.chatgptUserId ?? null,
45836
+ workspaceId: workspace.id ?? null
45837
+ };
45838
+ } catch {
45839
+ return {
45840
+ fingerprint,
45841
+ email: null,
45842
+ accountId: null,
45843
+ userId: null,
45844
+ chatgptUserId: null,
45845
+ workspaceId: null
45846
+ };
45847
+ }
45848
+ }
45719
45849
  /**
45720
45850
  * Decode a JWT payload into an object without validating the signature.
45721
45851
  */
@@ -49791,6 +49921,10 @@ function recordRefreshRedeemed(session, output) {
49791
49921
  appendSessionError(session, detected);
49792
49922
  }
49793
49923
  }
49924
+ function describeActiveAuthOwner(snapshot) {
49925
+ if (!snapshot) return null;
49926
+ return snapshot.email ?? snapshot.userId ?? snapshot.chatgptUserId ?? snapshot.accountId ?? null;
49927
+ }
49794
49928
  async function resolveCodexBinaryOrThrow(context) {
49795
49929
  try {
49796
49930
  return await requireCodexCli();
@@ -49898,10 +50032,20 @@ const createServer = fn(function* () {
49898
50032
  return canonicalizeProjectRoot(normalizedWorkspaceRoot);
49899
50033
  });
49900
50034
  const normalizeDispatchCommand = fnUntraced(function* (input) {
49901
- if (input.command.type === "project.create") return {
49902
- ...input.command,
49903
- workspaceRoot: yield* normalizeProjectWorkspaceRoot(input.command.workspaceRoot)
49904
- };
50035
+ if (input.command.type === "project.create") {
50036
+ const workspaceRoot = yield* normalizeProjectWorkspaceRoot(input.command.workspaceRoot);
50037
+ const snapshot = yield* projectionReadModelQuery.getSnapshot().pipe(mapError((cause) => new RouteRequestError({ message: `Failed to validate project creation: ${String(cause)}` })));
50038
+ if (!findActiveProjectByCanonicalRoot(snapshot.projects, workspaceRoot)) {
50039
+ if (!(yield* tryPromise({
50040
+ try: () => readProjectPolicy(snapshot),
50041
+ catch: (cause) => new RouteRequestError({ message: `Failed to validate project creation: ${String(cause)}` })
50042
+ })).canCreateProject) return yield* new RouteRequestError({ message: PROJECT_LIMIT_MESSAGE });
50043
+ }
50044
+ return {
50045
+ ...input.command,
50046
+ workspaceRoot
50047
+ };
50048
+ }
49905
50049
  if (input.command.type === "project.meta.update" && input.command.workspaceRoot !== void 0) return {
49906
50050
  ...input.command,
49907
50051
  workspaceRoot: yield* normalizeProjectWorkspaceRoot(input.command.workspaceRoot)
@@ -50195,6 +50339,7 @@ const createServer = fn(function* () {
50195
50339
  let bootstrapProjectDefaultModel;
50196
50340
  const normalizedCwd = canonicalizeProjectRoot(cwd);
50197
50341
  if (!existingProject) {
50342
+ if (!(yield* promise(() => readProjectPolicy(snapshot))).canCreateProject) return;
50198
50343
  const createdAt = (/* @__PURE__ */ new Date()).toISOString();
50199
50344
  bootstrapProjectId = ProjectId.makeUnsafe(crypto.randomUUID());
50200
50345
  const bootstrapProjectTitle = path.basename(normalizedCwd) || "project";
@@ -50617,6 +50762,7 @@ const createServer = fn(function* () {
50617
50762
  authSessions.delete(name);
50618
50763
  }
50619
50764
  const startedAt = Date.now();
50765
+ const initialAuthSnapshot = yield* promise(() => profileManager.captureActiveAuthSnapshot());
50620
50766
  let cleanupConfig = null;
50621
50767
  const restoreConfig = async () => {
50622
50768
  if (!cleanupConfig) return;
@@ -50648,6 +50794,7 @@ const createServer = fn(function* () {
50648
50794
  exitCode: null,
50649
50795
  mode,
50650
50796
  startedAt,
50797
+ initialAuthSnapshot,
50651
50798
  restoreConfig
50652
50799
  };
50653
50800
  authSessions.set(name, session);
@@ -50722,6 +50869,16 @@ const createServer = fn(function* () {
50722
50869
  trackTelemetryEvent("profile_auth_failed", { mode: session.mode });
50723
50870
  return yield* new RouteRequestError({ message: formatUserFacingError(session.error ?? `Authentication failed with code ${session.exitCode}`, { fallback: "Authentication failed. Try again." }) });
50724
50871
  }
50872
+ if (session.mode === "create") {
50873
+ const currentAuthSnapshot = yield* promise(() => profileManager.captureActiveAuthSnapshot());
50874
+ if (currentAuthSnapshot.fingerprint === (session.initialAuthSnapshot?.fingerprint ?? null)) {
50875
+ authSessions.delete(body.name);
50876
+ trackTelemetryEvent("profile_auth_complete_failed", { mode: session.mode });
50877
+ const activeOwner = describeActiveAuthOwner(currentAuthSnapshot);
50878
+ const ownerText = activeOwner ? ` The active auth still belongs to '${activeOwner}'.` : "";
50879
+ return yield* new RouteRequestError({ message: `Codex login finished without updating the active auth for '${body.name}'.${ownerText} Finish the browser login for the new account and try again.` });
50880
+ }
50881
+ }
50725
50882
  try {
50726
50883
  if (session.mode === "refresh") yield* promise(() => profileManager.refreshProfileAuth(body.name));
50727
50884
  else {
@@ -52564,7 +52721,7 @@ const makeAnalyticsService = gen(function* () {
52564
52721
  event
52565
52722
  });
52566
52723
  });
52567
- yield* forever(sleep$1(1e3).pipe(flatMap(() => flush)), { disableYield: true }).pipe(forkScoped);
52724
+ yield* forever(sleep$2(1e3).pipe(flatMap(() => flush)), { disableYield: true }).pipe(forkScoped);
52568
52725
  yield* addFinalizer$1(() => flush);
52569
52726
  return {
52570
52727
  record,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codexuse-cli",
3
- "version": "3.1.2",
3
+ "version": "3.1.4",
4
4
  "description": "CodexUse CLI for managing Codex profiles and licenses.",
5
5
  "author": {
6
6
  "name": "Hoang",