@cmmd-center/forge 0.13.73 → 0.13.75

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/bin.mjs CHANGED
@@ -65979,7 +65979,7 @@ function normalizeNumberish(value) {
65979
65979
  }
65980
65980
  //#endregion
65981
65981
  //#region package.json
65982
- var version$1 = "0.13.73";
65982
+ var version$1 = "0.13.75";
65983
65983
  //#endregion
65984
65984
  //#region src/sentry.ts
65985
65985
  const SERVER_APP_NAME = "forge-server";
@@ -68063,7 +68063,8 @@ const OAuthTokenExchangeInput = Struct({
68063
68063
  const CommandOAuthTokenInput = Struct({
68064
68064
  grant_type: String$1,
68065
68065
  device_code: String$1,
68066
- client_id: String$1
68066
+ client_id: String$1,
68067
+ pop_public_key: optionalKey(String$1)
68067
68068
  });
68068
68069
  const CommandPasswordTokenInput = Struct({
68069
68070
  email: String$1,
@@ -68706,7 +68707,8 @@ const authCmmdOAuthTokenRouteLayer = add$1("POST", "/api/auth/cmmd-oauth/token",
68706
68707
  return yield* proxyCmmdOAuthRequest("/api/mcp-server/oauth/token", {
68707
68708
  client_id: payload.client_id,
68708
68709
  grant_type: payload.grant_type,
68709
- device_code: payload.device_code
68710
+ device_code: payload.device_code,
68711
+ ...payload.pop_public_key ? { pop_public_key: payload.pop_public_key } : {}
68710
68712
  });
68711
68713
  }).pipe(catchTag("AuthError", (error) => respondToAuthError(error))));
68712
68714
  /**
@@ -241209,17 +241211,30 @@ function isPromiseLike(value) {
241209
241211
  * outlives the delete re-acquires the hold on its next tick; that was
241210
241212
  * previously measured leaking 37 renewals over 18 minutes, pinning a sprite
241211
241213
  * running — and billing — 33 minutes after its work had ended.
241212
- * 2. Stopping the interval only cancels FUTURE ticks. A PUT already on the wire
241213
- * must be JOINED before the DELETE, or it lands afterwards and recreates the
241214
- * hold for another full expiry window. fly.io's reference worker cancels and
241215
- * awaits its heartbeat for the same reason.
241214
+ * 2. Cancellation must be CONFIRMED before the final DELETE is trusted. A PUT
241215
+ * already on the wire has to settle first, or the DELETE can land mid-PUT
241216
+ * and the PUT recreate the hold for another full expiry window; fly.io's
241217
+ * reference worker cancels and awaits its heartbeat for the same reason.
241218
+ * The join is bounded on the shutdown path
241219
+ * (SPRITE_TASK_HOLD_RELEASE_JOIN_TIMEOUT_MS) and the bound decides the
241220
+ * shape: every PUT settled within it, with no earlier PUT rejection left
241221
+ * unanswered by a clean refresh, confirms cancellation and one DELETE
241222
+ * finishes the hold; the bound firing first means cancellation cannot be
241223
+ * confirmed, so the release sweeps, DELETE, verify with a bounded GET, and
241224
+ * re-DELETE while the server still shows the hold, capped at
241225
+ * SPRITE_TASK_HOLD_SWEEP_ROUNDS rounds. Every hold gets at least one
241226
+ * DELETE, a resurrected hold is cleaned and swept again, and only a hold
241227
+ * positively present after the cap is reported unreleased at warn instead
241228
+ * of hanging SIGTERM open.
241216
241229
  * 3. `release` can arrive while `acquire` is still awaiting its own PUT —
241217
241230
  * `releaseAll` runs from runtime drain and the shutdown finalizer,
241218
241231
  * concurrently with the provider event stream. The hold is registered before
241219
- * that await (so a duplicate turn.started cannot double-acquire), so release
241220
- * can remove the map entry first; `acquire` must then NOT install a
241221
- * refresher. One attached to an unmapped hold is unreachable by release,
241222
- * releaseThread and releaseAll alike, and re-PUTs every 60 s for the life of
241232
+ * that await (so a duplicate turn.started cannot double-acquire), and while
241233
+ * a release runs the hold stays mapped (joining, then deleting), so the
241234
+ * shutdown finalizer's bounded `releaseAll` can take a parked hold over;
241235
+ * `acquire` must then NOT install a refresher on the old hold, and a fresh
241236
+ * acquire replaces a released hold in the map. One refresher attached to a
241237
+ * hold no release path can reach would re-PUT every 60 s for the life of
241223
241238
  * the process — an unbounded pin.
241224
241239
  *
241225
241240
  * All three are pinned by tests.
@@ -241243,6 +241258,30 @@ const SPRITE_TASK_HOLD_REFRESH_MS = 6e4;
241243
241258
  */
241244
241259
  const SPRITE_TASK_HOLD_REQUEST_TIMEOUT_MS = 1e4;
241245
241260
  /**
241261
+ * Shutdown bounds for the release the server finalizer issues. Both are one
241262
+ * request deadline. With a transport that honors its abort, every PUT still on
241263
+ * the wire settles within its own 10 s deadline, so a join sized at one
241264
+ * deadline always completes, cancellation is confirmed, and a single DELETE is
241265
+ * issued; the DELETE answers within its own deadline too.
241266
+ *
241267
+ * When the join bound fires, cancellation is unconfirmed and the release
241268
+ * sweeps: DELETE, verify with a bounded GET, and re-DELETE if the hold
241269
+ * survived, capped at SPRITE_TASK_HOLD_SWEEP_ROUNDS rounds. Worst case a
241270
+ * shutdown release costs join + 2 x (delete + verify), about 50 s, after
241271
+ * which the process exits and any hold left behind expires on its own within
241272
+ * 5 minutes. Drain passes no bounds. It keeps the full join, and its tick is
241273
+ * already capped by the heartbeat timeout.
241274
+ */
241275
+ const SPRITE_TASK_HOLD_RELEASE_JOIN_TIMEOUT_MS = SPRITE_TASK_HOLD_REQUEST_TIMEOUT_MS;
241276
+ const SPRITE_TASK_HOLD_RELEASE_DELETE_TIMEOUT_MS = SPRITE_TASK_HOLD_REQUEST_TIMEOUT_MS;
241277
+ /**
241278
+ * How many delete-plus-verify rounds an unconfirmed release sweeps before it
241279
+ * gives up and reports the hold unreleased. Two is one retry past the first
241280
+ * delete: enough to clean a timed-out PUT that commits late, cheap enough
241281
+ * that a truly wedged socket cannot hold SIGTERM open much past a minute.
241282
+ */
241283
+ const SPRITE_TASK_HOLD_SWEEP_ROUNDS = 2;
241284
+ /**
241246
241285
  * Resolve the hold configuration from the process environment.
241247
241286
  *
241248
241287
  * Returns null on every runtime that is not a project sprite — desktop-local and
@@ -241264,6 +241303,20 @@ function resolveSpriteTaskHoldConfig(env = process.env) {
241264
241303
  function spriteTaskHoldName(namePrefix, turnId) {
241265
241304
  return `${namePrefix}${turnId}`;
241266
241305
  }
241306
+ const noTimer = () => {};
241307
+ /**
241308
+ * Resolve with `promise`, but stop waiting after `timeoutMs`. Rejections pass
241309
+ * through untouched, and the caller decides what a timeout means. The
241310
+ * underlying operation keeps running either way.
241311
+ */
241312
+ function boundedAwait(promise, timeoutMs) {
241313
+ if (timeoutMs === void 0) return promise;
241314
+ let clearTimer = noTimer;
241315
+ return Promise.race([promise, new Promise((resolve) => {
241316
+ const timer = setTimeout(resolve, timeoutMs);
241317
+ clearTimer = () => clearTimeout(timer);
241318
+ })]).finally(() => clearTimer());
241319
+ }
241267
241320
  const DEFAULT_TIMER = {
241268
241321
  setInterval: (handler, ms) => setInterval(handler, ms),
241269
241322
  clearInterval: (handle) => {
@@ -241299,7 +241352,8 @@ var SpriteTaskHoldManager = class {
241299
241352
  * whose turn may never start. When the budget is spent the hold releases itself.
241300
241353
  */
241301
241354
  async acquire(turnId, threadId = null, options = {}) {
241302
- if (this.#holds.has(turnId)) return;
241355
+ const existing = this.#holds.get(turnId);
241356
+ if (existing !== void 0 && !existing.released) return;
241303
241357
  let refreshesLeft = options.maxRefreshes ?? Number.POSITIVE_INFINITY;
241304
241358
  const name = spriteTaskHoldName(this.#config.namePrefix, turnId);
241305
241359
  const hold = {
@@ -241307,15 +241361,21 @@ var SpriteTaskHoldManager = class {
241307
241361
  threadId,
241308
241362
  refresher: null,
241309
241363
  inFlight: /* @__PURE__ */ new Set(),
241310
- released: false
241364
+ released: false,
241365
+ phase: "idle",
241366
+ releaseAttempt: null,
241367
+ deletion: null,
241368
+ uncertainPut: false
241311
241369
  };
241312
241370
  this.#holds.set(turnId, hold);
241313
241371
  const put = this.#transport.put(name, 300);
241314
- const tracked = put.then(() => {}, () => {});
241372
+ const tracked = put.then(() => "succeeded", () => "failed");
241315
241373
  hold.inFlight.add(tracked);
241316
241374
  try {
241317
241375
  await put;
241376
+ hold.uncertainPut = false;
241318
241377
  } catch (cause) {
241378
+ hold.uncertainPut = true;
241319
241379
  hold.inFlight.delete(tracked);
241320
241380
  this.#onError(`failed to acquire sprite task hold for turn ${turnId}`, cause);
241321
241381
  if (hold.released || this.#holds.get(turnId) !== hold) return;
@@ -241329,28 +241389,189 @@ var SpriteTaskHoldManager = class {
241329
241389
  return;
241330
241390
  }
241331
241391
  refreshesLeft -= 1;
241332
- const refresh = this.#transport.put(name, 300).catch((cause) => this.#onError(`failed to refresh sprite task hold for turn ${turnId}`, cause));
241392
+ const refresh = this.#transport.put(name, 300).then(() => {
241393
+ hold.uncertainPut = false;
241394
+ return "succeeded";
241395
+ }, (cause) => {
241396
+ hold.uncertainPut = true;
241397
+ this.#onError(`failed to refresh sprite task hold for turn ${turnId}`, cause);
241398
+ return "failed";
241399
+ });
241333
241400
  hold.inFlight.add(refresh);
241334
241401
  refresh.finally(() => hold.inFlight.delete(refresh));
241335
241402
  }, SPRITE_TASK_HOLD_REFRESH_MS);
241336
241403
  }
241337
- async release(turnId) {
241404
+ /**
241405
+ * Release one hold.
241406
+ *
241407
+ * Cancellation must be confirmed before a single DELETE is trusted: every
241408
+ * PUT on the wire has to settle successfully, or the DELETE can land mid-PUT
241409
+ * and the PUT re-create the hold behind it. With a join bound (shutdown),
241410
+ * PUTs that do not settle within the bound, or settle as rejections, make
241411
+ * the attempt sweep instead: DELETE, verify, re-DELETE while the server
241412
+ * still shows the hold, capped at two rounds. The fate outlives the PUT's
241413
+ * settlement: a PUT that rejected before the release began, with no
241414
+ * successful refresh after it, sweeps too. Without a bound (drain,
241415
+ * per-turn release) the join is patient and never gives up, though a PUT
241416
+ * that rejects still routes the release through the sweep.
241417
+ *
241418
+ * While an attempt runs, the hold stays in the map in its joining or
241419
+ * deleting phase, so shutdown can see it. A bounded (shutdown) caller takes
241420
+ * a parked hold over with its own bounded pass; a hold already in its
241421
+ * deleting phase is skipped, because its single deletion is already in
241422
+ * flight. Unbounded duplicate callers join the running attempt instead.
241423
+ */
241424
+ async release(turnId, options = {}) {
241338
241425
  const hold = this.#holds.get(turnId);
241339
- if (!hold) return;
241426
+ if (!hold) return "released";
241427
+ if (hold.phase === "deleting") return "released";
241428
+ const bounded = options.joinTimeoutMs !== void 0;
241429
+ if (hold.releaseAttempt !== null) {
241430
+ if (!bounded) return hold.releaseAttempt;
241431
+ return this.#concludeRelease(hold, turnId, options);
241432
+ }
241340
241433
  hold.released = true;
241341
241434
  if (hold.refresher !== null) {
241342
241435
  this.#timer.clearInterval(hold.refresher);
241343
241436
  hold.refresher = null;
241344
241437
  }
241345
- this.#holds.delete(turnId);
241346
- if (hold.inFlight.size > 0) await Promise.all(hold.inFlight);
241438
+ hold.phase = "joining";
241439
+ const attempt = (async () => {
241440
+ const outcome = await this.#concludeRelease(hold, turnId, options);
241441
+ if (outcome === "unreleased") {
241442
+ hold.phase = "idle";
241443
+ this.#removeIfCurrent(turnId, hold);
241444
+ }
241445
+ return outcome;
241446
+ })();
241447
+ hold.releaseAttempt = attempt;
241448
+ try {
241449
+ return await attempt;
241450
+ } finally {
241451
+ if (hold.releaseAttempt === attempt) hold.releaseAttempt = null;
241452
+ }
241453
+ }
241454
+ /**
241455
+ * Drive one release attempt to its outcome. On the confirmed path (every
241456
+ * PUT on the wire settled within the join bound) a single DELETE finishes
241457
+ * the hold. On the unconfirmed path cancellation is unknown, so the hold
241458
+ * is swept: DELETE, verify, and re-DELETE while the server still shows it,
241459
+ * capped. Shared by the first attempt and a shutdown takeover: whichever
241460
+ * caller first reaches its verdict installs the hold's single deletion
241461
+ * promise and the rest join it, so the DELETE or sweep is issued once and
241462
+ * concurrent callers report the same outcome.
241463
+ */
241464
+ async #concludeRelease(hold, turnId, options) {
241465
+ const verdict = await this.#confirmCancellation(hold, options.joinTimeoutMs);
241466
+ if (hold.deletion !== null) return hold.deletion;
241467
+ hold.phase = "deleting";
241468
+ const deletion = verdict === "confirmed" ? this.#deleteConfirmed(hold, turnId, options) : this.#sweepUnconfirmed(hold, turnId, options);
241469
+ hold.deletion = deletion;
241470
+ return deletion;
241471
+ }
241472
+ /**
241473
+ * The confirmed-path deletion: every PUT on the wire settled cleanly, so
241474
+ * one DELETE finishes the hold. A rejected DELETE is logged, never thrown;
241475
+ * the hold still leaves the map and expires on its own server-side.
241476
+ */
241477
+ async #deleteConfirmed(hold, turnId, options) {
241478
+ await this.#issueDelete(hold, options.deleteTimeoutMs, turnId);
241479
+ this.#removeIfCurrent(turnId, hold);
241480
+ return "released";
241481
+ }
241482
+ /**
241483
+ * Best-effort cleanup for a hold whose cancellation is uncertain: the join
241484
+ * bound fired with a PUT unsettled, or a PUT rejected after possibly being
241485
+ * processed server-side. The hold is owed its delete either way. Each round
241486
+ * is a bounded DELETE followed by a bounded GET; a verify that still shows
241487
+ * the hold (the timed-out PUT committed after our delete, or the delete
241488
+ * never landed) triggers the next round. Verification is best-effort too:
241489
+ * "absent" proves cleanup, "unknown" proves nothing and cannot by itself
241490
+ * report the hold unreleased, so after the cap an unverifiable hold is
241491
+ * reported released-with-its-delete while a positively present one is
241492
+ * reported unreleased at warn. Either way the hold expires on its own
241493
+ * within 300 s. Only `#concludeRelease` starts this, after it has already
241494
+ * moved the hold into its deleting phase.
241495
+ */
241496
+ async #sweepUnconfirmed(hold, turnId, options) {
241497
+ for (let round = 1; round <= SPRITE_TASK_HOLD_SWEEP_ROUNDS; round += 1) {
241498
+ await this.#issueDelete(hold, options.deleteTimeoutMs, turnId);
241499
+ const state = await this.#verifyHold(hold, options.deleteTimeoutMs, turnId);
241500
+ const last = round === SPRITE_TASK_HOLD_SWEEP_ROUNDS;
241501
+ if (state === "absent") {
241502
+ this.#removeIfCurrent(turnId, hold);
241503
+ return "released";
241504
+ }
241505
+ if (state === "present") {
241506
+ this.#onError(`sprite task hold for turn ${turnId} was still present after delete (sweep ${round}/${SPRITE_TASK_HOLD_SWEEP_ROUNDS})`, "a refresh PUT that ignored its abort appears to have committed after the delete");
241507
+ if (last) {
241508
+ this.#onError(`sprite task hold for turn ${turnId} was left unreleased: still present after ${SPRITE_TASK_HOLD_SWEEP_ROUNDS} delete+verify sweeps, expires on its own`, "hold survived the full shutdown sweep");
241509
+ this.#removeIfCurrent(turnId, hold);
241510
+ return "unreleased";
241511
+ }
241512
+ continue;
241513
+ }
241514
+ this.#onError(`sprite task hold for turn ${turnId} could not be verified after delete (sweep ${round}/${SPRITE_TASK_HOLD_SWEEP_ROUNDS})`, "hold state unverifiable");
241515
+ if (last) {
241516
+ this.#removeIfCurrent(turnId, hold);
241517
+ return "released";
241518
+ }
241519
+ }
241520
+ return "released";
241521
+ }
241522
+ /**
241523
+ * Ask the transport whether the hold still exists. No transport `get`, a
241524
+ * rejection, or a bound that fires all come back "unknown": the sweep has
241525
+ * no evidence, and never invents it.
241526
+ */
241527
+ async #verifyHold(hold, timeoutMs, turnId) {
241528
+ const get = this.#transport.get;
241529
+ if (!get) return "unknown";
241530
+ try {
241531
+ return await boundedAwait(get(hold.name), timeoutMs);
241532
+ } catch (cause) {
241533
+ this.#onError(`failed to verify sprite task hold for turn ${turnId}`, cause);
241534
+ return "unknown";
241535
+ }
241536
+ }
241537
+ /**
241538
+ * Wait for every PUT on the wire to settle and report whether cancellation
241539
+ * is confirmed. Only a clean success confirms: a PUT that REJECTED is
241540
+ * uncertain, because the server may have processed the request before the
241541
+ * failure surfaced, and a DELETE trusted after it could be raced by the
241542
+ * hold it re-created. `inFlight` forgets each PUT once it settles, so a
241543
+ * rejection that settled before the release even started is read from
241544
+ * `uncertainPut` instead, and stays uncertain until some later PUT
241545
+ * succeeds. With no bound the wait is patient; unbounded callers
241546
+ * (drain, per-turn release) trade shutdown speed for the certainty.
241547
+ */
241548
+ async #confirmCancellation(hold, timeoutMs) {
241549
+ if (hold.inFlight.size === 0) return hold.uncertainPut ? "uncertain" : "confirmed";
241550
+ const settled = Promise.all(hold.inFlight).then((fates) => fates.every((fate) => fate === "succeeded") && !hold.uncertainPut ? "confirmed" : "uncertain");
241551
+ if (timeoutMs === void 0) return settled;
241552
+ let clearTimer = noTimer;
241553
+ return Promise.race([settled, new Promise((resolve) => {
241554
+ const timer = setTimeout(() => resolve("uncertain"), timeoutMs);
241555
+ clearTimer = () => clearTimeout(timer);
241556
+ })]).finally(() => clearTimer());
241557
+ }
241558
+ /** Issue the DELETE, reporting (never throwing) a failure. */
241559
+ async #issueDelete(hold, deleteTimeoutMs, turnId) {
241347
241560
  try {
241348
- await this.#transport.delete(hold.name);
241561
+ await boundedAwait(this.#transport.delete(hold.name), deleteTimeoutMs);
241349
241562
  } catch (cause) {
241350
241563
  this.#onError(`failed to release sprite task hold for turn ${turnId}`, cause);
241351
241564
  }
241352
241565
  }
241353
241566
  /**
241567
+ * Drop the map entry only if this attempt's hold still owns the id: a newer
241568
+ * acquire may have replaced it while the release was awaiting, and deleting
241569
+ * by key alone would evict the replacement.
241570
+ */
241571
+ #removeIfCurrent(turnId, hold) {
241572
+ if (this.#holds.get(turnId) === hold) this.#holds.delete(turnId);
241573
+ }
241574
+ /**
241354
241575
  * Release every hold belonging to one thread.
241355
241576
  *
241356
241577
  * `session.exited` names only the thread whose provider process died, and a
@@ -241365,9 +241586,22 @@ var SpriteTaskHoldManager = class {
241365
241586
  /**
241366
241587
  * Release everything. Runtime drain and server shutdown must call this, or a
241367
241588
  * drained sprite keeps billing until each hold expires.
241589
+ *
241590
+ * Shutdown passes `SPRITE_TASK_HOLD_RELEASE_JOIN_TIMEOUT_MS` /
241591
+ * `SPRITE_TASK_HOLD_RELEASE_DELETE_TIMEOUT_MS` so a socket that never
241592
+ * settles cannot hang the process open past its own termination, and gets a
241593
+ * per-hold report back: every hold gets its DELETE, and only holds the
241594
+ * sweep still saw present after the full delete+verify cap come back
241595
+ * unreleased, left to their own 300 s expiry. Drain passes no bounds and
241596
+ * keeps the patient join.
241368
241597
  */
241369
- async releaseAll() {
241370
- await Promise.all([...this.#holds.keys()].map((turnId) => this.release(turnId)));
241598
+ async releaseAll(options = {}) {
241599
+ const turnIds = [...this.#holds.keys()];
241600
+ const outcomes = await Promise.all(turnIds.map(async (turnId) => [turnId, await this.release(turnId, options)]));
241601
+ return {
241602
+ released: outcomes.filter(([, outcome]) => outcome === "released").map(([turnId]) => turnId),
241603
+ unreleased: outcomes.filter(([, outcome]) => outcome === "unreleased").map(([turnId]) => turnId)
241604
+ };
241371
241605
  }
241372
241606
  };
241373
241607
  /**
@@ -241398,7 +241632,25 @@ function makeSpriteTaskHoldTransport(config, fetchImpl = fetch) {
241398
241632
  headers: { "content-type": "application/json" },
241399
241633
  body: JSON.stringify({ expire: `${expireSeconds}s` })
241400
241634
  }),
241401
- delete: (name) => call(`/${encodeURIComponent(name)}`, { method: "DELETE" })
241635
+ delete: (name) => call(`/${encodeURIComponent(name)}`, { method: "DELETE" }),
241636
+ get: async (name) => {
241637
+ const controller = new AbortController();
241638
+ const deadline = setTimeout(() => controller.abort(), SPRITE_TASK_HOLD_REQUEST_TIMEOUT_MS);
241639
+ try {
241640
+ const response = await fetchImpl(`http://sprite/v1/tasks/${encodeURIComponent(name)}`, {
241641
+ method: "GET",
241642
+ signal: controller.signal,
241643
+ unix: config.socketPath
241644
+ });
241645
+ if (response.ok) return "present";
241646
+ if (response.status === 404) return "absent";
241647
+ return "unknown";
241648
+ } catch {
241649
+ return "unknown";
241650
+ } finally {
241651
+ clearTimeout(deadline);
241652
+ }
241653
+ }
241402
241654
  };
241403
241655
  }
241404
241656
  /**
@@ -285989,10 +286241,10 @@ const AgentBrowserManagerLive = effect(BrowserManager, gen(function* () {
285989
286241
  mediaSourceFactory: displayCaptureRuntime.mediaSourceFactory,
285990
286242
  taskHold: displayTaskHoldManager ? {
285991
286243
  acquire: (holdId) => displayTaskHoldManager.acquire(holdId),
285992
- release: (holdId) => displayTaskHoldManager.release(holdId)
286244
+ release: (holdId) => displayTaskHoldManager.release(holdId).then(() => {})
285993
286245
  } : void 0
285994
286246
  });
285995
- yield* addFinalizer$2(() => promise(() => displayTaskHoldManager?.releaseAll() ?? Promise.resolve()));
286247
+ yield* addFinalizer$2(() => promise(() => displayTaskHoldManager?.releaseAll().then(() => {}) ?? Promise.resolve()));
285996
286248
  const baseBackendOptions = displayCaptureRuntime.backendOptions;
285997
286249
  const sessionInitialUrls = /* @__PURE__ */ new Map();
285998
286250
  let runtimeBuild = null;
@@ -293932,6 +294184,19 @@ const SpriteTaskHoldReactorLive = effect(SpriteTaskHoldReactor, gen(function* ()
293932
294184
  const manager = makeSpriteTaskHoldManager(process.env, (message, cause) => {
293933
294185
  runFork(logWarning$1(message, { cause: cause instanceof Error ? cause.message : cause }));
293934
294186
  });
294187
+ /**
294188
+ * Run a manager call, or nothing on runtimes that are not sprites. One
294189
+ * null-guard for every caller: the releaseAll service and the shutdown
294190
+ * finalizer alike.
294191
+ */
294192
+ const onManager = (run) => promise(async () => {
294193
+ if (manager === null) return;
294194
+ await run(manager);
294195
+ });
294196
+ yield* addFinalizer$2(() => onManager((taskHolds) => taskHolds.releaseAll({
294197
+ joinTimeoutMs: SPRITE_TASK_HOLD_RELEASE_JOIN_TIMEOUT_MS,
294198
+ deleteTimeoutMs: SPRITE_TASK_HOLD_RELEASE_DELETE_TIMEOUT_MS
294199
+ })));
293935
294200
  const launchCallers = /* @__PURE__ */ new Map();
293936
294201
  const start = fn$1("start")(function* () {
293937
294202
  if (manager === null) return;
@@ -293948,12 +294213,12 @@ const SpriteTaskHoldReactorLive = effect(SpriteTaskHoldReactor, gen(function* ()
293948
294213
  if (event.type === "turn.completed") {
293949
294214
  const turnId = event.turnId;
293950
294215
  if (turnId === void 0) return void_$1;
293951
- return promise(() => manager.release(String(turnId)));
294216
+ return promise(() => manager.release(String(turnId)).then(() => {}));
293952
294217
  }
293953
294218
  if (event.type === "turn.aborted") {
293954
294219
  const turnId = event.turnId;
293955
294220
  if (turnId === void 0) return void_$1;
293956
- return promise(() => manager.release(String(turnId)));
294221
+ return promise(() => manager.release(String(turnId)).then(() => {}));
293957
294222
  }
293958
294223
  if (event.type === "session.exited") {
293959
294224
  launchCallers.delete(String(event.threadId));
@@ -293980,7 +294245,7 @@ const SpriteTaskHoldReactorLive = effect(SpriteTaskHoldReactor, gen(function* ()
293980
294245
  start,
293981
294246
  holdLaunch,
293982
294247
  releaseLaunch,
293983
- releaseAll: promise(() => manager === null ? Promise.resolve() : manager.releaseAll())
294248
+ releaseAll: onManager((taskHolds) => taskHolds.releaseAll())
293984
294249
  };
293985
294250
  }));
293986
294251
  //#endregion
@@ -298094,7 +298359,7 @@ function resolveBuildCommitFromEnv(env) {
298094
298359
  * environment descriptor down instead of reporting an honest "unknown".
298095
298360
  */
298096
298361
  function readBakedBuildCommit() {
298097
- return "9beb25327a2591f7938669b9014396e64c2bb674";
298362
+ return "56e2269e0c33f44c636004fc33f6c402fc8e59f4";
298098
298363
  }
298099
298364
  async function resolveServerBuildCommit(input) {
298100
298365
  if (isFullCommitSha(input.baked)) return input.baked;
@@ -1,4 +1,4 @@
1
- import{r as e}from"./rolldown-runtime-hePW80VL.js";import{Ha as t,Mi as n,Ua as r,Wa as i}from"./Stream-mUTFnSY9.js";import{Al as a,Fn as o,Gc as s,Hr as c,Jc as l,Qr as u,Rr as d,Sr as f,Tn as p,Uc as m,Xr as h,_r as g,d as _,fn as v,fr as y,gr as b,i as x,is as S,jn as C,l as w,m as T,ms as E,n as D,qc as O,qt as k,r as A,u as j,za as M,zr as N}from"./DiffPanelShell-BoAQcVta.js";import{hn as P}from"./CompositeItem-B_Qce_Zi.js";import{a as F,c as I,f as L,i as R,l as z,m as B,n as V,o as H,p as U,r as W,s as G,t as K}from"./Virtualizer-B4jYnrUE.js";import{Dn as q,at as J,it as ee}from"./src-IM0FnQax.js";import{a as te,c as ne,d as re,h as ie,i as ae,l as oe,m as se,n as ce,o as Y,p as le,r as ue,s as de,t as fe,u as pe}from"./DiffPanel.logic-Bw1O_6UU.js";var X=e(i(),1),me=typeof window>`u`?X.useEffect:X.useLayoutEffect;function he({fileDiff:e,options:t,editorOptions:n,lineAnnotations:r,selectedLines:i,prerenderedHTML:a,metrics:o,hasGutterRenderUtility:s,hasCustomHeader:c,disableWorkerPool:l,edit:u}){let d=V(),f=i!==void 0,p=(0,X.useContext)(x),m=j(),h=(0,X.useRef)(null),g=_(n=>{if(n!=null){if(h.current!=null)throw Error(`useFileDiffInstance: An instance should not already exist when a node is created`);d==null?h.current=new re(Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),l?void 0:p,!0):h.current=new pe(Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),d,o,l?void 0:p,!0),h.current.hydrate({fileDiff:e,fileContainer:n,lineAnnotations:r,prerenderedHTML:a})}else{if(h.current==null)throw Error(`useFileDiffInstance: A FileDiff instance should exist when unmounting`);h.current.cleanUp(),h.current=null}});return me(()=>{let{current:n}=h;if(n==null)return;let a=Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),o=a!==void 0&&!k(n.options,a);n.setOptions(a),n.render({forceRender:o,fileDiff:e,lineAnnotations:r}),i!==void 0&&n.setSelectedLines(i)}),me(()=>{if(u&&h.current!=null){if(m===void 0)throw Error(`FileDiff: EditContext is not attached`);let e=m(n??{});if(e==null)throw Error(`FileDiff: EditProvider.createEditor must return an editor instance`);try{return e.edit(h.current)}catch(t){throw e.cleanUp(),t}}},[u]),{ref:g,getHoveredLine:(0,X.useCallback)(()=>h.current?.getHoveredLine(),[])}}function Z({options:e,controlledSelection:t,hasCustomHeader:n,hasGutterRenderUtility:r}){return t||r||n?{...e,controlledSelection:t,renderCustomHeader:n?w:e?.renderCustomHeader,renderGutterUtility:r?w:e?.renderGutterUtility}:e}var Q=r();function ge({fileDiff:e,options:t,editorOptions:n,metrics:r,lineAnnotations:i,selectedLines:a,className:o,style:s,prerenderedHTML:c,renderAnnotation:l,renderCustomHeader:u,renderHeaderPrefix:d,renderHeaderFilenameSuffix:f,renderHeaderMetadata:p,renderGutterUtility:m,disableWorkerPool:h=!1,edit:g=!1}){let{ref:_,getHoveredLine:y}=he({fileDiff:e,options:t,editorOptions:n,metrics:r,lineAnnotations:i,selectedLines:a,prerenderedHTML:c,hasGutterRenderUtility:m!=null,hasCustomHeader:u!=null,disableWorkerPool:h,edit:g});return(0,Q.jsx)(v,{ref:_,className:o,style:s,children:W(oe({fileDiff:e,renderCustomHeader:u,renderHeaderPrefix:d,renderHeaderFilenameSuffix:f,renderHeaderMetadata:p,renderAnnotation:l,renderGutterUtility:m,lineAnnotations:i,getHoveredLine:y}),c)})}var $=t();function _e(e){return e.fromTurnCount===0?q(ee)({threadId:e.threadId,toTurnCount:e.toTurnCount}).pipe(n(e=>({kind:`fullThreadDiff`,input:e}))):q(J)({threadId:e.threadId,fromTurnCount:e.fromTurnCount,toTurnCount:e.toTurnCount}).pipe(n(e=>({kind:`turnDiff`,input:e})))}function ve(e){return e instanceof Error?e.message:typeof e==`string`?e:``}function ye(e){let t=ve(e).trim();if(t.length===0)return`Failed to load checkpoint diff.`;let n=t.toLowerCase();if(n.includes(`not a git repository`))return`Turn diffs are unavailable because this project is not a git repository.`;if(n.includes(`checkpoint unavailable for thread`)||n.includes(`checkpoint invariant violation`)){let e=t.indexOf(`:`);if(e>=0){let n=t.slice(e+1).trim();if(n.length>0)return n}}return t}function be(e){let t=ve(e).toLowerCase();return t.includes(`exceeds current turn count`)||t.includes(`checkpoint is unavailable for turn`)||t.includes(`filesystem checkpoint is unavailable`)}function xe(e){let t=_e(e);return O({queryKey:M.checkpointDiff(e),queryFn:async({signal:n})=>{if(!e.environmentId||!e.threadId||t._tag===`None`)throw Error(`Checkpoint diff is unavailable.`);let r=c(e.environmentId);try{return t.value.kind===`fullThreadDiff`?await r.orchestration.getFullThreadDiff(t.value.input,{signal:n}):await r.orchestration.getTurnDiff(t.value.input,{signal:n})}catch(e){throw Error(ye(e),{cause:e})}},enabled:(e.enabled??!0)&&!!e.environmentId&&!!e.threadId&&t._tag===`Some`,staleTime:1/0,retry:(e,t)=>be(t)?e<12:e<3,retryDelay:(e,t)=>be(t)?Math.min(5e3,250*2**(e-1)):Math.min(1e3,100*2**(e-1))})}function Se(e){if(!(!e.canScrollLeft&&!e.canScrollRight))return{maskImage:`linear-gradient(to right, ${e.canScrollLeft?`transparent 24px, black 72px`:`black`}, ${e.canScrollRight?`black calc(100% - 72px), transparent calc(100% - 24px)`:`black`})`}}function Ce(e){return e instanceof Error?e.message:e?`Failed to load checkpoint diff.`:null}function we(e){return{environmentId:e.environmentId??null,threadId:e.threadId,fromTurnCount:e.range?.fromTurnCount??null,toTurnCount:e.range?.toTurnCount??null,cacheScope:e.selectedTurnId?`turn:${e.selectedTurnId}`:e.conversationCacheScope,enabled:e.enabled}}function Te(){let e=(0,$.c)(8),t=(0,X.useRef)(null),[n,r]=(0,X.useState)(!1),[i,a]=(0,X.useState)(!1),o;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(o=()=>{let e=t.current;if(!e){r(!1),a(!1);return}let n=de({scrollLeft:e.scrollLeft,scrollWidth:e.scrollWidth,clientWidth:e.clientWidth});r(n.canScrollLeft),a(n.canScrollRight)},e[0]=o):o=e[0];let s=o,c;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(c=e=>{t.current?.scrollBy({left:e,behavior:`smooth`})},e[1]=c):c=e[1];let l=c,u;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(u=e=>{let n=t.current;n&&ne({scrollWidth:n.scrollWidth,clientWidth:n.clientWidth,deltaX:e.deltaX,deltaY:e.deltaY})&&(e.preventDefault(),n.scrollBy({left:e.deltaY,behavior:`auto`}))},e[2]=u):u=e[2];let d=u,f,p;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(f=()=>{let e=t.current;if(!e)return;let n=window.requestAnimationFrame(s),r=()=>s();e.addEventListener(`scroll`,r,{passive:!0});let i=new ResizeObserver(()=>s());return i.observe(e),()=>{window.cancelAnimationFrame(n),e.removeEventListener(`scroll`,r),i.disconnect()}},p=[s],e[3]=f,e[4]=p):(f=e[3],p=e[4]),(0,X.useEffect)(f,p);let m;return e[5]!==n||e[6]!==i?(m={ref:t,canScrollLeft:n,canScrollRight:i,scrollBy:l,onWheel:d,remeasure:s},e[5]=n,e[6]=i,e[7]=m):m=e[7],m}function Ee(e,t){let n=(0,$.c)(5),r;n[0]===e.current?r=n[1]:(r=()=>{(e.current?.querySelector(`[data-turn-chip-selected='true']`))?.scrollIntoView({block:`nearest`,inline:`nearest`,behavior:`smooth`})},n[0]=e.current,n[1]=r);let i;n[2]!==e||n[3]!==t?(i=[e,t],n[2]=e,n[3]=t,n[4]=i):i=n[4],(0,X.useEffect)(r,i)}var De=`
1
+ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{Ha as t,Mi as n,Ua as r,Wa as i}from"./Stream-mUTFnSY9.js";import{Fn as a,Hr as o,Jc as s,Kc as c,Qr as l,Rr as u,Sr as d,Tn as f,Wc as p,Xr as m,Yc as h,_r as g,d as _,fn as v,fr as y,gr as b,i as x,is as S,jl as C,jn as w,l as T,m as E,ms as D,n as O,qt as k,r as A,u as j,za as M,zr as N}from"./DiffPanelShell-BNlM5rgR.js";import{hn as P}from"./CompositeItem-B_Qce_Zi.js";import{a as F,c as I,f as L,i as R,l as z,m as B,n as V,o as H,p as U,r as W,s as G,t as K}from"./Virtualizer-D7RZbEUD.js";import{Dn as q,at as J,it as ee}from"./src-IM0FnQax.js";import{a as te,c as ne,d as re,h as ie,i as ae,l as oe,m as se,n as ce,o as Y,p as le,r as ue,s as de,t as fe,u as pe}from"./DiffPanel.logic-D4uCCekM.js";var X=e(i(),1),me=typeof window>`u`?X.useEffect:X.useLayoutEffect;function he({fileDiff:e,options:t,editorOptions:n,lineAnnotations:r,selectedLines:i,prerenderedHTML:a,metrics:o,hasGutterRenderUtility:s,hasCustomHeader:c,disableWorkerPool:l,edit:u}){let d=V(),f=i!==void 0,p=(0,X.useContext)(x),m=j(),h=(0,X.useRef)(null),g=_(n=>{if(n!=null){if(h.current!=null)throw Error(`useFileDiffInstance: An instance should not already exist when a node is created`);d==null?h.current=new re(Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),l?void 0:p,!0):h.current=new pe(Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),d,o,l?void 0:p,!0),h.current.hydrate({fileDiff:e,fileContainer:n,lineAnnotations:r,prerenderedHTML:a})}else{if(h.current==null)throw Error(`useFileDiffInstance: A FileDiff instance should exist when unmounting`);h.current.cleanUp(),h.current=null}});return me(()=>{let{current:n}=h;if(n==null)return;let a=Z({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),o=a!==void 0&&!k(n.options,a);n.setOptions(a),n.render({forceRender:o,fileDiff:e,lineAnnotations:r}),i!==void 0&&n.setSelectedLines(i)}),me(()=>{if(u&&h.current!=null){if(m===void 0)throw Error(`FileDiff: EditContext is not attached`);let e=m(n??{});if(e==null)throw Error(`FileDiff: EditProvider.createEditor must return an editor instance`);try{return e.edit(h.current)}catch(t){throw e.cleanUp(),t}}},[u]),{ref:g,getHoveredLine:(0,X.useCallback)(()=>h.current?.getHoveredLine(),[])}}function Z({options:e,controlledSelection:t,hasCustomHeader:n,hasGutterRenderUtility:r}){return t||r||n?{...e,controlledSelection:t,renderCustomHeader:n?T:e?.renderCustomHeader,renderGutterUtility:r?T:e?.renderGutterUtility}:e}var Q=r();function ge({fileDiff:e,options:t,editorOptions:n,metrics:r,lineAnnotations:i,selectedLines:a,className:o,style:s,prerenderedHTML:c,renderAnnotation:l,renderCustomHeader:u,renderHeaderPrefix:d,renderHeaderFilenameSuffix:f,renderHeaderMetadata:p,renderGutterUtility:m,disableWorkerPool:h=!1,edit:g=!1}){let{ref:_,getHoveredLine:y}=he({fileDiff:e,options:t,editorOptions:n,metrics:r,lineAnnotations:i,selectedLines:a,prerenderedHTML:c,hasGutterRenderUtility:m!=null,hasCustomHeader:u!=null,disableWorkerPool:h,edit:g});return(0,Q.jsx)(v,{ref:_,className:o,style:s,children:W(oe({fileDiff:e,renderCustomHeader:u,renderHeaderPrefix:d,renderHeaderFilenameSuffix:f,renderHeaderMetadata:p,renderAnnotation:l,renderGutterUtility:m,lineAnnotations:i,getHoveredLine:y}),c)})}var $=t();function _e(e){return e.fromTurnCount===0?q(ee)({threadId:e.threadId,toTurnCount:e.toTurnCount}).pipe(n(e=>({kind:`fullThreadDiff`,input:e}))):q(J)({threadId:e.threadId,fromTurnCount:e.fromTurnCount,toTurnCount:e.toTurnCount}).pipe(n(e=>({kind:`turnDiff`,input:e})))}function ve(e){return e instanceof Error?e.message:typeof e==`string`?e:``}function ye(e){let t=ve(e).trim();if(t.length===0)return`Failed to load checkpoint diff.`;let n=t.toLowerCase();if(n.includes(`not a git repository`))return`Turn diffs are unavailable because this project is not a git repository.`;if(n.includes(`checkpoint unavailable for thread`)||n.includes(`checkpoint invariant violation`)){let e=t.indexOf(`:`);if(e>=0){let n=t.slice(e+1).trim();if(n.length>0)return n}}return t}function be(e){let t=ve(e).toLowerCase();return t.includes(`exceeds current turn count`)||t.includes(`checkpoint is unavailable for turn`)||t.includes(`filesystem checkpoint is unavailable`)}function xe(e){let t=_e(e);return s({queryKey:M.checkpointDiff(e),queryFn:async({signal:n})=>{if(!e.environmentId||!e.threadId||t._tag===`None`)throw Error(`Checkpoint diff is unavailable.`);let r=o(e.environmentId);try{return t.value.kind===`fullThreadDiff`?await r.orchestration.getFullThreadDiff(t.value.input,{signal:n}):await r.orchestration.getTurnDiff(t.value.input,{signal:n})}catch(e){throw Error(ye(e),{cause:e})}},enabled:(e.enabled??!0)&&!!e.environmentId&&!!e.threadId&&t._tag===`Some`,staleTime:1/0,retry:(e,t)=>be(t)?e<12:e<3,retryDelay:(e,t)=>be(t)?Math.min(5e3,250*2**(e-1)):Math.min(1e3,100*2**(e-1))})}function Se(e){if(!(!e.canScrollLeft&&!e.canScrollRight))return{maskImage:`linear-gradient(to right, ${e.canScrollLeft?`transparent 24px, black 72px`:`black`}, ${e.canScrollRight?`black calc(100% - 72px), transparent calc(100% - 24px)`:`black`})`}}function Ce(e){return e instanceof Error?e.message:e?`Failed to load checkpoint diff.`:null}function we(e){return{environmentId:e.environmentId??null,threadId:e.threadId,fromTurnCount:e.range?.fromTurnCount??null,toTurnCount:e.range?.toTurnCount??null,cacheScope:e.selectedTurnId?`turn:${e.selectedTurnId}`:e.conversationCacheScope,enabled:e.enabled}}function Te(){let e=(0,$.c)(8),t=(0,X.useRef)(null),[n,r]=(0,X.useState)(!1),[i,a]=(0,X.useState)(!1),o;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(o=()=>{let e=t.current;if(!e){r(!1),a(!1);return}let n=de({scrollLeft:e.scrollLeft,scrollWidth:e.scrollWidth,clientWidth:e.clientWidth});r(n.canScrollLeft),a(n.canScrollRight)},e[0]=o):o=e[0];let s=o,c;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(c=e=>{t.current?.scrollBy({left:e,behavior:`smooth`})},e[1]=c):c=e[1];let l=c,u;e[2]===Symbol.for(`react.memo_cache_sentinel`)?(u=e=>{let n=t.current;n&&ne({scrollWidth:n.scrollWidth,clientWidth:n.clientWidth,deltaX:e.deltaX,deltaY:e.deltaY})&&(e.preventDefault(),n.scrollBy({left:e.deltaY,behavior:`auto`}))},e[2]=u):u=e[2];let d=u,f,p;e[3]===Symbol.for(`react.memo_cache_sentinel`)?(f=()=>{let e=t.current;if(!e)return;let n=window.requestAnimationFrame(s),r=()=>s();e.addEventListener(`scroll`,r,{passive:!0});let i=new ResizeObserver(()=>s());return i.observe(e),()=>{window.cancelAnimationFrame(n),e.removeEventListener(`scroll`,r),i.disconnect()}},p=[s],e[3]=f,e[4]=p):(f=e[3],p=e[4]),(0,X.useEffect)(f,p);let m;return e[5]!==n||e[6]!==i?(m={ref:t,canScrollLeft:n,canScrollRight:i,scrollBy:l,onWheel:d,remeasure:s},e[5]=n,e[6]=i,e[7]=m):m=e[7],m}function Ee(e,t){let n=(0,$.c)(5),r;n[0]===e.current?r=n[1]:(r=()=>{(e.current?.querySelector(`[data-turn-chip-selected='true']`))?.scrollIntoView({block:`nearest`,inline:`nearest`,behavior:`smooth`})},n[0]=e.current,n[1]=r);let i;n[2]!==e||n[3]!==t?(i=[e,t],n[2]=e,n[3]=t,n[4]=i):i=n[4],(0,X.useEffect)(r,i)}var De=`
2
2
  [data-diffs-header],
3
3
  [data-diff],
4
4
  [data-file],
@@ -60,5 +60,5 @@ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{Ha as t,Mi as n,Ua as
60
60
  color: color-mix(in srgb, var(--foreground) 84%, var(--primary)) !important;
61
61
  text-decoration-color: currentColor;
62
62
  }
63
- `;function Oe(e){let t=(0,$.c)(44),{mode:n}=e,r=n===void 0?`inline`:n,{resolvedTheme:i}=b(),a=g(),[c,l]=(0,X.useState)(`stacked`),[u,d]=(0,X.useState)(a.diffWordWrap),h=(0,X.useRef)(null),_=(0,X.useRef)(!1),v=Te(),{activeCwd:y,activeThread:x,bodyState:S,diffOpen:C,inferredCheckpointTurnCountByTurnId:w,orderedTurnDiffSummaries:T,renderableFiles:E,renderablePatch:D,selectedFilePath:O,selectedTurn:k,selectedTurnId:j}=Le(i),M,P;t[0]!==C||t[1]!==a.diffWordWrap?(M=()=>{C&&!_.current&&d(a.diffWordWrap),_.current=C},P=[C,a.diffWordWrap],t[0]=C,t[1]=a.diffWordWrap,t[2]=M,t[3]=P):(M=t[2],P=t[3]),(0,X.useEffect)(M,P);let F;t[4]===O?F=t[5]:(F=()=>{!O||!h.current||Array.from(h.current.querySelectorAll(`[data-diff-file-path]`)).find(e=>e.dataset.diffFilePath===O)?.scrollIntoView({block:`nearest`})},t[4]=O,t[5]=F);let I;t[6]!==E||t[7]!==O?(I=[O,E],t[6]=E,t[7]=O,t[8]=I):I=t[8],(0,X.useEffect)(F,I);let L;t[9]===y?L=t[10]:(L=e=>{let t=f();if(!t)return;let n=y?p(e,y):e;N(t,n).catch(ke)},t[9]=y,t[10]=L);let R=L,z;t[11]===x?z=t[12]:(z=e=>{x&&o.getState().openDiff(s(m(x.environmentId,x.id)),e)},t[11]=x,t[12]=z);let B=z,V;t[13]===x?V=t[14]:(V=()=>{x&&o.getState().openDiff(s(m(x.environmentId,x.id)))},t[13]=x,t[14]=V);let H=V,U;t[15]===v.remeasure?U=t[16]:(U=()=>{let e=window.requestAnimationFrame(v.remeasure);return()=>window.cancelAnimationFrame(e)},t[15]=v.remeasure,t[16]=U);let W;t[17]!==T||t[18]!==j||t[19]!==v.remeasure?(W=[T,j,v.remeasure],t[17]=T,t[18]=j,t[19]=v.remeasure,t[20]=W):W=t[20],(0,X.useEffect)(U,W),Ee(v.ref,k?.turnId??j);let G;t[21]!==c||t[22]!==u||t[23]!==w||t[24]!==T||t[25]!==B||t[26]!==H||t[27]!==k||t[28]!==j||t[29]!==a||t[30]!==v?(G=(0,Q.jsx)(Ae,{diffRenderMode:c,diffWordWrap:u,inferredCheckpointTurnCountByTurnId:w,orderedTurnDiffSummaries:T,selectTurn:B,selectWholeConversation:H,selectedTurn:k,selectedTurnId:j,setDiffRenderMode:l,setDiffWordWrap:d,settings:a,turnStrip:v}),t[21]=c,t[22]=u,t[23]=w,t[24]=T,t[25]=B,t[26]=H,t[27]=k,t[28]=j,t[29]=a,t[30]=v,t[31]=G):G=t[31];let K=G,q;t[32]!==S||t[33]!==c||t[34]!==u||t[35]!==R||t[36]!==E||t[37]!==D||t[38]!==i?(q=(0,Q.jsx)(je,{bodyState:S,diffRenderMode:c,diffWordWrap:u,openDiffFileInEditor:R,patchViewportRef:h,renderableFiles:E,renderablePatch:D,resolvedTheme:i}),t[32]=S,t[33]=c,t[34]=u,t[35]=R,t[36]=E,t[37]=D,t[38]=i,t[39]=q):q=t[39];let J;return t[40]!==K||t[41]!==r||t[42]!==q?(J=(0,Q.jsx)(A,{mode:r,header:K,children:q}),t[40]=K,t[41]=r,t[42]=q,t[43]=J):J=t[43],J}function ke(e){console.warn(`Failed to open diff file in editor.`,e)}function Ae(e){let t=(0,$.c)(59),{diffRenderMode:n,diffWordWrap:r,inferredCheckpointTurnCountByTurnId:i,orderedTurnDiffSummaries:a,selectTurn:o,selectWholeConversation:s,selectedTurn:c,selectedTurnId:l,setDiffRenderMode:u,setDiffWordWrap:d,settings:f,turnStrip:p}=e,m,h;t[0]===p?(m=t[1],h=t[2]):(m=(0,Q.jsx)(Be,{direction:`left`,strip:p}),h=(0,Q.jsx)(Be,{direction:`right`,strip:p}),t[0]=p,t[1]=m,t[2]=h);let g=p.ref,_;t[3]!==p.canScrollLeft||t[4]!==p.canScrollRight?(_=Se({canScrollLeft:p.canScrollLeft,canScrollRight:p.canScrollRight}),t[3]=p.canScrollLeft,t[4]=p.canScrollRight,t[5]=_):_=t[5];let v=p.onWheel,y=l===null,b=l===null?`border-border bg-accent text-accent-foreground`:`border-border/70 bg-background/70 text-muted-foreground/80 hover:border-border hover:text-foreground/80`,x;t[6]===b?x=t[7]:(x=P(`rounded-md border px-2 py-1 text-left transition-colors`,b),t[6]=b,t[7]=x);let S;t[8]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,Q.jsx)(`div`,{className:`text-[10px] leading-tight font-medium`,children:`All turns`}),t[8]=S):S=t[8];let C;t[9]===x?C=t[10]:(C=(0,Q.jsx)(`div`,{className:x,children:S}),t[9]=x,t[10]=C);let w;t[11]!==s||t[12]!==C||t[13]!==y?(w=(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 rounded-md`,onClick:s,"data-turn-chip-selected":y,children:C}),t[11]=s,t[12]=C,t[13]=y,t[14]=w):w=t[14];let T;if(t[15]!==i||t[16]!==a||t[17]!==o||t[18]!==c?.turnId||t[19]!==f){let e;t[21]!==i||t[22]!==o||t[23]!==c?.turnId||t[24]!==f?(e=e=>(0,Q.jsx)(Ve,{summary:e,selected:e.turnId===c?.turnId,turnCount:e.checkpointTurnCount??i[e.turnId],timestampFormat:f.timestampFormat,onSelect:o},e.turnId),t[21]=i,t[22]=o,t[23]=c?.turnId,t[24]=f,t[25]=e):e=t[25],T=a.map(e),t[15]=i,t[16]=a,t[17]=o,t[18]=c?.turnId,t[19]=f,t[20]=T}else T=t[20];let E;t[26]!==w||t[27]!==T||t[28]!==_||t[29]!==p.onWheel||t[30]!==p.ref?(E=(0,Q.jsxs)(`div`,{ref:g,className:`turn-chip-strip flex gap-1 overflow-x-auto px-8 py-0.5`,style:_,onWheel:v,children:[w,T]}),t[26]=w,t[27]=T,t[28]=_,t[29]=p.onWheel,t[30]=p.ref,t[31]=E):E=t[31];let D;t[32]!==m||t[33]!==E||t[34]!==h?(D=(0,Q.jsxs)(`div`,{className:`relative min-w-0 flex-1 [-webkit-app-region:no-drag]`,children:[m,h,E]}),t[32]=m,t[33]=E,t[34]=h,t[35]=D):D=t[35];let O;t[36]===n?O=t[37]:(O=[n],t[36]=n,t[37]=O);let k;t[38]===u?k=t[39]:(k=e=>{let t=e[0];(t===`stacked`||t===`split`)&&u(t)},t[38]=u,t[39]=k);let A;t[40]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,Q.jsx)(R,{"aria-label":`Stacked diff view`,value:`stacked`,children:(0,Q.jsx)(se,{className:`size-3`})}),t[40]=A):A=t[40];let j;t[41]===Symbol.for(`react.memo_cache_sentinel`)?(j=(0,Q.jsx)(R,{"aria-label":`Split diff view`,value:`split`,children:(0,Q.jsx)(ie,{className:`size-3`})}),t[41]=j):j=t[41];let M;t[42]!==O||t[43]!==k?(M=(0,Q.jsxs)(F,{className:`shrink-0`,variant:`outline`,size:`xs`,value:O,onValueChange:k,children:[A,j]}),t[42]=O,t[43]=k,t[44]=M):M=t[44];let N=r?`Disable diff line wrapping`:`Enable diff line wrapping`,I=r?`Disable line wrapping`:`Enable line wrapping`,L;t[45]===d?L=t[46]:(L=e=>{d(!!e)},t[45]=d,t[46]=L);let z;t[47]===Symbol.for(`react.memo_cache_sentinel`)?(z=(0,Q.jsx)(le,{className:`size-3`}),t[47]=z):z=t[47];let B;t[48]!==r||t[49]!==N||t[50]!==I||t[51]!==L?(B=(0,Q.jsx)(R,{"aria-label":N,title:I,variant:`outline`,size:`xs`,pressed:r,onPressedChange:L,children:z}),t[48]=r,t[49]=N,t[50]=I,t[51]=L,t[52]=B):B=t[52];let V;t[53]!==M||t[54]!==B?(V=(0,Q.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1 [-webkit-app-region:no-drag]`,children:[M,B]}),t[53]=M,t[54]=B,t[55]=V):V=t[55];let H;return t[56]!==D||t[57]!==V?(H=(0,Q.jsxs)(Q.Fragment,{children:[D,V]}),t[56]=D,t[57]=V,t[58]=H):H=t[58],H}function je(e){let t=(0,$.c)(18),{bodyState:n,diffRenderMode:r,diffWordWrap:i,openDiffFileInEditor:a,patchViewportRef:o,renderableFiles:s,renderablePatch:c,resolvedTheme:l}=e;if(n.kind===`no-thread`){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`Select a thread to inspect turn diffs.`}),t[0]=e):e=t[0],e}if(n.kind===`not-git-repo`){let e;return t[1]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`Turn diffs are unavailable because this project is not a git repository.`}),t[1]=e):e=t[1],e}if(n.kind===`no-completed-turns`){let e;return t[2]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`No completed turns yet.`}),t[2]=e):e=t[2],e}let u;t[3]!==n.error||t[4]!==c?(u=n.error&&!c&&(0,Q.jsx)(`div`,{className:`px-3`,children:(0,Q.jsx)(`p`,{className:`mb-2 text-[11px] text-destructive-foreground`,children:n.error})}),t[3]=n.error,t[4]=c,t[5]=u):u=t[5];let d;t[6]!==n||t[7]!==r||t[8]!==i||t[9]!==a||t[10]!==s||t[11]!==c||t[12]!==l?(d=c?c.kind===`files`?(0,Q.jsx)(K,{className:`diff-render-surface h-full min-h-0 overflow-auto px-2 pb-2`,config:{overscrollSize:600,intersectionObserverMargin:1200},children:s.map(e=>{let t=Y(e),n=`${fe(e)}:${l}`;return(0,Q.jsx)(`div`,{"data-diff-file-path":t,className:`diff-render-file mb-2 rounded-md first:mt-2 last:mb-0`,onClickCapture:e=>{(e.nativeEvent.composedPath?.()??[]).some(Me)&&a(t)},children:(0,Q.jsx)(ge,{fileDiff:e,options:{diffStyle:r===`split`?`split`:`unified`,lineDiffType:`none`,overflow:i?`wrap`:`scroll`,theme:T(l),themeType:l,unsafeCSS:De}})},n)})}):(0,Q.jsx)(`div`,{className:`h-full overflow-auto p-2`,children:(0,Q.jsxs)(`div`,{className:`space-y-2`,children:[(0,Q.jsx)(`p`,{className:`text-[11px] text-muted-foreground/75`,children:c.reason}),(0,Q.jsx)(`pre`,{className:P(`max-h-[72vh] rounded-md border border-border/70 bg-background/70 p-3 font-mono text-[11px] leading-relaxed text-muted-foreground/90`,i?`overflow-auto whitespace-pre-wrap wrap-break-word`:`overflow-auto`),children:c.text})]})}):(0,Q.jsx)(Re,{bodyState:n}),t[6]=n,t[7]=r,t[8]=i,t[9]=a,t[10]=s,t[11]=c,t[12]=l,t[13]=d):d=t[13];let f;return t[14]!==o||t[15]!==u||t[16]!==d?(f=(0,Q.jsx)(Q.Fragment,{children:(0,Q.jsxs)(`div`,{ref:o,className:`diff-panel-viewport min-h-0 min-w-0 flex-1 overflow-hidden`,children:[u,d]})}),t[14]=o,t[15]=u,t[16]=d,t[17]=f):f=t[17],f}function Me(e){return e instanceof Element&&e.hasAttribute(`data-title`)}function Ne(e){let t=(0,$.c)(2),{children:n}=e,r;return t[0]===n?r=t[1]:(r=(0,Q.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:n}),t[0]=n,t[1]=r),r}function Pe(){let e=(0,$.c)(19),t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={strict:!1,select:Ie},e[0]=t):t=e[0];let n=a(t),r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r={strict:!1,select:Fe},e[1]=r):r=e[1];let i=B(r),o=i.rightPanel===`diff`,s=n?.threadId??null,c,l;e[2]===n?l=e[3]:(l=C(n),e[2]=n,e[3]=l),c=l;let u=E(c),f=He(u),p=u?.worktreePath,m=f?.cwd,h;e[4]!==p||e[5]!==m?(h=I({threadWorktreePath:p,projectCwd:m}),e[4]=p,e[5]=m,e[6]=h):h=e[6];let g=h,_=u?.environmentId??null,v=g??null,y;e[7]!==_||e[8]!==v?(y={environmentId:_,cwd:v},e[7]=_,e[8]=v,e[9]=y):y=e[9];let b=d(y),x;e[10]===b.data?x=e[11]:(x=z(b.data),e[10]=b.data,e[11]=x);let S=x,w;return e[12]!==g||e[13]!==u||e[14]!==s||e[15]!==o||e[16]!==i||e[17]!==S?(w={activeThread:u,activeThreadId:s,activeCwd:g,isGitRepo:S,diffSearch:i,diffOpen:o},e[12]=g,e[13]=u,e[14]=s,e[15]=o,e[16]=i,e[17]=S,e[18]=w):w=e[18],w}function Fe(e){return G(e)}function Ie(e){return h(e)}function Le(e){let{activeThread:t,activeThreadId:n,activeCwd:r,isGitRepo:i,diffSearch:a,diffOpen:o}=Pe(),{turnDiffSummaries:s,inferredCheckpointTurnCountByTurnId:c}=H(t),u=a.diffTurnId??null,d=u===null?null:a.diffFilePath??null,{activeCheckpointRange:f,conversationCacheScope:p,orderedTurnDiffSummaries:m,selectedTurn:h}=(0,X.useMemo)(()=>te({summaries:s,inferredCheckpointTurnCountByTurnId:c,selectedTurnId:u}),[c,u,s]),g=l(xe(we({environmentId:t?.environmentId,threadId:n,range:f,selectedTurnId:h?.turnId,conversationCacheScope:p,enabled:i}))),_=g.isLoading,v=Ce(g.error),y=g.data?.diff,b=typeof y==`string`&&y.trim().length===0,{emptyDiffMessage:x}=(0,X.useMemo)(()=>ae(h),[h]),S=(0,X.useMemo)(()=>ce(y,`diff-panel:${e}`),[e,y]),C=(0,X.useMemo)(()=>Ue(S),[S]);return{activeCwd:r,activeThread:t,bodyState:ue({hasActiveThread:!!t,isGitRepo:i,turnSummaryCount:m.length,checkpointDiffError:v,hasRenderablePatch:!!S,isLoadingCheckpointDiff:_,hasNoNetChanges:b,emptyDiffMessage:x}),diffOpen:o,inferredCheckpointTurnCountByTurnId:c,orderedTurnDiffSummaries:m,renderableFiles:C,renderablePatch:S,selectedFilePath:d,selectedTurn:h,selectedTurnId:u}}function Re(e){let t=(0,$.c)(4),{bodyState:n}=e;if(n.kind===`loading`){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(D,{label:`Loading checkpoint diff...`}),t[0]=e):e=t[0],e}let r;t[1]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,Q.jsx)(L,{className:`size-7 text-muted-foreground/25`}),t[1]=r):r=t[1];let i=n.kind===`empty`?n.message:`No diff is available for this range.`,a;return t[2]===i?a=t[3]:(a=(0,Q.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-2 px-5 py-2 text-center`,children:[r,(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground/70`,children:i})]}),t[2]=i,t[3]=a),a}var ze=180;function Be(e){let t=(0,$.c)(14),{direction:n,strip:r}=e,i=n===`left`,a=i?r.canScrollLeft:r.canScrollRight,o=i?U:u,s=i?`left-0`:`right-0`,c=a?`border-border/70 hover:border-border hover:text-foreground`:`cursor-not-allowed border-border/40 text-muted-foreground/40`,l;t[0]!==s||t[1]!==c?(l=P(`absolute top-1/2 z-20 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md border bg-background/90 text-muted-foreground transition-colors`,s,c),t[0]=s,t[1]=c,t[2]=l):l=t[2];let d;t[3]!==i||t[4]!==r?(d=()=>r.scrollBy(i?-180:ze),t[3]=i,t[4]=r,t[5]=d):d=t[5];let f=!a,p=`Scroll turn list ${n}`,m;t[6]===o?m=t[7]:(m=(0,Q.jsx)(o,{className:`size-3.5`}),t[6]=o,t[7]=m);let h;return t[8]!==l||t[9]!==d||t[10]!==f||t[11]!==p||t[12]!==m?(h=(0,Q.jsx)(`button`,{type:`button`,className:l,onClick:d,disabled:f,"aria-label":p,children:m}),t[8]=l,t[9]=d,t[10]=f,t[11]=p,t[12]=m,t[13]=h):h=t[13],h}function Ve(e){let t=(0,$.c)(23),{summary:n,selected:r,turnCount:i,timestampFormat:a,onSelect:o}=e,s;t[0]!==o||t[1]!==n.turnId?(s=()=>o(n.turnId),t[0]=o,t[1]=n.turnId,t[2]=s):s=t[2];let c=n.turnId,l=r?`border-border bg-accent text-accent-foreground`:`border-border/70 bg-background/70 text-muted-foreground/80 hover:border-border hover:text-foreground/80`,u;t[3]===l?u=t[4]:(u=P(`rounded-md border px-2 py-1 text-left transition-colors`,l),t[3]=l,t[4]=u);let d=i??`?`,f;t[5]===d?f=t[6]:(f=(0,Q.jsxs)(`span`,{className:`text-[10px] leading-tight font-medium`,children:[`Turn `,d]}),t[5]=d,t[6]=f);let p;t[7]!==n.completedAt||t[8]!==a?(p=y(n.completedAt,a),t[7]=n.completedAt,t[8]=a,t[9]=p):p=t[9];let m;t[10]===p?m=t[11]:(m=(0,Q.jsx)(`span`,{className:`text-[9px] leading-tight opacity-70`,children:p}),t[10]=p,t[11]=m);let h;t[12]!==f||t[13]!==m?(h=(0,Q.jsxs)(`div`,{className:`flex items-center gap-1`,children:[f,m]}),t[12]=f,t[13]=m,t[14]=h):h=t[14];let g;t[15]!==u||t[16]!==h?(g=(0,Q.jsx)(`div`,{className:u,children:h}),t[15]=u,t[16]=h,t[17]=g):g=t[17];let _;return t[18]!==r||t[19]!==n.turnId||t[20]!==s||t[21]!==g?(_=(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 rounded-md`,onClick:s,title:c,"data-turn-chip-selected":r,children:g}),t[18]=r,t[19]=n.turnId,t[20]=s,t[21]=g,t[22]=_):_=t[22],_}function He(e){let t=(0,$.c)(3),n=e?.environmentId,r=e?.projectId,i;return t[0]!==n||t[1]!==r?(i=e=>n&&r?S(e,{environmentId:n,projectId:r}):void 0,t[0]=n,t[1]=r,t[2]=i):i=t[2],E(i)}function Ue(e){return!e||e.kind!==`files`?[]:e.files.toSorted((e,t)=>Y(e).localeCompare(Y(t),void 0,{numeric:!0,sensitivity:`base`}))}export{Oe as default};
64
- //# sourceMappingURL=DiffPanel-BEf3EXPK.js.map
63
+ `;function Oe(e){let t=(0,$.c)(44),{mode:n}=e,r=n===void 0?`inline`:n,{resolvedTheme:i}=b(),o=g(),[s,l]=(0,X.useState)(`stacked`),[u,m]=(0,X.useState)(o.diffWordWrap),h=(0,X.useRef)(null),_=(0,X.useRef)(!1),v=Te(),{activeCwd:y,activeThread:x,bodyState:S,diffOpen:C,inferredCheckpointTurnCountByTurnId:w,orderedTurnDiffSummaries:T,renderableFiles:E,renderablePatch:D,selectedFilePath:O,selectedTurn:k,selectedTurnId:j}=Le(i),M,P;t[0]!==C||t[1]!==o.diffWordWrap?(M=()=>{C&&!_.current&&m(o.diffWordWrap),_.current=C},P=[C,o.diffWordWrap],t[0]=C,t[1]=o.diffWordWrap,t[2]=M,t[3]=P):(M=t[2],P=t[3]),(0,X.useEffect)(M,P);let F;t[4]===O?F=t[5]:(F=()=>{!O||!h.current||Array.from(h.current.querySelectorAll(`[data-diff-file-path]`)).find(e=>e.dataset.diffFilePath===O)?.scrollIntoView({block:`nearest`})},t[4]=O,t[5]=F);let I;t[6]!==E||t[7]!==O?(I=[O,E],t[6]=E,t[7]=O,t[8]=I):I=t[8],(0,X.useEffect)(F,I);let L;t[9]===y?L=t[10]:(L=e=>{let t=d();if(!t)return;let n=y?f(e,y):e;N(t,n).catch(ke)},t[9]=y,t[10]=L);let R=L,z;t[11]===x?z=t[12]:(z=e=>{x&&a.getState().openDiff(c(p(x.environmentId,x.id)),e)},t[11]=x,t[12]=z);let B=z,V;t[13]===x?V=t[14]:(V=()=>{x&&a.getState().openDiff(c(p(x.environmentId,x.id)))},t[13]=x,t[14]=V);let H=V,U;t[15]===v.remeasure?U=t[16]:(U=()=>{let e=window.requestAnimationFrame(v.remeasure);return()=>window.cancelAnimationFrame(e)},t[15]=v.remeasure,t[16]=U);let W;t[17]!==T||t[18]!==j||t[19]!==v.remeasure?(W=[T,j,v.remeasure],t[17]=T,t[18]=j,t[19]=v.remeasure,t[20]=W):W=t[20],(0,X.useEffect)(U,W),Ee(v.ref,k?.turnId??j);let G;t[21]!==s||t[22]!==u||t[23]!==w||t[24]!==T||t[25]!==B||t[26]!==H||t[27]!==k||t[28]!==j||t[29]!==o||t[30]!==v?(G=(0,Q.jsx)(Ae,{diffRenderMode:s,diffWordWrap:u,inferredCheckpointTurnCountByTurnId:w,orderedTurnDiffSummaries:T,selectTurn:B,selectWholeConversation:H,selectedTurn:k,selectedTurnId:j,setDiffRenderMode:l,setDiffWordWrap:m,settings:o,turnStrip:v}),t[21]=s,t[22]=u,t[23]=w,t[24]=T,t[25]=B,t[26]=H,t[27]=k,t[28]=j,t[29]=o,t[30]=v,t[31]=G):G=t[31];let K=G,q;t[32]!==S||t[33]!==s||t[34]!==u||t[35]!==R||t[36]!==E||t[37]!==D||t[38]!==i?(q=(0,Q.jsx)(je,{bodyState:S,diffRenderMode:s,diffWordWrap:u,openDiffFileInEditor:R,patchViewportRef:h,renderableFiles:E,renderablePatch:D,resolvedTheme:i}),t[32]=S,t[33]=s,t[34]=u,t[35]=R,t[36]=E,t[37]=D,t[38]=i,t[39]=q):q=t[39];let J;return t[40]!==K||t[41]!==r||t[42]!==q?(J=(0,Q.jsx)(A,{mode:r,header:K,children:q}),t[40]=K,t[41]=r,t[42]=q,t[43]=J):J=t[43],J}function ke(e){console.warn(`Failed to open diff file in editor.`,e)}function Ae(e){let t=(0,$.c)(59),{diffRenderMode:n,diffWordWrap:r,inferredCheckpointTurnCountByTurnId:i,orderedTurnDiffSummaries:a,selectTurn:o,selectWholeConversation:s,selectedTurn:c,selectedTurnId:l,setDiffRenderMode:u,setDiffWordWrap:d,settings:f,turnStrip:p}=e,m,h;t[0]===p?(m=t[1],h=t[2]):(m=(0,Q.jsx)(Be,{direction:`left`,strip:p}),h=(0,Q.jsx)(Be,{direction:`right`,strip:p}),t[0]=p,t[1]=m,t[2]=h);let g=p.ref,_;t[3]!==p.canScrollLeft||t[4]!==p.canScrollRight?(_=Se({canScrollLeft:p.canScrollLeft,canScrollRight:p.canScrollRight}),t[3]=p.canScrollLeft,t[4]=p.canScrollRight,t[5]=_):_=t[5];let v=p.onWheel,y=l===null,b=l===null?`border-border bg-accent text-accent-foreground`:`border-border/70 bg-background/70 text-muted-foreground/80 hover:border-border hover:text-foreground/80`,x;t[6]===b?x=t[7]:(x=P(`rounded-md border px-2 py-1 text-left transition-colors`,b),t[6]=b,t[7]=x);let S;t[8]===Symbol.for(`react.memo_cache_sentinel`)?(S=(0,Q.jsx)(`div`,{className:`text-[10px] leading-tight font-medium`,children:`All turns`}),t[8]=S):S=t[8];let C;t[9]===x?C=t[10]:(C=(0,Q.jsx)(`div`,{className:x,children:S}),t[9]=x,t[10]=C);let w;t[11]!==s||t[12]!==C||t[13]!==y?(w=(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 rounded-md`,onClick:s,"data-turn-chip-selected":y,children:C}),t[11]=s,t[12]=C,t[13]=y,t[14]=w):w=t[14];let T;if(t[15]!==i||t[16]!==a||t[17]!==o||t[18]!==c?.turnId||t[19]!==f){let e;t[21]!==i||t[22]!==o||t[23]!==c?.turnId||t[24]!==f?(e=e=>(0,Q.jsx)(Ve,{summary:e,selected:e.turnId===c?.turnId,turnCount:e.checkpointTurnCount??i[e.turnId],timestampFormat:f.timestampFormat,onSelect:o},e.turnId),t[21]=i,t[22]=o,t[23]=c?.turnId,t[24]=f,t[25]=e):e=t[25],T=a.map(e),t[15]=i,t[16]=a,t[17]=o,t[18]=c?.turnId,t[19]=f,t[20]=T}else T=t[20];let E;t[26]!==w||t[27]!==T||t[28]!==_||t[29]!==p.onWheel||t[30]!==p.ref?(E=(0,Q.jsxs)(`div`,{ref:g,className:`turn-chip-strip flex gap-1 overflow-x-auto px-8 py-0.5`,style:_,onWheel:v,children:[w,T]}),t[26]=w,t[27]=T,t[28]=_,t[29]=p.onWheel,t[30]=p.ref,t[31]=E):E=t[31];let D;t[32]!==m||t[33]!==E||t[34]!==h?(D=(0,Q.jsxs)(`div`,{className:`relative min-w-0 flex-1 [-webkit-app-region:no-drag]`,children:[m,h,E]}),t[32]=m,t[33]=E,t[34]=h,t[35]=D):D=t[35];let O;t[36]===n?O=t[37]:(O=[n],t[36]=n,t[37]=O);let k;t[38]===u?k=t[39]:(k=e=>{let t=e[0];(t===`stacked`||t===`split`)&&u(t)},t[38]=u,t[39]=k);let A;t[40]===Symbol.for(`react.memo_cache_sentinel`)?(A=(0,Q.jsx)(R,{"aria-label":`Stacked diff view`,value:`stacked`,children:(0,Q.jsx)(se,{className:`size-3`})}),t[40]=A):A=t[40];let j;t[41]===Symbol.for(`react.memo_cache_sentinel`)?(j=(0,Q.jsx)(R,{"aria-label":`Split diff view`,value:`split`,children:(0,Q.jsx)(ie,{className:`size-3`})}),t[41]=j):j=t[41];let M;t[42]!==O||t[43]!==k?(M=(0,Q.jsxs)(F,{className:`shrink-0`,variant:`outline`,size:`xs`,value:O,onValueChange:k,children:[A,j]}),t[42]=O,t[43]=k,t[44]=M):M=t[44];let N=r?`Disable diff line wrapping`:`Enable diff line wrapping`,I=r?`Disable line wrapping`:`Enable line wrapping`,L;t[45]===d?L=t[46]:(L=e=>{d(!!e)},t[45]=d,t[46]=L);let z;t[47]===Symbol.for(`react.memo_cache_sentinel`)?(z=(0,Q.jsx)(le,{className:`size-3`}),t[47]=z):z=t[47];let B;t[48]!==r||t[49]!==N||t[50]!==I||t[51]!==L?(B=(0,Q.jsx)(R,{"aria-label":N,title:I,variant:`outline`,size:`xs`,pressed:r,onPressedChange:L,children:z}),t[48]=r,t[49]=N,t[50]=I,t[51]=L,t[52]=B):B=t[52];let V;t[53]!==M||t[54]!==B?(V=(0,Q.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1 [-webkit-app-region:no-drag]`,children:[M,B]}),t[53]=M,t[54]=B,t[55]=V):V=t[55];let H;return t[56]!==D||t[57]!==V?(H=(0,Q.jsxs)(Q.Fragment,{children:[D,V]}),t[56]=D,t[57]=V,t[58]=H):H=t[58],H}function je(e){let t=(0,$.c)(18),{bodyState:n,diffRenderMode:r,diffWordWrap:i,openDiffFileInEditor:a,patchViewportRef:o,renderableFiles:s,renderablePatch:c,resolvedTheme:l}=e;if(n.kind===`no-thread`){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`Select a thread to inspect turn diffs.`}),t[0]=e):e=t[0],e}if(n.kind===`not-git-repo`){let e;return t[1]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`Turn diffs are unavailable because this project is not a git repository.`}),t[1]=e):e=t[1],e}if(n.kind===`no-completed-turns`){let e;return t[2]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(Ne,{children:`No completed turns yet.`}),t[2]=e):e=t[2],e}let u;t[3]!==n.error||t[4]!==c?(u=n.error&&!c&&(0,Q.jsx)(`div`,{className:`px-3`,children:(0,Q.jsx)(`p`,{className:`mb-2 text-[11px] text-destructive-foreground`,children:n.error})}),t[3]=n.error,t[4]=c,t[5]=u):u=t[5];let d;t[6]!==n||t[7]!==r||t[8]!==i||t[9]!==a||t[10]!==s||t[11]!==c||t[12]!==l?(d=c?c.kind===`files`?(0,Q.jsx)(K,{className:`diff-render-surface h-full min-h-0 overflow-auto px-2 pb-2`,config:{overscrollSize:600,intersectionObserverMargin:1200},children:s.map(e=>{let t=Y(e),n=`${fe(e)}:${l}`;return(0,Q.jsx)(`div`,{"data-diff-file-path":t,className:`diff-render-file mb-2 rounded-md first:mt-2 last:mb-0`,onClickCapture:e=>{(e.nativeEvent.composedPath?.()??[]).some(Me)&&a(t)},children:(0,Q.jsx)(ge,{fileDiff:e,options:{diffStyle:r===`split`?`split`:`unified`,lineDiffType:`none`,overflow:i?`wrap`:`scroll`,theme:E(l),themeType:l,unsafeCSS:De}})},n)})}):(0,Q.jsx)(`div`,{className:`h-full overflow-auto p-2`,children:(0,Q.jsxs)(`div`,{className:`space-y-2`,children:[(0,Q.jsx)(`p`,{className:`text-[11px] text-muted-foreground/75`,children:c.reason}),(0,Q.jsx)(`pre`,{className:P(`max-h-[72vh] rounded-md border border-border/70 bg-background/70 p-3 font-mono text-[11px] leading-relaxed text-muted-foreground/90`,i?`overflow-auto whitespace-pre-wrap wrap-break-word`:`overflow-auto`),children:c.text})]})}):(0,Q.jsx)(Re,{bodyState:n}),t[6]=n,t[7]=r,t[8]=i,t[9]=a,t[10]=s,t[11]=c,t[12]=l,t[13]=d):d=t[13];let f;return t[14]!==o||t[15]!==u||t[16]!==d?(f=(0,Q.jsx)(Q.Fragment,{children:(0,Q.jsxs)(`div`,{ref:o,className:`diff-panel-viewport min-h-0 min-w-0 flex-1 overflow-hidden`,children:[u,d]})}),t[14]=o,t[15]=u,t[16]=d,t[17]=f):f=t[17],f}function Me(e){return e instanceof Element&&e.hasAttribute(`data-title`)}function Ne(e){let t=(0,$.c)(2),{children:n}=e,r;return t[0]===n?r=t[1]:(r=(0,Q.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:n}),t[0]=n,t[1]=r),r}function Pe(){let e=(0,$.c)(19),t;e[0]===Symbol.for(`react.memo_cache_sentinel`)?(t={strict:!1,select:Ie},e[0]=t):t=e[0];let n=C(t),r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r={strict:!1,select:Fe},e[1]=r):r=e[1];let i=B(r),a=i.rightPanel===`diff`,o=n?.threadId??null,s,c;e[2]===n?c=e[3]:(c=w(n),e[2]=n,e[3]=c),s=c;let l=D(s),d=He(l),f=l?.worktreePath,p=d?.cwd,m;e[4]!==f||e[5]!==p?(m=I({threadWorktreePath:f,projectCwd:p}),e[4]=f,e[5]=p,e[6]=m):m=e[6];let h=m,g=l?.environmentId??null,_=h??null,v;e[7]!==g||e[8]!==_?(v={environmentId:g,cwd:_},e[7]=g,e[8]=_,e[9]=v):v=e[9];let y=u(v),b;e[10]===y.data?b=e[11]:(b=z(y.data),e[10]=y.data,e[11]=b);let x=b,S;return e[12]!==h||e[13]!==l||e[14]!==o||e[15]!==a||e[16]!==i||e[17]!==x?(S={activeThread:l,activeThreadId:o,activeCwd:h,isGitRepo:x,diffSearch:i,diffOpen:a},e[12]=h,e[13]=l,e[14]=o,e[15]=a,e[16]=i,e[17]=x,e[18]=S):S=e[18],S}function Fe(e){return G(e)}function Ie(e){return m(e)}function Le(e){let{activeThread:t,activeThreadId:n,activeCwd:r,isGitRepo:i,diffSearch:a,diffOpen:o}=Pe(),{turnDiffSummaries:s,inferredCheckpointTurnCountByTurnId:c}=H(t),l=a.diffTurnId??null,u=l===null?null:a.diffFilePath??null,{activeCheckpointRange:d,conversationCacheScope:f,orderedTurnDiffSummaries:p,selectedTurn:m}=(0,X.useMemo)(()=>te({summaries:s,inferredCheckpointTurnCountByTurnId:c,selectedTurnId:l}),[c,l,s]),g=h(xe(we({environmentId:t?.environmentId,threadId:n,range:d,selectedTurnId:m?.turnId,conversationCacheScope:f,enabled:i}))),_=g.isLoading,v=Ce(g.error),y=g.data?.diff,b=typeof y==`string`&&y.trim().length===0,{emptyDiffMessage:x}=(0,X.useMemo)(()=>ae(m),[m]),S=(0,X.useMemo)(()=>ce(y,`diff-panel:${e}`),[e,y]),C=(0,X.useMemo)(()=>Ue(S),[S]);return{activeCwd:r,activeThread:t,bodyState:ue({hasActiveThread:!!t,isGitRepo:i,turnSummaryCount:p.length,checkpointDiffError:v,hasRenderablePatch:!!S,isLoadingCheckpointDiff:_,hasNoNetChanges:b,emptyDiffMessage:x}),diffOpen:o,inferredCheckpointTurnCountByTurnId:c,orderedTurnDiffSummaries:p,renderableFiles:C,renderablePatch:S,selectedFilePath:u,selectedTurn:m,selectedTurnId:l}}function Re(e){let t=(0,$.c)(4),{bodyState:n}=e;if(n.kind===`loading`){let e;return t[0]===Symbol.for(`react.memo_cache_sentinel`)?(e=(0,Q.jsx)(O,{label:`Loading checkpoint diff...`}),t[0]=e):e=t[0],e}let r;t[1]===Symbol.for(`react.memo_cache_sentinel`)?(r=(0,Q.jsx)(L,{className:`size-7 text-muted-foreground/25`}),t[1]=r):r=t[1];let i=n.kind===`empty`?n.message:`No diff is available for this range.`,a;return t[2]===i?a=t[3]:(a=(0,Q.jsxs)(`div`,{className:`flex h-full flex-col items-center justify-center gap-2 px-5 py-2 text-center`,children:[r,(0,Q.jsx)(`p`,{className:`text-xs text-muted-foreground/70`,children:i})]}),t[2]=i,t[3]=a),a}var ze=180;function Be(e){let t=(0,$.c)(14),{direction:n,strip:r}=e,i=n===`left`,a=i?r.canScrollLeft:r.canScrollRight,o=i?U:l,s=i?`left-0`:`right-0`,c=a?`border-border/70 hover:border-border hover:text-foreground`:`cursor-not-allowed border-border/40 text-muted-foreground/40`,u;t[0]!==s||t[1]!==c?(u=P(`absolute top-1/2 z-20 inline-flex size-6 -translate-y-1/2 items-center justify-center rounded-md border bg-background/90 text-muted-foreground transition-colors`,s,c),t[0]=s,t[1]=c,t[2]=u):u=t[2];let d;t[3]!==i||t[4]!==r?(d=()=>r.scrollBy(i?-180:ze),t[3]=i,t[4]=r,t[5]=d):d=t[5];let f=!a,p=`Scroll turn list ${n}`,m;t[6]===o?m=t[7]:(m=(0,Q.jsx)(o,{className:`size-3.5`}),t[6]=o,t[7]=m);let h;return t[8]!==u||t[9]!==d||t[10]!==f||t[11]!==p||t[12]!==m?(h=(0,Q.jsx)(`button`,{type:`button`,className:u,onClick:d,disabled:f,"aria-label":p,children:m}),t[8]=u,t[9]=d,t[10]=f,t[11]=p,t[12]=m,t[13]=h):h=t[13],h}function Ve(e){let t=(0,$.c)(23),{summary:n,selected:r,turnCount:i,timestampFormat:a,onSelect:o}=e,s;t[0]!==o||t[1]!==n.turnId?(s=()=>o(n.turnId),t[0]=o,t[1]=n.turnId,t[2]=s):s=t[2];let c=n.turnId,l=r?`border-border bg-accent text-accent-foreground`:`border-border/70 bg-background/70 text-muted-foreground/80 hover:border-border hover:text-foreground/80`,u;t[3]===l?u=t[4]:(u=P(`rounded-md border px-2 py-1 text-left transition-colors`,l),t[3]=l,t[4]=u);let d=i??`?`,f;t[5]===d?f=t[6]:(f=(0,Q.jsxs)(`span`,{className:`text-[10px] leading-tight font-medium`,children:[`Turn `,d]}),t[5]=d,t[6]=f);let p;t[7]!==n.completedAt||t[8]!==a?(p=y(n.completedAt,a),t[7]=n.completedAt,t[8]=a,t[9]=p):p=t[9];let m;t[10]===p?m=t[11]:(m=(0,Q.jsx)(`span`,{className:`text-[9px] leading-tight opacity-70`,children:p}),t[10]=p,t[11]=m);let h;t[12]!==f||t[13]!==m?(h=(0,Q.jsxs)(`div`,{className:`flex items-center gap-1`,children:[f,m]}),t[12]=f,t[13]=m,t[14]=h):h=t[14];let g;t[15]!==u||t[16]!==h?(g=(0,Q.jsx)(`div`,{className:u,children:h}),t[15]=u,t[16]=h,t[17]=g):g=t[17];let _;return t[18]!==r||t[19]!==n.turnId||t[20]!==s||t[21]!==g?(_=(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 rounded-md`,onClick:s,title:c,"data-turn-chip-selected":r,children:g}),t[18]=r,t[19]=n.turnId,t[20]=s,t[21]=g,t[22]=_):_=t[22],_}function He(e){let t=(0,$.c)(3),n=e?.environmentId,r=e?.projectId,i;return t[0]!==n||t[1]!==r?(i=e=>n&&r?S(e,{environmentId:n,projectId:r}):void 0,t[0]=n,t[1]=r,t[2]=i):i=t[2],D(i)}function Ue(e){return!e||e.kind!==`files`?[]:e.files.toSorted((e,t)=>Y(e).localeCompare(Y(t),void 0,{numeric:!0,sensitivity:`base`}))}export{Oe as default};
64
+ //# sourceMappingURL=DiffPanel-BuASe_Qh.js.map