@cmmd-center/forge 0.13.87 → 0.13.89
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 +165 -21
- package/dist/bin.mjs +165 -21
- package/dist/client/assets/{CanvasPanel-Dyho_JDo.js → CanvasPanel-D9NzolmF.js} +3 -3
- package/dist/client/assets/{CompositeItem-DeDhuBZB.js → CompositeItem-DU4kdAw6.js} +2 -2
- package/dist/client/assets/{DiffPanel-LdZieNJf.js → DiffPanel-Dx1AY0mg.js} +3 -3
- package/dist/client/assets/{DiffPanel.logic-CU1JloJt.js → DiffPanel.logic-BiyBXIja.js} +2 -2
- package/dist/client/assets/{DiffWorkerPoolProvider-BMlqcnLd.js → DiffWorkerPoolProvider-jDqu6eJj.js} +12 -12
- package/dist/client/assets/{PullRequestCodePanel-DUSNwNQ9.js → PullRequestCodePanel-CqrN4lB_.js} +3 -3
- package/dist/client/assets/{Virtualizer-DZvTW6Dy.js → Virtualizer-D-5QCW79.js} +2 -2
- package/dist/client/assets/WorkerPoolContext-BxfSg7K_.js +2540 -0
- package/dist/client/assets/{canvasStateStore-DJ_OzrrC.js → canvasStateStore-CBQkAlnK.js} +2 -2
- package/dist/client/assets/{cmmdAuthRedirect-Bqx90tp9.js → cmmdAuthRedirect-CCwq2L-I.js} +2 -2
- package/dist/client/assets/index-BrOo-A0J.js +153 -0
- package/dist/client/assets/index-BvseDV5h.css +1 -0
- package/dist/client/assets/{popover-D20eY2oM.js → popover-DJpPSHsy.js} +2 -2
- package/dist/client/assets/{src-CoTxmdk3.js → src-CF8xm6xH.js} +2 -2
- package/dist/client/assets/{toggle-AqC0QUc1.js → toggle-Bv2GfLGu.js} +2 -2
- package/dist/client/index.html +11 -11
- package/dist/forge-build.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/WorkerPoolContext-Cqf93ctM.js +0 -2537
- package/dist/client/assets/index-C-3BZaMd.css +0 -1
- package/dist/client/assets/index-CUQ9jU7z.js +0 -153
package/dist/bin.cjs
CHANGED
|
@@ -22535,6 +22535,16 @@ const TerminalFontSize = require_Schema$1.Int.check(require_Schema$1.isGreaterTh
|
|
|
22535
22535
|
const FontFamilyPreference = require_Schema$1.String.check(require_Schema$1.isMaxLength(200));
|
|
22536
22536
|
const AutoSettleAfterDays = require_Schema$1.NullOr(require_Schema$1.Int.check(require_Schema$1.isGreaterThanOrEqualTo(1)).check(require_Schema$1.isLessThanOrEqualTo(90)));
|
|
22537
22537
|
const GlassOpacity = require_Schema$1.Int.check(require_Schema$1.isGreaterThanOrEqualTo(40)).check(require_Schema$1.isLessThanOrEqualTo(100));
|
|
22538
|
+
/**
|
|
22539
|
+
* Interface contrast, in percent of the shipped look. 100 disables mixing;
|
|
22540
|
+
* above it the `--contrast-*` axis in `apps/web/src/index.css` raises text
|
|
22541
|
+
* and border contrast from the semantic roles, below it softens them.
|
|
22542
|
+
* Upstream's axis and bounds, adopted by the token union.
|
|
22543
|
+
*/
|
|
22544
|
+
const AppearanceContrast = require_Schema$1.Int.check(require_Schema$1.isBetween({
|
|
22545
|
+
minimum: 50,
|
|
22546
|
+
maximum: 200
|
|
22547
|
+
}));
|
|
22538
22548
|
const ClientSettingsSchema = require_Schema$1.Struct({
|
|
22539
22549
|
theme: ThemePreference.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed("system"))),
|
|
22540
22550
|
themeId: ThemeId,
|
|
@@ -22550,6 +22560,7 @@ const ClientSettingsSchema = require_Schema$1.Struct({
|
|
|
22550
22560
|
fontSmoothing: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
|
|
22551
22561
|
sidebarAutoSettleAfterDays: AutoSettleAfterDays.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(3))),
|
|
22552
22562
|
glassOpacity: GlassOpacity.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(80))),
|
|
22563
|
+
appearanceContrast: AppearanceContrast.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(100))),
|
|
22553
22564
|
confirmThreadArchive: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
|
|
22554
22565
|
confirmThreadDelete: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(true))),
|
|
22555
22566
|
showInteractionModeToggle: require_Schema$1.Boolean.pipe(require_Schema$1.withDecodingDefault(require_Schema$1.succeed(false))),
|
|
@@ -66285,7 +66296,7 @@ function normalizeNumberish(value) {
|
|
|
66285
66296
|
}
|
|
66286
66297
|
//#endregion
|
|
66287
66298
|
//#region package.json
|
|
66288
|
-
var version$1 = "0.13.
|
|
66299
|
+
var version$1 = "0.13.89";
|
|
66289
66300
|
//#endregion
|
|
66290
66301
|
//#region src/sentry.ts
|
|
66291
66302
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -241815,6 +241826,22 @@ function resolveSpriteTaskHoldConfig(env = process.env) {
|
|
|
241815
241826
|
function spriteTaskHoldName(namePrefix, turnId) {
|
|
241816
241827
|
return `${namePrefix}${turnId}`;
|
|
241817
241828
|
}
|
|
241829
|
+
/**
|
|
241830
|
+
* Thrown by the production transport when the guest API answers a non-2xx
|
|
241831
|
+
* status. Carries the status so a caller can tell a 409 (already held, and
|
|
241832
|
+
* generally benign) apart from a real transport failure.
|
|
241833
|
+
*/
|
|
241834
|
+
var SpriteTaskHoldTransportError = class extends Error {
|
|
241835
|
+
status;
|
|
241836
|
+
constructor(status) {
|
|
241837
|
+
super(`sprite task API responded ${status}`);
|
|
241838
|
+
this.name = "SpriteTaskHoldTransportError";
|
|
241839
|
+
this.status = status;
|
|
241840
|
+
}
|
|
241841
|
+
};
|
|
241842
|
+
function transportStatus(cause) {
|
|
241843
|
+
return cause instanceof SpriteTaskHoldTransportError ? cause.status : void 0;
|
|
241844
|
+
}
|
|
241818
241845
|
const noTimer = () => {};
|
|
241819
241846
|
/**
|
|
241820
241847
|
* Resolve with `promise`, but stop waiting after `timeoutMs`. Rejections pass
|
|
@@ -241848,12 +241875,25 @@ var SpriteTaskHoldManager = class {
|
|
|
241848
241875
|
#transport;
|
|
241849
241876
|
#timer;
|
|
241850
241877
|
#onError;
|
|
241878
|
+
#onEvent;
|
|
241851
241879
|
#holds = /* @__PURE__ */ new Map();
|
|
241852
241880
|
constructor(options) {
|
|
241853
241881
|
this.#config = options.config;
|
|
241854
241882
|
this.#transport = options.transport;
|
|
241855
241883
|
this.#timer = options.timer ?? DEFAULT_TIMER;
|
|
241856
241884
|
this.#onError = options.onError ?? (() => {});
|
|
241885
|
+
this.#onEvent = options.onEvent ?? (() => {});
|
|
241886
|
+
}
|
|
241887
|
+
/** Compose and report one acquire/refresh/release outcome, if a caller wants to log it. */
|
|
241888
|
+
#emitEvent(action, holdKey, hold, outcome, status) {
|
|
241889
|
+
this.#onEvent({
|
|
241890
|
+
action,
|
|
241891
|
+
holdKey,
|
|
241892
|
+
holdName: hold.name,
|
|
241893
|
+
threadId: hold.threadId,
|
|
241894
|
+
outcome,
|
|
241895
|
+
...status !== void 0 ? { status } : {}
|
|
241896
|
+
});
|
|
241857
241897
|
}
|
|
241858
241898
|
/** Turn ids that currently hold the sprite awake. Test/diagnostic surface. */
|
|
241859
241899
|
activeTurnIds() {
|
|
@@ -241862,10 +241902,19 @@ var SpriteTaskHoldManager = class {
|
|
|
241862
241902
|
/**
|
|
241863
241903
|
* `maxRefreshes` bounds a hold that has no terminal event of its own, such as a launch
|
|
241864
241904
|
* whose turn may never start. When the budget is spent the hold releases itself.
|
|
241905
|
+
*
|
|
241906
|
+
* Resolves to whether this hold has ever landed a PUT, never throwing (a
|
|
241907
|
+
* hold problem must not fail a turn). A caller handing off from a
|
|
241908
|
+
* predecessor hold (forge#3589) must not release it on anything less than
|
|
241909
|
+
* "succeeded": a failed initial PUT still installs the refresher below and
|
|
241910
|
+
* keeps retrying every `SPRITE_TASK_HOLD_REFRESH_MS`, so the predecessor is
|
|
241911
|
+
* the only thing covering the sprite until one of those retries lands. A
|
|
241912
|
+
* duplicate call against a live, unreleased hold reports that hold's own
|
|
241913
|
+
* confirmed state rather than a blanket "succeeded", for the same reason.
|
|
241865
241914
|
*/
|
|
241866
241915
|
async acquire(turnId, threadId = null, options = {}) {
|
|
241867
|
-
const existing = this.#
|
|
241868
|
-
if (existing !== void 0
|
|
241916
|
+
const existing = this.#liveHold(turnId);
|
|
241917
|
+
if (existing !== void 0) return existing.confirmed ? "succeeded" : "failed";
|
|
241869
241918
|
let refreshesLeft = options.maxRefreshes ?? Number.POSITIVE_INFINITY;
|
|
241870
241919
|
const name = spriteTaskHoldName(this.#config.namePrefix, turnId);
|
|
241871
241920
|
const hold = {
|
|
@@ -241877,24 +241926,54 @@ var SpriteTaskHoldManager = class {
|
|
|
241877
241926
|
phase: "idle",
|
|
241878
241927
|
releaseAttempt: null,
|
|
241879
241928
|
deletion: null,
|
|
241880
|
-
uncertainPut: false
|
|
241929
|
+
uncertainPut: false,
|
|
241930
|
+
confirmed: false
|
|
241881
241931
|
};
|
|
241882
241932
|
this.#holds.set(turnId, hold);
|
|
241883
241933
|
const put = this.#transport.put(name, 300);
|
|
241884
241934
|
const tracked = put.then(() => "succeeded", () => "failed");
|
|
241885
241935
|
hold.inFlight.add(tracked);
|
|
241936
|
+
let outcome = "succeeded";
|
|
241886
241937
|
try {
|
|
241887
241938
|
await put;
|
|
241888
241939
|
hold.uncertainPut = false;
|
|
241940
|
+
hold.confirmed = true;
|
|
241941
|
+
this.#emitEvent("acquire", turnId, hold, "success");
|
|
241889
241942
|
} catch (cause) {
|
|
241943
|
+
outcome = "failed";
|
|
241890
241944
|
hold.uncertainPut = true;
|
|
241891
241945
|
hold.inFlight.delete(tracked);
|
|
241892
241946
|
this.#onError(`failed to acquire sprite task hold for turn ${turnId}`, cause);
|
|
241893
|
-
|
|
241947
|
+
this.#emitEvent("acquire", turnId, hold, "failure", transportStatus(cause));
|
|
241948
|
+
if (this.#isStale(turnId, hold)) return outcome;
|
|
241894
241949
|
}
|
|
241895
241950
|
hold.inFlight.delete(tracked);
|
|
241896
|
-
if (
|
|
241897
|
-
hold.refresher = this.#
|
|
241951
|
+
if (this.#isStale(turnId, hold)) return outcome;
|
|
241952
|
+
hold.refresher = this.#installRefresher(turnId, hold, name, refreshesLeft);
|
|
241953
|
+
return outcome;
|
|
241954
|
+
}
|
|
241955
|
+
/** The hold registered for `turnId`, if it is still live: not mid-release or concluded. */
|
|
241956
|
+
#liveHold(turnId) {
|
|
241957
|
+
const existing = this.#holds.get(turnId);
|
|
241958
|
+
return existing !== void 0 && !existing.released ? existing : void 0;
|
|
241959
|
+
}
|
|
241960
|
+
/**
|
|
241961
|
+
* Whether `hold` has been superseded since the caller last checked: either
|
|
241962
|
+
* released, or no longer the map's current entry for `turnId` (a fresh
|
|
241963
|
+
* acquire replaced it). Both `acquire`'s post-await fences use this so
|
|
241964
|
+
* neither has to repeat the compound condition inline.
|
|
241965
|
+
*/
|
|
241966
|
+
#isStale(turnId, hold) {
|
|
241967
|
+
return hold.released || this.#holds.get(turnId) !== hold;
|
|
241968
|
+
}
|
|
241969
|
+
/**
|
|
241970
|
+
* Install a hold's refresh interval. Extracted out of `acquire` so that
|
|
241971
|
+
* method's own branching stays flat; the ordering and identity-fence rules
|
|
241972
|
+
* around it are unchanged, and this closure owns only the refresh tick.
|
|
241973
|
+
*/
|
|
241974
|
+
#installRefresher(turnId, hold, name, initialBudget) {
|
|
241975
|
+
let refreshesLeft = initialBudget;
|
|
241976
|
+
return this.#timer.setInterval(() => {
|
|
241898
241977
|
if (hold.inFlight.size > 0) return;
|
|
241899
241978
|
if (refreshesLeft <= 0) {
|
|
241900
241979
|
if (this.#holds.get(turnId) === hold) this.release(turnId);
|
|
@@ -241903,10 +241982,13 @@ var SpriteTaskHoldManager = class {
|
|
|
241903
241982
|
refreshesLeft -= 1;
|
|
241904
241983
|
const refresh = this.#transport.put(name, 300).then(() => {
|
|
241905
241984
|
hold.uncertainPut = false;
|
|
241985
|
+
hold.confirmed = true;
|
|
241986
|
+
this.#emitEvent("refresh", turnId, hold, "success");
|
|
241906
241987
|
return "succeeded";
|
|
241907
241988
|
}, (cause) => {
|
|
241908
241989
|
hold.uncertainPut = true;
|
|
241909
241990
|
this.#onError(`failed to refresh sprite task hold for turn ${turnId}`, cause);
|
|
241991
|
+
this.#emitEvent("refresh", turnId, hold, "failure", transportStatus(cause));
|
|
241910
241992
|
return "failed";
|
|
241911
241993
|
});
|
|
241912
241994
|
hold.inFlight.add(refresh);
|
|
@@ -241950,6 +242032,7 @@ var SpriteTaskHoldManager = class {
|
|
|
241950
242032
|
hold.phase = "joining";
|
|
241951
242033
|
const attempt = (async () => {
|
|
241952
242034
|
const outcome = await this.#concludeRelease(hold, turnId, options);
|
|
242035
|
+
this.#emitEvent("release", turnId, hold, outcome);
|
|
241953
242036
|
if (outcome === "unreleased") {
|
|
241954
242037
|
hold.phase = "idle";
|
|
241955
242038
|
this.#removeIfCurrent(turnId, hold);
|
|
@@ -242133,7 +242216,7 @@ function makeSpriteTaskHoldTransport(config, fetchImpl = fetch) {
|
|
|
242133
242216
|
signal: controller.signal,
|
|
242134
242217
|
unix: config.socketPath
|
|
242135
242218
|
});
|
|
242136
|
-
if (!response.ok) throw new
|
|
242219
|
+
if (!response.ok) throw new SpriteTaskHoldTransportError(response.status);
|
|
242137
242220
|
} finally {
|
|
242138
242221
|
clearTimeout(deadline);
|
|
242139
242222
|
}
|
|
@@ -242169,13 +242252,14 @@ function makeSpriteTaskHoldTransport(config, fetchImpl = fetch) {
|
|
|
242169
242252
|
* Build a manager for this process, or null when the runtime is not a sprite.
|
|
242170
242253
|
* Callers treat null as "this feature does not apply here".
|
|
242171
242254
|
*/
|
|
242172
|
-
function makeSpriteTaskHoldManager(env = process.env, onError) {
|
|
242255
|
+
function makeSpriteTaskHoldManager(env = process.env, onError, onEvent) {
|
|
242173
242256
|
const config = resolveSpriteTaskHoldConfig(env);
|
|
242174
242257
|
if (config === null) return null;
|
|
242175
242258
|
return new SpriteTaskHoldManager({
|
|
242176
242259
|
config,
|
|
242177
242260
|
transport: makeSpriteTaskHoldTransport(config),
|
|
242178
|
-
...onError ? { onError } : {}
|
|
242261
|
+
...onError ? { onError } : {},
|
|
242262
|
+
...onEvent ? { onEvent } : {}
|
|
242179
242263
|
});
|
|
242180
242264
|
}
|
|
242181
242265
|
//#endregion
|
|
@@ -286759,7 +286843,7 @@ const AgentBrowserManagerLive = require_Schema$1.effect(BrowserManager, require_
|
|
|
286759
286843
|
const displayPeers = createWebRtcDisplaySessionManager({
|
|
286760
286844
|
mediaSourceFactory: displayCaptureRuntime.mediaSourceFactory,
|
|
286761
286845
|
taskHold: displayTaskHoldManager ? {
|
|
286762
|
-
acquire: (holdId) => displayTaskHoldManager.acquire(holdId),
|
|
286846
|
+
acquire: (holdId) => displayTaskHoldManager.acquire(holdId).then(() => {}),
|
|
286763
286847
|
release: (holdId) => displayTaskHoldManager.release(holdId).then(() => {})
|
|
286764
286848
|
} : void 0
|
|
286765
286849
|
});
|
|
@@ -295134,6 +295218,15 @@ const make$6 = require_Schema$1.gen(function* () {
|
|
|
295134
295218
|
const providerService = yield* ProviderService;
|
|
295135
295219
|
const manager = makeSpriteTaskHoldManager(process.env, (message, cause) => {
|
|
295136
295220
|
require_Schema$1.runFork(require_Schema$1.logWarning(message, { cause: cause instanceof Error ? cause.message : cause }));
|
|
295221
|
+
}, (event) => {
|
|
295222
|
+
require_Schema$1.runFork(require_Schema$1.logInfo("sprite task hold", {
|
|
295223
|
+
action: event.action,
|
|
295224
|
+
holdKey: event.holdKey,
|
|
295225
|
+
holdName: event.holdName,
|
|
295226
|
+
threadId: event.threadId,
|
|
295227
|
+
outcome: event.outcome,
|
|
295228
|
+
...event.status !== void 0 ? { status: event.status } : {}
|
|
295229
|
+
}));
|
|
295137
295230
|
});
|
|
295138
295231
|
/**
|
|
295139
295232
|
* Run a manager call, or nothing on runtimes that are not sprites. One
|
|
@@ -295149,27 +295242,58 @@ const make$6 = require_Schema$1.gen(function* () {
|
|
|
295149
295242
|
deleteTimeoutMs: SPRITE_TASK_HOLD_RELEASE_DELETE_TIMEOUT_MS
|
|
295150
295243
|
})));
|
|
295151
295244
|
const launchCallers = /* @__PURE__ */ new Map();
|
|
295245
|
+
const launchGeneration = /* @__PURE__ */ new Map();
|
|
295246
|
+
const turnLaunchGeneration = /* @__PURE__ */ new Map();
|
|
295247
|
+
/**
|
|
295248
|
+
* Belt-and-braces cleanup for a turn reaching a terminal state
|
|
295249
|
+
* (turn.completed or turn.aborted): a launch hold whose hand-off never
|
|
295250
|
+
* confirmed (the turn hold's PUT kept failing) is still up, refreshing on
|
|
295251
|
+
* its own budget, and the turn ending either way means the launch phase is
|
|
295252
|
+
* over. `manager.release(String(turnId))` above can itself wait on the
|
|
295253
|
+
* guest API, so by the time this runs the NEXT stage's own dispatch may
|
|
295254
|
+
* already have acquired a fresh launch hold for the same thread; only
|
|
295255
|
+
* release it here when no such newer launch has started since this turn's
|
|
295256
|
+
* own turn.started was processed (CodeRabbit review, forge#3592). A no-op
|
|
295257
|
+
* when this turn's own generation is stale, or when the hold was already
|
|
295258
|
+
* released.
|
|
295259
|
+
*/
|
|
295260
|
+
const releaseLingeringLaunchHold = async (turnId, threadId) => {
|
|
295261
|
+
const capturedGeneration = turnLaunchGeneration.get(turnId);
|
|
295262
|
+
turnLaunchGeneration.delete(turnId);
|
|
295263
|
+
if (manager === null || capturedGeneration === void 0) return;
|
|
295264
|
+
if (launchGeneration.get(threadId) !== capturedGeneration) return;
|
|
295265
|
+
await manager.release(launchHoldId(threadId));
|
|
295266
|
+
};
|
|
295152
295267
|
const start = require_Schema$1.fn("start")(function* () {
|
|
295153
295268
|
if (manager === null) return;
|
|
295154
295269
|
yield* require_Schema$1.forkScoped(require_Path.runForEach(providerService.streamEvents, (event) => {
|
|
295155
295270
|
if (event.type === "turn.started") {
|
|
295156
295271
|
const turnId = event.turnId;
|
|
295157
295272
|
if (turnId === void 0) return require_Schema$1.void_;
|
|
295273
|
+
const threadId = String(event.threadId);
|
|
295274
|
+
const generation = launchGeneration.get(threadId) ?? 0;
|
|
295158
295275
|
return require_Schema$1.promise(async () => {
|
|
295159
|
-
await manager.acquire(String(turnId),
|
|
295160
|
-
launchCallers.delete(
|
|
295161
|
-
|
|
295276
|
+
const outcome = await manager.acquire(String(turnId), threadId);
|
|
295277
|
+
launchCallers.delete(threadId);
|
|
295278
|
+
turnLaunchGeneration.set(String(turnId), generation);
|
|
295279
|
+
if (outcome === "succeeded") await manager.release(launchHoldId(threadId));
|
|
295162
295280
|
});
|
|
295163
295281
|
}
|
|
295164
295282
|
if (event.type === "turn.completed") {
|
|
295165
295283
|
const turnId = event.turnId;
|
|
295166
295284
|
if (turnId === void 0) return require_Schema$1.void_;
|
|
295167
|
-
return require_Schema$1.promise(
|
|
295285
|
+
return require_Schema$1.promise(async () => {
|
|
295286
|
+
await manager.release(String(turnId));
|
|
295287
|
+
await releaseLingeringLaunchHold(String(turnId), String(event.threadId));
|
|
295288
|
+
});
|
|
295168
295289
|
}
|
|
295169
295290
|
if (event.type === "turn.aborted") {
|
|
295170
295291
|
const turnId = event.turnId;
|
|
295171
295292
|
if (turnId === void 0) return require_Schema$1.void_;
|
|
295172
|
-
return require_Schema$1.promise(
|
|
295293
|
+
return require_Schema$1.promise(async () => {
|
|
295294
|
+
await manager.release(String(turnId));
|
|
295295
|
+
await releaseLingeringLaunchHold(String(turnId), String(event.threadId));
|
|
295296
|
+
});
|
|
295173
295297
|
}
|
|
295174
295298
|
if (event.type === "session.exited") {
|
|
295175
295299
|
launchCallers.delete(String(event.threadId));
|
|
@@ -295181,7 +295305,9 @@ const make$6 = require_Schema$1.gen(function* () {
|
|
|
295181
295305
|
/** Takes the launch hold for one more caller. The budget bounds a launch that never starts a turn. */
|
|
295182
295306
|
const holdLaunch = (threadId) => require_Schema$1.promise(async () => {
|
|
295183
295307
|
if (manager === null) return;
|
|
295184
|
-
|
|
295308
|
+
const callers = launchCallers.get(threadId) ?? 0;
|
|
295309
|
+
launchCallers.set(threadId, callers + 1);
|
|
295310
|
+
if (callers === 0) launchGeneration.set(threadId, (launchGeneration.get(threadId) ?? 0) + 1);
|
|
295185
295311
|
await manager.acquire(launchHoldId(threadId), threadId, { maxRefreshes: LAUNCH_HOLD_MAX_REFRESHES });
|
|
295186
295312
|
});
|
|
295187
295313
|
/** Lets one caller go. The hold itself is released when the last caller has let go. */
|
|
@@ -299352,7 +299478,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
299352
299478
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
299353
299479
|
*/
|
|
299354
299480
|
function readBakedBuildCommit() {
|
|
299355
|
-
return "
|
|
299481
|
+
return "394b2a7cd449282f2845ec5fa3bd9093f20b8bb8";
|
|
299356
299482
|
}
|
|
299357
299483
|
async function resolveServerBuildCommit(input) {
|
|
299358
299484
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -316810,6 +316936,7 @@ const makePipelineRunCoordinator = require_Schema$1.gen(function* () {
|
|
|
316810
316936
|
const policy = yield* PipelineStagePolicy;
|
|
316811
316937
|
const secretStore = yield* ServerSecretStore;
|
|
316812
316938
|
const orchestration = yield* OrchestrationEngineService;
|
|
316939
|
+
const spriteTaskHoldReactor = yield* require_Schema$1.serviceOption(SpriteTaskHoldReactor);
|
|
316813
316940
|
const projectionSnapshotQuery = yield* ProjectionSnapshotQuery;
|
|
316814
316941
|
const projectionTurns = yield* ProjectionTurnRepository;
|
|
316815
316942
|
const changeInspector = yield* PipelineChangeInspector;
|
|
@@ -317537,6 +317664,23 @@ const makePipelineRunCoordinator = require_Schema$1.gen(function* () {
|
|
|
317537
317664
|
});
|
|
317538
317665
|
yield* drainReports();
|
|
317539
317666
|
});
|
|
317667
|
+
/**
|
|
317668
|
+
* Holds the sprite awake around a freshly dispatched thread.turn.start, the
|
|
317669
|
+
* same way bootstrapLaunch.ts's withLaunchHold does for a turn started from
|
|
317670
|
+
* the Forge web composer or a bootstrap launch (forge#3589). A turn kicked
|
|
317671
|
+
* from a CMMD card reaches the engine through dispatchStage /
|
|
317672
|
+
* recoverMissingProviderStart below, never through that HTTP dispatch
|
|
317673
|
+
* route, so nothing else covers the window between this dispatch and the
|
|
317674
|
+
* provider's own turn.started.
|
|
317675
|
+
*
|
|
317676
|
+
* Releases only on error: a successful dispatch hands the hold off to the
|
|
317677
|
+
* turn's own, in SpriteTaskHoldReactor's turn.started handler.
|
|
317678
|
+
*/
|
|
317679
|
+
const withPipelineLaunchHold = (threadId, dispatch) => {
|
|
317680
|
+
if (require_Schema$1.isNone(spriteTaskHoldReactor)) return dispatch;
|
|
317681
|
+
const reactor = spriteTaskHoldReactor.value;
|
|
317682
|
+
return require_Schema$1.uninterruptible(reactor.holdLaunch(threadId)).pipe(require_Schema$1.andThen(require_Schema$1.yieldNow), require_Schema$1.andThen(dispatch), require_Schema$1.onError(() => reactor.releaseLaunch(threadId)));
|
|
317683
|
+
};
|
|
317540
317684
|
const dispatchStage = (binding, snapshot, authority) => require_Schema$1.gen(function* () {
|
|
317541
317685
|
const thread = (yield* orchestration.getReadModel()).threads.find((candidate) => candidate.id === ThreadId.make(binding.threadId) && candidate.deletedAt === null);
|
|
317542
317686
|
if (thread === void 0) {
|
|
@@ -317612,7 +317756,7 @@ const makePipelineRunCoordinator = require_Schema$1.gen(function* () {
|
|
|
317612
317756
|
messageId: `${commandId}:message`,
|
|
317613
317757
|
createdAt: startedAt
|
|
317614
317758
|
});
|
|
317615
|
-
yield* orchestration.dispatch(command).pipe(require_Schema$1.tapError(() => store.resetDispatch(binding.runId, commandId)));
|
|
317759
|
+
yield* withPipelineLaunchHold(binding.threadId, orchestration.dispatch(command)).pipe(require_Schema$1.tapError(() => store.resetDispatch(binding.runId, commandId)));
|
|
317616
317760
|
yield* store.markDispatched(binding.runId, commandId);
|
|
317617
317761
|
});
|
|
317618
317762
|
const resumeRun = (runId) => require_Schema$1.gen(function* () {
|
|
@@ -318252,7 +318396,7 @@ const makePipelineRunCoordinator = require_Schema$1.gen(function* () {
|
|
|
318252
318396
|
});
|
|
318253
318397
|
if (workerCoordination.kind !== "single" && workerCoordination.kind !== "ready") return;
|
|
318254
318398
|
const commandId = `${originalCommandId}:provider-start-recovery`;
|
|
318255
|
-
yield* orchestration.dispatch(buildStageTurnCommand({
|
|
318399
|
+
yield* withPipelineLaunchHold(input.binding.threadId, orchestration.dispatch(buildStageTurnCommand({
|
|
318256
318400
|
binding: input.binding,
|
|
318257
318401
|
attempt: input.binding.attempt,
|
|
318258
318402
|
snapshot: input.snapshot,
|
|
@@ -318263,7 +318407,7 @@ const makePipelineRunCoordinator = require_Schema$1.gen(function* () {
|
|
|
318263
318407
|
commandId,
|
|
318264
318408
|
messageId: `${commandId}:message`,
|
|
318265
318409
|
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
318266
|
-
}));
|
|
318410
|
+
})));
|
|
318267
318411
|
});
|
|
318268
318412
|
}
|
|
318269
318413
|
function reconcileActiveThread(input) {
|