@cmmd-center/forge 0.13.44 → 0.13.46
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.cjs +112 -42
- package/dist/bin.mjs +127 -42
- package/dist/client/assets/{DiffPanel-BHAsKkKi.js → DiffPanel-DtwPM18A.js} +2 -2
- package/dist/client/assets/{DiffPanel.logic-BdWiyvx0.js → DiffPanel.logic-ChgJm5ah.js} +2 -2
- package/dist/client/assets/{DiffPanelShell-Bobn6Clg.js → DiffPanelShell-src4jZSc.js} +4 -4
- package/dist/client/assets/{DiffWorkerPoolProvider-Z5jpxH96.js → DiffWorkerPoolProvider-CBvutvTu.js} +2 -2
- package/dist/client/assets/{PullRequestCodePanel-GiNxYEaL.js → PullRequestCodePanel-DTWGpKE_.js} +2 -2
- package/dist/client/assets/{Virtualizer-CuZEUMDS.js → Virtualizer-B7bxYYIG.js} +2 -2
- package/dist/client/assets/{index-BC6ONxVh.js → index-FcNN5Jgi.js} +6 -6
- package/dist/client/index.html +4 -4
- package/dist/forge-build.json +1 -1
- package/package.json +1 -1
package/dist/bin.cjs
CHANGED
|
@@ -66243,7 +66243,7 @@ function normalizeNumberish(value) {
|
|
|
66243
66243
|
}
|
|
66244
66244
|
//#endregion
|
|
66245
66245
|
//#region package.json
|
|
66246
|
-
var version$1 = "0.13.
|
|
66246
|
+
var version$1 = "0.13.46";
|
|
66247
66247
|
//#endregion
|
|
66248
66248
|
//#region src/sentry.ts
|
|
66249
66249
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -78810,7 +78810,7 @@ var GitStatusBroadcaster = class extends require_Schema$1.Service()("forge/git/S
|
|
|
78810
78810
|
//#endregion
|
|
78811
78811
|
//#region ../../packages/shared/src/git.ts
|
|
78812
78812
|
const WORKTREE_BRANCH_PREFIX = "forge";
|
|
78813
|
-
const TEMP_WORKTREE_BRANCH_PATTERN = new RegExp(
|
|
78813
|
+
const TEMP_WORKTREE_BRANCH_PATTERN = new RegExp(`^(?:${WORKTREE_BRANCH_PREFIX}|t3code)\\/(?:[0-9a-f]{8}|[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$`);
|
|
78814
78814
|
/**
|
|
78815
78815
|
* Sanitize an arbitrary string into a valid, lowercase git branch fragment.
|
|
78816
78816
|
* Strips quotes, collapses separators, limits to 64 chars.
|
|
@@ -94509,7 +94509,7 @@ const prepareBootstrapWorktree = (input) => require_Schema$1.gen(function* () {
|
|
|
94509
94509
|
projectCwd: bootstrapWorktree.projectCwd
|
|
94510
94510
|
};
|
|
94511
94511
|
});
|
|
94512
|
-
const dispatchBootstrapTurnStart = (input, command) => require_Schema$1.gen(function* () {
|
|
94512
|
+
const dispatchBootstrapTurnStart$1 = (input, command) => require_Schema$1.gen(function* () {
|
|
94513
94513
|
const { orchestrationEngine, git, gitStatusBroadcaster, projectSetupScriptRunner } = input;
|
|
94514
94514
|
const bootstrap = command.bootstrap;
|
|
94515
94515
|
const { bootstrap: _bootstrap, ...finalTurnStartCommand } = command;
|
|
@@ -94659,6 +94659,48 @@ const dispatchBootstrapTurnStart = (input, command) => require_Schema$1.gen(func
|
|
|
94659
94659
|
})), command.threadId);
|
|
94660
94660
|
});
|
|
94661
94661
|
//#endregion
|
|
94662
|
+
//#region src/orchestration/Services/SpriteTaskHoldReactor.ts
|
|
94663
|
+
/**
|
|
94664
|
+
* SpriteTaskHoldReactor - keeps a Fly.io Sprite awake while a turn is running.
|
|
94665
|
+
*
|
|
94666
|
+
* Reacts to provider turn lifecycle events and holds the sprite's run open for
|
|
94667
|
+
* the duration of each turn. See `sprite/spriteTaskHold.ts` for the measurements
|
|
94668
|
+
* and the ordering rule this depends on.
|
|
94669
|
+
*
|
|
94670
|
+
* @module SpriteTaskHoldReactor
|
|
94671
|
+
*/
|
|
94672
|
+
/**
|
|
94673
|
+
* SpriteTaskHoldReactor - Service tag for the sprite task hold worker.
|
|
94674
|
+
*/
|
|
94675
|
+
var SpriteTaskHoldReactor = class extends require_Schema$1.Service()("forge/orchestration/Services/SpriteTaskHoldReactor") {};
|
|
94676
|
+
//#endregion
|
|
94677
|
+
//#region src/orchestration/bootstrapLaunch.ts
|
|
94678
|
+
/**
|
|
94679
|
+
* The entry point for launching a thread: a bootstrap turn start, held awake.
|
|
94680
|
+
*
|
|
94681
|
+
* A launch creates the thread, adds the worktree and starts the setup script before the first
|
|
94682
|
+
* provider event exists, so no turn hold covers it. On a sprite with nothing connected that
|
|
94683
|
+
* work advances at about 1.7% of wall clock (`sprite/spriteTaskHold.ts`). A person who sends a
|
|
94684
|
+
* first message and closes the tab would otherwise wait most of an hour for a one-minute
|
|
94685
|
+
* install.
|
|
94686
|
+
*
|
|
94687
|
+
* Callers import the dispatch from here. `bootstrapDispatch.ts` stays unaware of sprites.
|
|
94688
|
+
*/
|
|
94689
|
+
/**
|
|
94690
|
+
* Runs a launch with the sprite held awake. A launch that fails or is cancelled releases the
|
|
94691
|
+
* hold. One that succeeds keeps it: the reactor hands over to the turn's own hold when the turn
|
|
94692
|
+
* starts, and the hold's refresh budget ends it if the turn never does. Where no reactor is
|
|
94693
|
+
* wired the launch runs unchanged.
|
|
94694
|
+
*/
|
|
94695
|
+
const withLaunchHold = (threadId, launch) => require_Schema$1.gen(function* () {
|
|
94696
|
+
const reactor = yield* require_Schema$1.serviceOption(SpriteTaskHoldReactor);
|
|
94697
|
+
if (require_Schema$1.isNone(reactor)) return yield* launch;
|
|
94698
|
+
const release = () => reactor.value.releaseLaunch(threadId);
|
|
94699
|
+
return yield* require_Schema$1.uninterruptible(reactor.value.holdLaunch(threadId)).pipe(require_Schema$1.andThen(require_Schema$1.yieldNow), require_Schema$1.andThen(launch), require_Schema$1.onError(release));
|
|
94700
|
+
});
|
|
94701
|
+
/** `dispatchBootstrapTurnStart` from `bootstrapDispatch.ts`, with the launch held awake. */
|
|
94702
|
+
const dispatchBootstrapTurnStart = (input, command) => withLaunchHold(String(command.threadId), dispatchBootstrapTurnStart$1(input, command));
|
|
94703
|
+
//#endregion
|
|
94662
94704
|
//#region src/orchestration/Services/OrchestrationEngine.ts
|
|
94663
94705
|
/**
|
|
94664
94706
|
* OrchestrationEngineService - Service tag for orchestration engine access.
|
|
@@ -240999,8 +241041,13 @@ var SpriteTaskHoldManager = class {
|
|
|
240999
241041
|
activeTurnIds() {
|
|
241000
241042
|
return [...this.#holds.keys()];
|
|
241001
241043
|
}
|
|
241002
|
-
|
|
241044
|
+
/**
|
|
241045
|
+
* `maxRefreshes` bounds a hold that has no terminal event of its own, such as a launch
|
|
241046
|
+
* whose turn may never start. When the budget is spent the hold releases itself.
|
|
241047
|
+
*/
|
|
241048
|
+
async acquire(turnId, threadId = null, options = {}) {
|
|
241003
241049
|
if (this.#holds.has(turnId)) return;
|
|
241050
|
+
let refreshesLeft = options.maxRefreshes ?? Number.POSITIVE_INFINITY;
|
|
241004
241051
|
const name = spriteTaskHoldName(this.#config.namePrefix, turnId);
|
|
241005
241052
|
const hold = {
|
|
241006
241053
|
name,
|
|
@@ -241024,6 +241071,11 @@ var SpriteTaskHoldManager = class {
|
|
|
241024
241071
|
if (hold.released || this.#holds.get(turnId) !== hold) return;
|
|
241025
241072
|
hold.refresher = this.#timer.setInterval(() => {
|
|
241026
241073
|
if (hold.inFlight.size > 0) return;
|
|
241074
|
+
if (refreshesLeft <= 0) {
|
|
241075
|
+
if (this.#holds.get(turnId) === hold) this.release(turnId);
|
|
241076
|
+
return;
|
|
241077
|
+
}
|
|
241078
|
+
refreshesLeft -= 1;
|
|
241027
241079
|
const refresh = this.#transport.put(name, 300).catch((cause) => this.#onError(`failed to refresh sprite task hold for turn ${turnId}`, cause));
|
|
241028
241080
|
hold.inFlight.add(refresh);
|
|
241029
241081
|
refresh.finally(() => hold.inFlight.delete(refresh));
|
|
@@ -287087,21 +287139,6 @@ var ProviderRuntimeIngestionService = class extends require_Schema$1.Service()("
|
|
|
287087
287139
|
//#region src/orchestration/Services/PlanTaskCreationReactor.ts
|
|
287088
287140
|
var PlanTaskCreationReactor = class extends require_Schema$1.Service()("forge/orchestration/Services/PlanTaskCreationReactor") {};
|
|
287089
287141
|
//#endregion
|
|
287090
|
-
//#region src/orchestration/Services/SpriteTaskHoldReactor.ts
|
|
287091
|
-
/**
|
|
287092
|
-
* SpriteTaskHoldReactor - keeps a Fly.io Sprite awake while a turn is running.
|
|
287093
|
-
*
|
|
287094
|
-
* Reacts to provider turn lifecycle events and holds the sprite's run open for
|
|
287095
|
-
* the duration of each turn. See `sprite/spriteTaskHold.ts` for the measurements
|
|
287096
|
-
* and the ordering rule this depends on.
|
|
287097
|
-
*
|
|
287098
|
-
* @module SpriteTaskHoldReactor
|
|
287099
|
-
*/
|
|
287100
|
-
/**
|
|
287101
|
-
* SpriteTaskHoldReactor - Service tag for the sprite task hold worker.
|
|
287102
|
-
*/
|
|
287103
|
-
var SpriteTaskHoldReactor = class extends require_Schema$1.Service()("forge/orchestration/Services/SpriteTaskHoldReactor") {};
|
|
287104
|
-
//#endregion
|
|
287105
287142
|
//#region src/persistence/Services/ProjectionProjects.ts
|
|
287106
287143
|
/**
|
|
287107
287144
|
* ProjectionProjectRepository - Projection repository interface for projects.
|
|
@@ -293651,34 +293688,67 @@ const CheckpointReactorLive = require_Schema$1.effect(CheckpointReactor, make$7)
|
|
|
293651
293688
|
* it is provider-agnostic: codex, claude and every other adapter emit
|
|
293652
293689
|
* `turn.started` / `turn.completed` through `ProviderService.streamEvents`.
|
|
293653
293690
|
*/
|
|
293691
|
+
/**
|
|
293692
|
+
* A launch hold refreshes every 60 s, so this budget is about ten minutes. A launch whose turn
|
|
293693
|
+
* never starts, because the provider refused it or the process died first, has no event to
|
|
293694
|
+
* release it. The budget is what stops that hold from keeping the sprite billing.
|
|
293695
|
+
*/
|
|
293696
|
+
const LAUNCH_HOLD_MAX_REFRESHES = 10;
|
|
293697
|
+
/** The hold id of a thread's launch. One launch per thread, so the thread names it. */
|
|
293698
|
+
const launchHoldId = (threadId) => `launch-${threadId}`;
|
|
293654
293699
|
const make$6 = require_Schema$1.gen(function* () {
|
|
293655
293700
|
const providerService = yield* ProviderService;
|
|
293656
293701
|
const manager = makeSpriteTaskHoldManager(process.env, (message, cause) => {
|
|
293657
293702
|
require_Schema$1.runFork(require_Schema$1.logWarning(message, { cause: cause instanceof Error ? cause.message : cause }));
|
|
293658
293703
|
});
|
|
293704
|
+
const launchCallers = /* @__PURE__ */ new Map();
|
|
293705
|
+
const start = require_Schema$1.fn("start")(function* () {
|
|
293706
|
+
if (manager === null) return;
|
|
293707
|
+
yield* require_Schema$1.forkScoped(require_Path.runForEach(providerService.streamEvents, (event) => {
|
|
293708
|
+
if (event.type === "turn.started") {
|
|
293709
|
+
const turnId = event.turnId;
|
|
293710
|
+
if (turnId === void 0) return require_Schema$1.void_;
|
|
293711
|
+
return require_Schema$1.promise(async () => {
|
|
293712
|
+
await manager.acquire(String(turnId), String(event.threadId));
|
|
293713
|
+
launchCallers.delete(String(event.threadId));
|
|
293714
|
+
await manager.release(launchHoldId(String(event.threadId)));
|
|
293715
|
+
});
|
|
293716
|
+
}
|
|
293717
|
+
if (event.type === "turn.completed") {
|
|
293718
|
+
const turnId = event.turnId;
|
|
293719
|
+
if (turnId === void 0) return require_Schema$1.void_;
|
|
293720
|
+
return require_Schema$1.promise(() => manager.release(String(turnId)));
|
|
293721
|
+
}
|
|
293722
|
+
if (event.type === "turn.aborted") {
|
|
293723
|
+
const turnId = event.turnId;
|
|
293724
|
+
if (turnId === void 0) return require_Schema$1.void_;
|
|
293725
|
+
return require_Schema$1.promise(() => manager.release(String(turnId)));
|
|
293726
|
+
}
|
|
293727
|
+
if (event.type === "session.exited") {
|
|
293728
|
+
launchCallers.delete(String(event.threadId));
|
|
293729
|
+
return require_Schema$1.promise(() => manager.releaseThread(String(event.threadId)));
|
|
293730
|
+
}
|
|
293731
|
+
return require_Schema$1.void_;
|
|
293732
|
+
}));
|
|
293733
|
+
});
|
|
293734
|
+
/** Takes the launch hold for one more caller. The budget bounds a launch that never starts a turn. */
|
|
293735
|
+
const holdLaunch = (threadId) => require_Schema$1.promise(async () => {
|
|
293736
|
+
if (manager === null) return;
|
|
293737
|
+
launchCallers.set(threadId, (launchCallers.get(threadId) ?? 0) + 1);
|
|
293738
|
+
await manager.acquire(launchHoldId(threadId), threadId, { maxRefreshes: LAUNCH_HOLD_MAX_REFRESHES });
|
|
293739
|
+
});
|
|
293740
|
+
/** Lets one caller go. The hold itself is released when the last caller has let go. */
|
|
293741
|
+
const releaseLaunch = (threadId) => require_Schema$1.promise(async () => {
|
|
293742
|
+
if (manager === null) return;
|
|
293743
|
+
const remaining = (launchCallers.get(threadId) ?? 1) - 1;
|
|
293744
|
+
if (remaining > 0) return void launchCallers.set(threadId, remaining);
|
|
293745
|
+
launchCallers.delete(threadId);
|
|
293746
|
+
await manager.release(launchHoldId(threadId));
|
|
293747
|
+
});
|
|
293659
293748
|
return {
|
|
293660
|
-
start
|
|
293661
|
-
|
|
293662
|
-
|
|
293663
|
-
if (event.type === "turn.started") {
|
|
293664
|
-
const turnId = event.turnId;
|
|
293665
|
-
if (turnId === void 0) return require_Schema$1.void_;
|
|
293666
|
-
return require_Schema$1.promise(() => manager.acquire(String(turnId), String(event.threadId)));
|
|
293667
|
-
}
|
|
293668
|
-
if (event.type === "turn.completed") {
|
|
293669
|
-
const turnId = event.turnId;
|
|
293670
|
-
if (turnId === void 0) return require_Schema$1.void_;
|
|
293671
|
-
return require_Schema$1.promise(() => manager.release(String(turnId)));
|
|
293672
|
-
}
|
|
293673
|
-
if (event.type === "turn.aborted") {
|
|
293674
|
-
const turnId = event.turnId;
|
|
293675
|
-
if (turnId === void 0) return require_Schema$1.void_;
|
|
293676
|
-
return require_Schema$1.promise(() => manager.release(String(turnId)));
|
|
293677
|
-
}
|
|
293678
|
-
if (event.type === "session.exited") return require_Schema$1.promise(() => manager.releaseThread(String(event.threadId)));
|
|
293679
|
-
return require_Schema$1.void_;
|
|
293680
|
-
}));
|
|
293681
|
-
}),
|
|
293749
|
+
start,
|
|
293750
|
+
holdLaunch,
|
|
293751
|
+
releaseLaunch,
|
|
293682
293752
|
releaseAll: require_Schema$1.promise(() => manager === null ? Promise.resolve() : manager.releaseAll())
|
|
293683
293753
|
};
|
|
293684
293754
|
});
|
|
@@ -297824,7 +297894,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
297824
297894
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
297825
297895
|
*/
|
|
297826
297896
|
function readBakedBuildCommit() {
|
|
297827
|
-
return "
|
|
297897
|
+
return "94219ed51a87e35a63d9bdc1b81bfe21c7977c17";
|
|
297828
297898
|
}
|
|
297829
297899
|
async function resolveServerBuildCommit(input) {
|
|
297830
297900
|
if (isFullCommitSha(input.baked)) return input.baked;
|
package/dist/bin.mjs
CHANGED
|
@@ -65948,7 +65948,7 @@ function normalizeNumberish(value) {
|
|
|
65948
65948
|
}
|
|
65949
65949
|
//#endregion
|
|
65950
65950
|
//#region package.json
|
|
65951
|
-
var version$1 = "0.13.
|
|
65951
|
+
var version$1 = "0.13.46";
|
|
65952
65952
|
//#endregion
|
|
65953
65953
|
//#region src/sentry.ts
|
|
65954
65954
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -78481,7 +78481,7 @@ var GitStatusBroadcaster = class extends Service$1()("forge/git/Services/GitStat
|
|
|
78481
78481
|
//#endregion
|
|
78482
78482
|
//#region ../../packages/shared/src/git.ts
|
|
78483
78483
|
const WORKTREE_BRANCH_PREFIX = "forge";
|
|
78484
|
-
const TEMP_WORKTREE_BRANCH_PATTERN = new RegExp(
|
|
78484
|
+
const TEMP_WORKTREE_BRANCH_PATTERN = new RegExp(`^(?:${WORKTREE_BRANCH_PREFIX}|t3code)\\/(?:[0-9a-f]{8}|[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12})$`);
|
|
78485
78485
|
/**
|
|
78486
78486
|
* Sanitize an arbitrary string into a valid, lowercase git branch fragment.
|
|
78487
78487
|
* Strips quotes, collapses separators, limits to 64 chars.
|
|
@@ -94146,7 +94146,7 @@ const prepareBootstrapWorktree = (input) => gen(function* () {
|
|
|
94146
94146
|
projectCwd: bootstrapWorktree.projectCwd
|
|
94147
94147
|
};
|
|
94148
94148
|
});
|
|
94149
|
-
const dispatchBootstrapTurnStart = (input, command) => gen(function* () {
|
|
94149
|
+
const dispatchBootstrapTurnStart$1 = (input, command) => gen(function* () {
|
|
94150
94150
|
const { orchestrationEngine, git, gitStatusBroadcaster, projectSetupScriptRunner } = input;
|
|
94151
94151
|
const bootstrap = command.bootstrap;
|
|
94152
94152
|
const { bootstrap: _bootstrap, ...finalTurnStartCommand } = command;
|
|
@@ -94296,6 +94296,48 @@ const dispatchBootstrapTurnStart = (input, command) => gen(function* () {
|
|
|
94296
94296
|
})), command.threadId);
|
|
94297
94297
|
});
|
|
94298
94298
|
//#endregion
|
|
94299
|
+
//#region src/orchestration/Services/SpriteTaskHoldReactor.ts
|
|
94300
|
+
/**
|
|
94301
|
+
* SpriteTaskHoldReactor - keeps a Fly.io Sprite awake while a turn is running.
|
|
94302
|
+
*
|
|
94303
|
+
* Reacts to provider turn lifecycle events and holds the sprite's run open for
|
|
94304
|
+
* the duration of each turn. See `sprite/spriteTaskHold.ts` for the measurements
|
|
94305
|
+
* and the ordering rule this depends on.
|
|
94306
|
+
*
|
|
94307
|
+
* @module SpriteTaskHoldReactor
|
|
94308
|
+
*/
|
|
94309
|
+
/**
|
|
94310
|
+
* SpriteTaskHoldReactor - Service tag for the sprite task hold worker.
|
|
94311
|
+
*/
|
|
94312
|
+
var SpriteTaskHoldReactor = class extends Service$1()("forge/orchestration/Services/SpriteTaskHoldReactor") {};
|
|
94313
|
+
//#endregion
|
|
94314
|
+
//#region src/orchestration/bootstrapLaunch.ts
|
|
94315
|
+
/**
|
|
94316
|
+
* The entry point for launching a thread: a bootstrap turn start, held awake.
|
|
94317
|
+
*
|
|
94318
|
+
* A launch creates the thread, adds the worktree and starts the setup script before the first
|
|
94319
|
+
* provider event exists, so no turn hold covers it. On a sprite with nothing connected that
|
|
94320
|
+
* work advances at about 1.7% of wall clock (`sprite/spriteTaskHold.ts`). A person who sends a
|
|
94321
|
+
* first message and closes the tab would otherwise wait most of an hour for a one-minute
|
|
94322
|
+
* install.
|
|
94323
|
+
*
|
|
94324
|
+
* Callers import the dispatch from here. `bootstrapDispatch.ts` stays unaware of sprites.
|
|
94325
|
+
*/
|
|
94326
|
+
/**
|
|
94327
|
+
* Runs a launch with the sprite held awake. A launch that fails or is cancelled releases the
|
|
94328
|
+
* hold. One that succeeds keeps it: the reactor hands over to the turn's own hold when the turn
|
|
94329
|
+
* starts, and the hold's refresh budget ends it if the turn never does. Where no reactor is
|
|
94330
|
+
* wired the launch runs unchanged.
|
|
94331
|
+
*/
|
|
94332
|
+
const withLaunchHold = (threadId, launch) => gen(function* () {
|
|
94333
|
+
const reactor = yield* serviceOption(SpriteTaskHoldReactor);
|
|
94334
|
+
if (isNone(reactor)) return yield* launch;
|
|
94335
|
+
const release = () => reactor.value.releaseLaunch(threadId);
|
|
94336
|
+
return yield* uninterruptible(reactor.value.holdLaunch(threadId)).pipe(andThen(yieldNow), andThen(launch), onError$1(release));
|
|
94337
|
+
});
|
|
94338
|
+
/** `dispatchBootstrapTurnStart` from `bootstrapDispatch.ts`, with the launch held awake. */
|
|
94339
|
+
const dispatchBootstrapTurnStart = (input, command) => withLaunchHold(String(command.threadId), dispatchBootstrapTurnStart$1(input, command));
|
|
94340
|
+
//#endregion
|
|
94299
94341
|
//#region src/orchestration/Services/OrchestrationEngine.ts
|
|
94300
94342
|
/**
|
|
94301
94343
|
* OrchestrationEngineService - Service tag for orchestration engine access.
|
|
@@ -240517,8 +240559,13 @@ var SpriteTaskHoldManager = class {
|
|
|
240517
240559
|
activeTurnIds() {
|
|
240518
240560
|
return [...this.#holds.keys()];
|
|
240519
240561
|
}
|
|
240520
|
-
|
|
240562
|
+
/**
|
|
240563
|
+
* `maxRefreshes` bounds a hold that has no terminal event of its own, such as a launch
|
|
240564
|
+
* whose turn may never start. When the budget is spent the hold releases itself.
|
|
240565
|
+
*/
|
|
240566
|
+
async acquire(turnId, threadId = null, options = {}) {
|
|
240521
240567
|
if (this.#holds.has(turnId)) return;
|
|
240568
|
+
let refreshesLeft = options.maxRefreshes ?? Number.POSITIVE_INFINITY;
|
|
240522
240569
|
const name = spriteTaskHoldName(this.#config.namePrefix, turnId);
|
|
240523
240570
|
const hold = {
|
|
240524
240571
|
name,
|
|
@@ -240542,6 +240589,11 @@ var SpriteTaskHoldManager = class {
|
|
|
240542
240589
|
if (hold.released || this.#holds.get(turnId) !== hold) return;
|
|
240543
240590
|
hold.refresher = this.#timer.setInterval(() => {
|
|
240544
240591
|
if (hold.inFlight.size > 0) return;
|
|
240592
|
+
if (refreshesLeft <= 0) {
|
|
240593
|
+
if (this.#holds.get(turnId) === hold) this.release(turnId);
|
|
240594
|
+
return;
|
|
240595
|
+
}
|
|
240596
|
+
refreshesLeft -= 1;
|
|
240545
240597
|
const refresh = this.#transport.put(name, 300).catch((cause) => this.#onError(`failed to refresh sprite task hold for turn ${turnId}`, cause));
|
|
240546
240598
|
hold.inFlight.add(refresh);
|
|
240547
240599
|
refresh.finally(() => hold.inFlight.delete(refresh));
|
|
@@ -286597,21 +286649,6 @@ var ProviderRuntimeIngestionService = class extends Service$1()("forge/orchestra
|
|
|
286597
286649
|
//#region src/orchestration/Services/PlanTaskCreationReactor.ts
|
|
286598
286650
|
var PlanTaskCreationReactor = class extends Service$1()("forge/orchestration/Services/PlanTaskCreationReactor") {};
|
|
286599
286651
|
//#endregion
|
|
286600
|
-
//#region src/orchestration/Services/SpriteTaskHoldReactor.ts
|
|
286601
|
-
/**
|
|
286602
|
-
* SpriteTaskHoldReactor - keeps a Fly.io Sprite awake while a turn is running.
|
|
286603
|
-
*
|
|
286604
|
-
* Reacts to provider turn lifecycle events and holds the sprite's run open for
|
|
286605
|
-
* the duration of each turn. See `sprite/spriteTaskHold.ts` for the measurements
|
|
286606
|
-
* and the ordering rule this depends on.
|
|
286607
|
-
*
|
|
286608
|
-
* @module SpriteTaskHoldReactor
|
|
286609
|
-
*/
|
|
286610
|
-
/**
|
|
286611
|
-
* SpriteTaskHoldReactor - Service tag for the sprite task hold worker.
|
|
286612
|
-
*/
|
|
286613
|
-
var SpriteTaskHoldReactor = class extends Service$1()("forge/orchestration/Services/SpriteTaskHoldReactor") {};
|
|
286614
|
-
//#endregion
|
|
286615
286652
|
//#region src/persistence/Services/ProjectionProjects.ts
|
|
286616
286653
|
/**
|
|
286617
286654
|
* ProjectionProjectRepository - Projection repository interface for projects.
|
|
@@ -293113,34 +293150,82 @@ const CheckpointReactorLive = effect(CheckpointReactor, gen(function* () {
|
|
|
293113
293150
|
drain: worker.drain
|
|
293114
293151
|
};
|
|
293115
293152
|
}));
|
|
293153
|
+
//#endregion
|
|
293154
|
+
//#region src/orchestration/Layers/SpriteTaskHoldReactor.ts
|
|
293155
|
+
/**
|
|
293156
|
+
* Holds the sprite awake for the duration of every agent turn.
|
|
293157
|
+
*
|
|
293158
|
+
* A sprite's cgroup freezes ~1s after the last inbound request, so a turn that
|
|
293159
|
+
* nobody is watching advances at ~1.7% of wall clock. A task hold restores it to
|
|
293160
|
+
* 100%. Measurements and the release-ordering rule live in
|
|
293161
|
+
* `sprite/spriteTaskHold.ts`; the platform contract is documented in
|
|
293162
|
+
* `docs/specs/2026-07-30-sprites-platform-ground-truth.md` §1.
|
|
293163
|
+
*
|
|
293164
|
+
* This subscribes to the same provider event stream CheckpointReactor uses, so
|
|
293165
|
+
* it is provider-agnostic: codex, claude and every other adapter emit
|
|
293166
|
+
* `turn.started` / `turn.completed` through `ProviderService.streamEvents`.
|
|
293167
|
+
*/
|
|
293168
|
+
/**
|
|
293169
|
+
* A launch hold refreshes every 60 s, so this budget is about ten minutes. A launch whose turn
|
|
293170
|
+
* never starts, because the provider refused it or the process died first, has no event to
|
|
293171
|
+
* release it. The budget is what stops that hold from keeping the sprite billing.
|
|
293172
|
+
*/
|
|
293173
|
+
const LAUNCH_HOLD_MAX_REFRESHES = 10;
|
|
293174
|
+
/** The hold id of a thread's launch. One launch per thread, so the thread names it. */
|
|
293175
|
+
const launchHoldId = (threadId) => `launch-${threadId}`;
|
|
293116
293176
|
const SpriteTaskHoldReactorLive = effect(SpriteTaskHoldReactor, gen(function* () {
|
|
293117
293177
|
const providerService = yield* ProviderService;
|
|
293118
293178
|
const manager = makeSpriteTaskHoldManager(process.env, (message, cause) => {
|
|
293119
293179
|
runFork(logWarning$1(message, { cause: cause instanceof Error ? cause.message : cause }));
|
|
293120
293180
|
});
|
|
293181
|
+
const launchCallers = /* @__PURE__ */ new Map();
|
|
293182
|
+
const start = fn$1("start")(function* () {
|
|
293183
|
+
if (manager === null) return;
|
|
293184
|
+
yield* forkScoped(runForEach(providerService.streamEvents, (event) => {
|
|
293185
|
+
if (event.type === "turn.started") {
|
|
293186
|
+
const turnId = event.turnId;
|
|
293187
|
+
if (turnId === void 0) return void_$1;
|
|
293188
|
+
return promise(async () => {
|
|
293189
|
+
await manager.acquire(String(turnId), String(event.threadId));
|
|
293190
|
+
launchCallers.delete(String(event.threadId));
|
|
293191
|
+
await manager.release(launchHoldId(String(event.threadId)));
|
|
293192
|
+
});
|
|
293193
|
+
}
|
|
293194
|
+
if (event.type === "turn.completed") {
|
|
293195
|
+
const turnId = event.turnId;
|
|
293196
|
+
if (turnId === void 0) return void_$1;
|
|
293197
|
+
return promise(() => manager.release(String(turnId)));
|
|
293198
|
+
}
|
|
293199
|
+
if (event.type === "turn.aborted") {
|
|
293200
|
+
const turnId = event.turnId;
|
|
293201
|
+
if (turnId === void 0) return void_$1;
|
|
293202
|
+
return promise(() => manager.release(String(turnId)));
|
|
293203
|
+
}
|
|
293204
|
+
if (event.type === "session.exited") {
|
|
293205
|
+
launchCallers.delete(String(event.threadId));
|
|
293206
|
+
return promise(() => manager.releaseThread(String(event.threadId)));
|
|
293207
|
+
}
|
|
293208
|
+
return void_$1;
|
|
293209
|
+
}));
|
|
293210
|
+
});
|
|
293211
|
+
/** Takes the launch hold for one more caller. The budget bounds a launch that never starts a turn. */
|
|
293212
|
+
const holdLaunch = (threadId) => promise(async () => {
|
|
293213
|
+
if (manager === null) return;
|
|
293214
|
+
launchCallers.set(threadId, (launchCallers.get(threadId) ?? 0) + 1);
|
|
293215
|
+
await manager.acquire(launchHoldId(threadId), threadId, { maxRefreshes: LAUNCH_HOLD_MAX_REFRESHES });
|
|
293216
|
+
});
|
|
293217
|
+
/** Lets one caller go. The hold itself is released when the last caller has let go. */
|
|
293218
|
+
const releaseLaunch = (threadId) => promise(async () => {
|
|
293219
|
+
if (manager === null) return;
|
|
293220
|
+
const remaining = (launchCallers.get(threadId) ?? 1) - 1;
|
|
293221
|
+
if (remaining > 0) return void launchCallers.set(threadId, remaining);
|
|
293222
|
+
launchCallers.delete(threadId);
|
|
293223
|
+
await manager.release(launchHoldId(threadId));
|
|
293224
|
+
});
|
|
293121
293225
|
return {
|
|
293122
|
-
start
|
|
293123
|
-
|
|
293124
|
-
|
|
293125
|
-
if (event.type === "turn.started") {
|
|
293126
|
-
const turnId = event.turnId;
|
|
293127
|
-
if (turnId === void 0) return void_$1;
|
|
293128
|
-
return promise(() => manager.acquire(String(turnId), String(event.threadId)));
|
|
293129
|
-
}
|
|
293130
|
-
if (event.type === "turn.completed") {
|
|
293131
|
-
const turnId = event.turnId;
|
|
293132
|
-
if (turnId === void 0) return void_$1;
|
|
293133
|
-
return promise(() => manager.release(String(turnId)));
|
|
293134
|
-
}
|
|
293135
|
-
if (event.type === "turn.aborted") {
|
|
293136
|
-
const turnId = event.turnId;
|
|
293137
|
-
if (turnId === void 0) return void_$1;
|
|
293138
|
-
return promise(() => manager.release(String(turnId)));
|
|
293139
|
-
}
|
|
293140
|
-
if (event.type === "session.exited") return promise(() => manager.releaseThread(String(event.threadId)));
|
|
293141
|
-
return void_$1;
|
|
293142
|
-
}));
|
|
293143
|
-
}),
|
|
293226
|
+
start,
|
|
293227
|
+
holdLaunch,
|
|
293228
|
+
releaseLaunch,
|
|
293144
293229
|
releaseAll: promise(() => manager === null ? Promise.resolve() : manager.releaseAll())
|
|
293145
293230
|
};
|
|
293146
293231
|
}));
|
|
@@ -297255,7 +297340,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
297255
297340
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
297256
297341
|
*/
|
|
297257
297342
|
function readBakedBuildCommit() {
|
|
297258
|
-
return "
|
|
297343
|
+
return "94219ed51a87e35a63d9bdc1b81bfe21c7977c17";
|
|
297259
297344
|
}
|
|
297260
297345
|
async function resolveServerBuildCommit(input) {
|
|
297261
297346
|
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-
|
|
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-src4jZSc.js";import{hn as P}from"./CompositeItem-DZBAkVp1.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-B7bxYYIG.js";import{Dn as q,at as J,it as ee}from"./src-rKJju-ZW.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-ChgJm5ah.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=`
|
|
2
2
|
[data-diffs-header],
|
|
3
3
|
[data-diff],
|
|
4
4
|
[data-file],
|
|
@@ -61,4 +61,4 @@ import{r as e}from"./rolldown-runtime-hePW80VL.js";import{Ha as t,Mi as n,Ua as
|
|
|
61
61
|
text-decoration-color: currentColor;
|
|
62
62
|
}
|
|
63
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-
|
|
64
|
+
//# sourceMappingURL=DiffPanel-DtwPM18A.js.map
|