@tutti-os/agent-gui 0.0.45 → 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 +148 -25
- package/dist/{chunk-ZG3WZSMV.js → chunk-2FOBSURO.js} +29 -10
- 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-UGV6JTWM.js → chunk-7NCWSH7U.js} +9 -9
- package/dist/{chunk-UGV6JTWM.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-CZ7PS3DU.js → chunk-ZAF4IVUT.js} +859 -104
- 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 +1011 -825
- 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 +19 -12
- package/dist/chunk-CZ7PS3DU.js.map +0 -1
- package/dist/chunk-QT45WUPQ.js.map +0 -1
- package/dist/chunk-VFQR7AZI.js.map +0 -1
- package/dist/chunk-ZG3WZSMV.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,14 +10,15 @@ import {
|
|
|
10
10
|
resolveWorkspaceFileLinkAction,
|
|
11
11
|
resolveWorkspaceFilePathCandidate,
|
|
12
12
|
resolveWorkspaceLinkAction
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-XJXSR5XI.js";
|
|
14
14
|
import {
|
|
15
|
+
AGENT_RICH_TEXT_CARET_ANCHOR,
|
|
15
16
|
attrsToMentionItem,
|
|
16
17
|
createAgentFileMentionExtension,
|
|
17
18
|
formatAgentMentionMarkdown,
|
|
18
19
|
mentionItemToAttrs,
|
|
19
20
|
parseAgentMentionMarkdown
|
|
20
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2FOBSURO.js";
|
|
21
22
|
import {
|
|
22
23
|
fileChangeCountFromChanges,
|
|
23
24
|
fileChangeEntriesFromChanges,
|
|
@@ -27,13 +28,14 @@ import {
|
|
|
27
28
|
import {
|
|
28
29
|
getOptionalAgentActivityRuntime,
|
|
29
30
|
useOptionalAgentHostApi
|
|
30
|
-
} from "./chunk-
|
|
31
|
+
} from "./chunk-VE6JY2TH.js";
|
|
31
32
|
import {
|
|
32
33
|
workspaceAgentProviderLabel
|
|
33
34
|
} from "./chunk-TYGL25EL.js";
|
|
34
35
|
import {
|
|
36
|
+
getActiveUiLanguage,
|
|
35
37
|
translate
|
|
36
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-5QTC2L52.js";
|
|
37
39
|
|
|
38
40
|
// shared/imageGenerationTool.ts
|
|
39
41
|
var KNOWN_IMAGE_GENERATION_TOOL_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -3349,7 +3351,10 @@ function tryExtractContentField(text) {
|
|
|
3349
3351
|
|
|
3350
3352
|
// shared/agentConversation/projection/agentTurnSummaryProjection.ts
|
|
3351
3353
|
function projectAgentTurnSummaryRows(detail) {
|
|
3352
|
-
const options = {
|
|
3354
|
+
const options = {
|
|
3355
|
+
defaultCwd: detail.cwd,
|
|
3356
|
+
workspaceRoot: detail.workspaceRoot
|
|
3357
|
+
};
|
|
3353
3358
|
const rows = detail.turns.flatMap(
|
|
3354
3359
|
(turn) => projectAgentTurnSummaryRowForTurn(turn, options)
|
|
3355
3360
|
);
|
|
@@ -3401,16 +3406,14 @@ function normalizedActivityFilePath(value, options) {
|
|
|
3401
3406
|
}) ? path : null;
|
|
3402
3407
|
}
|
|
3403
3408
|
function projectAgentTurnSummaryRowForTurn(turn, options = {}) {
|
|
3409
|
+
const summaryCalls = turnToolCallsForSummary(turn);
|
|
3404
3410
|
const files = applyShortestUniqueFileLabels(
|
|
3405
|
-
dedupeFiles(
|
|
3406
|
-
turnToolCallsForSummary(turn).flatMap(
|
|
3407
|
-
(call) => filesFromCall(call, options)
|
|
3408
|
-
)
|
|
3409
|
-
)
|
|
3411
|
+
dedupeFiles(summaryCalls.flatMap((call) => filesFromCall(call, options)))
|
|
3410
3412
|
);
|
|
3411
3413
|
if (files.length === 0) {
|
|
3412
3414
|
return [];
|
|
3413
3415
|
}
|
|
3416
|
+
const patchBatches = patchBatchesFromCalls(summaryCalls, options);
|
|
3414
3417
|
const fileCount = files.length;
|
|
3415
3418
|
const createdCount = files.filter(
|
|
3416
3419
|
(file) => file.changeType === "created"
|
|
@@ -3423,6 +3426,7 @@ function projectAgentTurnSummaryRowForTurn(turn, options = {}) {
|
|
|
3423
3426
|
id: `turn-summary:${turn.id}`,
|
|
3424
3427
|
turnId: turn.id,
|
|
3425
3428
|
files,
|
|
3429
|
+
...patchBatches.length > 0 ? { patchBatches } : {},
|
|
3426
3430
|
fileCount,
|
|
3427
3431
|
modifiedCount,
|
|
3428
3432
|
createdCount,
|
|
@@ -3452,11 +3456,10 @@ function turnToolCallsForSummary(turn) {
|
|
|
3452
3456
|
}
|
|
3453
3457
|
function filesFromCall(call, options) {
|
|
3454
3458
|
const toolState = objectValue5(call.payload?.tool_state);
|
|
3455
|
-
const metadata = objectValue5(call.payload?.metadata);
|
|
3456
3459
|
const input = objectValue5(call.payload?.input) ?? objectValue5(toolState?.input) ?? summaryPathInput(call.summary, options);
|
|
3457
3460
|
const output = objectValue5(call.payload?.output) ?? objectValue5(toolState?.output);
|
|
3458
3461
|
const error = objectValue5(call.payload?.error) ?? objectValue5(toolState?.error);
|
|
3459
|
-
const nestedTaskSteps =
|
|
3462
|
+
const nestedTaskSteps = nestedTaskStepsFromPayload(call.payload, output);
|
|
3460
3463
|
const directChanges = extractFileChanges({
|
|
3461
3464
|
id: call.id,
|
|
3462
3465
|
toolName: call.toolName,
|
|
@@ -3476,11 +3479,7 @@ function filesFromCall(call, options) {
|
|
|
3476
3479
|
return extractFileChanges({
|
|
3477
3480
|
id: stringValue6(step.toolUseId) ?? stringValue6(step.id) ?? `${call.id}:step:${index + 1}`,
|
|
3478
3481
|
toolName: stringValue6(step.toolName) ?? stringValue6(step.tool_name) ?? stringValue6(step.name) ?? null,
|
|
3479
|
-
statusKind:
|
|
3480
|
-
stringValue6(step.statusKind),
|
|
3481
|
-
stringValue6(step.status),
|
|
3482
|
-
stringValue6(step.toolStatus)
|
|
3483
|
-
) ?? call.statusKind ?? null,
|
|
3482
|
+
statusKind: nestedTaskStepStatusKind(step, call.statusKind ?? null),
|
|
3484
3483
|
occurredAtUnixMs: numberValue2(step.occurredAtUnixMs) ?? numberValue2(step.occurred_at_unix_ms) ?? call.occurredAtUnixMs ?? null,
|
|
3485
3484
|
payload: objectValue5(step.payload),
|
|
3486
3485
|
input: objectValue5(step.toolInput) ?? objectValue5(step.tool_input),
|
|
@@ -3491,6 +3490,125 @@ function filesFromCall(call, options) {
|
|
|
3491
3490
|
});
|
|
3492
3491
|
return [...directChanges, ...nestedChanges];
|
|
3493
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
|
+
}
|
|
3494
3612
|
function summaryPathInput(summary, options) {
|
|
3495
3613
|
const path = normalizedFilePath(summary, options);
|
|
3496
3614
|
return path ? { path, summaryPathFallback: true } : null;
|
|
@@ -3531,21 +3649,21 @@ function extractFileChanges(input) {
|
|
|
3531
3649
|
stringValue6(payload?.patch),
|
|
3532
3650
|
stringValue6(metadata?.patch)
|
|
3533
3651
|
),
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
|
|
3538
|
-
|
|
3652
|
+
firstPresentString6(
|
|
3653
|
+
literalStringValue(input.output?.oldString),
|
|
3654
|
+
literalStringValue(input.output?.old_string),
|
|
3655
|
+
literalStringValue(input.input?.oldString),
|
|
3656
|
+
literalStringValue(input.input?.old_string)
|
|
3539
3657
|
),
|
|
3540
|
-
|
|
3541
|
-
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
|
|
3658
|
+
firstPresentString6(
|
|
3659
|
+
literalStringValue(input.output?.newString),
|
|
3660
|
+
literalStringValue(input.output?.new_string),
|
|
3661
|
+
literalStringValue(input.input?.newString),
|
|
3662
|
+
literalStringValue(input.input?.new_string)
|
|
3545
3663
|
),
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3664
|
+
firstPresentString6(
|
|
3665
|
+
literalStringValue(input.output?.content),
|
|
3666
|
+
literalStringValue(input.input?.content)
|
|
3549
3667
|
),
|
|
3550
3668
|
input.options
|
|
3551
3669
|
);
|
|
@@ -3604,25 +3722,25 @@ function extractFileChanges(input) {
|
|
|
3604
3722
|
stringValue6(metadata?.patch),
|
|
3605
3723
|
stringValue6(input.output?.content)
|
|
3606
3724
|
) ?? null;
|
|
3607
|
-
const oldString =
|
|
3608
|
-
|
|
3609
|
-
|
|
3610
|
-
|
|
3611
|
-
|
|
3612
|
-
)
|
|
3613
|
-
const newString =
|
|
3614
|
-
|
|
3615
|
-
|
|
3616
|
-
|
|
3617
|
-
|
|
3618
|
-
)
|
|
3619
|
-
const content =
|
|
3620
|
-
|
|
3621
|
-
|
|
3622
|
-
|
|
3623
|
-
|
|
3624
|
-
|
|
3625
|
-
)
|
|
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
|
+
);
|
|
3626
3744
|
const explicitChangeType = normalizeChangeType(
|
|
3627
3745
|
firstNonEmptyString(
|
|
3628
3746
|
stringValue6(payload?.fileChangeKind),
|
|
@@ -3721,16 +3839,16 @@ function collectChangeMapFiles(messageId, toolName, occurredAtUnixMs, changes, o
|
|
|
3721
3839
|
stringValue6(change.diff),
|
|
3722
3840
|
stringValue6(change.patch)
|
|
3723
3841
|
);
|
|
3724
|
-
let oldString =
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
)
|
|
3728
|
-
const explicitContent =
|
|
3729
|
-
let newString =
|
|
3730
|
-
|
|
3731
|
-
|
|
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),
|
|
3732
3850
|
explicitContent
|
|
3733
|
-
)
|
|
3851
|
+
);
|
|
3734
3852
|
if (normalizedType === "created" && oldString === null && newString !== null) {
|
|
3735
3853
|
oldString = "";
|
|
3736
3854
|
}
|
|
@@ -3741,10 +3859,10 @@ function collectChangeMapFiles(messageId, toolName, occurredAtUnixMs, changes, o
|
|
|
3741
3859
|
if (normalizedType === "deleted" && newString === null && oldString !== null) {
|
|
3742
3860
|
newString = "";
|
|
3743
3861
|
}
|
|
3744
|
-
const content =
|
|
3862
|
+
const content = firstPresentString6(
|
|
3745
3863
|
normalizedType === "deleted" ? null : explicitContent,
|
|
3746
3864
|
normalizedType === "created" ? newString : null
|
|
3747
|
-
)
|
|
3865
|
+
);
|
|
3748
3866
|
if (!unifiedDiff && oldString === null && newString === null && content === null) {
|
|
3749
3867
|
return [];
|
|
3750
3868
|
}
|
|
@@ -3796,20 +3914,20 @@ function collectContentDiffFiles(messageId, toolName, occurredAtUnixMs, contentI
|
|
|
3796
3914
|
stringValue6(relatedChange?.unified_diff),
|
|
3797
3915
|
stringValue6(relatedChange?.unifiedDiff)
|
|
3798
3916
|
);
|
|
3799
|
-
let oldString =
|
|
3800
|
-
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
|
|
3804
|
-
)
|
|
3805
|
-
const relatedContent =
|
|
3806
|
-
let newString =
|
|
3807
|
-
|
|
3808
|
-
|
|
3809
|
-
|
|
3810
|
-
|
|
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),
|
|
3811
3929
|
relatedContent
|
|
3812
|
-
)
|
|
3930
|
+
);
|
|
3813
3931
|
if (normalizedType === "created" && oldString === null && newString !== null) {
|
|
3814
3932
|
oldString = "";
|
|
3815
3933
|
}
|
|
@@ -3820,7 +3938,10 @@ function collectContentDiffFiles(messageId, toolName, occurredAtUnixMs, contentI
|
|
|
3820
3938
|
if (normalizedType === "deleted" && newString === null && oldString !== null) {
|
|
3821
3939
|
newString = "";
|
|
3822
3940
|
}
|
|
3823
|
-
const explicitContent =
|
|
3941
|
+
const explicitContent = firstPresentString6(
|
|
3942
|
+
literalStringValue(item.content),
|
|
3943
|
+
relatedContent
|
|
3944
|
+
);
|
|
3824
3945
|
const inferredType = normalizedType ?? inferChangeTypeFromToolContent(
|
|
3825
3946
|
toolName,
|
|
3826
3947
|
normalizedType === "deleted" ? null : explicitContent,
|
|
@@ -3830,10 +3951,10 @@ function collectContentDiffFiles(messageId, toolName, occurredAtUnixMs, contentI
|
|
|
3830
3951
|
if (inferredType === "created" && oldString === null && newString !== null) {
|
|
3831
3952
|
oldString = "";
|
|
3832
3953
|
}
|
|
3833
|
-
const content =
|
|
3954
|
+
const content = firstPresentString6(
|
|
3834
3955
|
inferredType === "deleted" ? null : explicitContent,
|
|
3835
3956
|
inferredType === "created" ? newString : null
|
|
3836
|
-
)
|
|
3957
|
+
);
|
|
3837
3958
|
if (!unifiedDiff && oldString === null && newString === null && content === null) {
|
|
3838
3959
|
return [];
|
|
3839
3960
|
}
|
|
@@ -4036,7 +4157,7 @@ function normalizeChangeType(value) {
|
|
|
4036
4157
|
function inferChangeTypeFromToolContent(toolName, content, oldString, newString) {
|
|
4037
4158
|
const normalizedToolName = normalizeToolName4(toolName);
|
|
4038
4159
|
if (normalizedToolName === "write" || normalizedToolName === "writefile") {
|
|
4039
|
-
return content || newString ? "created" : null;
|
|
4160
|
+
return content !== null || newString !== null ? "created" : null;
|
|
4040
4161
|
}
|
|
4041
4162
|
if (oldString !== null || newString !== null) {
|
|
4042
4163
|
return "modified";
|
|
@@ -4071,6 +4192,17 @@ function firstFileChangeValue(...values) {
|
|
|
4071
4192
|
function arrayValue5(value) {
|
|
4072
4193
|
return Array.isArray(value) ? value : null;
|
|
4073
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
|
+
}
|
|
4074
4206
|
function firstLocationPath(value) {
|
|
4075
4207
|
if (!value) {
|
|
4076
4208
|
return null;
|
|
@@ -4099,6 +4231,9 @@ function firstPathValue(value) {
|
|
|
4099
4231
|
function stringValue6(value) {
|
|
4100
4232
|
return typeof value === "string" && value.trim() ? value.trim() : null;
|
|
4101
4233
|
}
|
|
4234
|
+
function literalStringValue(value) {
|
|
4235
|
+
return typeof value === "string" ? value : null;
|
|
4236
|
+
}
|
|
4102
4237
|
function numberValue2(value) {
|
|
4103
4238
|
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
4104
4239
|
}
|
|
@@ -4110,6 +4245,14 @@ function firstNonEmptyString(...values) {
|
|
|
4110
4245
|
}
|
|
4111
4246
|
return null;
|
|
4112
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
|
+
}
|
|
4113
4256
|
|
|
4114
4257
|
// shared/agentConversation/projection/agentConversationProjection.ts
|
|
4115
4258
|
var RENDER_IRRELEVANT_TRANSCRIPT_ROW_FIELDS = /* @__PURE__ */ new Set(["occurredAtUnixMs"]);
|
|
@@ -4886,6 +5029,186 @@ var Button = React.forwardRef(
|
|
|
4886
5029
|
);
|
|
4887
5030
|
Button.displayName = "Button";
|
|
4888
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
|
+
|
|
4889
5212
|
// shared/agentConversation/components/AgentPlanCard.tsx
|
|
4890
5213
|
import { useCallback, useRef, useState } from "react";
|
|
4891
5214
|
import { Check, ChevronDown, ChevronUp, Copy, ListChecks } from "lucide-react";
|
|
@@ -5284,6 +5607,9 @@ function createEmptyDocument() {
|
|
|
5284
5607
|
content: [{ type: "paragraph" }]
|
|
5285
5608
|
};
|
|
5286
5609
|
}
|
|
5610
|
+
function isVisualLineStart(content) {
|
|
5611
|
+
return content.length === 0 || content.at(-1)?.type === "hardBreak";
|
|
5612
|
+
}
|
|
5287
5613
|
function createParagraphFromText(text, options = {}) {
|
|
5288
5614
|
const content = [];
|
|
5289
5615
|
let index = 0;
|
|
@@ -5306,6 +5632,9 @@ function createParagraphFromText(text, options = {}) {
|
|
|
5306
5632
|
const parsedMention = parseAgentMentionMarkdown(text, index);
|
|
5307
5633
|
if (parsedMention) {
|
|
5308
5634
|
flushTextBuffer();
|
|
5635
|
+
if (isVisualLineStart(content)) {
|
|
5636
|
+
content.push({ type: "text", text: AGENT_RICH_TEXT_CARET_ANCHOR });
|
|
5637
|
+
}
|
|
5309
5638
|
content.push({
|
|
5310
5639
|
type: "agentFileMention",
|
|
5311
5640
|
// 转成规范 node attrs(如 workspace-reference 的 source/groupId/fileCount),
|
|
@@ -5383,7 +5712,7 @@ function isBlockPromptNode(node) {
|
|
|
5383
5712
|
}
|
|
5384
5713
|
function nodeToPromptText(node) {
|
|
5385
5714
|
if (node.type === "text") {
|
|
5386
|
-
return node.text ?? "";
|
|
5715
|
+
return (node.text ?? "").replaceAll(AGENT_RICH_TEXT_CARET_ANCHOR, "");
|
|
5387
5716
|
}
|
|
5388
5717
|
if (node.type === "agentFileMention") {
|
|
5389
5718
|
return formatAgentMentionMarkdown(attrsToMentionItem(node.attrs ?? {}));
|
|
@@ -5603,7 +5932,9 @@ function isMentionOnlyRichTextDoc(doc) {
|
|
|
5603
5932
|
if (paragraph?.type !== "paragraph") {
|
|
5604
5933
|
return false;
|
|
5605
5934
|
}
|
|
5606
|
-
const inlineContent = paragraph.content ?? []
|
|
5935
|
+
const inlineContent = (paragraph.content ?? []).filter(
|
|
5936
|
+
(node) => !(node.type === "text" && (node.text ?? "").replaceAll(AGENT_RICH_TEXT_CARET_ANCHOR, "").length === 0)
|
|
5937
|
+
);
|
|
5607
5938
|
return inlineContent.length === 1 && inlineContent[0]?.type === "agentFileMention";
|
|
5608
5939
|
}
|
|
5609
5940
|
function plainTextToAgentRichTextDocWithWorkspaceAppIcons(value, availableSkills, workspaceAppIcons) {
|
|
@@ -6799,6 +7130,7 @@ function AgentMessageBlock({
|
|
|
6799
7130
|
AgentCopyableMessageGroup,
|
|
6800
7131
|
{
|
|
6801
7132
|
copyText: message.copyText ?? null,
|
|
7133
|
+
occurredAtUnixMs: message.occurredAtUnixMs,
|
|
6802
7134
|
speaker: row.speaker,
|
|
6803
7135
|
onCopyMessageText: handleCopyMessageText,
|
|
6804
7136
|
children: [
|
|
@@ -6815,6 +7147,7 @@ function AgentMessageBlock({
|
|
|
6815
7147
|
AgentCopyableMessageGroup,
|
|
6816
7148
|
{
|
|
6817
7149
|
copyText,
|
|
7150
|
+
occurredAtUnixMs: message.occurredAtUnixMs,
|
|
6818
7151
|
speaker: row.speaker,
|
|
6819
7152
|
onCopyMessageText: handleCopyMessageText,
|
|
6820
7153
|
children: content
|
|
@@ -6831,19 +7164,24 @@ function AgentMessageBlock({
|
|
|
6831
7164
|
function AgentCopyableMessageGroup({
|
|
6832
7165
|
children,
|
|
6833
7166
|
copyText,
|
|
7167
|
+
occurredAtUnixMs,
|
|
6834
7168
|
onCopyMessageText,
|
|
6835
7169
|
speaker
|
|
6836
7170
|
}) {
|
|
6837
7171
|
"use memo";
|
|
7172
|
+
const timestamp = formatAgentMessageTimestamp(occurredAtUnixMs);
|
|
6838
7173
|
return /* @__PURE__ */ jsxs7("div", { className: AgentGUIConversation_styles_default.messageGroup, "data-agent-message-speaker": speaker, children: [
|
|
6839
7174
|
children,
|
|
6840
|
-
copyText ? /* @__PURE__ */
|
|
6841
|
-
|
|
6842
|
-
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
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
|
|
6847
7185
|
] });
|
|
6848
7186
|
}
|
|
6849
7187
|
function AgentMessageCopyButton({
|
|
@@ -11913,8 +12251,21 @@ function renderToolCard(call, onLinkClick, previewMode = false, showRawTimelineJ
|
|
|
11913
12251
|
}
|
|
11914
12252
|
|
|
11915
12253
|
// shared/agentConversation/components/AgentTurnSummaryRow.tsx
|
|
11916
|
-
import { useMemo as useMemo5, useState as useState16 } from "react";
|
|
11917
|
-
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";
|
|
11918
12269
|
|
|
11919
12270
|
// app/renderer/components/icons/DirectLinedIcon.tsx
|
|
11920
12271
|
import { jsx as jsx53 } from "react/jsx-runtime";
|
|
@@ -11941,6 +12292,195 @@ function DirectLinedIcon(props) {
|
|
|
11941
12292
|
);
|
|
11942
12293
|
}
|
|
11943
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
|
+
|
|
11944
12484
|
// shared/agentConversation/components/AgentTurnSummaryRow.tsx
|
|
11945
12485
|
import { jsx as jsx54, jsxs as jsxs41 } from "react/jsx-runtime";
|
|
11946
12486
|
function AgentTurnSummaryRow({
|
|
@@ -11953,29 +12493,201 @@ function AgentTurnSummaryRow({
|
|
|
11953
12493
|
{}
|
|
11954
12494
|
);
|
|
11955
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();
|
|
11956
12500
|
const aggregateStats = useMemo5(
|
|
11957
12501
|
() => summarizeRowDiff(row.files),
|
|
11958
12502
|
[row.files]
|
|
11959
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]);
|
|
11960
12576
|
const visibleFiles = row.files.slice(0, 3);
|
|
11961
12577
|
const hiddenFiles = row.files.slice(3);
|
|
11962
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
|
+
};
|
|
11963
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: [
|
|
11964
|
-
/* @__PURE__ */
|
|
11965
|
-
/* @__PURE__ */ jsx54("div", { className: "min-w-0
|
|
11966
|
-
|
|
11967
|
-
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
"
|
|
11971
|
-
|
|
11972
|
-
|
|
11973
|
-
|
|
11974
|
-
"-",
|
|
11975
|
-
|
|
11976
|
-
|
|
11977
|
-
|
|
11978
|
-
|
|
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
|
+
] }),
|
|
11979
12691
|
/* @__PURE__ */ jsxs41("div", { className: "agent-turn-summary-card__list", children: [
|
|
11980
12692
|
visibleFiles.map((file) => {
|
|
11981
12693
|
const key = `${file.path}:${file.messageId}`;
|
|
@@ -12206,6 +12918,47 @@ function summarizeRowDiff(files) {
|
|
|
12206
12918
|
{ added: 0, removed: 0 }
|
|
12207
12919
|
);
|
|
12208
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
|
+
}
|
|
12209
12962
|
function summarizeFileDiff(file) {
|
|
12210
12963
|
if (file.unifiedDiff?.trim()) {
|
|
12211
12964
|
return parseAgentUnifiedDiffStats(file.unifiedDiff);
|
|
@@ -12736,6 +13489,8 @@ function useProjectedAgentConversation({
|
|
|
12736
13489
|
}
|
|
12737
13490
|
|
|
12738
13491
|
export {
|
|
13492
|
+
getAppErrorCode,
|
|
13493
|
+
toLocalShortDateTime,
|
|
12739
13494
|
Button,
|
|
12740
13495
|
buildWorkspaceAgentSessionDetailViewModel,
|
|
12741
13496
|
projectAgentConversationVM,
|
|
@@ -12755,4 +13510,4 @@ export {
|
|
|
12755
13510
|
AgentConversationFlow,
|
|
12756
13511
|
useProjectedAgentConversation
|
|
12757
13512
|
};
|
|
12758
|
-
//# sourceMappingURL=chunk-
|
|
13513
|
+
//# sourceMappingURL=chunk-ZAF4IVUT.js.map
|