@tutti-os/agent-gui 0.0.46 → 0.0.47
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/{AgentMentionSearchController-D5ks45fN.d.ts → AgentMentionSearchController-CExFPobz.d.ts} +1 -1
- package/dist/AgentMessageMarkdown-DeYPURtF.d.ts +7 -0
- package/dist/agent-conversation/index.d.ts +4 -3
- package/dist/agent-conversation/index.js +8 -8
- package/dist/agent-message-center/index.d.ts +1 -1
- package/dist/agent-message-center/index.js +9 -9
- package/dist/{agentConversationVM-1QgRwvwZ.d.ts → agentConversationVM-BTMtRteS.d.ts} +14 -0
- package/dist/{AgentMessageMarkdown-Cts0dAIm.d.ts → agentGuiNodeTypes-B5Y6yDKy.d.ts} +43 -9
- package/dist/app/renderer/agentactivity.css +92 -9
- package/dist/{chunk-FRG36S6N.js → chunk-2FOBSURO.js} +5 -5
- package/dist/chunk-2FOBSURO.js.map +1 -0
- package/dist/{chunk-AMNXH4DJ.js → chunk-2RYZ4EBF.js} +2 -2
- package/dist/{chunk-EIC7XS3C.js → chunk-5QTC2L52.js} +2 -2
- package/dist/{chunk-ZJ7OSY4T.js → chunk-7NCWSH7U.js} +9 -9
- package/dist/{chunk-ZJ7OSY4T.js.map → chunk-7NCWSH7U.js.map} +1 -1
- package/dist/{chunk-62QOR3TC.js → chunk-HCS3HUUX.js} +5 -5
- package/dist/{chunk-OL54R6OL.js → chunk-J3SJZMI5.js} +2 -2
- package/dist/{chunk-VFQR7AZI.js → chunk-KACBTC7Y.js} +25 -3
- package/dist/chunk-KACBTC7Y.js.map +1 -0
- package/dist/{chunk-FJG2EH4V.js → chunk-KUCWRSXU.js} +2 -2
- package/dist/{chunk-D6IYEVDT.js → chunk-MCH35MAX.js} +2 -2
- package/dist/{chunk-NZ2BGOJU.js → chunk-Q4X6Q4E6.js} +2 -2
- package/dist/{chunk-EU7RWKHE.js → chunk-R6GOICRO.js} +5 -5
- package/dist/chunk-SD56WDSC.js +359 -0
- package/dist/chunk-SD56WDSC.js.map +1 -0
- package/dist/{chunk-TXXWUG2J.js → chunk-VE6JY2TH.js} +2 -1
- package/dist/{chunk-TXXWUG2J.js.map → chunk-VE6JY2TH.js.map} +1 -1
- package/dist/{chunk-QT45WUPQ.js → chunk-XJXSR5XI.js} +244 -21
- package/dist/chunk-XJXSR5XI.js.map +1 -0
- package/dist/{chunk-BAQTM6VS.js → chunk-ZAF4IVUT.js} +848 -102
- package/dist/chunk-ZAF4IVUT.js.map +1 -0
- package/dist/context-mention-palette/index.d.ts +3 -3
- package/dist/context-mention-palette/index.js +9 -9
- package/dist/i18n/index.d.ts +24 -2
- package/dist/i18n/index.js +2 -2
- package/dist/index.d.ts +22 -6
- package/dist/index.js +847 -812
- package/dist/index.js.map +1 -1
- package/dist/plan-decision-ops.d.ts +1 -1
- package/dist/queued-prompt-runtime.d.ts +97 -0
- package/dist/queued-prompt-runtime.js +9 -0
- package/dist/queued-prompt-runtime.js.map +1 -0
- package/dist/workbench/contribution.js +3 -3
- package/dist/workbench/index.js +9 -9
- package/dist/workbench/launch.js +2 -2
- package/dist/workbench/sessionTitle.js +3 -3
- package/dist/workspace-agent-generated-files.js +3 -3
- package/package.json +21 -14
- package/dist/chunk-BAQTM6VS.js.map +0 -1
- package/dist/chunk-FRG36S6N.js.map +0 -1
- package/dist/chunk-QT45WUPQ.js.map +0 -1
- package/dist/chunk-VFQR7AZI.js.map +0 -1
- /package/dist/{chunk-AMNXH4DJ.js.map → chunk-2RYZ4EBF.js.map} +0 -0
- /package/dist/{chunk-EIC7XS3C.js.map → chunk-5QTC2L52.js.map} +0 -0
- /package/dist/{chunk-62QOR3TC.js.map → chunk-HCS3HUUX.js.map} +0 -0
- /package/dist/{chunk-OL54R6OL.js.map → chunk-J3SJZMI5.js.map} +0 -0
- /package/dist/{chunk-FJG2EH4V.js.map → chunk-KUCWRSXU.js.map} +0 -0
- /package/dist/{chunk-D6IYEVDT.js.map → chunk-MCH35MAX.js.map} +0 -0
- /package/dist/{chunk-NZ2BGOJU.js.map → chunk-Q4X6Q4E6.js.map} +0 -0
- /package/dist/{chunk-EU7RWKHE.js.map → chunk-R6GOICRO.js.map} +0 -0
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
resolveWorkspaceFileLinkAction,
|
|
11
11
|
resolveWorkspaceFilePathCandidate,
|
|
12
12
|
resolveWorkspaceLinkAction
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XJXSR5XI.js";
|
|
14
14
|
import {
|
|
15
15
|
AGENT_RICH_TEXT_CARET_ANCHOR,
|
|
16
16
|
attrsToMentionItem,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
formatAgentMentionMarkdown,
|
|
19
19
|
mentionItemToAttrs,
|
|
20
20
|
parseAgentMentionMarkdown
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2FOBSURO.js";
|
|
22
22
|
import {
|
|
23
23
|
fileChangeCountFromChanges,
|
|
24
24
|
fileChangeEntriesFromChanges,
|
|
@@ -28,13 +28,14 @@ import {
|
|
|
28
28
|
import {
|
|
29
29
|
getOptionalAgentActivityRuntime,
|
|
30
30
|
useOptionalAgentHostApi
|
|
31
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-VE6JY2TH.js";
|
|
32
32
|
import {
|
|
33
33
|
workspaceAgentProviderLabel
|
|
34
34
|
} from "./chunk-TYGL25EL.js";
|
|
35
35
|
import {
|
|
36
|
+
getActiveUiLanguage,
|
|
36
37
|
translate
|
|
37
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-5QTC2L52.js";
|
|
38
39
|
|
|
39
40
|
// shared/imageGenerationTool.ts
|
|
40
41
|
var KNOWN_IMAGE_GENERATION_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -3350,7 +3351,10 @@ function tryExtractContentField(text) {
|
|
|
3350
3351
|
|
|
3351
3352
|
// shared/agentConversation/projection/agentTurnSummaryProjection.ts
|
|
3352
3353
|
function projectAgentTurnSummaryRows(detail) {
|
|
3353
|
-
const options = {
|
|
3354
|
+
const options = {
|
|
3355
|
+
defaultCwd: detail.cwd,
|
|
3356
|
+
workspaceRoot: detail.workspaceRoot
|
|
3357
|
+
};
|
|
3354
3358
|
const rows = detail.turns.flatMap(
|
|
3355
3359
|
(turn) => projectAgentTurnSummaryRowForTurn(turn, options)
|
|
3356
3360
|
);
|
|
@@ -3402,16 +3406,14 @@ function normalizedActivityFilePath(value, options) {
|
|
|
3402
3406
|
}) ? path : null;
|
|
3403
3407
|
}
|
|
3404
3408
|
function projectAgentTurnSummaryRowForTurn(turn, options = {}) {
|
|
3409
|
+
const summaryCalls = turnToolCallsForSummary(turn);
|
|
3405
3410
|
const files = applyShortestUniqueFileLabels(
|
|
3406
|
-
dedupeFiles(
|
|
3407
|
-
turnToolCallsForSummary(turn).flatMap(
|
|
3408
|
-
(call) => filesFromCall(call, options)
|
|
3409
|
-
)
|
|
3410
|
-
)
|
|
3411
|
+
dedupeFiles(summaryCalls.flatMap((call) => filesFromCall(call, options)))
|
|
3411
3412
|
);
|
|
3412
3413
|
if (files.length === 0) {
|
|
3413
3414
|
return [];
|
|
3414
3415
|
}
|
|
3416
|
+
const patchBatches = patchBatchesFromCalls(summaryCalls, options);
|
|
3415
3417
|
const fileCount = files.length;
|
|
3416
3418
|
const createdCount = files.filter(
|
|
3417
3419
|
(file) => file.changeType === "created"
|
|
@@ -3424,6 +3426,7 @@ function projectAgentTurnSummaryRowForTurn(turn, options = {}) {
|
|
|
3424
3426
|
id: `turn-summary:${turn.id}`,
|
|
3425
3427
|
turnId: turn.id,
|
|
3426
3428
|
files,
|
|
3429
|
+
...patchBatches.length > 0 ? { patchBatches } : {},
|
|
3427
3430
|
fileCount,
|
|
3428
3431
|
modifiedCount,
|
|
3429
3432
|
createdCount,
|
|
@@ -3453,11 +3456,10 @@ function turnToolCallsForSummary(turn) {
|
|
|
3453
3456
|
}
|
|
3454
3457
|
function filesFromCall(call, options) {
|
|
3455
3458
|
const toolState = objectValue5(call.payload?.tool_state);
|
|
3456
|
-
const metadata = objectValue5(call.payload?.metadata);
|
|
3457
3459
|
const input = objectValue5(call.payload?.input) ?? objectValue5(toolState?.input) ?? summaryPathInput(call.summary, options);
|
|
3458
3460
|
const output = objectValue5(call.payload?.output) ?? objectValue5(toolState?.output);
|
|
3459
3461
|
const error = objectValue5(call.payload?.error) ?? objectValue5(toolState?.error);
|
|
3460
|
-
const nestedTaskSteps =
|
|
3462
|
+
const nestedTaskSteps = nestedTaskStepsFromPayload(call.payload, output);
|
|
3461
3463
|
const directChanges = extractFileChanges({
|
|
3462
3464
|
id: call.id,
|
|
3463
3465
|
toolName: call.toolName,
|
|
@@ -3477,11 +3479,7 @@ function filesFromCall(call, options) {
|
|
|
3477
3479
|
return extractFileChanges({
|
|
3478
3480
|
id: stringValue6(step.toolUseId) ?? stringValue6(step.id) ?? `${call.id}:step:${index + 1}`,
|
|
3479
3481
|
toolName: stringValue6(step.toolName) ?? stringValue6(step.tool_name) ?? stringValue6(step.name) ?? null,
|
|
3480
|
-
statusKind:
|
|
3481
|
-
stringValue6(step.statusKind),
|
|
3482
|
-
stringValue6(step.status),
|
|
3483
|
-
stringValue6(step.toolStatus)
|
|
3484
|
-
) ?? call.statusKind ?? null,
|
|
3482
|
+
statusKind: nestedTaskStepStatusKind(step, call.statusKind ?? null),
|
|
3485
3483
|
occurredAtUnixMs: numberValue2(step.occurredAtUnixMs) ?? numberValue2(step.occurred_at_unix_ms) ?? call.occurredAtUnixMs ?? null,
|
|
3486
3484
|
payload: objectValue5(step.payload),
|
|
3487
3485
|
input: objectValue5(step.toolInput) ?? objectValue5(step.tool_input),
|
|
@@ -3492,6 +3490,125 @@ function filesFromCall(call, options) {
|
|
|
3492
3490
|
});
|
|
3493
3491
|
return [...directChanges, ...nestedChanges];
|
|
3494
3492
|
}
|
|
3493
|
+
function patchBatchesFromCalls(calls, options) {
|
|
3494
|
+
return calls.flatMap((call) => patchBatchesFromCall(call, options));
|
|
3495
|
+
}
|
|
3496
|
+
function patchBatchesFromCall(call, options) {
|
|
3497
|
+
const directBatch = isFailedToolStatus(call.statusKind ?? null) ? [] : patchBatchFromPayload({
|
|
3498
|
+
id: call.id,
|
|
3499
|
+
payload: call.payload ?? null,
|
|
3500
|
+
toolInput: null,
|
|
3501
|
+
toolOutput: null,
|
|
3502
|
+
toolError: null,
|
|
3503
|
+
options
|
|
3504
|
+
});
|
|
3505
|
+
const output = objectValue5(call.payload?.output);
|
|
3506
|
+
const nestedTaskSteps = nestedTaskStepsFromPayload(call.payload, output);
|
|
3507
|
+
const nestedBatches = nestedTaskSteps.flatMap((value, index) => {
|
|
3508
|
+
const step = objectValue5(value);
|
|
3509
|
+
if (!step) {
|
|
3510
|
+
return [];
|
|
3511
|
+
}
|
|
3512
|
+
if (isFailedToolStatus(
|
|
3513
|
+
nestedTaskStepStatusKind(step, call.statusKind ?? null)
|
|
3514
|
+
)) {
|
|
3515
|
+
return [];
|
|
3516
|
+
}
|
|
3517
|
+
return patchBatchFromPayload({
|
|
3518
|
+
id: stringValue6(step.toolUseId) ?? stringValue6(step.id) ?? `${call.id}:step:${index + 1}`,
|
|
3519
|
+
payload: objectValue5(step.payload),
|
|
3520
|
+
toolInput: objectValue5(step.toolInput) ?? objectValue5(step.tool_input),
|
|
3521
|
+
toolOutput: objectValue5(step.toolResult) ?? objectValue5(step.tool_result),
|
|
3522
|
+
toolError: objectValue5(step.toolError) ?? objectValue5(step.tool_error),
|
|
3523
|
+
options
|
|
3524
|
+
});
|
|
3525
|
+
});
|
|
3526
|
+
return [...directBatch, ...nestedBatches];
|
|
3527
|
+
}
|
|
3528
|
+
function patchBatchFromPayload(input) {
|
|
3529
|
+
const toolState = objectValue5(input.payload?.tool_state);
|
|
3530
|
+
const metadata = objectValue5(input.payload?.metadata);
|
|
3531
|
+
const payloadInput = input.toolInput ?? objectValue5(input.payload?.input) ?? objectValue5(toolState?.input);
|
|
3532
|
+
const payloadOutput = input.toolOutput ?? objectValue5(input.payload?.output) ?? objectValue5(toolState?.output);
|
|
3533
|
+
const rawInput = objectValue5(payloadInput?.rawInput);
|
|
3534
|
+
const changes = firstFileChangeValue(
|
|
3535
|
+
payloadOutput?.changes,
|
|
3536
|
+
input.payload?.changes,
|
|
3537
|
+
payloadInput?.changes,
|
|
3538
|
+
rawInput?.changes
|
|
3539
|
+
);
|
|
3540
|
+
const patchChanges = patchChangesFromChangeMap(changes);
|
|
3541
|
+
if (patchChanges.length === 0) {
|
|
3542
|
+
return [];
|
|
3543
|
+
}
|
|
3544
|
+
return [
|
|
3545
|
+
{
|
|
3546
|
+
cwd: firstNonEmptyString(
|
|
3547
|
+
stringValue6(input.payload?.cwd),
|
|
3548
|
+
stringValue6(payloadInput?.cwd),
|
|
3549
|
+
stringValue6(rawInput?.cwd),
|
|
3550
|
+
stringValue6(payloadOutput?.cwd),
|
|
3551
|
+
stringValue6(metadata?.cwd),
|
|
3552
|
+
input.options.defaultCwd ?? null
|
|
3553
|
+
) ?? null,
|
|
3554
|
+
toolCallId: input.id,
|
|
3555
|
+
changes: patchChanges
|
|
3556
|
+
}
|
|
3557
|
+
];
|
|
3558
|
+
}
|
|
3559
|
+
function patchChangesFromChangeMap(changes) {
|
|
3560
|
+
return fileChangeEntriesFromChanges(changes).flatMap((entry) => {
|
|
3561
|
+
const change = entry.change;
|
|
3562
|
+
const normalizedPath = entry.path.trim();
|
|
3563
|
+
if (!normalizedPath) {
|
|
3564
|
+
return [];
|
|
3565
|
+
}
|
|
3566
|
+
const normalizedType = normalizeChangeType(fileChangeTypeValue(change));
|
|
3567
|
+
const unifiedDiff = firstNonEmptyString(
|
|
3568
|
+
stringValue6(change.unified_diff),
|
|
3569
|
+
stringValue6(change.unifiedDiff),
|
|
3570
|
+
stringValue6(change.diff),
|
|
3571
|
+
stringValue6(change.patch)
|
|
3572
|
+
) ?? null;
|
|
3573
|
+
let oldString = firstPresentString6(
|
|
3574
|
+
literalStringValue(change.old_string),
|
|
3575
|
+
literalStringValue(change.oldString)
|
|
3576
|
+
);
|
|
3577
|
+
const explicitContent = literalStringValue(change.content);
|
|
3578
|
+
let newString = firstPresentString6(
|
|
3579
|
+
literalStringValue(change.new_string),
|
|
3580
|
+
literalStringValue(change.newString),
|
|
3581
|
+
explicitContent
|
|
3582
|
+
);
|
|
3583
|
+
if (normalizedType === "created" && oldString === null && newString !== null) {
|
|
3584
|
+
oldString = "";
|
|
3585
|
+
}
|
|
3586
|
+
if (normalizedType === "deleted" && oldString === null && newString !== null) {
|
|
3587
|
+
oldString = newString;
|
|
3588
|
+
newString = "";
|
|
3589
|
+
}
|
|
3590
|
+
if (normalizedType === "deleted" && newString === null && oldString !== null) {
|
|
3591
|
+
newString = "";
|
|
3592
|
+
}
|
|
3593
|
+
const content = firstPresentString6(
|
|
3594
|
+
normalizedType === "deleted" ? null : explicitContent,
|
|
3595
|
+
normalizedType === "created" ? newString : null
|
|
3596
|
+
);
|
|
3597
|
+
if (!unifiedDiff && oldString === null && newString === null && content === null) {
|
|
3598
|
+
return [];
|
|
3599
|
+
}
|
|
3600
|
+
return [
|
|
3601
|
+
{
|
|
3602
|
+
path: normalizedPath,
|
|
3603
|
+
changeType: normalizedType ?? inferAgentPatchChangeType(unifiedDiff),
|
|
3604
|
+
unifiedDiff,
|
|
3605
|
+
oldString,
|
|
3606
|
+
newString,
|
|
3607
|
+
content
|
|
3608
|
+
}
|
|
3609
|
+
];
|
|
3610
|
+
});
|
|
3611
|
+
}
|
|
3495
3612
|
function summaryPathInput(summary, options) {
|
|
3496
3613
|
const path = normalizedFilePath(summary, options);
|
|
3497
3614
|
return path ? { path, summaryPathFallback: true } : null;
|
|
@@ -3532,21 +3649,21 @@ function extractFileChanges(input) {
|
|
|
3532
3649
|
stringValue6(payload?.patch),
|
|
3533
3650
|
stringValue6(metadata?.patch)
|
|
3534
3651
|
),
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3539
|
-
|
|
3652
|
+
firstPresentString6(
|
|
3653
|
+
literalStringValue(input.output?.oldString),
|
|
3654
|
+
literalStringValue(input.output?.old_string),
|
|
3655
|
+
literalStringValue(input.input?.oldString),
|
|
3656
|
+
literalStringValue(input.input?.old_string)
|
|
3540
3657
|
),
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3545
|
-
|
|
3658
|
+
firstPresentString6(
|
|
3659
|
+
literalStringValue(input.output?.newString),
|
|
3660
|
+
literalStringValue(input.output?.new_string),
|
|
3661
|
+
literalStringValue(input.input?.newString),
|
|
3662
|
+
literalStringValue(input.input?.new_string)
|
|
3546
3663
|
),
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3664
|
+
firstPresentString6(
|
|
3665
|
+
literalStringValue(input.output?.content),
|
|
3666
|
+
literalStringValue(input.input?.content)
|
|
3550
3667
|
),
|
|
3551
3668
|
input.options
|
|
3552
3669
|
);
|
|
@@ -3605,25 +3722,25 @@ function extractFileChanges(input) {
|
|
|
3605
3722
|
stringValue6(metadata?.patch),
|
|
3606
3723
|
stringValue6(input.output?.content)
|
|
3607
3724
|
) ?? null;
|
|
3608
|
-
const oldString =
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
|
|
3613
|
-
)
|
|
3614
|
-
const newString =
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
|
|
3619
|
-
)
|
|
3620
|
-
const content =
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
|
|
3626
|
-
)
|
|
3725
|
+
const oldString = firstPresentString6(
|
|
3726
|
+
literalStringValue(input.output?.oldString),
|
|
3727
|
+
literalStringValue(input.output?.old_string),
|
|
3728
|
+
literalStringValue(input.input?.oldString),
|
|
3729
|
+
literalStringValue(input.input?.old_string)
|
|
3730
|
+
);
|
|
3731
|
+
const newString = firstPresentString6(
|
|
3732
|
+
literalStringValue(input.output?.newString),
|
|
3733
|
+
literalStringValue(input.output?.new_string),
|
|
3734
|
+
literalStringValue(input.input?.newString),
|
|
3735
|
+
literalStringValue(input.input?.new_string)
|
|
3736
|
+
);
|
|
3737
|
+
const content = firstPresentString6(
|
|
3738
|
+
literalStringValue(input.input?.content),
|
|
3739
|
+
literalStringValue(rawInput?.content),
|
|
3740
|
+
literalStringValue(input.input?.new_source),
|
|
3741
|
+
literalStringValue(input.output?.content),
|
|
3742
|
+
literalStringValue(input.output?.new_source)
|
|
3743
|
+
);
|
|
3627
3744
|
const explicitChangeType = normalizeChangeType(
|
|
3628
3745
|
firstNonEmptyString(
|
|
3629
3746
|
stringValue6(payload?.fileChangeKind),
|
|
@@ -3722,16 +3839,16 @@ function collectChangeMapFiles(messageId, toolName, occurredAtUnixMs, changes, o
|
|
|
3722
3839
|
stringValue6(change.diff),
|
|
3723
3840
|
stringValue6(change.patch)
|
|
3724
3841
|
);
|
|
3725
|
-
let oldString =
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
)
|
|
3729
|
-
const explicitContent =
|
|
3730
|
-
let newString =
|
|
3731
|
-
|
|
3732
|
-
|
|
3842
|
+
let oldString = firstPresentString6(
|
|
3843
|
+
literalStringValue(change.old_string),
|
|
3844
|
+
literalStringValue(change.oldString)
|
|
3845
|
+
);
|
|
3846
|
+
const explicitContent = literalStringValue(change.content);
|
|
3847
|
+
let newString = firstPresentString6(
|
|
3848
|
+
literalStringValue(change.new_string),
|
|
3849
|
+
literalStringValue(change.newString),
|
|
3733
3850
|
explicitContent
|
|
3734
|
-
)
|
|
3851
|
+
);
|
|
3735
3852
|
if (normalizedType === "created" && oldString === null && newString !== null) {
|
|
3736
3853
|
oldString = "";
|
|
3737
3854
|
}
|
|
@@ -3742,10 +3859,10 @@ function collectChangeMapFiles(messageId, toolName, occurredAtUnixMs, changes, o
|
|
|
3742
3859
|
if (normalizedType === "deleted" && newString === null && oldString !== null) {
|
|
3743
3860
|
newString = "";
|
|
3744
3861
|
}
|
|
3745
|
-
const content =
|
|
3862
|
+
const content = firstPresentString6(
|
|
3746
3863
|
normalizedType === "deleted" ? null : explicitContent,
|
|
3747
3864
|
normalizedType === "created" ? newString : null
|
|
3748
|
-
)
|
|
3865
|
+
);
|
|
3749
3866
|
if (!unifiedDiff && oldString === null && newString === null && content === null) {
|
|
3750
3867
|
return [];
|
|
3751
3868
|
}
|
|
@@ -3797,20 +3914,20 @@ function collectContentDiffFiles(messageId, toolName, occurredAtUnixMs, contentI
|
|
|
3797
3914
|
stringValue6(relatedChange?.unified_diff),
|
|
3798
3915
|
stringValue6(relatedChange?.unifiedDiff)
|
|
3799
3916
|
);
|
|
3800
|
-
let oldString =
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
|
|
3805
|
-
)
|
|
3806
|
-
const relatedContent =
|
|
3807
|
-
let newString =
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3917
|
+
let oldString = firstPresentString6(
|
|
3918
|
+
literalStringValue(item.oldText),
|
|
3919
|
+
literalStringValue(item.oldString),
|
|
3920
|
+
literalStringValue(relatedChange?.old_string),
|
|
3921
|
+
literalStringValue(relatedChange?.oldString)
|
|
3922
|
+
);
|
|
3923
|
+
const relatedContent = literalStringValue(relatedChange?.content);
|
|
3924
|
+
let newString = firstPresentString6(
|
|
3925
|
+
literalStringValue(item.newText),
|
|
3926
|
+
literalStringValue(item.newString),
|
|
3927
|
+
literalStringValue(relatedChange?.new_string),
|
|
3928
|
+
literalStringValue(relatedChange?.newString),
|
|
3812
3929
|
relatedContent
|
|
3813
|
-
)
|
|
3930
|
+
);
|
|
3814
3931
|
if (normalizedType === "created" && oldString === null && newString !== null) {
|
|
3815
3932
|
oldString = "";
|
|
3816
3933
|
}
|
|
@@ -3821,7 +3938,10 @@ function collectContentDiffFiles(messageId, toolName, occurredAtUnixMs, contentI
|
|
|
3821
3938
|
if (normalizedType === "deleted" && newString === null && oldString !== null) {
|
|
3822
3939
|
newString = "";
|
|
3823
3940
|
}
|
|
3824
|
-
const explicitContent =
|
|
3941
|
+
const explicitContent = firstPresentString6(
|
|
3942
|
+
literalStringValue(item.content),
|
|
3943
|
+
relatedContent
|
|
3944
|
+
);
|
|
3825
3945
|
const inferredType = normalizedType ?? inferChangeTypeFromToolContent(
|
|
3826
3946
|
toolName,
|
|
3827
3947
|
normalizedType === "deleted" ? null : explicitContent,
|
|
@@ -3831,10 +3951,10 @@ function collectContentDiffFiles(messageId, toolName, occurredAtUnixMs, contentI
|
|
|
3831
3951
|
if (inferredType === "created" && oldString === null && newString !== null) {
|
|
3832
3952
|
oldString = "";
|
|
3833
3953
|
}
|
|
3834
|
-
const content =
|
|
3954
|
+
const content = firstPresentString6(
|
|
3835
3955
|
inferredType === "deleted" ? null : explicitContent,
|
|
3836
3956
|
inferredType === "created" ? newString : null
|
|
3837
|
-
)
|
|
3957
|
+
);
|
|
3838
3958
|
if (!unifiedDiff && oldString === null && newString === null && content === null) {
|
|
3839
3959
|
return [];
|
|
3840
3960
|
}
|
|
@@ -4037,7 +4157,7 @@ function normalizeChangeType(value) {
|
|
|
4037
4157
|
function inferChangeTypeFromToolContent(toolName, content, oldString, newString) {
|
|
4038
4158
|
const normalizedToolName = normalizeToolName4(toolName);
|
|
4039
4159
|
if (normalizedToolName === "write" || normalizedToolName === "writefile") {
|
|
4040
|
-
return content || newString ? "created" : null;
|
|
4160
|
+
return content !== null || newString !== null ? "created" : null;
|
|
4041
4161
|
}
|
|
4042
4162
|
if (oldString !== null || newString !== null) {
|
|
4043
4163
|
return "modified";
|
|
@@ -4072,6 +4192,17 @@ function firstFileChangeValue(...values) {
|
|
|
4072
4192
|
function arrayValue5(value) {
|
|
4073
4193
|
return Array.isArray(value) ? value : null;
|
|
4074
4194
|
}
|
|
4195
|
+
function nestedTaskStepsFromPayload(payload, output) {
|
|
4196
|
+
const metadata = objectValue5(payload?.metadata);
|
|
4197
|
+
return arrayValue5(metadata?.steps) ?? arrayValue5(output?.steps) ?? arrayValue5(payload?.steps) ?? [];
|
|
4198
|
+
}
|
|
4199
|
+
function nestedTaskStepStatusKind(step, fallback) {
|
|
4200
|
+
return firstNonEmptyString(
|
|
4201
|
+
stringValue6(step.statusKind),
|
|
4202
|
+
stringValue6(step.status),
|
|
4203
|
+
stringValue6(step.toolStatus)
|
|
4204
|
+
) ?? fallback ?? null;
|
|
4205
|
+
}
|
|
4075
4206
|
function firstLocationPath(value) {
|
|
4076
4207
|
if (!value) {
|
|
4077
4208
|
return null;
|
|
@@ -4100,6 +4231,9 @@ function firstPathValue(value) {
|
|
|
4100
4231
|
function stringValue6(value) {
|
|
4101
4232
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
4102
4233
|
}
|
|
4234
|
+
function literalStringValue(value) {
|
|
4235
|
+
return typeof value === "string" ? value : null;
|
|
4236
|
+
}
|
|
4103
4237
|
function numberValue2(value) {
|
|
4104
4238
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4105
4239
|
}
|
|
@@ -4111,6 +4245,14 @@ function firstNonEmptyString(...values) {
|
|
|
4111
4245
|
}
|
|
4112
4246
|
return null;
|
|
4113
4247
|
}
|
|
4248
|
+
function firstPresentString6(...values) {
|
|
4249
|
+
for (const value of values) {
|
|
4250
|
+
if (typeof value === "string") {
|
|
4251
|
+
return value;
|
|
4252
|
+
}
|
|
4253
|
+
}
|
|
4254
|
+
return null;
|
|
4255
|
+
}
|
|
4114
4256
|
|
|
4115
4257
|
// shared/agentConversation/projection/agentConversationProjection.ts
|
|
4116
4258
|
var RENDER_IRRELEVANT_TRANSCRIPT_ROW_FIELDS = /* @__PURE__ */ new Set(["occurredAtUnixMs"]);
|
|
@@ -4887,6 +5029,186 @@ var Button = React.forwardRef(
|
|
|
4887
5029
|
);
|
|
4888
5030
|
Button.displayName = "Button";
|
|
4889
5031
|
|
|
5032
|
+
// shared/errors/appError.ts
|
|
5033
|
+
function createMessageMap() {
|
|
5034
|
+
return {
|
|
5035
|
+
"common.invalid_input": "The request was invalid.",
|
|
5036
|
+
"common.approved_path_required": "The selected path is outside approved workspaces.",
|
|
5037
|
+
"common.unavailable": "This feature is unavailable.",
|
|
5038
|
+
"common.unexpected": "Something went wrong. Please try again.",
|
|
5039
|
+
"session.not_found": "Session not found.",
|
|
5040
|
+
"control_surface.unauthorized": "Unauthorized request.",
|
|
5041
|
+
"workspace.select_directory_failed": "Unable to open the directory picker.",
|
|
5042
|
+
"workspace.select_files_failed": "Unable to open the file picker.",
|
|
5043
|
+
"workspace.ensure_directory_failed": "Unable to create the directory.",
|
|
5044
|
+
"workspace.import_files_failed": "Unable to import the selected files.",
|
|
5045
|
+
"workspace.read_file_failed": "Unable to load the selected file.",
|
|
5046
|
+
"workspace.write_file_failed": "Unable to save the selected file.",
|
|
5047
|
+
"workspace.export_file_failed": "Unable to export the selected file.",
|
|
5048
|
+
"workspace.copy_path_failed": "Unable to copy the path.",
|
|
5049
|
+
"workspace.host_unsupported": "This Mac cannot run the workspace environment required by tsh. Please use macOS 13 or later on Apple Silicon (or an Intel Mac that supports Apple Virtualization), and ensure virtualization is not blocked by MDM.",
|
|
5050
|
+
"workspace.runtime_artifact_unavailable": "Unable to prepare the workspace environment required by tsh. Check your network connection and try again.",
|
|
5051
|
+
"runtime.guest_agent_lane_unavailable": "The workspace environment connection is unavailable. Refresh and try again.",
|
|
5052
|
+
"workspace.room_full": "Room is full.",
|
|
5053
|
+
"workspace.room_delete_forbidden": "Only the space owner can delete this space.",
|
|
5054
|
+
"workspace.room_delete_not_found": "This space no longer exists.",
|
|
5055
|
+
"filesystem.create_directory_failed": "Unable to create the directory.",
|
|
5056
|
+
"filesystem.read_file_bytes_failed": "Unable to read the file.",
|
|
5057
|
+
"filesystem.read_file_text_failed": "Unable to read the file.",
|
|
5058
|
+
"filesystem.write_file_text_failed": "Unable to save the file.",
|
|
5059
|
+
"filesystem.copy_entry_failed": "Unable to copy the file or folder.",
|
|
5060
|
+
"filesystem.move_entry_failed": "Unable to move the file or folder.",
|
|
5061
|
+
"filesystem.rename_entry_failed": "Unable to rename the file or folder.",
|
|
5062
|
+
"filesystem.delete_entry_failed": "Unable to delete the file or folder.",
|
|
5063
|
+
"filesystem.read_directory_failed": "Unable to load the directory.",
|
|
5064
|
+
"filesystem.stat_failed": "Unable to read file details.",
|
|
5065
|
+
"terminal.spawn_failed": "Unable to start the terminal.",
|
|
5066
|
+
"terminal.write_failed": "Unable to write to the terminal.",
|
|
5067
|
+
"terminal.resize_failed": "Unable to resize the terminal.",
|
|
5068
|
+
"terminal.close_failed": "Unable to close the terminal.",
|
|
5069
|
+
"terminal.attach_failed": "Unable to attach the terminal session.",
|
|
5070
|
+
"terminal.detach_failed": "Unable to detach the terminal session.",
|
|
5071
|
+
"terminal.snapshot_failed": "Unable to read terminal output.",
|
|
5072
|
+
"agent.list_models_failed": "Unable to load models for this provider.",
|
|
5073
|
+
"agent.launch_failed": "Unable to start the agent.",
|
|
5074
|
+
"agent.read_last_message_failed": "Unable to read the last agent message.",
|
|
5075
|
+
"agent.provider_session_not_found": "The previous agent session can no longer be restored.",
|
|
5076
|
+
"agent.resume_session_not_local": "The previous agent session is not available on this machine.",
|
|
5077
|
+
"agent.resume_session_resolve_failed": "Unable to resolve the previous agent session.",
|
|
5078
|
+
"agent.settings_require_new_session": "This model can only be used in a new session to preserve context.",
|
|
5079
|
+
"task.suggest_title_failed": "Unable to generate task details.",
|
|
5080
|
+
"persistence.unavailable": "Storage is unavailable; changes will not be saved.",
|
|
5081
|
+
"persistence.quota_exceeded": "Storage quota was exceeded.",
|
|
5082
|
+
"persistence.payload_too_large": "Workspace state is too large to save.",
|
|
5083
|
+
"persistence.io_failed": "Unable to save data to storage.",
|
|
5084
|
+
"persistence.invalid_state": "The workspace state could not be saved.",
|
|
5085
|
+
"persistence.invalid_node_id": "The terminal history could not be saved.",
|
|
5086
|
+
"update.get_state_failed": "Unable to read the update status.",
|
|
5087
|
+
"update.configure_failed": "Unable to apply update settings.",
|
|
5088
|
+
"update.check_failed": "Unable to check for updates.",
|
|
5089
|
+
"update.download_failed": "Unable to download the update.",
|
|
5090
|
+
"update.install_failed": "Unable to install the update.",
|
|
5091
|
+
PACKAGE_DOWNLOAD_INTERRUPTED: "The agent package download was interrupted. Check your network connection and retry.",
|
|
5092
|
+
PACKAGE_DOWNLOAD_HTTP_STATUS: "The agent package server rejected the download. Retry later or contact support.",
|
|
5093
|
+
PACKAGE_DOWNLOAD_INVALID: "The downloaded agent package failed integrity checks. Retry the download.",
|
|
5094
|
+
PACKAGE_DOWNLOAD_DISK_ERROR: "Unable to write the agent package cache. Check disk permissions and free space."
|
|
5095
|
+
};
|
|
5096
|
+
}
|
|
5097
|
+
var APP_ERROR_MESSAGES = createMessageMap();
|
|
5098
|
+
function createAppErrorDescriptor(code, options = {}) {
|
|
5099
|
+
return {
|
|
5100
|
+
code,
|
|
5101
|
+
...options.params ? { params: options.params } : {},
|
|
5102
|
+
...options.debugMessage ? { debugMessage: options.debugMessage } : {}
|
|
5103
|
+
};
|
|
5104
|
+
}
|
|
5105
|
+
function isAppErrorDescriptor(value) {
|
|
5106
|
+
if (!value || typeof value !== "object") {
|
|
5107
|
+
return false;
|
|
5108
|
+
}
|
|
5109
|
+
const record = value;
|
|
5110
|
+
return typeof record.code === "string" && record.code in APP_ERROR_MESSAGES;
|
|
5111
|
+
}
|
|
5112
|
+
function getAppErrorCode(error) {
|
|
5113
|
+
if (error instanceof TshAppError) {
|
|
5114
|
+
return error.code;
|
|
5115
|
+
}
|
|
5116
|
+
if (isAppErrorDescriptor(error)) {
|
|
5117
|
+
return error.code;
|
|
5118
|
+
}
|
|
5119
|
+
if (error && typeof error === "object") {
|
|
5120
|
+
const code = error.code;
|
|
5121
|
+
if (typeof code === "string" && code in APP_ERROR_MESSAGES) {
|
|
5122
|
+
return code;
|
|
5123
|
+
}
|
|
5124
|
+
}
|
|
5125
|
+
return null;
|
|
5126
|
+
}
|
|
5127
|
+
var TshAppError = class extends Error {
|
|
5128
|
+
code;
|
|
5129
|
+
params;
|
|
5130
|
+
debugMessage;
|
|
5131
|
+
constructor(descriptor) {
|
|
5132
|
+
super(formatAppErrorMessage(descriptor));
|
|
5133
|
+
this.name = "TshAppError";
|
|
5134
|
+
this.code = descriptor.code;
|
|
5135
|
+
this.params = descriptor.params;
|
|
5136
|
+
this.debugMessage = descriptor.debugMessage;
|
|
5137
|
+
}
|
|
5138
|
+
toDescriptor() {
|
|
5139
|
+
return createAppErrorDescriptor(this.code, {
|
|
5140
|
+
params: this.params,
|
|
5141
|
+
debugMessage: this.debugMessage
|
|
5142
|
+
});
|
|
5143
|
+
}
|
|
5144
|
+
};
|
|
5145
|
+
function formatAppErrorMessage(error) {
|
|
5146
|
+
const descriptor = error instanceof TshAppError ? error.toDescriptor() : error;
|
|
5147
|
+
return APP_ERROR_MESSAGES[descriptor.code] ?? APP_ERROR_MESSAGES["common.unexpected"];
|
|
5148
|
+
}
|
|
5149
|
+
|
|
5150
|
+
// app/renderer/shell/utils/format.ts
|
|
5151
|
+
var shortDateTimeFormatterByLanguage = /* @__PURE__ */ new Map();
|
|
5152
|
+
var weekdayTimeFormatterByLanguage = /* @__PURE__ */ new Map();
|
|
5153
|
+
function getShortDateTimeFormatter(language) {
|
|
5154
|
+
const cached = shortDateTimeFormatterByLanguage.get(language);
|
|
5155
|
+
if (cached) {
|
|
5156
|
+
return cached;
|
|
5157
|
+
}
|
|
5158
|
+
const formatter = new Intl.DateTimeFormat(language, {
|
|
5159
|
+
month: language === "en" ? "short" : "numeric",
|
|
5160
|
+
day: "numeric",
|
|
5161
|
+
hour: "2-digit",
|
|
5162
|
+
minute: "2-digit",
|
|
5163
|
+
hourCycle: "h23"
|
|
5164
|
+
});
|
|
5165
|
+
shortDateTimeFormatterByLanguage.set(language, formatter);
|
|
5166
|
+
return formatter;
|
|
5167
|
+
}
|
|
5168
|
+
function getWeekdayTimeFormatter(language) {
|
|
5169
|
+
const cached = weekdayTimeFormatterByLanguage.get(language);
|
|
5170
|
+
if (cached) {
|
|
5171
|
+
return cached;
|
|
5172
|
+
}
|
|
5173
|
+
const formatter = new Intl.DateTimeFormat(language, {
|
|
5174
|
+
weekday: "long",
|
|
5175
|
+
hour: "2-digit",
|
|
5176
|
+
minute: "2-digit",
|
|
5177
|
+
hourCycle: "h23"
|
|
5178
|
+
});
|
|
5179
|
+
weekdayTimeFormatterByLanguage.set(language, formatter);
|
|
5180
|
+
return formatter;
|
|
5181
|
+
}
|
|
5182
|
+
function toLocalWeekdayTime(value, language = getActiveUiLanguage()) {
|
|
5183
|
+
const formatter = getWeekdayTimeFormatter(language);
|
|
5184
|
+
const parts = formatter.formatToParts(value);
|
|
5185
|
+
const weekday = parts.find((part) => part.type === "weekday")?.value;
|
|
5186
|
+
const hour = parts.find((part) => part.type === "hour")?.value;
|
|
5187
|
+
const minute = parts.find((part) => part.type === "minute")?.value;
|
|
5188
|
+
if (weekday && hour && minute) {
|
|
5189
|
+
return `${weekday} ${hour}:${minute}`;
|
|
5190
|
+
}
|
|
5191
|
+
return formatter.format(value);
|
|
5192
|
+
}
|
|
5193
|
+
function toLocalShortDateTime(value, language = getActiveUiLanguage()) {
|
|
5194
|
+
return getShortDateTimeFormatter(language).format(value);
|
|
5195
|
+
}
|
|
5196
|
+
function formatAgentMessageTimestamp(unix, language = getActiveUiLanguage(), now = /* @__PURE__ */ new Date()) {
|
|
5197
|
+
if (unix == null || !Number.isFinite(unix)) {
|
|
5198
|
+
return null;
|
|
5199
|
+
}
|
|
5200
|
+
const value = unix > 1e12 ? unix : unix * 1e3;
|
|
5201
|
+
const messageDate = new Date(value);
|
|
5202
|
+
const startOfWeek = new Date(now);
|
|
5203
|
+
const daysSinceMonday = (startOfWeek.getDay() + 6) % 7;
|
|
5204
|
+
startOfWeek.setHours(0, 0, 0, 0);
|
|
5205
|
+
startOfWeek.setDate(startOfWeek.getDate() - daysSinceMonday);
|
|
5206
|
+
if (messageDate.getTime() >= startOfWeek.getTime()) {
|
|
5207
|
+
return toLocalWeekdayTime(value, language);
|
|
5208
|
+
}
|
|
5209
|
+
return toLocalShortDateTime(value, language);
|
|
5210
|
+
}
|
|
5211
|
+
|
|
4890
5212
|
// shared/agentConversation/components/AgentPlanCard.tsx
|
|
4891
5213
|
import { useCallback, useRef, useState } from "react";
|
|
4892
5214
|
import { Check, ChevronDown, ChevronUp, Copy, ListChecks } from "lucide-react";
|
|
@@ -6808,6 +7130,7 @@ function AgentMessageBlock({
|
|
|
6808
7130
|
AgentCopyableMessageGroup,
|
|
6809
7131
|
{
|
|
6810
7132
|
copyText: message.copyText ?? null,
|
|
7133
|
+
occurredAtUnixMs: message.occurredAtUnixMs,
|
|
6811
7134
|
speaker: row.speaker,
|
|
6812
7135
|
onCopyMessageText: handleCopyMessageText,
|
|
6813
7136
|
children: [
|
|
@@ -6824,6 +7147,7 @@ function AgentMessageBlock({
|
|
|
6824
7147
|
AgentCopyableMessageGroup,
|
|
6825
7148
|
{
|
|
6826
7149
|
copyText,
|
|
7150
|
+
occurredAtUnixMs: message.occurredAtUnixMs,
|
|
6827
7151
|
speaker: row.speaker,
|
|
6828
7152
|
onCopyMessageText: handleCopyMessageText,
|
|
6829
7153
|
children: content
|
|
@@ -6840,19 +7164,24 @@ function AgentMessageBlock({
|
|
|
6840
7164
|
function AgentCopyableMessageGroup({
|
|
6841
7165
|
children,
|
|
6842
7166
|
copyText,
|
|
7167
|
+
occurredAtUnixMs,
|
|
6843
7168
|
onCopyMessageText,
|
|
6844
7169
|
speaker
|
|
6845
7170
|
}) {
|
|
6846
7171
|
"use memo";
|
|
7172
|
+
const timestamp = formatAgentMessageTimestamp(occurredAtUnixMs);
|
|
6847
7173
|
return /* @__PURE__ */ jsxs7("div", { className: AgentGUIConversation_styles_default.messageGroup, "data-agent-message-speaker": speaker, children: [
|
|
6848
7174
|
children,
|
|
6849
|
-
copyText ? /* @__PURE__ */
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
|
|
7175
|
+
timestamp || copyText ? /* @__PURE__ */ jsxs7("div", { className: AgentGUIConversation_styles_default.messageFooter, children: [
|
|
7176
|
+
timestamp ? /* @__PURE__ */ jsx12("span", { className: AgentGUIConversation_styles_default.messageTimestamp, children: timestamp }) : null,
|
|
7177
|
+
copyText ? /* @__PURE__ */ jsx12(
|
|
7178
|
+
AgentMessageCopyButton,
|
|
7179
|
+
{
|
|
7180
|
+
copyText,
|
|
7181
|
+
onCopyMessageText
|
|
7182
|
+
}
|
|
7183
|
+
) : null
|
|
7184
|
+
] }) : null
|
|
6856
7185
|
] });
|
|
6857
7186
|
}
|
|
6858
7187
|
function AgentMessageCopyButton({
|
|
@@ -11922,8 +12251,21 @@ function renderToolCard(call, onLinkClick, previewMode = false, showRawTimelineJ
|
|
|
11922
12251
|
}
|
|
11923
12252
|
|
|
11924
12253
|
// shared/agentConversation/components/AgentTurnSummaryRow.tsx
|
|
11925
|
-
import { useMemo as useMemo5, useState as useState16 } from "react";
|
|
11926
|
-
import {
|
|
12254
|
+
import { useEffect as useEffect10, useMemo as useMemo5, useState as useState16 } from "react";
|
|
12255
|
+
import {
|
|
12256
|
+
ChevronDown as ChevronDown7,
|
|
12257
|
+
ChevronRight as ChevronRight7,
|
|
12258
|
+
LoaderCircle as LoaderCircle2,
|
|
12259
|
+
Redo2,
|
|
12260
|
+
Undo2
|
|
12261
|
+
} from "lucide-react";
|
|
12262
|
+
import {
|
|
12263
|
+
Tooltip,
|
|
12264
|
+
TooltipContent,
|
|
12265
|
+
TooltipProvider,
|
|
12266
|
+
TooltipTrigger,
|
|
12267
|
+
toast
|
|
12268
|
+
} from "@tutti-os/ui-system";
|
|
11927
12269
|
|
|
11928
12270
|
// app/renderer/components/icons/DirectLinedIcon.tsx
|
|
11929
12271
|
import { jsx as jsx53 } from "react/jsx-runtime";
|
|
@@ -11950,6 +12292,195 @@ function DirectLinedIcon(props) {
|
|
|
11950
12292
|
);
|
|
11951
12293
|
}
|
|
11952
12294
|
|
|
12295
|
+
// shared/agentConversation/rules/agentTurnSummaryPatchDiff.ts
|
|
12296
|
+
function buildAgentTurnSummaryPatchDiff(batch) {
|
|
12297
|
+
return batch.changes.map((change) => patchChangeToUnifiedDiff(change, batch.cwd)).filter((diff) => diff.trim().length > 0).join("\n");
|
|
12298
|
+
}
|
|
12299
|
+
function patchChangeToUnifiedDiff(change, cwd) {
|
|
12300
|
+
const path = patchPathRelativeToCwd(change.path, cwd);
|
|
12301
|
+
const rawDiff = normalizeAgentPatchText(change.unifiedDiff ?? "").trim();
|
|
12302
|
+
if (rawDiff && looksLikeUnifiedDiff(rawDiff)) {
|
|
12303
|
+
return ensureTrailingNewline(
|
|
12304
|
+
wrapUnifiedDiff(path, change.changeType, rawDiff)
|
|
12305
|
+
);
|
|
12306
|
+
}
|
|
12307
|
+
if (change.changeType === "created") {
|
|
12308
|
+
return fileContentPatch(
|
|
12309
|
+
path,
|
|
12310
|
+
"created",
|
|
12311
|
+
change.content ?? change.newString ?? rawDiff
|
|
12312
|
+
);
|
|
12313
|
+
}
|
|
12314
|
+
if (change.changeType === "deleted") {
|
|
12315
|
+
return fileContentPatch(
|
|
12316
|
+
path,
|
|
12317
|
+
"deleted",
|
|
12318
|
+
change.oldString ?? change.content ?? rawDiff
|
|
12319
|
+
);
|
|
12320
|
+
}
|
|
12321
|
+
if (change.oldString != null || change.newString != null) {
|
|
12322
|
+
return modifiedFilePatch(
|
|
12323
|
+
path,
|
|
12324
|
+
change.oldString ?? "",
|
|
12325
|
+
change.newString ?? ""
|
|
12326
|
+
);
|
|
12327
|
+
}
|
|
12328
|
+
return "";
|
|
12329
|
+
}
|
|
12330
|
+
function wrapUnifiedDiff(path, changeType, diff) {
|
|
12331
|
+
if (diff.startsWith("diff --git ")) {
|
|
12332
|
+
return diff;
|
|
12333
|
+
}
|
|
12334
|
+
const headers = [`diff --git a/${path} b/${path}`];
|
|
12335
|
+
if (changeType === "created") {
|
|
12336
|
+
headers.push("new file mode 100644", "--- /dev/null", `+++ b/${path}`);
|
|
12337
|
+
} else if (changeType === "deleted") {
|
|
12338
|
+
headers.push("deleted file mode 100644", `--- a/${path}`, "+++ /dev/null");
|
|
12339
|
+
} else if (!diff.startsWith("--- ") && !diff.includes("\n--- ")) {
|
|
12340
|
+
headers.push(`--- a/${path}`, `+++ b/${path}`);
|
|
12341
|
+
}
|
|
12342
|
+
return [...headers, diff].join("\n");
|
|
12343
|
+
}
|
|
12344
|
+
function fileContentPatch(path, changeType, content) {
|
|
12345
|
+
const lines = splitPatchContentLines(content);
|
|
12346
|
+
const count = Math.max(lines.length, 1);
|
|
12347
|
+
const prefix = changeType === "created" ? "+" : "-";
|
|
12348
|
+
const body = lines.length > 0 ? lines.map((line) => `${prefix}${line}`) : [`${prefix}`];
|
|
12349
|
+
const header = changeType === "created" ? [
|
|
12350
|
+
`diff --git a/${path} b/${path}`,
|
|
12351
|
+
"new file mode 100644",
|
|
12352
|
+
"--- /dev/null",
|
|
12353
|
+
`+++ b/${path}`,
|
|
12354
|
+
`@@ -0,0 +1,${count} @@`
|
|
12355
|
+
] : [
|
|
12356
|
+
`diff --git a/${path} b/${path}`,
|
|
12357
|
+
"deleted file mode 100644",
|
|
12358
|
+
`--- a/${path}`,
|
|
12359
|
+
"+++ /dev/null",
|
|
12360
|
+
`@@ -1,${count} +0,0 @@`
|
|
12361
|
+
];
|
|
12362
|
+
return ensureTrailingNewline([...header, ...body].join("\n"));
|
|
12363
|
+
}
|
|
12364
|
+
function modifiedFilePatch(path, oldContent, newContent) {
|
|
12365
|
+
const oldLines = splitPatchContentLines(oldContent);
|
|
12366
|
+
const newLines = splitPatchContentLines(newContent);
|
|
12367
|
+
const oldCount = Math.max(oldLines.length, 1);
|
|
12368
|
+
const newCount = Math.max(newLines.length, 1);
|
|
12369
|
+
return ensureTrailingNewline(
|
|
12370
|
+
[
|
|
12371
|
+
`diff --git a/${path} b/${path}`,
|
|
12372
|
+
`--- a/${path}`,
|
|
12373
|
+
`+++ b/${path}`,
|
|
12374
|
+
`@@ -1,${oldCount} +1,${newCount} @@`,
|
|
12375
|
+
...oldLines.map((line) => `-${line}`),
|
|
12376
|
+
...newLines.map((line) => `+${line}`)
|
|
12377
|
+
].join("\n")
|
|
12378
|
+
);
|
|
12379
|
+
}
|
|
12380
|
+
function patchPathRelativeToCwd(path, cwd) {
|
|
12381
|
+
const normalizedPath = normalizePathForPatch(path);
|
|
12382
|
+
const normalizedCwd = normalizePathForPatch(cwd ?? "");
|
|
12383
|
+
if (normalizedPath.startsWith("/") && normalizedCwd && normalizedPath.startsWith(`${normalizedCwd}/`)) {
|
|
12384
|
+
return normalizedPath.slice(normalizedCwd.length + 1);
|
|
12385
|
+
}
|
|
12386
|
+
return normalizedPath.replace(/^\/+/, "");
|
|
12387
|
+
}
|
|
12388
|
+
function normalizePathForPatch(path) {
|
|
12389
|
+
return path.trim().replaceAll("\\", "/").replace(/\/+$/, "");
|
|
12390
|
+
}
|
|
12391
|
+
function looksLikeUnifiedDiff(value) {
|
|
12392
|
+
return value.startsWith("diff --git ") || value.startsWith("@@ ") || value.startsWith("--- ") || value.includes("\n@@ ");
|
|
12393
|
+
}
|
|
12394
|
+
function splitPatchContentLines(content) {
|
|
12395
|
+
if (!content) {
|
|
12396
|
+
return [];
|
|
12397
|
+
}
|
|
12398
|
+
return content.replace(/\r\n/g, "\n").replace(/\n$/, "").split("\n");
|
|
12399
|
+
}
|
|
12400
|
+
function ensureTrailingNewline(value) {
|
|
12401
|
+
return value.endsWith("\n") ? value : `${value}
|
|
12402
|
+
`;
|
|
12403
|
+
}
|
|
12404
|
+
|
|
12405
|
+
// shared/agentConversation/rules/agentTurnSummaryPatchRuntime.ts
|
|
12406
|
+
function fileCanBuildPatch(file) {
|
|
12407
|
+
return file.unifiedDiff != null || file.content != null || file.oldString != null || file.newString != null;
|
|
12408
|
+
}
|
|
12409
|
+
function patchBatchDirectoryCwd(cwd, changes) {
|
|
12410
|
+
const normalizedCwd = normalizePatchHostPath(cwd ?? "");
|
|
12411
|
+
if (!normalizedCwd) {
|
|
12412
|
+
return null;
|
|
12413
|
+
}
|
|
12414
|
+
const cwdIsChangedFilePath = changes.some(
|
|
12415
|
+
(change) => normalizePatchHostPath(change.path) === normalizedCwd
|
|
12416
|
+
);
|
|
12417
|
+
return cwdIsChangedFilePath ? dirnameForPatchHostPath(normalizedCwd) : cwd;
|
|
12418
|
+
}
|
|
12419
|
+
function resolvePatchExecutionCwd(cwd, workspaceRoot) {
|
|
12420
|
+
const normalizedCwd = normalizePatchHostPath(cwd ?? "");
|
|
12421
|
+
const normalizedRoot = normalizePatchHostPath(workspaceRoot ?? "");
|
|
12422
|
+
if (!normalizedCwd) {
|
|
12423
|
+
return normalizedRoot || null;
|
|
12424
|
+
}
|
|
12425
|
+
if (!normalizedRoot) {
|
|
12426
|
+
return normalizedCwd;
|
|
12427
|
+
}
|
|
12428
|
+
if (isSyntheticWorkspacePath(normalizedRoot)) {
|
|
12429
|
+
return normalizedCwd;
|
|
12430
|
+
}
|
|
12431
|
+
if (normalizedCwd === "/workspace") {
|
|
12432
|
+
return normalizedRoot;
|
|
12433
|
+
}
|
|
12434
|
+
if (normalizedCwd.startsWith("/workspace/")) {
|
|
12435
|
+
return `${normalizedRoot}/${normalizedCwd.slice("/workspace/".length)}`;
|
|
12436
|
+
}
|
|
12437
|
+
return normalizedCwd;
|
|
12438
|
+
}
|
|
12439
|
+
function resolvePatchDiffCwd({
|
|
12440
|
+
sourceCwd,
|
|
12441
|
+
executionCwd,
|
|
12442
|
+
changes
|
|
12443
|
+
}) {
|
|
12444
|
+
const normalizedSourceCwd = normalizePatchHostPath(sourceCwd ?? "");
|
|
12445
|
+
const normalizedExecutionCwd = normalizePatchHostPath(executionCwd ?? "");
|
|
12446
|
+
if (!isSyntheticWorkspacePath(normalizedSourceCwd) || !normalizedExecutionCwd) {
|
|
12447
|
+
return sourceCwd;
|
|
12448
|
+
}
|
|
12449
|
+
const hasSyntheticChangePath = changes.some(
|
|
12450
|
+
(change) => isInsideOrEqualPatchPath(
|
|
12451
|
+
normalizePatchHostPath(change.path),
|
|
12452
|
+
normalizedSourceCwd
|
|
12453
|
+
)
|
|
12454
|
+
);
|
|
12455
|
+
const hasHostChangePath = changes.some(
|
|
12456
|
+
(change) => isInsideOrEqualPatchPath(
|
|
12457
|
+
normalizePatchHostPath(change.path),
|
|
12458
|
+
normalizedExecutionCwd
|
|
12459
|
+
)
|
|
12460
|
+
);
|
|
12461
|
+
return hasHostChangePath && !hasSyntheticChangePath ? normalizedExecutionCwd : sourceCwd;
|
|
12462
|
+
}
|
|
12463
|
+
function normalizePatchHostPath(path) {
|
|
12464
|
+
return path.trim().replaceAll("\\", "/").replace(/\/+$/, "");
|
|
12465
|
+
}
|
|
12466
|
+
function dirnameForPatchHostPath(path) {
|
|
12467
|
+
const normalized = normalizePatchHostPath(path);
|
|
12468
|
+
const index = normalized.lastIndexOf("/");
|
|
12469
|
+
if (index < 0) {
|
|
12470
|
+
return "";
|
|
12471
|
+
}
|
|
12472
|
+
if (index === 0) {
|
|
12473
|
+
return "/";
|
|
12474
|
+
}
|
|
12475
|
+
return normalized.slice(0, index);
|
|
12476
|
+
}
|
|
12477
|
+
function isSyntheticWorkspacePath(path) {
|
|
12478
|
+
return path === "/workspace" || path.startsWith("/workspace/");
|
|
12479
|
+
}
|
|
12480
|
+
function isInsideOrEqualPatchPath(path, root) {
|
|
12481
|
+
return path === root || path.startsWith(`${root}/`);
|
|
12482
|
+
}
|
|
12483
|
+
|
|
11953
12484
|
// shared/agentConversation/components/AgentTurnSummaryRow.tsx
|
|
11954
12485
|
import { jsx as jsx54, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
11955
12486
|
function AgentTurnSummaryRow({
|
|
@@ -11962,29 +12493,201 @@ function AgentTurnSummaryRow({
|
|
|
11962
12493
|
{}
|
|
11963
12494
|
);
|
|
11964
12495
|
const [showAllFiles, setShowAllFiles] = useState16(false);
|
|
12496
|
+
const [patchAction, setPatchAction] = useState16("undo");
|
|
12497
|
+
const [patchPending, setPatchPending] = useState16(false);
|
|
12498
|
+
const [patchSupportState, setPatchSupportState] = useState16(null);
|
|
12499
|
+
const agentHostApi = useOptionalAgentHostApi();
|
|
11965
12500
|
const aggregateStats = useMemo5(
|
|
11966
12501
|
() => summarizeRowDiff(row.files),
|
|
11967
12502
|
[row.files]
|
|
11968
12503
|
);
|
|
12504
|
+
const patchBatches = useMemo5(() => {
|
|
12505
|
+
const fileFallbackBatches = row.files.flatMap(
|
|
12506
|
+
(file) => fileCanBuildPatch(file) ? [
|
|
12507
|
+
{
|
|
12508
|
+
changes: [
|
|
12509
|
+
{
|
|
12510
|
+
path: file.path,
|
|
12511
|
+
changeType: file.changeType,
|
|
12512
|
+
unifiedDiff: file.unifiedDiff,
|
|
12513
|
+
oldString: file.oldString ?? null,
|
|
12514
|
+
newString: file.newString ?? null,
|
|
12515
|
+
content: file.content ?? null
|
|
12516
|
+
}
|
|
12517
|
+
],
|
|
12518
|
+
cwd: fallbackPatchFileCwd(file.path, workspaceRoot),
|
|
12519
|
+
toolCallId: `${row.id}:${file.messageId}:unified-diff`
|
|
12520
|
+
}
|
|
12521
|
+
] : []
|
|
12522
|
+
);
|
|
12523
|
+
const sourceBatches = row.patchBatches && row.patchBatches.length > 0 ? row.patchBatches : fileFallbackBatches;
|
|
12524
|
+
const batches = buildExecutablePatchBatches(sourceBatches, workspaceRoot);
|
|
12525
|
+
if (batches.length > 0 || sourceBatches === fileFallbackBatches) {
|
|
12526
|
+
return batches;
|
|
12527
|
+
}
|
|
12528
|
+
return buildExecutablePatchBatches(fileFallbackBatches, workspaceRoot);
|
|
12529
|
+
}, [row.files, row.id, row.patchBatches, workspaceRoot]);
|
|
12530
|
+
const canRenderPatchButton = Boolean(
|
|
12531
|
+
agentHostApi?.workspace.applyGitPatch && row.files.length > 0
|
|
12532
|
+
);
|
|
12533
|
+
const canApplyPatch = Boolean(
|
|
12534
|
+
agentHostApi?.workspace.applyGitPatch && patchBatches.length > 0
|
|
12535
|
+
);
|
|
12536
|
+
const patchSupportCwds = useMemo5(
|
|
12537
|
+
() => Array.from(new Set(patchBatches.map((batch) => batch.cwd))).sort(),
|
|
12538
|
+
[patchBatches]
|
|
12539
|
+
);
|
|
12540
|
+
const patchSupportKey = patchSupportCwds.join("\n");
|
|
12541
|
+
const resolveGitPatchSupport = agentHostApi?.workspace.resolveGitPatchSupport;
|
|
12542
|
+
useEffect10(() => {
|
|
12543
|
+
if (!resolveGitPatchSupport || patchSupportCwds.length === 0) {
|
|
12544
|
+
setPatchSupportState(null);
|
|
12545
|
+
return;
|
|
12546
|
+
}
|
|
12547
|
+
let disposed = false;
|
|
12548
|
+
setPatchSupportState({ key: patchSupportKey, status: "checking" });
|
|
12549
|
+
void (async () => {
|
|
12550
|
+
try {
|
|
12551
|
+
for (const cwd of patchSupportCwds) {
|
|
12552
|
+
const result = await resolveGitPatchSupport({ cwd });
|
|
12553
|
+
if (!result.supported) {
|
|
12554
|
+
if (!disposed) {
|
|
12555
|
+
setPatchSupportState({
|
|
12556
|
+
key: patchSupportKey,
|
|
12557
|
+
status: "unsupported"
|
|
12558
|
+
});
|
|
12559
|
+
}
|
|
12560
|
+
return;
|
|
12561
|
+
}
|
|
12562
|
+
}
|
|
12563
|
+
if (!disposed) {
|
|
12564
|
+
setPatchSupportState({ key: patchSupportKey, status: "supported" });
|
|
12565
|
+
}
|
|
12566
|
+
} catch {
|
|
12567
|
+
if (!disposed) {
|
|
12568
|
+
setPatchSupportState({ key: patchSupportKey, status: "supported" });
|
|
12569
|
+
}
|
|
12570
|
+
}
|
|
12571
|
+
})();
|
|
12572
|
+
return () => {
|
|
12573
|
+
disposed = true;
|
|
12574
|
+
};
|
|
12575
|
+
}, [patchSupportCwds, patchSupportKey, resolveGitPatchSupport]);
|
|
11969
12576
|
const visibleFiles = row.files.slice(0, 3);
|
|
11970
12577
|
const hiddenFiles = row.files.slice(3);
|
|
11971
12578
|
const hiddenFileCount = hiddenFiles.length;
|
|
12579
|
+
const patchActionLabel = patchAction === "undo" ? translate("agentHost.agentGui.turnSummaryUndo") : translate("agentHost.agentGui.turnSummaryReapply");
|
|
12580
|
+
const isPatchSupportChecking = Boolean(
|
|
12581
|
+
resolveGitPatchSupport && patchSupportCwds.length > 0 && (patchSupportState?.key !== patchSupportKey || patchSupportState.status === "checking")
|
|
12582
|
+
);
|
|
12583
|
+
const isPatchUnsupported = Boolean(
|
|
12584
|
+
patchSupportState?.key === patchSupportKey && patchSupportState.status === "unsupported"
|
|
12585
|
+
);
|
|
12586
|
+
const patchDisabledReason = isPatchUnsupported ? translate("agentHost.agentGui.turnSummaryGitRequired") : isPatchSupportChecking ? translate("agentHost.agentGui.turnSummaryCheckingGit") : !canApplyPatch ? translate("agentHost.agentGui.turnSummaryPatchUnavailable") : null;
|
|
12587
|
+
const isPatchActionDisabled = Boolean(
|
|
12588
|
+
patchPending || isPatchSupportChecking || isPatchUnsupported || !canApplyPatch
|
|
12589
|
+
);
|
|
12590
|
+
const handlePatchAction = async (event) => {
|
|
12591
|
+
event.stopPropagation();
|
|
12592
|
+
if (!agentHostApi?.workspace.applyGitPatch || isPatchActionDisabled) {
|
|
12593
|
+
return;
|
|
12594
|
+
}
|
|
12595
|
+
const orderedBatches = patchAction === "undo" ? [...patchBatches].reverse() : patchBatches;
|
|
12596
|
+
if (orderedBatches.length === 0) {
|
|
12597
|
+
return;
|
|
12598
|
+
}
|
|
12599
|
+
setPatchPending(true);
|
|
12600
|
+
let changed = false;
|
|
12601
|
+
const failureMessage = patchAction === "undo" ? translate("agentHost.agentGui.turnSummaryUndoFailed") : translate("agentHost.agentGui.turnSummaryReapplyFailed");
|
|
12602
|
+
try {
|
|
12603
|
+
for (const batch of orderedBatches) {
|
|
12604
|
+
const result = await agentHostApi.workspace.applyGitPatch({
|
|
12605
|
+
cwd: batch.cwd,
|
|
12606
|
+
diff: batch.diff,
|
|
12607
|
+
revert: patchAction === "undo"
|
|
12608
|
+
});
|
|
12609
|
+
if (result.status === "success" || result.appliedPaths.length > 0 || result.conflictedPaths.length > 0) {
|
|
12610
|
+
changed = true;
|
|
12611
|
+
}
|
|
12612
|
+
if (result.status !== "success") {
|
|
12613
|
+
showPatchFailureToast(agentHostApi, failureMessage);
|
|
12614
|
+
return;
|
|
12615
|
+
}
|
|
12616
|
+
}
|
|
12617
|
+
setPatchAction((current) => current === "undo" ? "reapply" : "undo");
|
|
12618
|
+
} catch {
|
|
12619
|
+
showPatchFailureToast(agentHostApi, failureMessage);
|
|
12620
|
+
} finally {
|
|
12621
|
+
setPatchPending(false);
|
|
12622
|
+
if (changed) {
|
|
12623
|
+
window.dispatchEvent(new CustomEvent("tutti-agent-git-patch-applied"));
|
|
12624
|
+
}
|
|
12625
|
+
}
|
|
12626
|
+
};
|
|
11972
12627
|
return /* @__PURE__ */ jsx54("section", { className: "workspace-agents-status-panel__detail-turn-summary", children: /* @__PURE__ */ jsxs41("div", { className: "agent-turn-summary-card w-full overflow-hidden rounded-[8px] text-[var(--text-primary)]", children: [
|
|
11973
|
-
/* @__PURE__ */
|
|
11974
|
-
/* @__PURE__ */ jsx54("div", { className: "min-w-0
|
|
11975
|
-
|
|
11976
|
-
|
|
11977
|
-
|
|
11978
|
-
|
|
11979
|
-
"
|
|
11980
|
-
|
|
11981
|
-
|
|
11982
|
-
|
|
11983
|
-
"-",
|
|
11984
|
-
|
|
11985
|
-
|
|
11986
|
-
|
|
11987
|
-
|
|
12628
|
+
/* @__PURE__ */ jsxs41("div", { className: "flex items-start gap-3 px-4 py-3", children: [
|
|
12629
|
+
/* @__PURE__ */ jsx54("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxs41("div", { className: "flex min-w-0 items-center gap-3", children: [
|
|
12630
|
+
/* @__PURE__ */ jsx54("div", { className: "min-w-0 text-[15px] font-semibold leading-5 tracking-[0] text-[var(--text-primary)]", children: translate("agentHost.agentGui.turnSummaryFilesChanged", {
|
|
12631
|
+
count: row.fileCount
|
|
12632
|
+
}) }),
|
|
12633
|
+
/* @__PURE__ */ jsxs41("div", { className: "inline-flex shrink-0 items-center gap-2.5 text-[11px] font-semibold", children: [
|
|
12634
|
+
aggregateStats.added > 0 ? /* @__PURE__ */ jsxs41("span", { className: "workspace-agents-status-panel__detail-tool-diff-added", children: [
|
|
12635
|
+
"+",
|
|
12636
|
+
aggregateStats.added
|
|
12637
|
+
] }) : null,
|
|
12638
|
+
aggregateStats.removed > 0 ? /* @__PURE__ */ jsxs41("span", { className: "workspace-agents-status-panel__detail-tool-diff-removed", children: [
|
|
12639
|
+
"-",
|
|
12640
|
+
aggregateStats.removed
|
|
12641
|
+
] }) : null
|
|
12642
|
+
] })
|
|
12643
|
+
] }) }),
|
|
12644
|
+
canRenderPatchButton ? /* @__PURE__ */ jsx54(TooltipProvider, { delayDuration: 200, children: /* @__PURE__ */ jsxs41(Tooltip, { children: [
|
|
12645
|
+
/* @__PURE__ */ jsx54(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsx54(
|
|
12646
|
+
"span",
|
|
12647
|
+
{
|
|
12648
|
+
className: `inline-flex shrink-0 ${isPatchActionDisabled ? "cursor-not-allowed" : ""}`,
|
|
12649
|
+
children: /* @__PURE__ */ jsxs41(
|
|
12650
|
+
CanvasNodeGhostIconButton,
|
|
12651
|
+
{
|
|
12652
|
+
"aria-label": patchActionLabel,
|
|
12653
|
+
className: "w-auto min-w-0 gap-1.5 px-2 text-[12px] font-medium leading-4 disabled:pointer-events-none",
|
|
12654
|
+
disabled: isPatchActionDisabled,
|
|
12655
|
+
onClick: handlePatchAction,
|
|
12656
|
+
children: [
|
|
12657
|
+
patchPending || isPatchSupportChecking ? /* @__PURE__ */ jsx54(
|
|
12658
|
+
LoaderCircle2,
|
|
12659
|
+
{
|
|
12660
|
+
width: 14,
|
|
12661
|
+
height: 14,
|
|
12662
|
+
"aria-hidden": "true",
|
|
12663
|
+
className: "animate-spin text-[var(--text-secondary)]"
|
|
12664
|
+
}
|
|
12665
|
+
) : patchAction === "undo" ? /* @__PURE__ */ jsx54(
|
|
12666
|
+
Undo2,
|
|
12667
|
+
{
|
|
12668
|
+
width: 14,
|
|
12669
|
+
height: 14,
|
|
12670
|
+
"aria-hidden": "true",
|
|
12671
|
+
className: "text-[var(--text-secondary)]"
|
|
12672
|
+
}
|
|
12673
|
+
) : /* @__PURE__ */ jsx54(
|
|
12674
|
+
Redo2,
|
|
12675
|
+
{
|
|
12676
|
+
width: 14,
|
|
12677
|
+
height: 14,
|
|
12678
|
+
"aria-hidden": "true",
|
|
12679
|
+
className: "text-[var(--text-secondary)]"
|
|
12680
|
+
}
|
|
12681
|
+
),
|
|
12682
|
+
/* @__PURE__ */ jsx54("span", { children: patchActionLabel })
|
|
12683
|
+
]
|
|
12684
|
+
}
|
|
12685
|
+
)
|
|
12686
|
+
}
|
|
12687
|
+
) }),
|
|
12688
|
+
patchDisabledReason ? /* @__PURE__ */ jsx54(TooltipContent, { className: "max-w-[260px] whitespace-normal text-left", children: patchDisabledReason }) : null
|
|
12689
|
+
] }) }) : null
|
|
12690
|
+
] }),
|
|
11988
12691
|
/* @__PURE__ */ jsxs41("div", { className: "agent-turn-summary-card__list", children: [
|
|
11989
12692
|
visibleFiles.map((file) => {
|
|
11990
12693
|
const key = `${file.path}:${file.messageId}`;
|
|
@@ -12215,6 +12918,47 @@ function summarizeRowDiff(files) {
|
|
|
12215
12918
|
{ added: 0, removed: 0 }
|
|
12216
12919
|
);
|
|
12217
12920
|
}
|
|
12921
|
+
function showPatchFailureToast(agentHostApi, message) {
|
|
12922
|
+
if (agentHostApi?.toast?.error) {
|
|
12923
|
+
agentHostApi.toast.error(message);
|
|
12924
|
+
return;
|
|
12925
|
+
}
|
|
12926
|
+
toast.error(message);
|
|
12927
|
+
}
|
|
12928
|
+
function buildExecutablePatchBatches(sourceBatches, workspaceRoot) {
|
|
12929
|
+
return sourceBatches.flatMap((batch) => {
|
|
12930
|
+
const sourceCwd = patchBatchDirectoryCwd(
|
|
12931
|
+
batch.cwd ?? workspaceRoot ?? null,
|
|
12932
|
+
batch.changes
|
|
12933
|
+
);
|
|
12934
|
+
const executionCwd = resolvePatchExecutionCwd(sourceCwd, workspaceRoot);
|
|
12935
|
+
const diffCwd = resolvePatchDiffCwd({
|
|
12936
|
+
executionCwd,
|
|
12937
|
+
sourceCwd,
|
|
12938
|
+
changes: batch.changes
|
|
12939
|
+
});
|
|
12940
|
+
const diff = buildAgentTurnSummaryPatchDiff({
|
|
12941
|
+
...batch,
|
|
12942
|
+
cwd: diffCwd
|
|
12943
|
+
});
|
|
12944
|
+
return executionCwd && diff.trim() ? [{ cwd: executionCwd, diff }] : [];
|
|
12945
|
+
});
|
|
12946
|
+
}
|
|
12947
|
+
function fallbackPatchFileCwd(path, workspaceRoot) {
|
|
12948
|
+
const root = workspaceRoot?.trim() ?? "";
|
|
12949
|
+
if (root && root !== "/") {
|
|
12950
|
+
return root;
|
|
12951
|
+
}
|
|
12952
|
+
const normalizedPath = path.trim().replaceAll("\\", "/").replace(/\/+$/, "");
|
|
12953
|
+
if (!normalizedPath.startsWith("/")) {
|
|
12954
|
+
return root || null;
|
|
12955
|
+
}
|
|
12956
|
+
const index = normalizedPath.lastIndexOf("/");
|
|
12957
|
+
if (index <= 0) {
|
|
12958
|
+
return "/";
|
|
12959
|
+
}
|
|
12960
|
+
return normalizedPath.slice(0, index);
|
|
12961
|
+
}
|
|
12218
12962
|
function summarizeFileDiff(file) {
|
|
12219
12963
|
if (file.unifiedDiff?.trim()) {
|
|
12220
12964
|
return parseAgentUnifiedDiffStats(file.unifiedDiff);
|
|
@@ -12745,6 +13489,8 @@ function useProjectedAgentConversation({
|
|
|
12745
13489
|
}
|
|
12746
13490
|
|
|
12747
13491
|
export {
|
|
13492
|
+
getAppErrorCode,
|
|
13493
|
+
toLocalShortDateTime,
|
|
12748
13494
|
Button,
|
|
12749
13495
|
buildWorkspaceAgentSessionDetailViewModel,
|
|
12750
13496
|
projectAgentConversationVM,
|
|
@@ -12764,4 +13510,4 @@ export {
|
|
|
12764
13510
|
AgentConversationFlow,
|
|
12765
13511
|
useProjectedAgentConversation
|
|
12766
13512
|
};
|
|
12767
|
-
//# sourceMappingURL=chunk-
|
|
13513
|
+
//# sourceMappingURL=chunk-ZAF4IVUT.js.map
|