@p4code/cli 0.5.14 → 0.5.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.mjs +328 -57
- package/dist/client/assets/{DiffPanel-Y_5Ia30d.js → DiffPanel-BnLuM3jo.js} +2 -2
- package/dist/client/assets/{FilePreviewPanel-BCttBIPR.js → FilePreviewPanel-oKmAHtSz.js} +2 -2
- package/dist/client/assets/{PreviewPanel-W6mUm9Or.js → PreviewPanel-DjTevyic.js} +2 -2
- package/dist/client/assets/{PullRequestCodeTab-DkjmJEJK.js → PullRequestCodeTab-L4j_GNQB.js} +2 -2
- package/dist/client/assets/{fileCommentAnnotations-PMEbyK4D.js → fileCommentAnnotations-CoOCi5GC.js} +2 -2
- package/dist/client/assets/{index-D_D9GtC6.js → index-CL8KBlld.js} +177 -173
- package/dist/client/assets/{previewAssetResource-DIMp8MLe.js → previewAssetResource-CKOao7Zb.js} +35 -35
- package/dist/client/assets/{renderFileChildren-1-7OIJeP.js → renderFileChildren-CC342tNt.js} +2 -2
- package/dist/client/assets/{toggle-group-D5iDw8-4.js → toggle-group-hqQeP7ri.js} +2 -2
- package/dist/client/index.html +2 -2
- package/package.json +1 -1
package/dist/bin.mjs
CHANGED
|
@@ -265,7 +265,7 @@ const make$120 = () => {
|
|
|
265
265
|
const layer$122 = Layer.sync(NetService, make$120);
|
|
266
266
|
//#endregion
|
|
267
267
|
//#region package.json
|
|
268
|
-
var version$1 = "0.5.
|
|
268
|
+
var version$1 = "0.5.15";
|
|
269
269
|
//#endregion
|
|
270
270
|
//#region src/config.ts
|
|
271
271
|
/**
|
|
@@ -12885,11 +12885,11 @@ const ThreadWatchReviewResult = Schema$1.Struct({
|
|
|
12885
12885
|
/**
|
|
12886
12886
|
* How a review ended, from the supervisor's own account of it.
|
|
12887
12887
|
*
|
|
12888
|
-
*
|
|
12888
|
+
* Three states rather than a boolean because they are acted on differently: a
|
|
12889
12889
|
* summary that arrived is evidence, a fallback is a working review that cost
|
|
12890
|
-
* full context, a failure is a misconfiguration worth fixing
|
|
12891
|
-
*
|
|
12892
|
-
*
|
|
12890
|
+
* full context, and a failure is a misconfiguration worth fixing. The fourth
|
|
12891
|
+
* state - a read no report ever answered - is not sayable here: only the
|
|
12892
|
+
* server can observe it, through `ThreadEvidenceActivityOutcome`.
|
|
12893
12893
|
*/
|
|
12894
12894
|
const ThreadEvidenceReportOutcome = Schema$1.Literals([
|
|
12895
12895
|
"summarized",
|
|
@@ -12942,19 +12942,50 @@ const ThreadEvidenceReportContext = Schema$1.Struct({
|
|
|
12942
12942
|
maxTokens: Schema$1.NullOr(NonNegativeInt),
|
|
12943
12943
|
capacityPercent: Schema$1.NullOr(Schema$1.Number)
|
|
12944
12944
|
});
|
|
12945
|
+
/**
|
|
12946
|
+
* How the recorded row ended, which is the supervisor's three outcomes plus the
|
|
12947
|
+
* one only the server can state: the review closed with no report at all.
|
|
12948
|
+
*
|
|
12949
|
+
* `unreported` is never accepted from a tool call. The server writes it when a
|
|
12950
|
+
* supervisor turn ends over an evidence read that nothing answered, so the
|
|
12951
|
+
* absence survives outside a live client that could infer it from two rows.
|
|
12952
|
+
*/
|
|
12953
|
+
const ThreadEvidenceActivityOutcome = Schema$1.Literals([
|
|
12954
|
+
"summarized",
|
|
12955
|
+
"fallback",
|
|
12956
|
+
"failed",
|
|
12957
|
+
"unreported"
|
|
12958
|
+
]);
|
|
12959
|
+
/**
|
|
12960
|
+
* Server clock around one review, never the supervisor's own account of it.
|
|
12961
|
+
*
|
|
12962
|
+
* `readAt` is when the evidence-read row was recorded and `closedAt` when the
|
|
12963
|
+
* row that closes the review was: the report for a reported review, the turn
|
|
12964
|
+
* boundary for an unreported one.
|
|
12965
|
+
*/
|
|
12966
|
+
const ThreadEvidenceReportTiming = Schema$1.Struct({
|
|
12967
|
+
readAt: IsoDateTime,
|
|
12968
|
+
closedAt: IsoDateTime,
|
|
12969
|
+
durationMs: NonNegativeInt
|
|
12970
|
+
});
|
|
12945
12971
|
Schema$1.Struct({
|
|
12946
12972
|
watchedThreadId: ThreadId,
|
|
12947
12973
|
firstSequence: NonNegativeInt,
|
|
12948
12974
|
lastSequence: NonNegativeInt,
|
|
12949
12975
|
throughSequence: NonNegativeInt,
|
|
12950
|
-
outcome:
|
|
12976
|
+
outcome: ThreadEvidenceActivityOutcome,
|
|
12951
12977
|
summary: Schema$1.NullOr(Schema$1.String),
|
|
12952
12978
|
/** True when a snapshot dropped the text of a superseded report. */
|
|
12953
12979
|
summaryDropped: Schema$1.optionalKey(Schema$1.Boolean),
|
|
12954
12980
|
model: Schema$1.NullOr(Schema$1.String),
|
|
12955
12981
|
reason: Schema$1.NullOr(Schema$1.String),
|
|
12956
12982
|
/** Null when no context-window row exists yet for the reporting thread. */
|
|
12957
|
-
context: Schema$1.NullOr(ThreadEvidenceReportContext)
|
|
12983
|
+
context: Schema$1.NullOr(ThreadEvidenceReportContext),
|
|
12984
|
+
/**
|
|
12985
|
+
* Null when the evidence-read row behind this review is no longer readable,
|
|
12986
|
+
* and absent on rows stored before the server measured a review at all.
|
|
12987
|
+
*/
|
|
12988
|
+
timing: Schema$1.optionalKey(Schema$1.NullOr(ThreadEvidenceReportTiming))
|
|
12958
12989
|
});
|
|
12959
12990
|
const ThreadEvidenceReportResult = Schema$1.Struct({
|
|
12960
12991
|
recorded: Schema$1.Boolean,
|
|
@@ -41541,6 +41572,28 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
41541
41572
|
detached_at AS "detachedAt"
|
|
41542
41573
|
FROM thread_pairs
|
|
41543
41574
|
ORDER BY created_at ASC, pair_id ASC
|
|
41575
|
+
`
|
|
41576
|
+
});
|
|
41577
|
+
const listActiveThreadPairRows = SqlSchema.findAll({
|
|
41578
|
+
Request: Schema$1.Void,
|
|
41579
|
+
Result: ProjectionThreadPairDbRowSchema,
|
|
41580
|
+
execute: () => sql`
|
|
41581
|
+
SELECT
|
|
41582
|
+
pair_id AS "id",
|
|
41583
|
+
implementer_thread_id AS "implementerThreadId",
|
|
41584
|
+
watcher_thread_id AS "watcherThreadId",
|
|
41585
|
+
last_reviewed_implementer_sequence AS "lastReviewedImplementerSequence",
|
|
41586
|
+
triaged_from_sequence AS "triagedFromSequence",
|
|
41587
|
+
activation_turn_id AS "activationTurnId",
|
|
41588
|
+
round_cap AS "roundCap",
|
|
41589
|
+
gate_timeout_ms AS "gateTimeoutMs",
|
|
41590
|
+
review_experiment_json AS "reviewExperiment",
|
|
41591
|
+
active_gate_json AS "activeGate",
|
|
41592
|
+
created_at AS "createdAt",
|
|
41593
|
+
detached_at AS "detachedAt"
|
|
41594
|
+
FROM thread_pairs
|
|
41595
|
+
WHERE detached_at IS NULL
|
|
41596
|
+
ORDER BY created_at ASC, pair_id ASC
|
|
41544
41597
|
`
|
|
41545
41598
|
});
|
|
41546
41599
|
const LatestContextWindowRow = Schema$1.Struct({
|
|
@@ -41562,15 +41615,66 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
41562
41615
|
LIMIT 1
|
|
41563
41616
|
`
|
|
41564
41617
|
});
|
|
41565
|
-
const EvidenceReadContextRow = Schema$1.Struct({
|
|
41618
|
+
const EvidenceReadContextRow = Schema$1.Struct({
|
|
41619
|
+
usedTokensAtRead: Schema$1.NullOr(Schema$1.Number),
|
|
41620
|
+
readAt: Schema$1.String,
|
|
41621
|
+
afterSequence: Schema$1.NullOr(Schema$1.Number)
|
|
41622
|
+
});
|
|
41566
41623
|
const getEvidenceReadContextRow = SqlSchema.findOneOption({
|
|
41567
41624
|
Request: Schema$1.String,
|
|
41568
41625
|
Result: EvidenceReadContextRow,
|
|
41569
41626
|
execute: (activityId) => sql`
|
|
41570
|
-
SELECT
|
|
41627
|
+
SELECT
|
|
41628
|
+
CASE
|
|
41629
|
+
WHEN json_extract(payload_json, '$.usedTokensAtRead') >= 0
|
|
41630
|
+
THEN json_extract(payload_json, '$.usedTokensAtRead')
|
|
41631
|
+
ELSE NULL
|
|
41632
|
+
END AS "usedTokensAtRead",
|
|
41633
|
+
created_at AS "readAt",
|
|
41634
|
+
json_extract(payload_json, '$.afterSequence') AS "afterSequence"
|
|
41571
41635
|
FROM projection_thread_activities
|
|
41572
41636
|
WHERE activity_id = ${activityId}
|
|
41573
|
-
|
|
41637
|
+
LIMIT 1
|
|
41638
|
+
`
|
|
41639
|
+
});
|
|
41640
|
+
const LatestEvidenceReadRow = Schema$1.Struct({
|
|
41641
|
+
watchedThreadId: ThreadId,
|
|
41642
|
+
afterSequence: Schema$1.NullOr(Schema$1.Number),
|
|
41643
|
+
throughSequence: Schema$1.Number,
|
|
41644
|
+
readAt: Schema$1.String,
|
|
41645
|
+
hasReport: Schema$1.Number
|
|
41646
|
+
});
|
|
41647
|
+
/**
|
|
41648
|
+
* The newest evidence read on a thread, with whether a report answered it.
|
|
41649
|
+
*
|
|
41650
|
+
* Newest only: a supervisor that read again against a later bound superseded
|
|
41651
|
+
* the earlier read rather than leaving it unanswered, which is the same
|
|
41652
|
+
* pairing rule the client's own rows follow.
|
|
41653
|
+
*/
|
|
41654
|
+
const getLatestEvidenceReadRow = SqlSchema.findOneOption({
|
|
41655
|
+
Request: ThreadId,
|
|
41656
|
+
Result: LatestEvidenceReadRow,
|
|
41657
|
+
execute: (threadId) => sql`
|
|
41658
|
+
SELECT
|
|
41659
|
+
json_extract(reads.payload_json, '$.watchedThreadId') AS "watchedThreadId",
|
|
41660
|
+
json_extract(reads.payload_json, '$.afterSequence') AS "afterSequence",
|
|
41661
|
+
json_extract(reads.payload_json, '$.throughSequence') AS "throughSequence",
|
|
41662
|
+
reads.created_at AS "readAt",
|
|
41663
|
+
EXISTS (
|
|
41664
|
+
SELECT 1
|
|
41665
|
+
FROM projection_thread_activities reports
|
|
41666
|
+
WHERE reports.thread_id = reads.thread_id
|
|
41667
|
+
AND reports.kind = 'fusion.evidence.summary'
|
|
41668
|
+
AND json_extract(reports.payload_json, '$.watchedThreadId')
|
|
41669
|
+
= json_extract(reads.payload_json, '$.watchedThreadId')
|
|
41670
|
+
AND json_extract(reports.payload_json, '$.throughSequence')
|
|
41671
|
+
= json_extract(reads.payload_json, '$.throughSequence')
|
|
41672
|
+
) AS "hasReport"
|
|
41673
|
+
FROM projection_thread_activities reads
|
|
41674
|
+
WHERE reads.thread_id = ${threadId}
|
|
41675
|
+
AND reads.kind = 'fusion.evidence.read'
|
|
41676
|
+
AND json_extract(reads.payload_json, '$.throughSequence') >= 0
|
|
41677
|
+
ORDER BY reads.created_at DESC, reads.rowid DESC
|
|
41574
41678
|
LIMIT 1
|
|
41575
41679
|
`
|
|
41576
41680
|
});
|
|
@@ -43362,8 +43466,16 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
43362
43466
|
})) };
|
|
43363
43467
|
});
|
|
43364
43468
|
const getLatestThreadContextWindow = (threadId) => getLatestContextWindowRow(threadId).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getLatestThreadContextWindow:query", "ProjectionSnapshotQuery.getLatestThreadContextWindow:decodeRow")));
|
|
43365
|
-
const getEvidenceReadContext = (activityId) => getEvidenceReadContextRow(activityId).pipe(Effect.
|
|
43469
|
+
const getEvidenceReadContext = (activityId) => getEvidenceReadContextRow(activityId).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getEvidenceReadContext:query", "ProjectionSnapshotQuery.getEvidenceReadContext:decodeRow")));
|
|
43470
|
+
const getLatestEvidenceRead = (threadId) => getLatestEvidenceReadRow(threadId).pipe(Effect.map(Option.map((row) => ({
|
|
43471
|
+
watchedThreadId: row.watchedThreadId,
|
|
43472
|
+
afterSequence: row.afterSequence,
|
|
43473
|
+
throughSequence: row.throughSequence,
|
|
43474
|
+
readAt: row.readAt,
|
|
43475
|
+
hasReport: row.hasReport !== 0
|
|
43476
|
+
}))), Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getLatestEvidenceRead:query", "ProjectionSnapshotQuery.getLatestEvidenceRead:decodeRow")));
|
|
43366
43477
|
const getThreadPairById = (pairId) => getThreadPairRow(pairId).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadPairById:query", "ProjectionSnapshotQuery.getThreadPairById:decodeRow")));
|
|
43478
|
+
const getActiveThreadPairs = () => listActiveThreadPairRows(void 0).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getActiveThreadPairs:query", "ProjectionSnapshotQuery.getActiveThreadPairs:decodeRows")));
|
|
43367
43479
|
const getThreadShellById = (threadId) => Effect.gen(function* () {
|
|
43368
43480
|
const [threadRow, latestTurnRow, sessionRow] = yield* Effect.all([
|
|
43369
43481
|
getActiveThreadRowById({ threadId }).pipe(Effect.mapError(toPersistenceSqlOrDecodeError$1("ProjectionSnapshotQuery.getThreadShellById:getThread:query", "ProjectionSnapshotQuery.getThreadShellById:getThread:decodeRow"))),
|
|
@@ -43584,6 +43696,8 @@ const makeProjectionSnapshotQuery = Effect.gen(function* () {
|
|
|
43584
43696
|
getThreadCheckpointContext,
|
|
43585
43697
|
getFullThreadDiffContext,
|
|
43586
43698
|
getThreadPairById,
|
|
43699
|
+
getActiveThreadPairs,
|
|
43700
|
+
getLatestEvidenceRead,
|
|
43587
43701
|
getThreadShellById,
|
|
43588
43702
|
getThreadDetailById,
|
|
43589
43703
|
getHandoffContext,
|
|
@@ -59353,6 +59467,21 @@ function fusionRoleInstructionsFor(role, options) {
|
|
|
59353
59467
|
const model = fusionSummarizerModelFor(options.provider, options.summarizerModelOverride);
|
|
59354
59468
|
return `${FUSION_WATCHER_INSTRUCTIONS} ${FUSION_EVIDENCE_SUMMARY_INSTRUCTIONS} ${summarizerModelLine(model)}`;
|
|
59355
59469
|
}
|
|
59470
|
+
/**
|
|
59471
|
+
* The closing duty, restated in the wake that asks for the review.
|
|
59472
|
+
*
|
|
59473
|
+
* The same duty is in the supervisor's role block, but a wake message spells
|
|
59474
|
+
* out the whole turn and a model follows the instruction it was just handed:
|
|
59475
|
+
* with the duty only in the session channel, this install recorded 58 evidence
|
|
59476
|
+
* reads and no reports at all. Stated here it travels the common provider
|
|
59477
|
+
* input path, so it reaches every provider whatever its session prompt does.
|
|
59478
|
+
*/
|
|
59479
|
+
function fusionReviewClosingInstruction(input) {
|
|
59480
|
+
const close = `Then close this review with exactly one thread_evidence_report call: threadId ${input.implementerThreadId}, throughSequence ${input.throughSequence} - that exact number, never lastSequence and never the final page's nextAfterSequence, because the server pairs the report to the read by it - plus the first and last sequence you actually covered.`;
|
|
59481
|
+
return input.evidenceSummary ? `Read that evidence through one summarizer subagent against the same fixed throughSequence ${input.throughSequence} and review from what it returns. Fail open: if no subagent is available, the spawn errors, it times out, or what comes back is empty or cites no sequences, read the range yourself instead. Never skip or shorten the review because a summary was unavailable.
|
|
59482
|
+
|
|
59483
|
+
${close} Outcome summarized with the subagent's exact returned text and the model it ran on, fallback when you read the range yourself, or failed when the summarizer could not run - with your reason in the last two cases. Report even when no summary ever arrived; an unreported review cannot be told from a supervisor that never tried. Never paste builder tool output into the report.` : `${close} Evidence summarization is off for this environment, so the outcome is fallback with the reason you read the range yourself. Never paste builder tool output into the report.`;
|
|
59484
|
+
}
|
|
59356
59485
|
function fusionRoleReferenceLineFor(role) {
|
|
59357
59486
|
return role === "implementer" ? FUSION_BUILDER_REFERENCE_LINE : FUSION_WATCHER_REFERENCE_LINE;
|
|
59358
59487
|
}
|
|
@@ -134032,6 +134161,86 @@ const TypeSafeToolkitHandlersLive = TypeSafeToolkit.toLayer({ typesafe_ask: (inp
|
|
|
134032
134161
|
}).pipe(Effect.mapError((error) => new TypeSafeAskFailedError({ reason: `TypeSafe: ${error.reason}` })));
|
|
134033
134162
|
}) });
|
|
134034
134163
|
//#endregion
|
|
134164
|
+
//#region src/orchestration/fusionEvidenceReport.ts
|
|
134165
|
+
/**
|
|
134166
|
+
* Shared shape of one Fusion review's evidence rows.
|
|
134167
|
+
*
|
|
134168
|
+
* Two writers close a review: the supervisor calling `thread_evidence_report`,
|
|
134169
|
+
* and the server itself when a supervisor turn ends over a read nothing
|
|
134170
|
+
* answered. Both key their row the same way and measure the same numbers from
|
|
134171
|
+
* the same recorded rows, so a reader cannot tell which writer it is looking at
|
|
134172
|
+
* apart from the outcome the row carries.
|
|
134173
|
+
*
|
|
134174
|
+
* @module fusionEvidenceReport
|
|
134175
|
+
*/
|
|
134176
|
+
/**
|
|
134177
|
+
* One activity per review, not one per page.
|
|
134178
|
+
*
|
|
134179
|
+
* A supervisor pages a range with a fixed `throughSequence`, so keying the id
|
|
134180
|
+
* on the watched thread and that bound collapses a whole paged read into a
|
|
134181
|
+
* single row: the projector replaces an activity of the same id rather than
|
|
134182
|
+
* appending beside it.
|
|
134183
|
+
*/
|
|
134184
|
+
const evidenceReadActivityId = (watchedThreadId, throughSequence) => EventId.make(`fusion-evidence:${watchedThreadId}:${throughSequence}`);
|
|
134185
|
+
/** One report per review, keyed like the read it reports on so a retry replaces. */
|
|
134186
|
+
const evidenceReportActivityId = (watchedThreadId, throughSequence) => EventId.make(`fusion-evidence-summary:${watchedThreadId}:${throughSequence}`);
|
|
134187
|
+
/**
|
|
134188
|
+
* Server clock across the review, from the two recorded rows that bracket it.
|
|
134189
|
+
*
|
|
134190
|
+
* An unparsable timestamp yields null rather than a zero, and a closing time
|
|
134191
|
+
* behind the read yields null as well: a negative duration is a clock problem,
|
|
134192
|
+
* not a review that took no time.
|
|
134193
|
+
*/
|
|
134194
|
+
const evidenceTiming = (readAt, closedAt) => {
|
|
134195
|
+
const read = Date.parse(readAt);
|
|
134196
|
+
const closed = Date.parse(closedAt);
|
|
134197
|
+
if (Number.isNaN(read) || Number.isNaN(closed) || closed < read) return null;
|
|
134198
|
+
return {
|
|
134199
|
+
readAt,
|
|
134200
|
+
closedAt,
|
|
134201
|
+
durationMs: closed - read
|
|
134202
|
+
};
|
|
134203
|
+
};
|
|
134204
|
+
/**
|
|
134205
|
+
* The reporting thread's own context and elapsed time around the read it is
|
|
134206
|
+
* closing.
|
|
134207
|
+
*
|
|
134208
|
+
* `before` comes off the evidence-read activity rather than the closing row, so
|
|
134209
|
+
* the pair of numbers brackets the ingestion instead of describing only the
|
|
134210
|
+
* moment the supervisor got around to reporting. A thread with no
|
|
134211
|
+
* context-window row yet yields null rather than a zero that would read as a
|
|
134212
|
+
* real measurement.
|
|
134213
|
+
*/
|
|
134214
|
+
const correlateEvidence = Effect.fn("fusionEvidenceReport.correlateEvidence")(function* (input) {
|
|
134215
|
+
const projections = yield* ProjectionSnapshotQuery;
|
|
134216
|
+
const latest = yield* projections.getLatestThreadContextWindow(input.readerThreadId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134217
|
+
const read = yield* projections.getEvidenceReadContext(input.readActivityId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134218
|
+
const timing = Option.match(read, {
|
|
134219
|
+
onNone: () => null,
|
|
134220
|
+
onSome: (row) => evidenceTiming(row.readAt, input.closedAt)
|
|
134221
|
+
});
|
|
134222
|
+
if (Option.isNone(latest)) return {
|
|
134223
|
+
context: null,
|
|
134224
|
+
timing
|
|
134225
|
+
};
|
|
134226
|
+
const usedTokensAfter = latest.value.usedTokens;
|
|
134227
|
+
const usedTokensBefore = Option.match(read, {
|
|
134228
|
+
onNone: () => null,
|
|
134229
|
+
onSome: (row) => row.usedTokensAtRead
|
|
134230
|
+
});
|
|
134231
|
+
const maxTokens = latest.value.maxTokens;
|
|
134232
|
+
return {
|
|
134233
|
+
context: {
|
|
134234
|
+
usedTokensBefore,
|
|
134235
|
+
usedTokensAfter,
|
|
134236
|
+
deltaTokens: usedTokensBefore === null ? null : usedTokensAfter - usedTokensBefore,
|
|
134237
|
+
maxTokens,
|
|
134238
|
+
capacityPercent: maxTokens === null || maxTokens <= 0 ? null : Math.round(usedTokensAfter / maxTokens * 1e3) / 10
|
|
134239
|
+
},
|
|
134240
|
+
timing
|
|
134241
|
+
};
|
|
134242
|
+
});
|
|
134243
|
+
//#endregion
|
|
134035
134244
|
//#region src/mcp/toolkits/watch/tools.ts
|
|
134036
134245
|
/**
|
|
134037
134246
|
* Cross-thread by design, which is exactly why it is the most guarded tool in
|
|
@@ -134085,17 +134294,6 @@ const ThreadEvidenceReportTool = Tool.make("thread_evidence_report", {
|
|
|
134085
134294
|
const WatchToolkit = Toolkit.make(ThreadWatchEventsTool, ThreadWatchReviewTool, ThreadEvidenceReportTool);
|
|
134086
134295
|
//#endregion
|
|
134087
134296
|
//#region src/mcp/toolkits/watch/handlers.ts
|
|
134088
|
-
/**
|
|
134089
|
-
* One activity per review, not one per page.
|
|
134090
|
-
*
|
|
134091
|
-
* A supervisor pages a range with a fixed `throughSequence`, so keying the id
|
|
134092
|
-
* on the watched thread and that bound collapses a whole paged read into a
|
|
134093
|
-
* single row: the projector replaces an activity of the same id rather than
|
|
134094
|
-
* appending beside it.
|
|
134095
|
-
*/
|
|
134096
|
-
const evidenceActivityId = (watchedThreadId, throughSequence) => EventId.make(`fusion-evidence:${watchedThreadId}:${throughSequence}`);
|
|
134097
|
-
/** One report per review, keyed like the read it reports on so a retry replaces. */
|
|
134098
|
-
const reportActivityId = (watchedThreadId, lastSequence) => EventId.make(`fusion-evidence-summary:${watchedThreadId}:${lastSequence}`);
|
|
134099
134297
|
const MODEL_ID_MAX_CHARS = 120;
|
|
134100
134298
|
/** Plain words, because the client capitalizes and renders them as the row heading. */
|
|
134101
134299
|
const REPORT_HEADING = {
|
|
@@ -134110,27 +134308,37 @@ const REPORT_HEADING = {
|
|
|
134110
134308
|
* for; losing the note that it happened is a smaller loss than losing the page,
|
|
134111
134309
|
* so a rejected dispatch is logged and the page is returned anyway.
|
|
134112
134310
|
*/
|
|
134113
|
-
const recordEvidenceRead = Effect.fn("mcp.watch.recordEvidenceRead")(function* (readerThreadId, page) {
|
|
134311
|
+
const recordEvidenceRead = Effect.fn("mcp.watch.recordEvidenceRead")(function* (readerThreadId, page, afterSequence) {
|
|
134114
134312
|
const engine = yield* OrchestrationEngineService;
|
|
134115
134313
|
const crypto = yield* Crypto.Crypto;
|
|
134116
134314
|
const projections = yield* ProjectionSnapshotQuery;
|
|
134117
134315
|
const createdAt = DateTime.formatIso(yield* DateTime.now);
|
|
134118
|
-
const recorded = yield* projections.getEvidenceReadContext(
|
|
134119
|
-
const
|
|
134316
|
+
const recorded = yield* projections.getEvidenceReadContext(evidenceReadActivityId(page.threadId, page.throughSequence)).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134317
|
+
const opened = Option.isSome(recorded);
|
|
134318
|
+
const readCreatedAt = Option.match(recorded, {
|
|
134319
|
+
onNone: () => createdAt,
|
|
134320
|
+
onSome: (row) => row.readAt
|
|
134321
|
+
});
|
|
134322
|
+
const readAfterSequence = Option.match(recorded, {
|
|
134323
|
+
onNone: () => afterSequence,
|
|
134324
|
+
onSome: (row) => row.afterSequence ?? afterSequence
|
|
134325
|
+
});
|
|
134326
|
+
const usedTokensAtRead = opened ? Option.getOrNull(Option.map(recorded, (row) => row.usedTokensAtRead)) : yield* projections.getLatestThreadContextWindow(readerThreadId).pipe(Effect.map(Option.map((row) => row.usedTokens)), Effect.orElseSucceed(() => Option.none()), Effect.map(Option.getOrNull));
|
|
134120
134327
|
yield* engine.dispatch({
|
|
134121
134328
|
type: "thread.activity.append",
|
|
134122
134329
|
commandId: CommandId.make(yield* crypto.randomUUIDv4.pipe(Effect.orDie)),
|
|
134123
134330
|
threadId: readerThreadId,
|
|
134124
134331
|
createdAt,
|
|
134125
134332
|
activity: {
|
|
134126
|
-
id:
|
|
134127
|
-
createdAt,
|
|
134333
|
+
id: evidenceReadActivityId(page.threadId, page.throughSequence),
|
|
134334
|
+
createdAt: readCreatedAt,
|
|
134128
134335
|
tone: "info",
|
|
134129
134336
|
kind: "fusion.evidence.read",
|
|
134130
134337
|
summary: "Read builder evidence",
|
|
134131
134338
|
turnId: null,
|
|
134132
134339
|
payload: {
|
|
134133
134340
|
watchedThreadId: page.threadId,
|
|
134341
|
+
afterSequence: readAfterSequence,
|
|
134134
134342
|
throughSequence: page.throughSequence,
|
|
134135
134343
|
nextAfterSequence: page.nextAfterSequence,
|
|
134136
134344
|
hasMore: page.hasMore,
|
|
@@ -134150,30 +134358,6 @@ const clip = (value, limit) => {
|
|
|
134150
134358
|
if (!trimmed) return null;
|
|
134151
134359
|
return trimmed.length <= limit ? trimmed : `${trimmed.slice(0, limit)}…`;
|
|
134152
134360
|
};
|
|
134153
|
-
/**
|
|
134154
|
-
* The reporting thread's own context around the read it is reporting on.
|
|
134155
|
-
*
|
|
134156
|
-
* `before` comes off the evidence-read activity rather than the report, so the
|
|
134157
|
-
* pair of numbers brackets the ingestion instead of describing only the moment
|
|
134158
|
-
* the supervisor got around to reporting. A thread with no context-window row
|
|
134159
|
-
* yet yields null rather than a zero that would read as a real measurement.
|
|
134160
|
-
*/
|
|
134161
|
-
const correlateContext = Effect.fn("mcp.watch.correlateContext")(function* (readerThreadId, readActivityId) {
|
|
134162
|
-
const projections = yield* ProjectionSnapshotQuery;
|
|
134163
|
-
const latest = yield* projections.getLatestThreadContextWindow(readerThreadId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134164
|
-
const before = yield* projections.getEvidenceReadContext(readActivityId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
134165
|
-
if (Option.isNone(latest)) return null;
|
|
134166
|
-
const usedTokensAfter = latest.value.usedTokens;
|
|
134167
|
-
const usedTokensBefore = Option.getOrNull(before);
|
|
134168
|
-
const maxTokens = latest.value.maxTokens;
|
|
134169
|
-
return {
|
|
134170
|
-
usedTokensBefore,
|
|
134171
|
-
usedTokensAfter,
|
|
134172
|
-
deltaTokens: usedTokensBefore === null ? null : usedTokensAfter - usedTokensBefore,
|
|
134173
|
-
maxTokens,
|
|
134174
|
-
capacityPercent: maxTokens === null || maxTokens <= 0 ? null : Math.round(usedTokensAfter / maxTokens * 1e3) / 10
|
|
134175
|
-
};
|
|
134176
|
-
});
|
|
134177
134361
|
const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
134178
134362
|
thread_watch_review: (input) => Effect.gen(function* () {
|
|
134179
134363
|
const invocation = yield* requireWatchCapability(input.threadId);
|
|
@@ -134181,7 +134365,7 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134181
134365
|
threadId: input.threadId,
|
|
134182
134366
|
detail: cause.message
|
|
134183
134367
|
})));
|
|
134184
|
-
yield* recordEvidenceRead(invocation.threadId, page);
|
|
134368
|
+
yield* recordEvidenceRead(invocation.threadId, page, input.afterSequence ?? 0);
|
|
134185
134369
|
return page;
|
|
134186
134370
|
}),
|
|
134187
134371
|
thread_evidence_report: (input) => Effect.gen(function* () {
|
|
@@ -134189,7 +134373,11 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134189
134373
|
const engine = yield* OrchestrationEngineService;
|
|
134190
134374
|
const crypto = yield* Crypto.Crypto;
|
|
134191
134375
|
const createdAt = DateTime.formatIso(yield* DateTime.now);
|
|
134192
|
-
const context = yield*
|
|
134376
|
+
const { context, timing } = yield* correlateEvidence({
|
|
134377
|
+
readerThreadId: invocation.threadId,
|
|
134378
|
+
readActivityId: evidenceReadActivityId(input.threadId, input.throughSequence),
|
|
134379
|
+
closedAt: createdAt
|
|
134380
|
+
});
|
|
134193
134381
|
const summary = clip(input.summary, THREAD_EVIDENCE_REPORT_MAX_CHARS);
|
|
134194
134382
|
const reason = clip(input.reason, 500);
|
|
134195
134383
|
const outcome = summary === null && input.outcome === "summarized" ? "failed" : input.outcome;
|
|
@@ -134200,7 +134388,7 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134200
134388
|
threadId: invocation.threadId,
|
|
134201
134389
|
createdAt,
|
|
134202
134390
|
activity: {
|
|
134203
|
-
id:
|
|
134391
|
+
id: evidenceReportActivityId(input.threadId, input.throughSequence),
|
|
134204
134392
|
createdAt,
|
|
134205
134393
|
tone: outcome === "failed" ? "error" : "info",
|
|
134206
134394
|
kind: "fusion.evidence.summary",
|
|
@@ -134215,7 +134403,8 @@ const WatchToolkitHandlersLive = WatchToolkit.toLayer({
|
|
|
134215
134403
|
summary,
|
|
134216
134404
|
model: clip(input.model, MODEL_ID_MAX_CHARS),
|
|
134217
134405
|
reason: reason ?? (outcome === "summarized" ? null : "the supervisor gave no reason"),
|
|
134218
|
-
context
|
|
134406
|
+
context,
|
|
134407
|
+
timing
|
|
134219
134408
|
}
|
|
134220
134409
|
}
|
|
134221
134410
|
}).pipe(Effect.as(true), Effect.catchCause((cause) => Effect.logWarning("could not record the supervisor's evidence report", {
|
|
@@ -139153,6 +139342,12 @@ ${FUSION_WATCHER_TOOL_INSTRUCTIONS}
|
|
|
139153
139342
|
|
|
139154
139343
|
Call thread_watch_review, threadId ${input.implementerThreadId}, afterSequence ${input.afterSequence}, throughSequence ${input.throughSequence}. Continue with nextAfterSequence and the same throughSequence until hasMore is false, including empty pages. Apply message append/replace operations by identity across pages. Recover truncated or uncertain evidence with targeted thread_watch_events reads using its source sequence range. Inspect repo when useful.
|
|
139155
139344
|
|
|
139345
|
+
${fusionReviewClosingInstruction({
|
|
139346
|
+
implementerThreadId: input.implementerThreadId,
|
|
139347
|
+
throughSequence: input.throughSequence,
|
|
139348
|
+
evidenceSummary: input.evidenceSummary
|
|
139349
|
+
})}
|
|
139350
|
+
|
|
139156
139351
|
Always report concise:
|
|
139157
139352
|
|
|
139158
139353
|
- Progress: work done; completeness.
|
|
@@ -139234,6 +139429,13 @@ const make$3 = Effect.gen(function* () {
|
|
|
139234
139429
|
activePairs: (readModel.threadPairs ?? []).filter((pair) => pair.detachedAt === null)
|
|
139235
139430
|
};
|
|
139236
139431
|
});
|
|
139432
|
+
/**
|
|
139433
|
+
* Activity events arrive at provider streaming speed on every thread in the
|
|
139434
|
+
* install, and only a pair's own activities matter here. The pair table
|
|
139435
|
+
* alone answers that, so the hot path never decodes the whole command read
|
|
139436
|
+
* model; the rare branches that need threads read it themselves.
|
|
139437
|
+
*/
|
|
139438
|
+
const readActivePairs = projectionSnapshotQuery.getActiveThreadPairs();
|
|
139237
139439
|
const appendGateActivity = Effect.fn("FusionWatcherReactor.appendGateActivity")(function* (input) {
|
|
139238
139440
|
yield* orchestrationEngine.dispatch({
|
|
139239
139441
|
type: "thread.activity.append",
|
|
@@ -139488,10 +139690,18 @@ const make$3 = Effect.gen(function* () {
|
|
|
139488
139690
|
const requestId = payload["requestId"];
|
|
139489
139691
|
return typeof requestId === "string" && requestId.length > 0 ? requestId : void 0;
|
|
139490
139692
|
};
|
|
139693
|
+
/** The only activity kinds this reactor reacts to; everything else returns first. */
|
|
139694
|
+
const FUSION_ACTIVITY_KINDS = /* @__PURE__ */ new Set([
|
|
139695
|
+
"provider.turn.start.failed",
|
|
139696
|
+
"approval.requested",
|
|
139697
|
+
"approval.resolved",
|
|
139698
|
+
"tool.completed"
|
|
139699
|
+
]);
|
|
139491
139700
|
const processActivityAppended = Effect.fn("FusionWatcherReactor.processActivityAppended")(function* (event) {
|
|
139492
139701
|
if (event.sequence <= liveEventsAfterSequence) return;
|
|
139493
139702
|
const activity = event.payload.activity;
|
|
139494
|
-
|
|
139703
|
+
if (!FUSION_ACTIVITY_KINDS.has(activity.kind)) return;
|
|
139704
|
+
const activePairs = yield* readActivePairs;
|
|
139495
139705
|
const pairedThread = activePairs.find((candidate) => candidate.implementerThreadId === event.payload.threadId || candidate.watcherThreadId === event.payload.threadId);
|
|
139496
139706
|
if (activity.kind === "provider.turn.start.failed" && pairedThread !== void 0) {
|
|
139497
139707
|
yield* pausePairAfterProviderFailure({
|
|
@@ -139657,6 +139867,14 @@ const make$3 = Effect.gen(function* () {
|
|
|
139657
139867
|
});
|
|
139658
139868
|
});
|
|
139659
139869
|
/**
|
|
139870
|
+
* Unreadable settings mean the shipped default, not off: a supervisor that
|
|
139871
|
+
* was told nothing about closing its review is the failure this line exists
|
|
139872
|
+
* to prevent.
|
|
139873
|
+
*/
|
|
139874
|
+
const readEvidenceSummaryEnabled = Effect.gen(function* () {
|
|
139875
|
+
return (yield* serverSettings.getSettings.pipe(Effect.catchCause(() => Effect.succeed(null))))?.fusionEvidenceSummary ?? DEFAULT_FUSION_PROMPT_SETTINGS.evidenceSummary;
|
|
139876
|
+
});
|
|
139877
|
+
/**
|
|
139660
139878
|
* The pre-filter's configuration, or null when it must not run at all.
|
|
139661
139879
|
*
|
|
139662
139880
|
* A settings read failure returns null rather than a default: an unreadable
|
|
@@ -139752,7 +139970,8 @@ const make$3 = Effect.gen(function* () {
|
|
|
139752
139970
|
text: watcherPrompt({
|
|
139753
139971
|
implementerThreadId: currentPair.implementerThreadId,
|
|
139754
139972
|
afterSequence: currentPair.lastReviewedImplementerSequence,
|
|
139755
|
-
throughSequence: completion.sequence
|
|
139973
|
+
throughSequence: completion.sequence,
|
|
139974
|
+
evidenceSummary: yield* readEvidenceSummaryEnabled
|
|
139756
139975
|
}) + "\n\n" + fusionReviewPolicyInstructions(currentPair.reviewExperiment),
|
|
139757
139976
|
attachments: []
|
|
139758
139977
|
},
|
|
@@ -139820,6 +140039,53 @@ const make$3 = Effect.gen(function* () {
|
|
|
139820
140039
|
yield* processReview(pair, completion, turn);
|
|
139821
140040
|
}
|
|
139822
140041
|
});
|
|
140042
|
+
/**
|
|
140043
|
+
* Closes a supervisor turn that read the builder's evidence and ended without
|
|
140044
|
+
* reporting on it.
|
|
140045
|
+
*
|
|
140046
|
+
* The row it writes is keyed exactly like the supervisor's own report, so a
|
|
140047
|
+
* later report replaces it rather than doubling it, and it carries the same
|
|
140048
|
+
* server-measured context and timing. Without it, a review that was never
|
|
140049
|
+
* reported is indistinguishable in stored history from one that was never
|
|
140050
|
+
* attempted.
|
|
140051
|
+
*/
|
|
140052
|
+
const recordUnreportedEvidence = Effect.fn("FusionWatcherReactor.recordUnreportedEvidence")(function* (pair, completion) {
|
|
140053
|
+
const read = yield* projectionSnapshotQuery.getLatestEvidenceRead(pair.watcherThreadId).pipe(Effect.orElseSucceed(() => Option.none()));
|
|
140054
|
+
if (Option.isNone(read)) return;
|
|
140055
|
+
const latest = read.value;
|
|
140056
|
+
if (latest.hasReport || latest.watchedThreadId !== pair.implementerThreadId) return;
|
|
140057
|
+
const { context, timing } = yield* correlateEvidence({
|
|
140058
|
+
readerThreadId: pair.watcherThreadId,
|
|
140059
|
+
readActivityId: evidenceReadActivityId(latest.watchedThreadId, latest.throughSequence),
|
|
140060
|
+
closedAt: completion.occurredAt
|
|
140061
|
+
});
|
|
140062
|
+
yield* orchestrationEngine.dispatch({
|
|
140063
|
+
type: "thread.activity.append",
|
|
140064
|
+
commandId: CommandId.make(`server:fusion:${pair.id}:evidence-unreported:${latest.throughSequence}`),
|
|
140065
|
+
threadId: pair.watcherThreadId,
|
|
140066
|
+
createdAt: completion.occurredAt,
|
|
140067
|
+
activity: {
|
|
140068
|
+
id: evidenceReportActivityId(latest.watchedThreadId, latest.throughSequence),
|
|
140069
|
+
createdAt: completion.occurredAt,
|
|
140070
|
+
tone: "error",
|
|
140071
|
+
kind: "fusion.evidence.summary",
|
|
140072
|
+
summary: "Evidence never reported",
|
|
140073
|
+
turnId: null,
|
|
140074
|
+
payload: {
|
|
140075
|
+
watchedThreadId: latest.watchedThreadId,
|
|
140076
|
+
firstSequence: latest.afterSequence === null ? latest.throughSequence : Math.min(latest.afterSequence + 1, latest.throughSequence),
|
|
140077
|
+
lastSequence: latest.throughSequence,
|
|
140078
|
+
throughSequence: latest.throughSequence,
|
|
140079
|
+
outcome: "unreported",
|
|
140080
|
+
summary: null,
|
|
140081
|
+
model: null,
|
|
140082
|
+
reason: "the supervisor ended its turn without reporting on the evidence it read",
|
|
140083
|
+
context,
|
|
140084
|
+
timing
|
|
140085
|
+
}
|
|
140086
|
+
}
|
|
140087
|
+
});
|
|
140088
|
+
});
|
|
139823
140089
|
const processCompletion = Effect.fn("FusionWatcherReactor.processCompletion")(function* (event) {
|
|
139824
140090
|
const activePairs = ((yield* projectionSnapshotQuery.getCommandReadModel()).threadPairs ?? []).filter((pair) => pair.detachedAt === null);
|
|
139825
140091
|
const failedPair = activePairs.find((pair) => pair.implementerThreadId === event.payload.threadId || pair.watcherThreadId === event.payload.threadId);
|
|
@@ -139834,6 +140100,11 @@ const make$3 = Effect.gen(function* () {
|
|
|
139834
140100
|
return;
|
|
139835
140101
|
}
|
|
139836
140102
|
if (event.payload.state !== "completed") return;
|
|
140103
|
+
const watcherPair = activePairs.find((pair) => pair.watcherThreadId === event.payload.threadId);
|
|
140104
|
+
if (watcherPair !== void 0) yield* recordUnreportedEvidence(watcherPair, event).pipe(Effect.catchCause((cause) => Effect.logWarning("could not record an unreported Fusion evidence read", {
|
|
140105
|
+
pairId: watcherPair.id,
|
|
140106
|
+
cause: Cause.pretty(cause)
|
|
140107
|
+
})));
|
|
139837
140108
|
const pairs = activePairs.filter((pair) => pair.implementerThreadId === event.payload.threadId && event.sequence > pair.lastReviewedImplementerSequence);
|
|
139838
140109
|
yield* Effect.forEach(pairs, (pair) => catchUpPair(pair, event.sequence), {
|
|
139839
140110
|
concurrency: 1,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,r as n,t as r}from"./compiler-runtime-CLAvuQ-D.js";import{$l as i,Ba as a,Et as o,Fa as s,Ga as c,Il as l,Ja as ee,Ka as te,Ma as u,Rr as d,Ur as ne,Uu as f,Ya as p,Yr as re,_n as m,au as h,b as ie,dl as g,fl as _,gt as v,gu as ae,h as y,ht as b,ml as x,pl as oe,qa as S,st as C,uu as se,vt as w,xn as T,za as E}from"./previewAssetResource-
|
|
1
|
+
import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,r as n,t as r}from"./compiler-runtime-CLAvuQ-D.js";import{$l as i,Ba as a,Et as o,Fa as s,Ga as c,Il as l,Ja as ee,Ka as te,Ma as u,Rr as d,Ur as ne,Uu as f,Ya as p,Yr as re,_n as m,au as h,b as ie,dl as g,fl as _,gt as v,gu as ae,h as y,ht as b,ml as x,pl as oe,qa as S,st as C,uu as se,vt as w,xn as T,za as E}from"./previewAssetResource-CKOao7Zb.js";import{a as D,c as O,i as k,n as A,o as j,r as M,s as ce,t as N}from"./toggle-group-hqQeP7ri.js";import{A as le,Fr as ue,J as de,Lr as fe,M as P,Mr as pe,Nr as me,Rr as he,Y as ge,_ as _e,_r as ve,at as ye,cr as be,ct as xe,dr as Se,fr as Ce,h as we,hr as Te,it as Ee,j as De,jr as Oe,k as ke,lr as Ae,lt as je,oi as Me,or as Ne,ot as Pe,pr as Fe,rt as Ie,si as Le,sr as Re,st as ze,ur as Be,yr as Ve}from"./index-CL8KBlld.js";import{a as He,n as Ue}from"./fileCommentAnnotations-CoOCi5GC.js";var We=x(`pilcrow`,[[`path`,{d:`M13 4v16`,key:`8vvj80`}],[`path`,{d:`M17 4v16`,key:`7dpous`}],[`path`,{d:`M19 4H9.5a4.5 4.5 0 0 0 0 9H13`,key:`sh4n9v`}]]),F=e(n(),1);function Ge({threadRef:e,filePath:t,activeCwd:n,openInEditor:r,openFileSurface:i}){if(e){if(i){i(t);return}C.getState().openFile(e,t);return}r(n?y(t,n):t)}var I=r();function Ke(e,t){let n=(0,I.c)(4),r=Te(e,t),i;return n[0]!==r.data||n[1]!==r.error||n[2]!==r.isPending?(i={data:r.data,error:r.error,isPending:r.isPending},n[0]=r.data,n[1]=r.error,n[2]=r.isPending,n[3]=i):i=n[3],i}var L=t(),qe=[];function Je(e){return(e.endSide??e.side)===`deletions`?`deletions`:`additions`}function R(e,t,n){let r=Je(t),i=e.findIndex(e=>e.side===r&&e.lineNumber===t.end);return i<0?[...e,{side:r,lineNumber:t.end,metadata:{entries:[n]}}]:e.map((e,t)=>t===i?{...e,metadata:{entries:[...e.metadata.entries,n]}}:e)}function Ye(e){let t=(0,I.c)(50),{files:n,sectionId:r,sectionTitle:i,composerDraftTarget:a,options:o,viewerRef:s,className:c,renderHeaderPrefix:l}=e,ee=d(Qe),te=d(B),u;t[0]===a?u=t[1]:(u=e=>e.getComposerDraft(a)?.reviewComments??qe,t[0]=a,t[1]=u);let f=d(u),[p,m]=(0,F.useState)(null),[h,ie]=(0,F.useState)(null),g;t[2]===n?g=t[3]:(g=new Map(n.map(Ze)),t[2]=n,t[3]=g);let _=g,v;if(t[4]!==h||t[5]!==n||t[6]!==f||t[7]!==r){let e;t[9]!==h||t[10]!==f||t[11]!==r?(e=e=>{let{fileDiff:t,filePath:n,fileKey:i,collapsed:a}=e,o=f.filter(e=>e.sectionId===r&&e.filePath===n&&(e.fenceLanguage??`diff`)===`diff`).reduce((e,n)=>{let r=re(t,n);return r?R(e,r,{id:n.id,kind:`comment`,range:r,rangeLabel:n.rangeLabel,text:n.text}):e},[]),s=h?.fileKey===i?[...o,h.annotation]:o;return{id:i,type:`diff`,fileDiff:t,annotations:s,collapsed:a,version:Ee(`${a?`1`:`0`}:${s.flatMap(z).join(`:`)}`)}},t[9]=h,t[10]=f,t[11]=r,t[12]=e):e=t[12],v=n.map(e),t[4]=h,t[5]=n,t[6]=f,t[7]=r,t[8]=v}else v=t[8];let ae=v,y;t[13]!==a||t[14]!==h?.annotation||t[15]!==te?(y=e=>{m(null),h?.annotation.metadata.entries.some(t=>t.id===e)?ie(null):te(a,e)},t[13]=a,t[14]=h?.annotation,t[15]=te,t[16]=y):y=t[16];let b=y,x;t[17]!==ee||t[18]!==a||t[19]!==h||t[20]!==_||t[21]!==r||t[22]!==i?(x=(e,t)=>{let n=h?.annotation.metadata.entries.find(t=>t.id===e),o=h?_.get(h.fileKey):void 0;if(!n||!o)return;let s=ne({id:n.id,sectionId:r,sectionTitle:i,filePath:o.filePath,fileDiff:o.fileDiff,range:n.range,text:t});s&&ee(a,s),m(null),ie(null)},t[17]=ee,t[18]=a,t[19]=h,t[20]=_,t[21]=r,t[22]=i,t[23]=x):x=t[23];let oe=x,S;t[24]!==_||t[25]!==r||t[26]!==i?(S=(e,t)=>{if(!e)return;let n=t.item;if(n.type!==`diff`)return;let a=_.get(n.id);if(!a)return;let o=Ue(),s=ne({id:o,sectionId:r,sectionTitle:i,filePath:a.filePath,fileDiff:a.fileDiff,range:e,text:``});s&&ie({fileKey:n.id,annotation:{side:Je(e),lineNumber:e.end,metadata:{entries:[{id:o,kind:`draft`,range:e,rangeLabel:s.rangeLabel,text:``}]}}})},t[24]=_,t[25]=r,t[26]=i,t[27]=S):S=t[27];let C=S,se=h!==null,w;t[28]===s?w=t[29]:(w=s?{ref:s}:{},t[28]=s,t[29]=w);let T;t[30]===c?T=t[31]:(T=c?{className:c}:{},t[30]=c,t[31]=T);let E=!se,O=!se,k;t[32]!==C||t[33]!==o||t[34]!==O||t[35]!==E?(k={...o,enableGutterUtility:E,enableLineSelection:O,onLineSelectionEnd:C},t[32]=C,t[33]=o,t[34]=O,t[35]=E,t[36]=k):k=t[36];let A;t[37]===l?A=t[38]:(A=e=>e.type===`diff`?l(e.fileDiff,e.id,e.collapsed===!0):null,t[37]=l,t[38]=A);let j;t[39]!==b||t[40]!==oe?(j=e=>(0,L.jsx)(`div`,{className:`py-1`,children:e.metadata.entries.map(e=>(0,L.jsx)(He,{kind:e.kind,rangeLabel:e.rangeLabel,text:e.text,onCancel:()=>b(e.id),onComment:t=>oe(e.id,t),onDelete:()=>b(e.id)},e.id))}),t[39]=b,t[40]=oe,t[41]=j):j=t[41];let M;return t[42]!==ae||t[43]!==p||t[44]!==k||t[45]!==A||t[46]!==j||t[47]!==w||t[48]!==T?(M=(0,L.jsx)(D,{...w,...T,items:ae,selectedLines:p,onSelectedLinesChange:m,options:k,renderHeaderPrefix:A,renderAnnotation:j}),t[42]=ae,t[43]=p,t[44]=k,t[45]=A,t[46]=j,t[47]=w,t[48]=T,t[49]=M):M=t[49],M}function z(e){return e.metadata.entries.map(Xe)}function Xe(e){return`${e.id}:${e.rangeLabel}:${e.text}`}function Ze(e){return[e.fileKey,e]}function B(e){return e.removeReviewComment}function Qe(e){return e.addReviewComment}function $e(e){return{diffPreview:i(e,{label:`environment-data:review:diff-preview`,tag:f.reviewGetDiffPreview,staleTimeMs:5e3})}}var et=$e(T);function V(e){return e.remoteName&&e.name.startsWith(`${e.remoteName}/`)?e.name.slice(e.remoteName.length+1):e.name}function tt(e,t){let n=new Set(t),r=e.map(e=>{let r=t.filter(t=>n.has(t)&&V(t)===e.name),i=r.find(e=>e.remoteName===`origin`)??r[0]??null;return i&&n.delete(i),{id:`local:${e.name}`,label:e.name,local:e,remote:i}}),i=t.filter(e=>n.has(e)).map(e=>({id:`remote:${e.name}`,label:e.name,local:null,remote:e}));return[...r,...i]}function nt(e,t){let n=t.trim().toLocaleLowerCase();return n.length===0?e:e.filter(e=>e.label.toLocaleLowerCase().includes(n)||e.local?.name.toLocaleLowerCase().includes(n)===!0||e.remote?.name.toLocaleLowerCase().includes(n)===!0)}var H=`__automatic_base_ref__`,rt=new Set,it=`
|
|
2
2
|
[data-diffs-header],
|
|
3
3
|
[data-diff],
|
|
4
4
|
[data-file],
|
|
@@ -95,4 +95,4 @@ import{r as e}from"./rolldown-runtime-QTnfLwEv.js";import{n as t,r as n,t as r}f
|
|
|
95
95
|
text-decoration-color: currentColor;
|
|
96
96
|
}
|
|
97
97
|
`;function U({mode:e=`inline`,composerDraftTarget:t,initialGitScope:n,threadRef:r}){let{resolvedTheme:i}=ie(),d=ue(),[ne]=(0,F.useState)(n),[f,re]=(0,F.useState)(`stacked`),[y,x]=(0,F.useState)(d.wordWrap),[C,T]=(0,F.useState)(d.diffIgnoreWhitespace),[D,_e]=(0,F.useState)(``),[Te,Ee]=(0,F.useState)(()=>({scopeKey:null,fileKeys:rt})),He=(0,F.useRef)(null),Ue=r.threadId,I=me(r),qe=I?.projectId??null,Je=pe(I&&qe?{environmentId:I.environmentId,projectId:qe}:null),R=I?.worktreePath??Je?.workspaceRoot,z=l(m.configValueAtom(I?.environmentId??null)),Xe=ve(I?.environmentId??null,z?.availableEditors??[]),Ze=o(I!=null&&R!=null?Oe.status({environmentId:I.environmentId,input:{cwd:R}}):null),B=P(e=>De(e.byThreadKey,r,ne===`unstaged`)),Qe=Ze.data?.isRepo??!0,{turnDiffSummaries:$e,inferredCheckpointTurnCountByTurnId:V}=le(I),U=(0,F.useMemo)(()=>[...$e].toSorted((e,t)=>{let n=e.checkpointTurnCount??V[e.turnId]??0,r=t.checkpointTurnCount??V[t.turnId]??0;return n===r?t.completedAt.localeCompare(e.completedAt):r-n}),[V,$e]);(0,F.useEffect)(()=>{B.kind===`turn`&&P.getState().reconcileTurnSelection(r,U.map(e=>e.turnId))},[B,U,r]);let W=B.kind===`turn`?B.turnId:null,G=B.kind===`unstaged`?`unstaged`:`branch`,K=B.kind===`branch`?B.baseRef:null,at=B.kind===`turn`?B.filePath:null,ot=B.kind===`turn`?B.revealRequestId:0,q=W===null?void 0:U.find(e=>e.turnId===W)??U[0],J=q&&(q.checkpointTurnCount??V[q.turnId]),st=U[0],ct=W===null?G===`unstaged`?`Working tree`:`Branch changes`:q?.turnId===st?.turnId?`Latest turn`:`Turn ${J??`?`}`,lt=q?`turn:${q.turnId}`:G,Y=`${r.environmentId}:${r.threadId}:${lt}`,ut=Te.scopeKey===Y?Te.fileKeys:rt,dt=q?`Turn ${J??`?`}`:G===`unstaged`?`Working tree`:`Branch changes`,ft=(0,F.useMemo)(()=>typeof J==`number`?{fromTurnCount:Math.max(0,J-1),toTurnCount:J}:null,[J]),pt=Ke({environmentId:I?.environmentId??null,threadId:Ue,fromTurnCount:ft?.fromTurnCount??null,toTurnCount:ft?.toTurnCount??null,ignoreWhitespace:C,cacheScope:q?`turn:${q.turnId}`:null},{enabled:Qe&&q!==void 0}),mt=o(W===null&&I&&R?et.diffPreview({environmentId:I.environmentId,input:{cwd:R,...K?{baseRef:K}:{},ignoreWhitespace:C}}):null),ht=W===null&&mt.error?.includes(`configured workspace root`)===!0&&z?.cwd!==void 0&&z.cwd!==R,gt=o(ht&&I&&z?et.diffPreview({environmentId:I.environmentId,input:{cwd:z.cwd,...K?{baseRef:K}:{},ignoreWhitespace:C}}):null),X=ht?gt:mt,Z=X.data?.sources.find(e=>e.kind===(G===`unstaged`?`working-tree`:`branch-range`)),_t=o(W===null&&G===`branch`&&I&&X.data?.cwd?Oe.listRefs({environmentId:I.environmentId,input:{cwd:X.data.cwd,includeMatchingRemoteRefs:!0,refKind:`local`,...D.trim().length>0?{query:D.trim()}:{},limit:100}}):null),vt=o(W===null&&G===`branch`&&I&&X.data?.cwd?Oe.listRefs({environmentId:I.environmentId,input:{cwd:X.data.cwd,includeMatchingRemoteRefs:!0,refKind:`remote`,...D.trim().length>0?{query:D.trim()}:{},limit:100}}):null),yt=tt(_t.data?.refs.filter(e=>e.name!==Z?.headRef)??[],vt.data?.refs??[]),bt=nt(yt,D),xt=e=>K&&K===e.remote?.name?K:e.local?.name??e.remote?.name??e.id,St=[H,...yt.map(xt)],Ct=[...D.trim().length===0?[H]:[],...bt.map(xt)],wt=Z?.diff,Tt=q?pt.data?.diff:wt,Et=!q&&Z?.truncated===!0,Dt=q?pt.isPending:X.isPending,Ot=q?pt.error:X.error,kt=typeof Tt==`string`&&Tt.trim().length===0,Q=(0,F.useMemo)(()=>ze(Tt,`diff-panel:${i}`,{compactPartialHunkOffsets:W===null}),[i,Tt,W]),At=(0,F.useMemo)(()=>!Q||Q.kind!==`files`?[]:Q.files.toSorted((e,t)=>je(e).localeCompare(je(t),void 0,{numeric:!0,sensitivity:`base`})),[Q]),$=(0,F.useMemo)(()=>At.map(e=>{let t=Ie(e);return{fileDiff:e,filePath:je(e),fileKey:t,collapsed:ut.has(t)}}),[ut,At]),jt=(0,F.useMemo)(()=>$.map(e=>e.fileKey),[$]),Mt=M(jt,ut),Nt=(0,F.useMemo)(()=>Pe(At),[At]);(0,F.useEffect)(()=>{if(!at)return;let e=$.find(e=>e.filePath===at);e&&He.current?.scrollTo({type:`item`,id:e.fileKey,align:`start`})},[$,at,ot]);let Pt=ke({threadRef:r,workspaceRoot:R??null}),Ft=(0,F.useCallback)(e=>{Ge({threadRef:r,filePath:e,activeCwd:R,openFileSurface:Pt,openInEditor:e=>{(async()=>{let t=await Xe(e);t._tag===`Failure`&&!h(t)&&console.warn(`Failed to open diff file in editor.`,{operation:`open-diff-file`,environmentId:r.environmentId,threadId:r.threadId,...ae(se(t))})})()}})},[R,Pt,Xe,r]),It=(0,F.useCallback)(e=>{Ee(t=>{let n=new Set(t.scopeKey===Y?t.fileKeys:[]);return n.has(e)?n.delete(e):n.add(e),{scopeKey:Y,fileKeys:n}})},[Y]),Lt=(0,F.useCallback)(()=>{Ee(e=>{let t=e.scopeKey===Y?e.fileKeys:rt;return{scopeKey:Y,fileKeys:k(jt,t)}})},[Y,jt]),Rt=e=>{P.getState().selectTurn(r,e)},zt=e=>{P.getState().selectGitScope(r,e)},Bt=e=>{P.getState().selectBranchBaseRef(r,e)};return(0,L.jsx)(ge,{mode:e,header:(0,L.jsxs)(L.Fragment,{children:[(0,L.jsxs)(`div`,{className:`flex min-w-0 flex-1 items-center gap-3 [-webkit-app-region:no-drag]`,children:[(0,L.jsxs)(s,{children:[(0,L.jsxs)(ee,{className:`inline-flex h-6 max-w-full items-center gap-1 rounded-md bg-muted/70 px-2 text-xs font-medium text-foreground outline-none transition-colors hover:bg-muted focus-visible:ring-2 focus-visible:ring-ring`,"aria-label":`Diff scope: ${ct}`,children:[(0,L.jsx)(`span`,{className:`truncate`,children:ct}),(0,L.jsx)(_,{className:`size-3.5 shrink-0 text-muted-foreground`})]}),(0,L.jsxs)(a,{align:`start`,className:`w-60`,children:[(0,L.jsx)(E,{className:W===null&&G===`unstaged`?`bg-foreground/[0.08]`:void 0,onClick:()=>zt(`unstaged`),children:(0,L.jsx)(`span`,{children:`Working tree`})}),(0,L.jsx)(E,{className:W===null&&G===`branch`?`bg-foreground/[0.08]`:void 0,onClick:()=>zt(`branch`),children:(0,L.jsx)(`span`,{children:`Branch changes`})}),(0,L.jsx)(E,{className:W!==null&&q?.turnId===st?.turnId?`bg-foreground/[0.08]`:void 0,onClick:()=>{st&&Rt(st.turnId)},children:(0,L.jsx)(`span`,{children:`Latest turn`})}),(0,L.jsxs)(c,{children:[(0,L.jsx)(S,{children:`Turn`}),(0,L.jsx)(te,{className:`w-64`,children:U.map(e=>{let t=e.checkpointTurnCount??V[e.turnId]??`?`;return(0,L.jsxs)(E,{className:e.turnId===q?.turnId?`bg-foreground/[0.08]`:void 0,onClick:()=>Rt(e.turnId),children:[(0,L.jsxs)(`span`,{children:[`Turn `,t]}),(0,L.jsx)(`span`,{className:`ml-auto text-xs tabular-nums text-muted-foreground`,children:Ve(e.completedAt,d.timestampFormat)})]},e.turnId)})})]})]})]}),W===null&&G===`branch`&&Z?.baseRef&&(0,L.jsxs)(`div`,{className:`flex min-w-0 max-w-full items-center gap-2 overflow-hidden text-xs text-muted-foreground`,title:`${Z.headRef??`HEAD`} → ${Z.baseRef}`,"aria-label":`Comparing ${Z.headRef??`HEAD`} against ${Z.baseRef}`,children:[(0,L.jsx)(`span`,{className:`min-w-0 max-w-48 truncate`,children:Z.headRef??`HEAD`}),(0,L.jsx)(Le,{className:`size-3.5 shrink-0 opacity-70`}),(0,L.jsxs)(Ne,{items:St,filteredItems:Ct,value:K??H,onOpenChange:e=>{e||_e(``)},onValueChange:e=>{e&&Bt(e===H?null:e)},children:[(0,L.jsxs)(Ce,{className:`inline-flex min-w-0 max-w-48 items-center gap-1 overflow-hidden rounded-md px-1.5 py-1 outline-none transition-colors hover:bg-muted hover:text-foreground focus-visible:ring-2 focus-visible:ring-ring`,"aria-label":`Change comparison target. Currently ${Z.baseRef}`,children:[(0,L.jsx)(`span`,{className:`min-w-0 truncate`,children:Z.baseRef}),(0,L.jsx)(_,{className:`size-3.5 shrink-0 opacity-70`})]}),(0,L.jsxs)(Se,{align:`start`,className:`w-72 min-w-0 max-w-[calc(100vw-1rem)] overflow-hidden [&>[data-slot=combobox-popup]]:min-w-0 [&>[data-slot=combobox-popup]]:overflow-hidden`,children:[(0,L.jsx)(`div`,{className:`min-w-0 shrink-0 px-3 pt-2.5`,children:(0,L.jsxs)(`div`,{className:`relative -translate-y-px border-b border-border/70 pb-1.5 transition-colors focus-within:border-ring`,children:[(0,L.jsx)(he,{"aria-hidden":`true`,className:`pointer-events-none absolute top-1.5 left-0 size-4 shrink-0 text-muted-foreground/55`}),(0,L.jsx)(be,{className:`[&_input]:h-6.5 [&_input]:ps-5 [&_input]:font-sans [&_input]:leading-6.5`,inputClassName:`rounded-none bg-transparent text-sm`,placeholder:`Search refs...`,showTrigger:!1,size:`sm`,unstyled:!0,value:D,onChange:e=>_e(e.target.value)})]})}),(0,L.jsxs)(`div`,{className:`grid shrink-0 grid-cols-[1rem_minmax(0,1fr)] items-center gap-2 border-b border-border/70 ps-3 pe-6.5 pt-2 pb-1.5 font-medium text-[10px] text-muted-foreground uppercase tracking-wide`,children:[(0,L.jsx)(`span`,{"aria-hidden":`true`}),(0,L.jsxs)(`div`,{className:`grid min-w-0 grid-cols-[minmax(0,1fr)_2rem] items-center`,children:[(0,L.jsx)(`span`,{children:`Branch`}),(0,L.jsx)(`span`,{className:`text-right`,children:`Remote`})]})]}),(0,L.jsx)(Re,{children:`No matching refs.`}),(0,L.jsxs)(Be,{className:`max-h-64 min-w-0 overflow-x-hidden`,children:[(0,L.jsx)(Ae,{className:`h-8 w-full min-w-0 grid-cols-[1rem_minmax(0,1fr)] py-0`,contentClassName:`w-full min-w-0 overflow-hidden`,value:H,children:(0,L.jsx)(`span`,{className:`block min-w-0 truncate`,children:`Automatic`})}),yt.map(e=>{let t=xt(e),n=e.local!==null&&e.remote!==null,r=e.remote?.name===t;return(0,L.jsx)(Ae,{className:`h-8 w-full min-w-0 grid-cols-[1rem_minmax(0,1fr)] py-0`,contentClassName:`w-full min-w-0 overflow-hidden`,value:t,children:(0,L.jsxs)(`div`,{className:`grid w-full min-w-0 grid-cols-[minmax(0,1fr)_2rem] items-center overflow-hidden`,children:[(0,L.jsx)(`span`,{className:`block min-w-0 truncate pe-2`,children:e.label}),n?(0,L.jsx)(`div`,{className:`flex justify-end`,onClick:e=>e.stopPropagation(),onPointerDown:e=>e.stopPropagation(),children:(0,L.jsx)(Fe,{"aria-label":`Use remote version of ${e.label}`,checked:r,className:`[--thumb-size:--spacing(3)]`,onCheckedChange:t=>{let n=t?e.remote?.name:e.local?.name;n&&Bt(n)}})}):e.remote?(0,L.jsx)(`span`,{className:`flex justify-end text-muted-foreground`,title:`Remote only`,children:(0,L.jsx)(oe,{"aria-hidden":`true`,className:`size-3`})}):null]})},e.id)})]})]})]})]})]}),(0,L.jsxs)(`div`,{className:`flex shrink-0 items-center gap-1 [-webkit-app-region:no-drag]`,children:[$.length>0&&(0,L.jsx)(we,{additions:Nt.additions,deletions:Nt.deletions,className:`mr-1 text-[11px]`,layout:`inline`}),$.length>0&&(0,L.jsxs)(b,{children:[(0,L.jsx)(w,{render:(0,L.jsx)(u,{type:`button`,size:`icon-xs`,variant:`outline`,"aria-label":Mt?`Expand all files`:`Collapse all files`,onClick:Lt}),children:Mt?(0,L.jsx)(Me,{className:`size-3`}):(0,L.jsx)(O,{className:`size-3`})}),(0,L.jsx)(v,{side:`top`,children:Mt?`Expand all files`:`Collapse all files`})]}),(0,L.jsxs)(A,{className:`shrink-0`,variant:`outline`,size:`xs`,value:[f],onValueChange:e=>{let t=e[0];(t===`stacked`||t===`split`)&&re(t)},children:[(0,L.jsx)(N,{"aria-label":`Stacked diff view`,value:`stacked`,children:(0,L.jsx)(j,{className:`size-3`})}),(0,L.jsx)(N,{"aria-label":`Split diff view`,value:`split`,children:(0,L.jsx)(ce,{className:`size-3`})})]}),(0,L.jsxs)(b,{children:[(0,L.jsx)(w,{render:(0,L.jsx)(N,{"aria-label":y?`Disable diff line wrapping`:`Enable diff line wrapping`,variant:`outline`,size:`xs`,pressed:y,onPressedChange:e=>{x(!!e)}}),children:(0,L.jsx)(fe,{className:`size-3`})}),(0,L.jsx)(v,{side:`top`,children:y?`Disable line wrapping`:`Enable line wrapping`})]}),(0,L.jsxs)(b,{children:[(0,L.jsx)(w,{render:(0,L.jsx)(N,{"aria-label":C?`Show whitespace changes`:`Hide whitespace changes`,variant:`outline`,size:`xs`,pressed:C,onPressedChange:e=>{T(!!e)}}),children:(0,L.jsx)(We,{className:`size-3`})}),(0,L.jsx)(v,{side:`top`,children:C?`Show whitespace changes`:`Hide whitespace changes`})]})]})]}),children:I?Qe?W!==null&&U.length===0?(0,L.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:`No completed turns yet.`}):(0,L.jsx)(L.Fragment,{children:(0,L.jsxs)(`div`,{className:`diff-panel-viewport flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden`,children:[Et&&(0,L.jsx)(`p`,{className:`shrink-0 border-b border-border/70 bg-muted/40 px-3 py-1.5 text-[11px] text-muted-foreground`,children:`This diff was truncated because it exceeded the preview limit. The changes shown are incomplete.`}),Ot&&!Q&&(0,L.jsx)(`div`,{className:`px-3`,children:(0,L.jsx)(`p`,{className:`mb-2 text-[11px] text-red-500/80`,children:Ot})}),Q?Q.kind===`files`?(0,L.jsx)(`div`,{className:`min-h-0 flex-1`,onClickCapture:e=>{let t=(e.nativeEvent.composedPath?.()??[]).find(e=>e instanceof HTMLElement&&e.hasAttribute(`data-title`))?.textContent?.trim();t&&Ft(t)},children:(0,L.jsx)(Ye,{viewerRef:He,className:`diff-render-surface h-full min-h-0 overflow-auto`,files:$,sectionId:lt,sectionTitle:dt,composerDraftTarget:t,renderHeaderPrefix:(e,t,n)=>{let r=je(e);return(0,L.jsxs)(b,{children:[(0,L.jsx)(w,{render:(0,L.jsx)(`button`,{type:`button`,className:p(`inline-flex size-5 shrink-0 cursor-pointer items-center justify-center rounded-sm border-0 bg-transparent p-0 transition-colors hover:bg-foreground/10 focus-visible:outline-hidden`,ye(e)),"aria-label":n?`Expand ${r}`:`Collapse ${r}`,"aria-expanded":!n,onClick:e=>{e.stopPropagation(),It(t)}}),children:n?(0,L.jsx)(g,{className:`size-4`}):(0,L.jsx)(_,{className:`size-4`})}),(0,L.jsx)(v,{side:`top`,children:n?`Expand diff`:`Collapse diff`})]})},options:{diffStyle:f===`split`?`split`:`unified`,lineDiffType:`none`,overflow:y?`wrap`:`scroll`,theme:xe(i),themeType:i,unsafeCSS:it,stickyHeaders:!0,itemMetrics:{diffHeaderHeight:33},layout:{paddingTop:0,paddingBottom:8,gap:8}}},Y??lt)}):(0,L.jsx)(`div`,{className:`min-h-0 flex-1 overflow-auto p-2`,children:(0,L.jsxs)(`div`,{className:`space-y-2`,children:[(0,L.jsx)(`p`,{className:`text-[11px] text-muted-foreground/75`,children:Q.reason}),(0,L.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`,y?`overflow-auto whitespace-pre-wrap wrap-break-word`:`overflow-auto`),children:Q.text})]})}):Dt?(0,L.jsx)(de,{label:q?`Loading checkpoint diff...`:G===`unstaged`?`Loading working tree diff...`:`Loading branch diff...`}):(0,L.jsx)(`div`,{className:`flex h-full items-center justify-center px-3 py-2 text-xs text-muted-foreground/70`,children:(0,L.jsx)(`p`,{children:kt?`No net changes in this selection.`:`No patch available for this selection.`})})]})}):(0,L.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:`Turn diffs are unavailable because this project is not a git repository.`}):(0,L.jsx)(`div`,{className:`flex flex-1 items-center justify-center px-5 text-center text-xs text-muted-foreground/70`,children:`Select a thread to inspect turn diffs.`})})}export{_e as DiffWorkerPoolProvider,U as default};
|
|
98
|
-
//# sourceMappingURL=DiffPanel-
|
|
98
|
+
//# sourceMappingURL=DiffPanel-BnLuM3jo.js.map
|