@cmmd-center/forge 0.13.122 → 0.13.124
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 +120 -13
- package/dist/bin.mjs +120 -13
- package/dist/client/assets/{DiffPanel-Bb6-z2pB.js → DiffPanel-C1le0UaP.js} +2 -2
- package/dist/client/assets/{DiffPanel.logic-DSBVU1IQ.js → DiffPanel.logic-DK4RDoiD.js} +2 -2
- package/dist/client/assets/{DiffWorkerPoolProvider-D4Xu0IB4.js → DiffWorkerPoolProvider-orOnVCAZ.js} +2 -2
- package/dist/client/assets/{PullRequestCodePanel-TGShyxuR.js → PullRequestCodePanel-Br2r3lbU.js} +2 -2
- package/dist/client/assets/{Virtualizer-K2JkXuTg.js → Virtualizer-D5o0Becp.js} +2 -2
- package/dist/client/assets/{WorkerPoolContext-6gkCtwqY.js → WorkerPoolContext-CpM1XKxV.js} +77 -77
- package/dist/client/assets/{index-BgBFPAe1.js → index-DB8H2s1H.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
|
@@ -66337,7 +66337,7 @@ function normalizeNumberish(value) {
|
|
|
66337
66337
|
}
|
|
66338
66338
|
//#endregion
|
|
66339
66339
|
//#region package.json
|
|
66340
|
-
var version$1 = "0.13.
|
|
66340
|
+
var version$1 = "0.13.124";
|
|
66341
66341
|
//#endregion
|
|
66342
66342
|
//#region src/sentry.ts
|
|
66343
66343
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -300407,7 +300407,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
300407
300407
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
300408
300408
|
*/
|
|
300409
300409
|
function readBakedBuildCommit() {
|
|
300410
|
-
return "
|
|
300410
|
+
return "52e8c25f0de536143b44ff1ac86510aa93d35772";
|
|
300411
300411
|
}
|
|
300412
300412
|
async function resolveServerBuildCommit(input) {
|
|
300413
300413
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -315066,9 +315066,17 @@ const RuntimeReplicationLive = require_Schema$1.effect(RuntimeReplication, requi
|
|
|
315066
315066
|
concurrency: 1,
|
|
315067
315067
|
discard: true
|
|
315068
315068
|
});
|
|
315069
|
+
const retryStuckThreadStreams = (streamKeys) => runtimeId ? require_Schema$1.forEach(streamKeys, (streamKey) => outbox.resetStuckThreadGeneration({
|
|
315070
|
+
runtimeId,
|
|
315071
|
+
streamKey
|
|
315072
|
+
}).pipe(require_Schema$1.flatMap((reset) => reset ? enqueueThread(threadIdFromStreamKey(streamKey)) : require_Schema$1.void_)), {
|
|
315073
|
+
concurrency: 1,
|
|
315074
|
+
discard: true
|
|
315075
|
+
}) : require_Schema$1.void_;
|
|
315069
315076
|
return RuntimeReplication.of({
|
|
315070
315077
|
start,
|
|
315071
|
-
retryReprojectionPending
|
|
315078
|
+
retryReprojectionPending,
|
|
315079
|
+
retryStuckThreadStreams
|
|
315072
315080
|
});
|
|
315073
315081
|
}));
|
|
315074
315082
|
//#endregion
|
|
@@ -315415,6 +315423,31 @@ const THREAD_STREAM_PAYLOAD_HASH_MISMATCH_CODE = "THREAD_STREAM_PAYLOAD_HASH_MIS
|
|
|
315415
315423
|
*/
|
|
315416
315424
|
const THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING_CODE = "THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING";
|
|
315417
315425
|
/**
|
|
315426
|
+
* Terminal park code for a thread-events reset `refusedResetIsStuck` judges
|
|
315427
|
+
* genuinely stuck: the exact canonical reset shape was already sent once
|
|
315428
|
+
* under this generation and CMMD refused it again with zero acknowledged
|
|
315429
|
+
* progress (forge#3635). Before this code existed, that case fell through to
|
|
315430
|
+
* `failGeneric`, which recorded the raw `THREAD_STREAM_PAYLOAD_CONFLICT` /
|
|
315431
|
+
* `THREAD_STREAM_HEAD_MISMATCH` code -- a code neither
|
|
315432
|
+
* `readReprojectionPendingThreadStreamKeys` nor
|
|
315433
|
+
* `MANUALLY_RECOVERABLE_BLOCKED_CODES` selects, so the manual retry endpoint
|
|
315434
|
+
* could never reach the row.
|
|
315435
|
+
*
|
|
315436
|
+
* Deliberately excluded from `CLAIMABLE_BLOCKED_CODES`,
|
|
315437
|
+
* `STARTUP_RECOVERABLE_BLOCKED_CODES`, and `MANUALLY_RECOVERABLE_BLOCKED_CODES`:
|
|
315438
|
+
* a plain status flip back to `pending` would resend the exact batch CMMD
|
|
315439
|
+
* already refused twice. `enqueueThread` also leaves a row parked under this
|
|
315440
|
+
* code alone on new domain events and the heartbeat (see the stuck check
|
|
315441
|
+
* inside `enqueueThread` below) instead of re-projecting it back to `pending`
|
|
315442
|
+
* the way it does for every other generation, so a stuck row only clears once
|
|
315443
|
+
* the operator retry endpoint calls `RuntimeReplicationOutboxShape`'s
|
|
315444
|
+
* `resetStuckThreadGeneration` (which mints a fresh, never-before-sent repair
|
|
315445
|
+
* generation before re-projecting) or
|
|
315446
|
+
* a genuinely new generation id supersedes it (e.g. the thread archives and
|
|
315447
|
+
* gets a `:final:` id).
|
|
315448
|
+
*/
|
|
315449
|
+
const THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE = "THREAD_STREAM_REMOTE_CONFLICT_STUCK";
|
|
315450
|
+
/**
|
|
315418
315451
|
* Whether a refused batch is the exact canonical reset shape (`fromSequence
|
|
315419
315452
|
* === 1`, empty previous head, deterministic content) under a generation the
|
|
315420
315453
|
* local cursor already holds with zero acknowledged progress -- i.e. this
|
|
@@ -315692,6 +315725,23 @@ const readReprojectionPendingThreadStreamKeys = require_Schema$1.gen(function* (
|
|
|
315692
315725
|
AND last_error_code = ${THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING_CODE}
|
|
315693
315726
|
`).map((row) => row.streamKey);
|
|
315694
315727
|
}).pipe(require_Schema$1.orDie);
|
|
315728
|
+
/**
|
|
315729
|
+
* Thread streams parked under THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE, for the
|
|
315730
|
+
* manual `/api/runtime-replication/retry` endpoint (forge#3635). Deliberately absent
|
|
315731
|
+
* from MANUALLY_RECOVERABLE_BLOCKED_CODES for the same reason
|
|
315732
|
+
* `readReprojectionPendingThreadStreamKeys` is: a plain status flip back to `pending`
|
|
315733
|
+
* would resend the exact reset CMMD already refused twice. `http.ts`'s retry handler
|
|
315734
|
+
* passes these to `RuntimeReplication`'s `retryStuckThreadStreams`, which calls
|
|
315735
|
+
* `resetStuckThreadGeneration` for each of these before re-projecting, so the retry
|
|
315736
|
+
* always sends a fresh, never-before-refused generation.
|
|
315737
|
+
*/
|
|
315738
|
+
const readStuckThreadStreamKeys = require_Schema$1.gen(function* () {
|
|
315739
|
+
return (yield* (yield* require_SqlError.SqlClient)`
|
|
315740
|
+
SELECT stream_key AS "streamKey" FROM runtime_replication_outbox
|
|
315741
|
+
WHERE operation = 'thread-events' AND status = 'blocked'
|
|
315742
|
+
AND last_error_code = ${THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE}
|
|
315743
|
+
`).map((row) => row.streamKey);
|
|
315744
|
+
}).pipe(require_Schema$1.orDie);
|
|
315695
315745
|
const RuntimeReplicationOutboxLive = require_Schema$1.effect(RuntimeReplicationOutbox, require_Schema$1.gen(function* () {
|
|
315696
315746
|
const sql = yield* require_SqlError.SqlClient;
|
|
315697
315747
|
const upsertPayload = (input) => {
|
|
@@ -315912,6 +315962,12 @@ const RuntimeReplicationOutboxLive = require_Schema$1.effect(RuntimeReplicationO
|
|
|
315912
315962
|
now
|
|
315913
315963
|
}).pipe(require_Schema$1.orDie);
|
|
315914
315964
|
};
|
|
315965
|
+
const isThreadStreamParkedStuck = (input) => sql`
|
|
315966
|
+
SELECT runtime_id AS "runtimeId" FROM runtime_replication_outbox
|
|
315967
|
+
WHERE runtime_id = ${input.runtimeId} AND stream_key = ${input.streamKey}
|
|
315968
|
+
AND operation = 'thread-events' AND status = 'blocked'
|
|
315969
|
+
AND last_error_code = ${THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE}
|
|
315970
|
+
`.pipe(require_Schema$1.map((rows) => rows.length === 1));
|
|
315915
315971
|
const enqueueThread = (input) => {
|
|
315916
315972
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
315917
315973
|
const baseGenerationId = runtimeThreadGenerationId(input.runtimeId, input.streamKey);
|
|
@@ -315920,6 +315976,7 @@ const RuntimeReplicationOutboxLive = require_Schema$1.effect(RuntimeReplicationO
|
|
|
315920
315976
|
const previousActiveGeneration = activeRuntimeThreadGenerationId(baseGenerationId, previousCursor?.generationId);
|
|
315921
315977
|
const generationId = input.historyFinalized ? runtimeThreadFinalGenerationId(input.runtimeId, input.streamKey, input.events) : previousActiveGeneration;
|
|
315922
315978
|
const replacesGeneration = previousCursor !== void 0 && previousCursor.generationId !== generationId;
|
|
315979
|
+
if (!replacesGeneration && (yield* isThreadStreamParkedStuck(input))) return;
|
|
315923
315980
|
yield* initializeThreadCursor({
|
|
315924
315981
|
runtimeId: input.runtimeId,
|
|
315925
315982
|
streamKey: input.streamKey,
|
|
@@ -316221,12 +316278,16 @@ const RuntimeReplicationOutboxLive = require_Schema$1.effect(RuntimeReplicationO
|
|
|
316221
316278
|
})).pipe(require_Schema$1.orDie);
|
|
316222
316279
|
/**
|
|
316223
316280
|
* Recovers from a CMMD-reported thread stream conflict (see
|
|
316224
|
-
* THREAD_STREAM_REMOTE_CONFLICT_CODES). Returns `null` when this
|
|
316225
|
-
*
|
|
316226
|
-
* says the exact reset shape
|
|
316227
|
-
*
|
|
316228
|
-
*
|
|
316229
|
-
*
|
|
316281
|
+
* THREAD_STREAM_REMOTE_CONFLICT_CODES). Returns `null` only when this
|
|
316282
|
+
* item's payload does not decode, in which case the caller falls back to
|
|
316283
|
+
* `failGeneric`. When `refusedResetIsStuck` says the exact reset shape
|
|
316284
|
+
* already failed once with zero progress, parks the row under
|
|
316285
|
+
* `THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE` directly (see that code's
|
|
316286
|
+
* doc comment) and returns `true`/`false` the same way the normal repair
|
|
316287
|
+
* path below does -- never `null` -- so the caller never falls through to
|
|
316288
|
+
* `failGeneric`'s raw conflict code (forge#3635). `false` means the row
|
|
316289
|
+
* was superseded before this could apply, mirroring `fail`'s own
|
|
316290
|
+
* supersession signal. Otherwise replaces the local cursor with a brand-new repair generation
|
|
316230
316291
|
* from sequence 1, empty previous head -- the shape CMMD's reset rule
|
|
316231
316292
|
* accepts unconditionally -- and parks the row blocked under
|
|
316232
316293
|
* `THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING_CODE`, deferring the
|
|
@@ -316245,13 +316306,30 @@ const RuntimeReplicationOutboxLive = require_Schema$1.effect(RuntimeReplicationO
|
|
|
316245
316306
|
runtimeId: item.runtimeId,
|
|
316246
316307
|
streamKey: item.streamKey
|
|
316247
316308
|
});
|
|
316309
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
316248
316310
|
if (refusedResetIsStuck({
|
|
316249
316311
|
baseGenerationId,
|
|
316250
316312
|
refusedGenerationId: parsedBatch.generationId,
|
|
316251
316313
|
refusedFromSequence: parsedBatch.fromSequence,
|
|
316252
316314
|
cursor
|
|
316253
|
-
}))
|
|
316254
|
-
|
|
316315
|
+
})) {
|
|
316316
|
+
if ((yield* sql`
|
|
316317
|
+
UPDATE runtime_replication_outbox SET
|
|
316318
|
+
status = 'blocked', next_attempt_at = '9999-12-31T23:59:59.999Z',
|
|
316319
|
+
last_error_code = ${"THREAD_STREAM_REMOTE_CONFLICT_STUCK"},
|
|
316320
|
+
last_error = ${`Runtime replication conflict (${failure.code}) refused a thread-events reset that had already been refused once with zero acknowledged progress under this generation. Parked as stuck rather than resent; use the manual retry endpoint to reset it to a fresh generation.`}, updated_at = ${now}
|
|
316321
|
+
WHERE runtime_id = ${item.runtimeId} AND stream_key = ${item.streamKey}
|
|
316322
|
+
AND payload_hash = ${item.payloadHash}
|
|
316323
|
+
RETURNING runtime_id AS "runtimeId"
|
|
316324
|
+
`).length !== 1) return false;
|
|
316325
|
+
yield* require_Schema$1.logWarning("Runtime replication parked a thread-stream repair as stuck after its reset was refused with zero progress.", {
|
|
316326
|
+
runtimeId: item.runtimeId,
|
|
316327
|
+
streamKey: item.streamKey,
|
|
316328
|
+
errorCode: failure.code,
|
|
316329
|
+
refusedGenerationId: parsedBatch.generationId
|
|
316330
|
+
});
|
|
316331
|
+
return true;
|
|
316332
|
+
}
|
|
316255
316333
|
const repairGenerationId = `${baseGenerationId}:repair:${node_crypto.randomUUID()}`;
|
|
316256
316334
|
const message = `Runtime replication conflict (${failure.code}) refused a thread-events batch; deferring to a full-history re-projection under a new repair generation.`;
|
|
316257
316335
|
if (!(yield* sql.withTransaction(require_Schema$1.gen(function* () {
|
|
@@ -316319,6 +316397,30 @@ const RuntimeReplicationOutboxLive = require_Schema$1.effect(RuntimeReplicationO
|
|
|
316319
316397
|
AND status = 'blocked'
|
|
316320
316398
|
AND last_error_code = 'RUNTIME_REVOKED'
|
|
316321
316399
|
`.pipe(require_Schema$1.asVoid, require_Schema$1.orDie);
|
|
316400
|
+
const resetStuckThreadGeneration = (input) => {
|
|
316401
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
316402
|
+
const repairGenerationId = `${runtimeThreadGenerationId(input.runtimeId, input.streamKey)}:repair:${node_crypto.randomUUID()}`;
|
|
316403
|
+
const message = "Runtime replication operator retry reset a stuck thread-stream repair to a new generation.";
|
|
316404
|
+
return sql.withTransaction(require_Schema$1.gen(function* () {
|
|
316405
|
+
if ((yield* sql`
|
|
316406
|
+
UPDATE runtime_replication_outbox SET
|
|
316407
|
+
status = 'blocked', next_attempt_at = '9999-12-31T23:59:59.999Z',
|
|
316408
|
+
last_error_code = ${"THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING"},
|
|
316409
|
+
last_error = ${message}, updated_at = ${now}
|
|
316410
|
+
WHERE runtime_id = ${input.runtimeId} AND stream_key = ${input.streamKey}
|
|
316411
|
+
AND operation = 'thread-events'
|
|
316412
|
+
AND last_error_code = ${"THREAD_STREAM_REMOTE_CONFLICT_STUCK"}
|
|
316413
|
+
RETURNING runtime_id AS "runtimeId"
|
|
316414
|
+
`).length !== 1) return false;
|
|
316415
|
+
yield* replaceThreadCursor({
|
|
316416
|
+
runtimeId: input.runtimeId,
|
|
316417
|
+
streamKey: input.streamKey,
|
|
316418
|
+
generationId: repairGenerationId,
|
|
316419
|
+
now
|
|
316420
|
+
});
|
|
316421
|
+
return true;
|
|
316422
|
+
})).pipe(require_Schema$1.orDie);
|
|
316423
|
+
};
|
|
316322
316424
|
const getStatus = () => readRuntimeReplicationOutboxStatus.pipe(require_Schema$1.provideService(require_SqlError.SqlClient, sql));
|
|
316323
316425
|
const getDiagnostics = () => require_Schema$1.gen(function* () {
|
|
316324
316426
|
const [diagnostics] = decodeDiagnostics(yield* sql`
|
|
@@ -316349,6 +316451,7 @@ const RuntimeReplicationOutboxLive = require_Schema$1.effect(RuntimeReplicationO
|
|
|
316349
316451
|
acknowledge,
|
|
316350
316452
|
fail,
|
|
316351
316453
|
retryBlocked,
|
|
316454
|
+
resetStuckThreadGeneration,
|
|
316352
316455
|
recover,
|
|
316353
316456
|
recoverLegacyRevokedInventory,
|
|
316354
316457
|
getStatus,
|
|
@@ -316481,10 +316584,14 @@ const retryHandler = require_Schema$1.gen(function* () {
|
|
|
316481
316584
|
const replication = yield* require_Schema$1.serviceOption(RuntimeReplication);
|
|
316482
316585
|
const requeued = yield* retryBlockedRuntimeReplicationOutbox;
|
|
316483
316586
|
const reprojectionPendingStreamKeys = yield* readReprojectionPendingThreadStreamKeys;
|
|
316484
|
-
|
|
316587
|
+
const stuckStreamKeys = yield* readStuckThreadStreamKeys;
|
|
316588
|
+
if (require_Schema$1.isSome(replication)) {
|
|
316589
|
+
yield* replication.value.retryReprojectionPending(reprojectionPendingStreamKeys);
|
|
316590
|
+
yield* replication.value.retryStuckThreadStreams(stuckStreamKeys);
|
|
316591
|
+
}
|
|
316485
316592
|
const status = yield* readRuntimeReplicationOutboxStatus;
|
|
316486
316593
|
return require_HttpServer.jsonUnsafe({
|
|
316487
|
-
requeued: requeued + (require_Schema$1.isSome(replication) ? reprojectionPendingStreamKeys.length : 0),
|
|
316594
|
+
requeued: requeued + (require_Schema$1.isSome(replication) ? reprojectionPendingStreamKeys.length + stuckStreamKeys.length : 0),
|
|
316488
316595
|
...responseFromStatus(status)
|
|
316489
316596
|
});
|
|
316490
316597
|
}).pipe(require_Schema$1.catchTag("AuthError", respondToAuthError));
|
package/dist/bin.mjs
CHANGED
|
@@ -66046,7 +66046,7 @@ function normalizeNumberish(value) {
|
|
|
66046
66046
|
}
|
|
66047
66047
|
//#endregion
|
|
66048
66048
|
//#region package.json
|
|
66049
|
-
var version$1 = "0.13.
|
|
66049
|
+
var version$1 = "0.13.124";
|
|
66050
66050
|
//#endregion
|
|
66051
66051
|
//#region src/sentry.ts
|
|
66052
66052
|
const SERVER_APP_NAME = "forge-server";
|
|
@@ -299854,7 +299854,7 @@ function resolveBuildCommitFromEnv(env) {
|
|
|
299854
299854
|
* environment descriptor down instead of reporting an honest "unknown".
|
|
299855
299855
|
*/
|
|
299856
299856
|
function readBakedBuildCommit() {
|
|
299857
|
-
return "
|
|
299857
|
+
return "52e8c25f0de536143b44ff1ac86510aa93d35772";
|
|
299858
299858
|
}
|
|
299859
299859
|
async function resolveServerBuildCommit(input) {
|
|
299860
299860
|
if (isFullCommitSha(input.baked)) return input.baked;
|
|
@@ -314427,9 +314427,17 @@ const RuntimeReplicationLive = effect(RuntimeReplication, gen(function* () {
|
|
|
314427
314427
|
concurrency: 1,
|
|
314428
314428
|
discard: true
|
|
314429
314429
|
});
|
|
314430
|
+
const retryStuckThreadStreams = (streamKeys) => runtimeId ? forEach(streamKeys, (streamKey) => outbox.resetStuckThreadGeneration({
|
|
314431
|
+
runtimeId,
|
|
314432
|
+
streamKey
|
|
314433
|
+
}).pipe(flatMap((reset) => reset ? enqueueThread(threadIdFromStreamKey(streamKey)) : void_$1)), {
|
|
314434
|
+
concurrency: 1,
|
|
314435
|
+
discard: true
|
|
314436
|
+
}) : void_$1;
|
|
314430
314437
|
return RuntimeReplication.of({
|
|
314431
314438
|
start,
|
|
314432
|
-
retryReprojectionPending
|
|
314439
|
+
retryReprojectionPending,
|
|
314440
|
+
retryStuckThreadStreams
|
|
314433
314441
|
});
|
|
314434
314442
|
}));
|
|
314435
314443
|
//#endregion
|
|
@@ -314764,6 +314772,31 @@ const THREAD_STREAM_PAYLOAD_HASH_MISMATCH_CODE = "THREAD_STREAM_PAYLOAD_HASH_MIS
|
|
|
314764
314772
|
*/
|
|
314765
314773
|
const THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING_CODE = "THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING";
|
|
314766
314774
|
/**
|
|
314775
|
+
* Terminal park code for a thread-events reset `refusedResetIsStuck` judges
|
|
314776
|
+
* genuinely stuck: the exact canonical reset shape was already sent once
|
|
314777
|
+
* under this generation and CMMD refused it again with zero acknowledged
|
|
314778
|
+
* progress (forge#3635). Before this code existed, that case fell through to
|
|
314779
|
+
* `failGeneric`, which recorded the raw `THREAD_STREAM_PAYLOAD_CONFLICT` /
|
|
314780
|
+
* `THREAD_STREAM_HEAD_MISMATCH` code -- a code neither
|
|
314781
|
+
* `readReprojectionPendingThreadStreamKeys` nor
|
|
314782
|
+
* `MANUALLY_RECOVERABLE_BLOCKED_CODES` selects, so the manual retry endpoint
|
|
314783
|
+
* could never reach the row.
|
|
314784
|
+
*
|
|
314785
|
+
* Deliberately excluded from `CLAIMABLE_BLOCKED_CODES`,
|
|
314786
|
+
* `STARTUP_RECOVERABLE_BLOCKED_CODES`, and `MANUALLY_RECOVERABLE_BLOCKED_CODES`:
|
|
314787
|
+
* a plain status flip back to `pending` would resend the exact batch CMMD
|
|
314788
|
+
* already refused twice. `enqueueThread` also leaves a row parked under this
|
|
314789
|
+
* code alone on new domain events and the heartbeat (see the stuck check
|
|
314790
|
+
* inside `enqueueThread` below) instead of re-projecting it back to `pending`
|
|
314791
|
+
* the way it does for every other generation, so a stuck row only clears once
|
|
314792
|
+
* the operator retry endpoint calls `RuntimeReplicationOutboxShape`'s
|
|
314793
|
+
* `resetStuckThreadGeneration` (which mints a fresh, never-before-sent repair
|
|
314794
|
+
* generation before re-projecting) or
|
|
314795
|
+
* a genuinely new generation id supersedes it (e.g. the thread archives and
|
|
314796
|
+
* gets a `:final:` id).
|
|
314797
|
+
*/
|
|
314798
|
+
const THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE = "THREAD_STREAM_REMOTE_CONFLICT_STUCK";
|
|
314799
|
+
/**
|
|
314767
314800
|
* Whether a refused batch is the exact canonical reset shape (`fromSequence
|
|
314768
314801
|
* === 1`, empty previous head, deterministic content) under a generation the
|
|
314769
314802
|
* local cursor already holds with zero acknowledged progress -- i.e. this
|
|
@@ -315041,6 +315074,23 @@ const readReprojectionPendingThreadStreamKeys = gen(function* () {
|
|
|
315041
315074
|
AND last_error_code = ${THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING_CODE}
|
|
315042
315075
|
`).map((row) => row.streamKey);
|
|
315043
315076
|
}).pipe(orDie);
|
|
315077
|
+
/**
|
|
315078
|
+
* Thread streams parked under THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE, for the
|
|
315079
|
+
* manual `/api/runtime-replication/retry` endpoint (forge#3635). Deliberately absent
|
|
315080
|
+
* from MANUALLY_RECOVERABLE_BLOCKED_CODES for the same reason
|
|
315081
|
+
* `readReprojectionPendingThreadStreamKeys` is: a plain status flip back to `pending`
|
|
315082
|
+
* would resend the exact reset CMMD already refused twice. `http.ts`'s retry handler
|
|
315083
|
+
* passes these to `RuntimeReplication`'s `retryStuckThreadStreams`, which calls
|
|
315084
|
+
* `resetStuckThreadGeneration` for each of these before re-projecting, so the retry
|
|
315085
|
+
* always sends a fresh, never-before-refused generation.
|
|
315086
|
+
*/
|
|
315087
|
+
const readStuckThreadStreamKeys = gen(function* () {
|
|
315088
|
+
return (yield* (yield* SqlClient)`
|
|
315089
|
+
SELECT stream_key AS "streamKey" FROM runtime_replication_outbox
|
|
315090
|
+
WHERE operation = 'thread-events' AND status = 'blocked'
|
|
315091
|
+
AND last_error_code = ${THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE}
|
|
315092
|
+
`).map((row) => row.streamKey);
|
|
315093
|
+
}).pipe(orDie);
|
|
315044
315094
|
const RuntimeReplicationOutboxLive = effect(RuntimeReplicationOutbox, gen(function* () {
|
|
315045
315095
|
const sql = yield* SqlClient;
|
|
315046
315096
|
const upsertPayload = (input) => {
|
|
@@ -315261,6 +315311,12 @@ const RuntimeReplicationOutboxLive = effect(RuntimeReplicationOutbox, gen(functi
|
|
|
315261
315311
|
now
|
|
315262
315312
|
}).pipe(orDie);
|
|
315263
315313
|
};
|
|
315314
|
+
const isThreadStreamParkedStuck = (input) => sql`
|
|
315315
|
+
SELECT runtime_id AS "runtimeId" FROM runtime_replication_outbox
|
|
315316
|
+
WHERE runtime_id = ${input.runtimeId} AND stream_key = ${input.streamKey}
|
|
315317
|
+
AND operation = 'thread-events' AND status = 'blocked'
|
|
315318
|
+
AND last_error_code = ${THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE}
|
|
315319
|
+
`.pipe(map$3((rows) => rows.length === 1));
|
|
315264
315320
|
const enqueueThread = (input) => {
|
|
315265
315321
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
315266
315322
|
const baseGenerationId = runtimeThreadGenerationId(input.runtimeId, input.streamKey);
|
|
@@ -315269,6 +315325,7 @@ const RuntimeReplicationOutboxLive = effect(RuntimeReplicationOutbox, gen(functi
|
|
|
315269
315325
|
const previousActiveGeneration = activeRuntimeThreadGenerationId(baseGenerationId, previousCursor?.generationId);
|
|
315270
315326
|
const generationId = input.historyFinalized ? runtimeThreadFinalGenerationId(input.runtimeId, input.streamKey, input.events) : previousActiveGeneration;
|
|
315271
315327
|
const replacesGeneration = previousCursor !== void 0 && previousCursor.generationId !== generationId;
|
|
315328
|
+
if (!replacesGeneration && (yield* isThreadStreamParkedStuck(input))) return;
|
|
315272
315329
|
yield* initializeThreadCursor({
|
|
315273
315330
|
runtimeId: input.runtimeId,
|
|
315274
315331
|
streamKey: input.streamKey,
|
|
@@ -315569,12 +315626,16 @@ const RuntimeReplicationOutboxLive = effect(RuntimeReplicationOutbox, gen(functi
|
|
|
315569
315626
|
})).pipe(orDie);
|
|
315570
315627
|
/**
|
|
315571
315628
|
* Recovers from a CMMD-reported thread stream conflict (see
|
|
315572
|
-
* THREAD_STREAM_REMOTE_CONFLICT_CODES). Returns `null` when this
|
|
315573
|
-
*
|
|
315574
|
-
* says the exact reset shape
|
|
315575
|
-
*
|
|
315576
|
-
*
|
|
315577
|
-
*
|
|
315629
|
+
* THREAD_STREAM_REMOTE_CONFLICT_CODES). Returns `null` only when this
|
|
315630
|
+
* item's payload does not decode, in which case the caller falls back to
|
|
315631
|
+
* `failGeneric`. When `refusedResetIsStuck` says the exact reset shape
|
|
315632
|
+
* already failed once with zero progress, parks the row under
|
|
315633
|
+
* `THREAD_STREAM_REMOTE_CONFLICT_STUCK_CODE` directly (see that code's
|
|
315634
|
+
* doc comment) and returns `true`/`false` the same way the normal repair
|
|
315635
|
+
* path below does -- never `null` -- so the caller never falls through to
|
|
315636
|
+
* `failGeneric`'s raw conflict code (forge#3635). `false` means the row
|
|
315637
|
+
* was superseded before this could apply, mirroring `fail`'s own
|
|
315638
|
+
* supersession signal. Otherwise replaces the local cursor with a brand-new repair generation
|
|
315578
315639
|
* from sequence 1, empty previous head -- the shape CMMD's reset rule
|
|
315579
315640
|
* accepts unconditionally -- and parks the row blocked under
|
|
315580
315641
|
* `THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING_CODE`, deferring the
|
|
@@ -315593,13 +315654,30 @@ const RuntimeReplicationOutboxLive = effect(RuntimeReplicationOutbox, gen(functi
|
|
|
315593
315654
|
runtimeId: item.runtimeId,
|
|
315594
315655
|
streamKey: item.streamKey
|
|
315595
315656
|
});
|
|
315657
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
315596
315658
|
if (refusedResetIsStuck({
|
|
315597
315659
|
baseGenerationId,
|
|
315598
315660
|
refusedGenerationId: parsedBatch.generationId,
|
|
315599
315661
|
refusedFromSequence: parsedBatch.fromSequence,
|
|
315600
315662
|
cursor
|
|
315601
|
-
}))
|
|
315602
|
-
|
|
315663
|
+
})) {
|
|
315664
|
+
if ((yield* sql`
|
|
315665
|
+
UPDATE runtime_replication_outbox SET
|
|
315666
|
+
status = 'blocked', next_attempt_at = '9999-12-31T23:59:59.999Z',
|
|
315667
|
+
last_error_code = ${"THREAD_STREAM_REMOTE_CONFLICT_STUCK"},
|
|
315668
|
+
last_error = ${`Runtime replication conflict (${failure.code}) refused a thread-events reset that had already been refused once with zero acknowledged progress under this generation. Parked as stuck rather than resent; use the manual retry endpoint to reset it to a fresh generation.`}, updated_at = ${now}
|
|
315669
|
+
WHERE runtime_id = ${item.runtimeId} AND stream_key = ${item.streamKey}
|
|
315670
|
+
AND payload_hash = ${item.payloadHash}
|
|
315671
|
+
RETURNING runtime_id AS "runtimeId"
|
|
315672
|
+
`).length !== 1) return false;
|
|
315673
|
+
yield* logWarning$1("Runtime replication parked a thread-stream repair as stuck after its reset was refused with zero progress.", {
|
|
315674
|
+
runtimeId: item.runtimeId,
|
|
315675
|
+
streamKey: item.streamKey,
|
|
315676
|
+
errorCode: failure.code,
|
|
315677
|
+
refusedGenerationId: parsedBatch.generationId
|
|
315678
|
+
});
|
|
315679
|
+
return true;
|
|
315680
|
+
}
|
|
315603
315681
|
const repairGenerationId = `${baseGenerationId}:repair:${Crypto.randomUUID()}`;
|
|
315604
315682
|
const message = `Runtime replication conflict (${failure.code}) refused a thread-events batch; deferring to a full-history re-projection under a new repair generation.`;
|
|
315605
315683
|
if (!(yield* sql.withTransaction(gen(function* () {
|
|
@@ -315667,6 +315745,30 @@ const RuntimeReplicationOutboxLive = effect(RuntimeReplicationOutbox, gen(functi
|
|
|
315667
315745
|
AND status = 'blocked'
|
|
315668
315746
|
AND last_error_code = 'RUNTIME_REVOKED'
|
|
315669
315747
|
`.pipe(asVoid, orDie);
|
|
315748
|
+
const resetStuckThreadGeneration = (input) => {
|
|
315749
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
315750
|
+
const repairGenerationId = `${runtimeThreadGenerationId(input.runtimeId, input.streamKey)}:repair:${Crypto.randomUUID()}`;
|
|
315751
|
+
const message = "Runtime replication operator retry reset a stuck thread-stream repair to a new generation.";
|
|
315752
|
+
return sql.withTransaction(gen(function* () {
|
|
315753
|
+
if ((yield* sql`
|
|
315754
|
+
UPDATE runtime_replication_outbox SET
|
|
315755
|
+
status = 'blocked', next_attempt_at = '9999-12-31T23:59:59.999Z',
|
|
315756
|
+
last_error_code = ${"THREAD_STREAM_REMOTE_CONFLICT_REPROJECTION_PENDING"},
|
|
315757
|
+
last_error = ${message}, updated_at = ${now}
|
|
315758
|
+
WHERE runtime_id = ${input.runtimeId} AND stream_key = ${input.streamKey}
|
|
315759
|
+
AND operation = 'thread-events'
|
|
315760
|
+
AND last_error_code = ${"THREAD_STREAM_REMOTE_CONFLICT_STUCK"}
|
|
315761
|
+
RETURNING runtime_id AS "runtimeId"
|
|
315762
|
+
`).length !== 1) return false;
|
|
315763
|
+
yield* replaceThreadCursor({
|
|
315764
|
+
runtimeId: input.runtimeId,
|
|
315765
|
+
streamKey: input.streamKey,
|
|
315766
|
+
generationId: repairGenerationId,
|
|
315767
|
+
now
|
|
315768
|
+
});
|
|
315769
|
+
return true;
|
|
315770
|
+
})).pipe(orDie);
|
|
315771
|
+
};
|
|
315670
315772
|
const getStatus = () => readRuntimeReplicationOutboxStatus.pipe(provideService(SqlClient, sql));
|
|
315671
315773
|
const getDiagnostics = () => gen(function* () {
|
|
315672
315774
|
const [diagnostics] = decodeDiagnostics(yield* sql`
|
|
@@ -315697,6 +315799,7 @@ const RuntimeReplicationOutboxLive = effect(RuntimeReplicationOutbox, gen(functi
|
|
|
315697
315799
|
acknowledge,
|
|
315698
315800
|
fail,
|
|
315699
315801
|
retryBlocked,
|
|
315802
|
+
resetStuckThreadGeneration,
|
|
315700
315803
|
recover,
|
|
315701
315804
|
recoverLegacyRevokedInventory,
|
|
315702
315805
|
getStatus,
|
|
@@ -315828,10 +315931,14 @@ const retryHandler = gen(function* () {
|
|
|
315828
315931
|
const replication = yield* serviceOption(RuntimeReplication);
|
|
315829
315932
|
const requeued = yield* retryBlockedRuntimeReplicationOutbox;
|
|
315830
315933
|
const reprojectionPendingStreamKeys = yield* readReprojectionPendingThreadStreamKeys;
|
|
315831
|
-
|
|
315934
|
+
const stuckStreamKeys = yield* readStuckThreadStreamKeys;
|
|
315935
|
+
if (isSome(replication)) {
|
|
315936
|
+
yield* replication.value.retryReprojectionPending(reprojectionPendingStreamKeys);
|
|
315937
|
+
yield* replication.value.retryStuckThreadStreams(stuckStreamKeys);
|
|
315938
|
+
}
|
|
315832
315939
|
const status = yield* readRuntimeReplicationOutboxStatus;
|
|
315833
315940
|
return jsonUnsafe({
|
|
315834
|
-
requeued: requeued + (isSome(replication) ? reprojectionPendingStreamKeys.length : 0),
|
|
315941
|
+
requeued: requeued + (isSome(replication) ? reprojectionPendingStreamKeys.length + stuckStreamKeys.length : 0),
|
|
315835
315942
|
...responseFromStatus(status)
|
|
315836
315943
|
});
|
|
315837
315944
|
}).pipe(catchTag("AuthError", respondToAuthError));
|
|
@@ -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{Jn as a,Nn as o,Tn as s,Us as c,Vn as l,Wn as u,_l as d,ai as f,br as p,c as m,d as h,di as g,eu as _,fn as v,hl as y,kn as b,m as x,o as S,pi as C,pl as w,ps as T,qt as E,rs as D,s as O,t as k,tr as A,u as j,vl as M,zn as N}from"./WorkerPoolContext-
|
|
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{Jn as a,Nn as o,Tn as s,Us as c,Vn as l,Wn as u,_l as d,ai as f,br as p,c as m,d as h,di as g,eu as _,fn as v,hl as y,kn as b,m as x,o as S,pi as C,pl as w,ps as T,qt as E,rs as D,s as O,t as k,tr as A,u as j,vl as M,zn as N}from"./WorkerPoolContext-CpM1XKxV.js";import{sn as P}from"./CompositeItem-DNVaubQt.js";import{a as F,c as I,i as L,l as R,n as z,o as B,r as V,s as H,t as U,u as W}from"./Virtualizer-D5o0Becp.js";import{On as G,at as K,ot as q}from"./src-BAHvoNAY.js";import"./cmmdAuthRedirect-BYBGztDm.js";import{a as J,c as ee,d as te,h as ne,i as re,l as ie,m as ae,n as oe,o as Y,p as se,r as ce,s as le,t as ue,u as de}from"./DiffPanel.logic-DK4RDoiD.js";import{n as fe,t as X}from"./toggle-group-Cqh7gA8I.js";var Z=e(i(),1),pe=typeof window>`u`?Z.useEffect:Z.useLayoutEffect;function me({fileDiff:e,options:t,editorOptions:n,lineAnnotations:r,selectedLines:i,prerenderedHTML:a,metrics:o,hasGutterRenderUtility:s,hasCustomHeader:c,disableWorkerPool:l,edit:u}){let d=z(),f=i!==void 0,p=(0,Z.useContext)(k),h=O(),g=(0,Z.useRef)(null),_=m(n=>{if(n!=null){if(g.current!=null)throw Error(`useFileDiffInstance: An instance should not already exist when a node is created`);d==null?g.current=new te(he({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),l?void 0:p,!0):g.current=new de(he({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),d,o,l?void 0:p,!0),g.current.hydrate({fileDiff:e,fileContainer:n,lineAnnotations:r,prerenderedHTML:a})}else{if(g.current==null)throw Error(`useFileDiffInstance: A FileDiff instance should exist when unmounting`);g.current.cleanUp(),g.current=null}});return pe(()=>{let{current:n}=g;if(n==null)return;let a=he({controlledSelection:f,hasCustomHeader:c,hasGutterRenderUtility:s,options:t}),o=a!==void 0&&!E(n.options,a);n.setOptions(a),n.render({forceRender:o,fileDiff:e,lineAnnotations:r}),i!==void 0&&n.setSelectedLines(i)}),pe(()=>{if(u&&g.current!=null){if(h===void 0)throw Error(`FileDiff: EditContext is not attached`);let e=h(n??{});if(e==null)throw Error(`FileDiff: EditProvider.createEditor must return an editor instance`);try{return e.edit(g.current)}catch(t){throw e.cleanUp(),t}}},[u]),{ref:_,getHoveredLine:(0,Z.useCallback)(()=>g.current?.getHoveredLine(),[])}}function he({options:e,controlledSelection:t,hasCustomHeader:n,hasGutterRenderUtility:r}){return t||r||n?{...e,controlledSelection:t,renderCustomHeader:n?S:e?.renderCustomHeader,renderGutterUtility:r?S: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}=me({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:V(ie({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?G(K)({threadId:e.threadId,toTurnCount:e.toTurnCount}).pipe(n(e=>({kind:`fullThreadDiff`,input:e}))):G(q)({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 d({queryKey:c.checkpointDiff(e),queryFn:async({signal:n})=>{if(!e.environmentId||!e.threadId||t._tag===`None`)throw Error(`Checkpoint diff is unavailable.`);let r=f(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,Z.useRef)(null),[n,r]=(0,Z.useState)(!1),[i,a]=(0,Z.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=le({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&&ee({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,Z.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,Z.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}=o(),a=A(),[c,l]=(0,Z.useState)(`stacked`),[u,d]=(0,Z.useState)(a.diffWordWrap),f=(0,Z.useRef)(null),m=(0,Z.useRef)(!1),g=Te(),{activeCwd:_,activeThread:v,bodyState:x,diffOpen:S,inferredCheckpointTurnCountByTurnId:C,orderedTurnDiffSummaries:T,renderableFiles:E,renderablePatch:D,selectedFilePath:O,selectedTurn:k,selectedTurnId:j}=Le(i),M,P;t[0]!==S||t[1]!==a.diffWordWrap?(M=()=>{S&&!m.current&&d(a.diffWordWrap),m.current=S},P=[S,a.diffWordWrap],t[0]=S,t[1]=a.diffWordWrap,t[2]=M,t[3]=P):(M=t[2],P=t[3]),(0,Z.useEffect)(M,P);let F;t[4]===O?F=t[5]:(F=()=>{!O||!f.current||Array.from(f.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,Z.useEffect)(F,I);let L;t[9]===_?L=t[10]:(L=e=>{let t=N();if(!t)return;let n=_?s(e,_):e;b(t,n).catch(ke)},t[9]=_,t[10]=L);let R=L,z;t[11]===v?z=t[12]:(z=e=>{v&&p.getState().openDiff(y(w(v.environmentId,v.id)),e)},t[11]=v,t[12]=z);let B=z,V;t[13]===v?V=t[14]:(V=()=>{v&&p.getState().openDiff(y(w(v.environmentId,v.id)))},t[13]=v,t[14]=V);let H=V,U;t[15]===g.remeasure?U=t[16]:(U=()=>{let e=window.requestAnimationFrame(g.remeasure);return()=>window.cancelAnimationFrame(e)},t[15]=g.remeasure,t[16]=U);let W;t[17]!==T||t[18]!==j||t[19]!==g.remeasure?(W=[T,j,g.remeasure],t[17]=T,t[18]=j,t[19]=g.remeasure,t[20]=W):W=t[20],(0,Z.useEffect)(U,W),Ee(g.ref,k?.turnId??j);let G;t[21]!==c||t[22]!==u||t[23]!==C||t[24]!==T||t[25]!==B||t[26]!==H||t[27]!==k||t[28]!==j||t[29]!==a||t[30]!==g?(G=(0,Q.jsx)(Ae,{diffRenderMode:c,diffWordWrap:u,inferredCheckpointTurnCountByTurnId:C,orderedTurnDiffSummaries:T,selectTurn:B,selectWholeConversation:H,selectedTurn:k,selectedTurnId:j,setDiffRenderMode:l,setDiffWordWrap:d,settings:a,turnStrip:g}),t[21]=c,t[22]=u,t[23]=C,t[24]=T,t[25]=B,t[26]=H,t[27]=k,t[28]=j,t[29]=a,t[30]=g,t[31]=G):G=t[31];let K=G,q;t[32]!==x||t[33]!==c||t[34]!==u||t[35]!==R||t[36]!==E||t[37]!==D||t[38]!==i?(q=(0,Q.jsx)(je,{bodyState:x,diffRenderMode:c,diffWordWrap:u,openDiffFileInEditor:R,patchViewportRef:f,renderableFiles:E,renderablePatch:D,resolvedTheme:i}),t[32]=x,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)(h,{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)(X,{"aria-label":`Stacked diff view`,value:`stacked`,children:(0,Q.jsx)(ae,{className:`size-3`})}),t[40]=A):A=t[40];let j;t[41]===Symbol.for(`react.memo_cache_sentinel`)?(j=(0,Q.jsx)(X,{"aria-label":`Split diff view`,value:`split`,children:(0,Q.jsx)(ne,{className:`size-3`})}),t[41]=j):j=t[41];let M;t[42]!==O||t[43]!==k?(M=(0,Q.jsxs)(fe,{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`,F=r?`Disable line wrapping`:`Enable line wrapping`,I;t[45]===d?I=t[46]:(I=e=>{d(!!e)},t[45]=d,t[46]=I);let L;t[47]===Symbol.for(`react.memo_cache_sentinel`)?(L=(0,Q.jsx)(se,{className:`size-3`}),t[47]=L):L=t[47];let R;t[48]!==r||t[49]!==N||t[50]!==F||t[51]!==I?(R=(0,Q.jsx)(X,{"aria-label":N,title:F,variant:`outline`,size:`xs`,pressed:r,onPressedChange:I,children:L}),t[48]=r,t[49]=N,t[50]=F,t[51]=I,t[52]=R):R=t[52];let z;t[53]!==M||t[54]!==R?(z=(0,Q.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1 [-webkit-app-region:no-drag]`,children:[M,R]}),t[53]=M,t[54]=R,t[55]=z):z=t[55];let B;return t[56]!==D||t[57]!==z?(B=(0,Q.jsxs)(Q.Fragment,{children:[D,z]}),t[56]=D,t[57]=z,t[58]=B):B=t[58],B}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)(U,{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=`${ue(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:x(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=_(t),r;e[1]===Symbol.for(`react.memo_cache_sentinel`)?(r={strict:!1,select:Fe},e[1]=r):r=e[1];let i=W(r),o=i.rightPanel===`diff`,s=n?.threadId??null,c,u;e[2]===n?u=e[3]:(u=a(n),e[2]=n,e[3]=u),c=u;let d=T(c),f=He(d),p=d?.worktreePath,m=f?.cwd,h;e[4]!==p||e[5]!==m?(h=B({threadWorktreePath:p,projectCwd:m}),e[4]=p,e[5]=m,e[6]=h):h=e[6];let g=h,v=d?.environmentId??null,y=g??null,b;e[7]!==v||e[8]!==y?(b={environmentId:v,cwd:y},e[7]=v,e[8]=y,e[9]=b):b=e[9];let x=l(b),S;e[10]===x.data?S=e[11]:(S=H(x.data),e[10]=x.data,e[11]=S);let C=S,w;return e[12]!==g||e[13]!==d||e[14]!==s||e[15]!==o||e[16]!==i||e[17]!==C?(w={activeThread:d,activeThreadId:s,activeCwd:g,isGitRepo:C,diffSearch:i,diffOpen:o},e[12]=g,e[13]=d,e[14]=s,e[15]=o,e[16]=i,e[17]=C,e[18]=w):w=e[18],w}function Fe(e){return F(e)}function Ie(e){return g(e)}function Le(e){let{activeThread:t,activeThreadId:n,activeCwd:r,isGitRepo:i,diffSearch:a,diffOpen:o}=Pe(),{turnDiffSummaries:s,inferredCheckpointTurnCountByTurnId:c}=L(t),l=a.diffTurnId??null,u=l===null?null:a.diffFilePath??null,{activeCheckpointRange:d,conversationCacheScope:f,orderedTurnDiffSummaries:p,selectedTurn:m}=(0,Z.useMemo)(()=>J({summaries:s,inferredCheckpointTurnCountByTurnId:c,selectedTurnId:l}),[c,l,s]),h=M(xe(we({environmentId:t?.environmentId,threadId:n,range:d,selectedTurnId:m?.turnId,conversationCacheScope:f,enabled:i}))),g=h.isLoading,_=Ce(h.error),v=h.data?.diff,y=typeof v==`string`&&v.trim().length===0,{emptyDiffMessage:b}=(0,Z.useMemo)(()=>re(m),[m]),x=(0,Z.useMemo)(()=>oe(v,`diff-panel:${e}`),[e,v]),S=(0,Z.useMemo)(()=>Ue(x),[x]);return{activeCwd:r,activeThread:t,bodyState:ce({hasActiveThread:!!t,isGitRepo:i,turnSummaryCount:p.length,checkpointDiffError:_,hasRenderablePatch:!!x,isLoadingCheckpointDiff:g,hasNoNetChanges:y,emptyDiffMessage:b}),diffOpen:o,inferredCheckpointTurnCountByTurnId:c,orderedTurnDiffSummaries:p,renderableFiles:S,renderablePatch:x,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)(j,{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)(I,{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?R:C,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 u;t[3]!==i||t[4]!==r?(u=()=>r.scrollBy(i?-180:ze),t[3]=i,t[4]=r,t[5]=u):u=t[5];let d=!a,f=`Scroll turn list ${n}`,p;t[6]===o?p=t[7]:(p=(0,Q.jsx)(o,{className:`size-3.5`}),t[6]=o,t[7]=p);let m;return t[8]!==l||t[9]!==u||t[10]!==d||t[11]!==f||t[12]!==p?(m=(0,Q.jsx)(`button`,{type:`button`,className:l,onClick:u,disabled:d,"aria-label":f,children:p}),t[8]=l,t[9]=u,t[10]=d,t[11]=f,t[12]=p,t[13]=m):m=t[13],m}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`,d;t[3]===l?d=t[4]:(d=P(`rounded-md border px-2 py-1 text-left transition-colors`,l),t[3]=l,t[4]=d);let f=i??`?`,p;t[5]===f?p=t[6]:(p=(0,Q.jsxs)(`span`,{className:`text-[10px] leading-tight font-medium`,children:[`Turn `,f]}),t[5]=f,t[6]=p);let m;t[7]!==n.completedAt||t[8]!==a?(m=u(n.completedAt,a),t[7]=n.completedAt,t[8]=a,t[9]=m):m=t[9];let h;t[10]===m?h=t[11]:(h=(0,Q.jsx)(`span`,{className:`text-[9px] leading-tight opacity-70`,children:m}),t[10]=m,t[11]=h);let g;t[12]!==p||t[13]!==h?(g=(0,Q.jsxs)(`div`,{className:`flex items-center gap-1`,children:[p,h]}),t[12]=p,t[13]=h,t[14]=g):g=t[14];let _;t[15]!==d||t[16]!==g?(_=(0,Q.jsx)(`div`,{className:d,children:g}),t[15]=d,t[16]=g,t[17]=_):_=t[17];let v;return t[18]!==r||t[19]!==n.turnId||t[20]!==s||t[21]!==_?(v=(0,Q.jsx)(`button`,{type:`button`,className:`shrink-0 rounded-md`,onClick:s,title:c,"data-turn-chip-selected":r,children:_}),t[18]=r,t[19]=n.turnId,t[20]=s,t[21]=_,t[22]=v):v=t[22],v}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?D(e,{environmentId:n,projectId:r}):void 0,t[0]=n,t[1]=r,t[2]=i):i=t[2],T(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-C1le0UaP.js.map
|