@ganglion/xacpx 0.20.1 → 0.20.3-beta.0
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/bridge/bridge-main.js +199 -21
- package/dist/cli.js +199 -21
- package/package.json +1 -1
|
@@ -3260,6 +3260,7 @@ function createStreamingPromptState(formatToolCalls = false, options) {
|
|
|
3260
3260
|
emittedToolCallIds: new Set,
|
|
3261
3261
|
positionedToolCallIds: new Set,
|
|
3262
3262
|
toolCalls: new Map,
|
|
3263
|
+
cursorPlanEntries: new Map,
|
|
3263
3264
|
toolEventMode,
|
|
3264
3265
|
driver,
|
|
3265
3266
|
rawStream,
|
|
@@ -3318,13 +3319,17 @@ function parseStreamingChunks(state, line) {
|
|
|
3318
3319
|
}
|
|
3319
3320
|
const wantsStructured = state.toolEventMode === "structured" || state.toolEventMode === "both";
|
|
3320
3321
|
const wantsText = (state.toolEventMode === "text" || state.toolEventMode === "both") && state.formatToolCalls;
|
|
3321
|
-
|
|
3322
|
-
|
|
3322
|
+
const merged = update.toolCallId && (state.onToolEvent || state.onPlan) ? mergeToolCallUpdate(state, update.toolCallId, update) : update;
|
|
3323
|
+
const cursorPlan = normalizeCursorPlanUpdate(state, merged);
|
|
3324
|
+
const consumedAsPlan = cursorPlan !== undefined && state.onPlan !== undefined;
|
|
3325
|
+
if (consumedAsPlan) {
|
|
3326
|
+
state.onPlan?.(cursorPlan);
|
|
3327
|
+
} else if (wantsStructured && state.onToolEvent) {
|
|
3323
3328
|
const toolEvent = buildToolUseEvent(merged, state.driver);
|
|
3324
3329
|
if (toolEvent)
|
|
3325
3330
|
state.onToolEvent(toolEvent);
|
|
3326
3331
|
}
|
|
3327
|
-
if (wantsText) {
|
|
3332
|
+
if (wantsText && !consumedAsPlan) {
|
|
3328
3333
|
const formatted = formatToolCallEvent(update, update.sessionUpdate);
|
|
3329
3334
|
if (formatted) {
|
|
3330
3335
|
const toolCallId = update.toolCallId;
|
|
@@ -3340,7 +3345,7 @@ function parseStreamingChunks(state, line) {
|
|
|
3340
3345
|
}
|
|
3341
3346
|
if (update.sessionUpdate === "plan") {
|
|
3342
3347
|
const entries = Array.isArray(update.entries) ? update.entries.filter((x) => !!x && typeof x === "object" && typeof x.content === "string" && typeof x.status === "string") : [];
|
|
3343
|
-
if (entries
|
|
3348
|
+
if (Array.isArray(update.entries))
|
|
3344
3349
|
state.onPlan?.(entries);
|
|
3345
3350
|
return;
|
|
3346
3351
|
}
|
|
@@ -3452,7 +3457,7 @@ function isEmptyToolField(v) {
|
|
|
3452
3457
|
function mergeToolCallUpdate(state, toolCallId, update) {
|
|
3453
3458
|
const prev = state.toolCalls.get(toolCallId) ?? { toolCallId };
|
|
3454
3459
|
const merged = { ...prev };
|
|
3455
|
-
for (const key of ["kind", "title", "rawInput", "content", "rawOutput", "locations", "status"]) {
|
|
3460
|
+
for (const key of ["kind", "title", "toolCallId", "parentToolCallId", "rawInput", "content", "rawOutput", "locations", "status"]) {
|
|
3456
3461
|
const next = update[key];
|
|
3457
3462
|
if (!isEmptyToolField(next))
|
|
3458
3463
|
merged[key] = next;
|
|
@@ -3484,19 +3489,7 @@ function buildToolUseEvent(update, driver) {
|
|
|
3484
3489
|
const toolCallId = update.toolCallId;
|
|
3485
3490
|
if (!toolCallId)
|
|
3486
3491
|
return null;
|
|
3487
|
-
const
|
|
3488
|
-
const kind = (() => {
|
|
3489
|
-
switch (kindRaw) {
|
|
3490
|
-
case "read":
|
|
3491
|
-
case "search":
|
|
3492
|
-
case "execute":
|
|
3493
|
-
case "edit":
|
|
3494
|
-
case "think":
|
|
3495
|
-
return kindRaw;
|
|
3496
|
-
default:
|
|
3497
|
-
return "other";
|
|
3498
|
-
}
|
|
3499
|
-
})();
|
|
3492
|
+
const kind = normalizeToolKind(update, driver);
|
|
3500
3493
|
const title = (update.title ?? "").trim();
|
|
3501
3494
|
const toolName = title || "Tool";
|
|
3502
3495
|
const summaryRaw = summarizeToolInput(update.rawInput, title) || summarizeToolInput(update.rawOutput, title);
|
|
@@ -3512,8 +3505,8 @@ function buildToolUseEvent(update, driver) {
|
|
|
3512
3505
|
const content = update.content;
|
|
3513
3506
|
const rawOutput = update.rawOutput ?? claudeToolResponse;
|
|
3514
3507
|
const locations = update.locations;
|
|
3515
|
-
const parentToolCallId = claudeMeta?.parentToolUseId?.trim();
|
|
3516
|
-
const isSubagent = claudeMeta?.toolName === "Agent" || driver === "qoder" && update._meta?.qoder?.toolName === "Agent" || driver === "kimi" && isKimiSubagentInput(rawInput) || driver === "codex" && isCodexSubagentMeta(update._meta?.codex?.subagent);
|
|
3508
|
+
const parentToolCallId = claudeMeta?.parentToolUseId?.trim() || update.parentToolCallId?.trim();
|
|
3509
|
+
const isSubagent = claudeMeta?.toolName === "Agent" || driver === "qoder" && update._meta?.qoder?.toolName === "Agent" || driver === "kimi" && isKimiSubagentInput(rawInput) || driver === "codex" && isCodexSubagentMeta(update._meta?.codex?.subagent) || driver === "cursor" && isCursorSubagentInput(rawInput, title);
|
|
3517
3510
|
return {
|
|
3518
3511
|
toolCallId,
|
|
3519
3512
|
...parentToolCallId ? { parentToolCallId } : {},
|
|
@@ -3528,6 +3521,165 @@ function buildToolUseEvent(update, driver) {
|
|
|
3528
3521
|
status
|
|
3529
3522
|
};
|
|
3530
3523
|
}
|
|
3524
|
+
function normalizeCursorPlanUpdate(state, update) {
|
|
3525
|
+
if (state.driver !== "cursor")
|
|
3526
|
+
return;
|
|
3527
|
+
if (!CURSOR_PLAN_TOOL_NAMES.has(cursorToolIdentity(update)))
|
|
3528
|
+
return;
|
|
3529
|
+
const input = cursorToolInput(update.rawInput);
|
|
3530
|
+
const output = cursorToolInput(update.rawOutput);
|
|
3531
|
+
const todos = readCursorTodoList(input) ?? readCursorTodoList(output);
|
|
3532
|
+
if (todos === undefined)
|
|
3533
|
+
return;
|
|
3534
|
+
const merge = input?.merge === true || output?.merge === true;
|
|
3535
|
+
if (todos.length === 0) {
|
|
3536
|
+
state.cursorPlanEntries.clear();
|
|
3537
|
+
return [];
|
|
3538
|
+
}
|
|
3539
|
+
const patches = todos.map((todo, index) => parseCursorPlanTodo(todo, index)).filter((todo) => todo !== undefined);
|
|
3540
|
+
if (patches.length === 0)
|
|
3541
|
+
return;
|
|
3542
|
+
if (!merge)
|
|
3543
|
+
state.cursorPlanEntries.clear();
|
|
3544
|
+
for (const patch of patches) {
|
|
3545
|
+
const previous = state.cursorPlanEntries.get(patch.key);
|
|
3546
|
+
const content = patch.content ?? previous?.content;
|
|
3547
|
+
if (!content)
|
|
3548
|
+
continue;
|
|
3549
|
+
const status = patch.status ?? previous?.status ?? "pending";
|
|
3550
|
+
const priority = patch.priority ?? previous?.priority;
|
|
3551
|
+
state.cursorPlanEntries.set(patch.key, {
|
|
3552
|
+
content,
|
|
3553
|
+
status,
|
|
3554
|
+
...priority ? { priority } : {}
|
|
3555
|
+
});
|
|
3556
|
+
}
|
|
3557
|
+
return [...state.cursorPlanEntries.values()];
|
|
3558
|
+
}
|
|
3559
|
+
function readCursorTodoList(input) {
|
|
3560
|
+
if (!input)
|
|
3561
|
+
return;
|
|
3562
|
+
for (const key of ["todos", "todoList"]) {
|
|
3563
|
+
if (Array.isArray(input[key]))
|
|
3564
|
+
return input[key];
|
|
3565
|
+
}
|
|
3566
|
+
return;
|
|
3567
|
+
}
|
|
3568
|
+
function parseCursorPlanTodo(value, index) {
|
|
3569
|
+
if (!isRecord2(value))
|
|
3570
|
+
return;
|
|
3571
|
+
const id = readFirstString(value, ["id", "todoId", "taskId"]);
|
|
3572
|
+
const content = readFirstString(value, ["content", "task", "description", "title", "text"]);
|
|
3573
|
+
const key = id ? `id:${id}` : content ? `content:${content}` : `index:${index}`;
|
|
3574
|
+
const status = normalizeCursorPlanStatus(value.status ?? value.state);
|
|
3575
|
+
const priority = normalizePlanPriority(value.priority);
|
|
3576
|
+
if (!content && !status && !priority && !id)
|
|
3577
|
+
return;
|
|
3578
|
+
return {
|
|
3579
|
+
key,
|
|
3580
|
+
...content ? { content } : {},
|
|
3581
|
+
...status ? { status } : {},
|
|
3582
|
+
...priority ? { priority } : {}
|
|
3583
|
+
};
|
|
3584
|
+
}
|
|
3585
|
+
function normalizeCursorPlanStatus(value) {
|
|
3586
|
+
if (typeof value !== "string")
|
|
3587
|
+
return;
|
|
3588
|
+
const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_").replace(/^todo_status_/, "");
|
|
3589
|
+
switch (normalized) {
|
|
3590
|
+
case "pending":
|
|
3591
|
+
case "todo":
|
|
3592
|
+
case "not_started":
|
|
3593
|
+
case "notstarted":
|
|
3594
|
+
case "incomplete":
|
|
3595
|
+
return "pending";
|
|
3596
|
+
case "in_progress":
|
|
3597
|
+
case "inprogress":
|
|
3598
|
+
case "active":
|
|
3599
|
+
case "working":
|
|
3600
|
+
return "in_progress";
|
|
3601
|
+
case "completed":
|
|
3602
|
+
case "complete":
|
|
3603
|
+
case "done":
|
|
3604
|
+
case "finished":
|
|
3605
|
+
return "completed";
|
|
3606
|
+
default:
|
|
3607
|
+
return;
|
|
3608
|
+
}
|
|
3609
|
+
}
|
|
3610
|
+
function normalizePlanPriority(value) {
|
|
3611
|
+
if (value !== "high" && value !== "medium" && value !== "low")
|
|
3612
|
+
return;
|
|
3613
|
+
return value;
|
|
3614
|
+
}
|
|
3615
|
+
function cursorToolInput(rawInput) {
|
|
3616
|
+
if (!isRecord2(rawInput))
|
|
3617
|
+
return;
|
|
3618
|
+
if (isRecord2(rawInput.args))
|
|
3619
|
+
return rawInput.args;
|
|
3620
|
+
return rawInput;
|
|
3621
|
+
}
|
|
3622
|
+
function normalizeCursorToolName(title) {
|
|
3623
|
+
return (title ?? "").trim().toLowerCase().replace(/[\s_-]+/g, "");
|
|
3624
|
+
}
|
|
3625
|
+
function cursorToolIdentity(update) {
|
|
3626
|
+
const input = cursorToolInput(update.rawInput);
|
|
3627
|
+
const declared = typeof input?.[CURSOR_TOOL_NAME_KEY] === "string" ? input[CURSOR_TOOL_NAME_KEY] : undefined;
|
|
3628
|
+
return normalizeCursorToolName(declared ?? update.title);
|
|
3629
|
+
}
|
|
3630
|
+
function normalizeToolKind(update, driver) {
|
|
3631
|
+
const kindRaw = update?.kind?.trim().toLowerCase() ?? "";
|
|
3632
|
+
switch (kindRaw) {
|
|
3633
|
+
case "read":
|
|
3634
|
+
case "search":
|
|
3635
|
+
case "execute":
|
|
3636
|
+
case "edit":
|
|
3637
|
+
case "think":
|
|
3638
|
+
return kindRaw;
|
|
3639
|
+
}
|
|
3640
|
+
if (driver !== "cursor")
|
|
3641
|
+
return "other";
|
|
3642
|
+
switch (cursorToolIdentity(update ?? {})) {
|
|
3643
|
+
case "read":
|
|
3644
|
+
case "readfile":
|
|
3645
|
+
return "read";
|
|
3646
|
+
case "grep":
|
|
3647
|
+
case "glob":
|
|
3648
|
+
case "find":
|
|
3649
|
+
case "codebasesearch":
|
|
3650
|
+
case "search":
|
|
3651
|
+
return "search";
|
|
3652
|
+
case "shell":
|
|
3653
|
+
case "bash":
|
|
3654
|
+
case "terminal":
|
|
3655
|
+
return "execute";
|
|
3656
|
+
case "strreplace":
|
|
3657
|
+
case "replace":
|
|
3658
|
+
case "edit":
|
|
3659
|
+
case "write":
|
|
3660
|
+
case "delete":
|
|
3661
|
+
return "edit";
|
|
3662
|
+
case "task":
|
|
3663
|
+
case "delegate":
|
|
3664
|
+
case "runsubagent":
|
|
3665
|
+
case "switchmode":
|
|
3666
|
+
case "todowrite":
|
|
3667
|
+
case "updatetodos":
|
|
3668
|
+
case "todoread":
|
|
3669
|
+
case "createplan":
|
|
3670
|
+
case "updateplan":
|
|
3671
|
+
case "plan":
|
|
3672
|
+
return "think";
|
|
3673
|
+
default:
|
|
3674
|
+
return "other";
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
function isCursorSubagentInput(rawInput, title) {
|
|
3678
|
+
if (!CURSOR_SUBAGENT_TOOL_NAMES.has(cursorToolIdentity({ title, rawInput })))
|
|
3679
|
+
return false;
|
|
3680
|
+
const input = cursorToolInput(rawInput);
|
|
3681
|
+
return input !== undefined && readFirstString(input, ["subagent_type", "subagentType", "agent", "agentType", "prompt", "instructions"]) !== undefined;
|
|
3682
|
+
}
|
|
3531
3683
|
function isKimiSubagentInput(rawInput) {
|
|
3532
3684
|
return isRecord2(rawInput) && readFirstString(rawInput, ["prompt"]) !== undefined && readFirstString(rawInput, ["subagent_type", "subagentType"]) !== undefined;
|
|
3533
3685
|
}
|
|
@@ -3542,6 +3694,12 @@ function summarizeToolInput(rawInput, title = "") {
|
|
|
3542
3694
|
}
|
|
3543
3695
|
if (!isRecord2(rawInput))
|
|
3544
3696
|
return;
|
|
3697
|
+
const nestedInput = cursorToolInput(rawInput);
|
|
3698
|
+
if (nestedInput !== rawInput) {
|
|
3699
|
+
const nestedSummary = summarizeToolInput(nestedInput, title);
|
|
3700
|
+
if (nestedSummary)
|
|
3701
|
+
return nestedSummary;
|
|
3702
|
+
}
|
|
3545
3703
|
const taskSummary = summarizeTaskInput(rawInput, title);
|
|
3546
3704
|
if (taskSummary)
|
|
3547
3705
|
return taskSummary;
|
|
@@ -3562,6 +3720,16 @@ function summarizeToolInput(rawInput, title = "") {
|
|
|
3562
3720
|
return parts.join(" ");
|
|
3563
3721
|
}
|
|
3564
3722
|
}
|
|
3723
|
+
const globPattern = readFirstString(rawInput, ["glob_pattern"]);
|
|
3724
|
+
if (globPattern) {
|
|
3725
|
+
const targetDirectory = readFirstString(rawInput, ["target_directory"]);
|
|
3726
|
+
return targetDirectory ? `${globPattern} in ${targetDirectory}` : globPattern;
|
|
3727
|
+
}
|
|
3728
|
+
const mode = readFirstString(rawInput, ["target_mode_id", "mode_id"]);
|
|
3729
|
+
const explanation = readFirstString(rawInput, ["explanation"]);
|
|
3730
|
+
if (mode || explanation) {
|
|
3731
|
+
return mode && explanation ? `${mode}: ${explanation}` : mode ?? explanation;
|
|
3732
|
+
}
|
|
3565
3733
|
return readFirstString(rawInput, [
|
|
3566
3734
|
"path",
|
|
3567
3735
|
"file",
|
|
@@ -3575,6 +3743,7 @@ function summarizeToolInput(rawInput, title = "") {
|
|
|
3575
3743
|
"pattern",
|
|
3576
3744
|
"text",
|
|
3577
3745
|
"search",
|
|
3746
|
+
"working_directory",
|
|
3578
3747
|
"name",
|
|
3579
3748
|
"description"
|
|
3580
3749
|
]);
|
|
@@ -3681,7 +3850,7 @@ function isGenericToolTitle(kind, title) {
|
|
|
3681
3850
|
}
|
|
3682
3851
|
return false;
|
|
3683
3852
|
}
|
|
3684
|
-
var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END, USAGE_BREAKDOWN_FIELDS;
|
|
3853
|
+
var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END, CURSOR_TOOL_NAME_KEY = "_toolName", CURSOR_PLAN_TOOL_NAMES, CURSOR_SUBAGENT_TOOL_NAMES, USAGE_BREAKDOWN_FIELDS;
|
|
3685
3854
|
var init_streaming_prompt = __esm(() => {
|
|
3686
3855
|
init_background_followup();
|
|
3687
3856
|
init_tool_kind_emoji();
|
|
@@ -3691,6 +3860,15 @@ var init_streaming_prompt = __esm(() => {
|
|
|
3691
3860
|
LINE_BREAK_AT_END = /\r?\n[\t ]*$/;
|
|
3692
3861
|
LINE_BREAK_AT_START = /^[\t ]*\r?\n/;
|
|
3693
3862
|
PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r$/;
|
|
3863
|
+
CURSOR_PLAN_TOOL_NAMES = new Set([
|
|
3864
|
+
"todowrite",
|
|
3865
|
+
"createplan",
|
|
3866
|
+
"updateplan",
|
|
3867
|
+
"plan",
|
|
3868
|
+
"updatetodos",
|
|
3869
|
+
"todoread"
|
|
3870
|
+
]);
|
|
3871
|
+
CURSOR_SUBAGENT_TOOL_NAMES = new Set(["task", "delegate", "runsubagent", "subagent"]);
|
|
3694
3872
|
USAGE_BREAKDOWN_FIELDS = [
|
|
3695
3873
|
["inputTokens", ["inputTokens", "input_tokens"]],
|
|
3696
3874
|
["outputTokens", ["outputTokens", "output_tokens"]],
|
package/dist/cli.js
CHANGED
|
@@ -52653,6 +52653,7 @@ function createStreamingPromptState(formatToolCalls = false, options) {
|
|
|
52653
52653
|
emittedToolCallIds: new Set,
|
|
52654
52654
|
positionedToolCallIds: new Set,
|
|
52655
52655
|
toolCalls: new Map,
|
|
52656
|
+
cursorPlanEntries: new Map,
|
|
52656
52657
|
toolEventMode,
|
|
52657
52658
|
driver,
|
|
52658
52659
|
rawStream,
|
|
@@ -52711,13 +52712,17 @@ function parseStreamingChunks(state, line) {
|
|
|
52711
52712
|
}
|
|
52712
52713
|
const wantsStructured = state.toolEventMode === "structured" || state.toolEventMode === "both";
|
|
52713
52714
|
const wantsText = (state.toolEventMode === "text" || state.toolEventMode === "both") && state.formatToolCalls;
|
|
52714
|
-
|
|
52715
|
-
|
|
52715
|
+
const merged = update.toolCallId && (state.onToolEvent || state.onPlan) ? mergeToolCallUpdate(state, update.toolCallId, update) : update;
|
|
52716
|
+
const cursorPlan = normalizeCursorPlanUpdate(state, merged);
|
|
52717
|
+
const consumedAsPlan = cursorPlan !== undefined && state.onPlan !== undefined;
|
|
52718
|
+
if (consumedAsPlan) {
|
|
52719
|
+
state.onPlan?.(cursorPlan);
|
|
52720
|
+
} else if (wantsStructured && state.onToolEvent) {
|
|
52716
52721
|
const toolEvent = buildToolUseEvent(merged, state.driver);
|
|
52717
52722
|
if (toolEvent)
|
|
52718
52723
|
state.onToolEvent(toolEvent);
|
|
52719
52724
|
}
|
|
52720
|
-
if (wantsText) {
|
|
52725
|
+
if (wantsText && !consumedAsPlan) {
|
|
52721
52726
|
const formatted = formatToolCallEvent(update, update.sessionUpdate);
|
|
52722
52727
|
if (formatted) {
|
|
52723
52728
|
const toolCallId = update.toolCallId;
|
|
@@ -52733,7 +52738,7 @@ function parseStreamingChunks(state, line) {
|
|
|
52733
52738
|
}
|
|
52734
52739
|
if (update.sessionUpdate === "plan") {
|
|
52735
52740
|
const entries = Array.isArray(update.entries) ? update.entries.filter((x) => !!x && typeof x === "object" && typeof x.content === "string" && typeof x.status === "string") : [];
|
|
52736
|
-
if (entries
|
|
52741
|
+
if (Array.isArray(update.entries))
|
|
52737
52742
|
state.onPlan?.(entries);
|
|
52738
52743
|
return;
|
|
52739
52744
|
}
|
|
@@ -52845,7 +52850,7 @@ function isEmptyToolField(v) {
|
|
|
52845
52850
|
function mergeToolCallUpdate(state, toolCallId, update) {
|
|
52846
52851
|
const prev = state.toolCalls.get(toolCallId) ?? { toolCallId };
|
|
52847
52852
|
const merged = { ...prev };
|
|
52848
|
-
for (const key of ["kind", "title", "rawInput", "content", "rawOutput", "locations", "status"]) {
|
|
52853
|
+
for (const key of ["kind", "title", "toolCallId", "parentToolCallId", "rawInput", "content", "rawOutput", "locations", "status"]) {
|
|
52849
52854
|
const next = update[key];
|
|
52850
52855
|
if (!isEmptyToolField(next))
|
|
52851
52856
|
merged[key] = next;
|
|
@@ -52877,19 +52882,7 @@ function buildToolUseEvent(update, driver) {
|
|
|
52877
52882
|
const toolCallId = update.toolCallId;
|
|
52878
52883
|
if (!toolCallId)
|
|
52879
52884
|
return null;
|
|
52880
|
-
const
|
|
52881
|
-
const kind = (() => {
|
|
52882
|
-
switch (kindRaw) {
|
|
52883
|
-
case "read":
|
|
52884
|
-
case "search":
|
|
52885
|
-
case "execute":
|
|
52886
|
-
case "edit":
|
|
52887
|
-
case "think":
|
|
52888
|
-
return kindRaw;
|
|
52889
|
-
default:
|
|
52890
|
-
return "other";
|
|
52891
|
-
}
|
|
52892
|
-
})();
|
|
52885
|
+
const kind = normalizeToolKind(update, driver);
|
|
52893
52886
|
const title = (update.title ?? "").trim();
|
|
52894
52887
|
const toolName = title || "Tool";
|
|
52895
52888
|
const summaryRaw = summarizeToolInput(update.rawInput, title) || summarizeToolInput(update.rawOutput, title);
|
|
@@ -52905,8 +52898,8 @@ function buildToolUseEvent(update, driver) {
|
|
|
52905
52898
|
const content = update.content;
|
|
52906
52899
|
const rawOutput = update.rawOutput ?? claudeToolResponse;
|
|
52907
52900
|
const locations = update.locations;
|
|
52908
|
-
const parentToolCallId = claudeMeta?.parentToolUseId?.trim();
|
|
52909
|
-
const isSubagent = claudeMeta?.toolName === "Agent" || driver === "qoder" && update._meta?.qoder?.toolName === "Agent" || driver === "kimi" && isKimiSubagentInput(rawInput) || driver === "codex" && isCodexSubagentMeta(update._meta?.codex?.subagent);
|
|
52901
|
+
const parentToolCallId = claudeMeta?.parentToolUseId?.trim() || update.parentToolCallId?.trim();
|
|
52902
|
+
const isSubagent = claudeMeta?.toolName === "Agent" || driver === "qoder" && update._meta?.qoder?.toolName === "Agent" || driver === "kimi" && isKimiSubagentInput(rawInput) || driver === "codex" && isCodexSubagentMeta(update._meta?.codex?.subagent) || driver === "cursor" && isCursorSubagentInput(rawInput, title);
|
|
52910
52903
|
return {
|
|
52911
52904
|
toolCallId,
|
|
52912
52905
|
...parentToolCallId ? { parentToolCallId } : {},
|
|
@@ -52921,6 +52914,165 @@ function buildToolUseEvent(update, driver) {
|
|
|
52921
52914
|
status
|
|
52922
52915
|
};
|
|
52923
52916
|
}
|
|
52917
|
+
function normalizeCursorPlanUpdate(state, update) {
|
|
52918
|
+
if (state.driver !== "cursor")
|
|
52919
|
+
return;
|
|
52920
|
+
if (!CURSOR_PLAN_TOOL_NAMES.has(cursorToolIdentity(update)))
|
|
52921
|
+
return;
|
|
52922
|
+
const input = cursorToolInput(update.rawInput);
|
|
52923
|
+
const output = cursorToolInput(update.rawOutput);
|
|
52924
|
+
const todos = readCursorTodoList(input) ?? readCursorTodoList(output);
|
|
52925
|
+
if (todos === undefined)
|
|
52926
|
+
return;
|
|
52927
|
+
const merge2 = input?.merge === true || output?.merge === true;
|
|
52928
|
+
if (todos.length === 0) {
|
|
52929
|
+
state.cursorPlanEntries.clear();
|
|
52930
|
+
return [];
|
|
52931
|
+
}
|
|
52932
|
+
const patches = todos.map((todo, index) => parseCursorPlanTodo(todo, index)).filter((todo) => todo !== undefined);
|
|
52933
|
+
if (patches.length === 0)
|
|
52934
|
+
return;
|
|
52935
|
+
if (!merge2)
|
|
52936
|
+
state.cursorPlanEntries.clear();
|
|
52937
|
+
for (const patch of patches) {
|
|
52938
|
+
const previous = state.cursorPlanEntries.get(patch.key);
|
|
52939
|
+
const content = patch.content ?? previous?.content;
|
|
52940
|
+
if (!content)
|
|
52941
|
+
continue;
|
|
52942
|
+
const status = patch.status ?? previous?.status ?? "pending";
|
|
52943
|
+
const priority = patch.priority ?? previous?.priority;
|
|
52944
|
+
state.cursorPlanEntries.set(patch.key, {
|
|
52945
|
+
content,
|
|
52946
|
+
status,
|
|
52947
|
+
...priority ? { priority } : {}
|
|
52948
|
+
});
|
|
52949
|
+
}
|
|
52950
|
+
return [...state.cursorPlanEntries.values()];
|
|
52951
|
+
}
|
|
52952
|
+
function readCursorTodoList(input) {
|
|
52953
|
+
if (!input)
|
|
52954
|
+
return;
|
|
52955
|
+
for (const key of ["todos", "todoList"]) {
|
|
52956
|
+
if (Array.isArray(input[key]))
|
|
52957
|
+
return input[key];
|
|
52958
|
+
}
|
|
52959
|
+
return;
|
|
52960
|
+
}
|
|
52961
|
+
function parseCursorPlanTodo(value, index) {
|
|
52962
|
+
if (!isRecord4(value))
|
|
52963
|
+
return;
|
|
52964
|
+
const id = readFirstString(value, ["id", "todoId", "taskId"]);
|
|
52965
|
+
const content = readFirstString(value, ["content", "task", "description", "title", "text"]);
|
|
52966
|
+
const key = id ? `id:${id}` : content ? `content:${content}` : `index:${index}`;
|
|
52967
|
+
const status = normalizeCursorPlanStatus(value.status ?? value.state);
|
|
52968
|
+
const priority = normalizePlanPriority(value.priority);
|
|
52969
|
+
if (!content && !status && !priority && !id)
|
|
52970
|
+
return;
|
|
52971
|
+
return {
|
|
52972
|
+
key,
|
|
52973
|
+
...content ? { content } : {},
|
|
52974
|
+
...status ? { status } : {},
|
|
52975
|
+
...priority ? { priority } : {}
|
|
52976
|
+
};
|
|
52977
|
+
}
|
|
52978
|
+
function normalizeCursorPlanStatus(value) {
|
|
52979
|
+
if (typeof value !== "string")
|
|
52980
|
+
return;
|
|
52981
|
+
const normalized = value.trim().toLowerCase().replace(/[\s-]+/g, "_").replace(/^todo_status_/, "");
|
|
52982
|
+
switch (normalized) {
|
|
52983
|
+
case "pending":
|
|
52984
|
+
case "todo":
|
|
52985
|
+
case "not_started":
|
|
52986
|
+
case "notstarted":
|
|
52987
|
+
case "incomplete":
|
|
52988
|
+
return "pending";
|
|
52989
|
+
case "in_progress":
|
|
52990
|
+
case "inprogress":
|
|
52991
|
+
case "active":
|
|
52992
|
+
case "working":
|
|
52993
|
+
return "in_progress";
|
|
52994
|
+
case "completed":
|
|
52995
|
+
case "complete":
|
|
52996
|
+
case "done":
|
|
52997
|
+
case "finished":
|
|
52998
|
+
return "completed";
|
|
52999
|
+
default:
|
|
53000
|
+
return;
|
|
53001
|
+
}
|
|
53002
|
+
}
|
|
53003
|
+
function normalizePlanPriority(value) {
|
|
53004
|
+
if (value !== "high" && value !== "medium" && value !== "low")
|
|
53005
|
+
return;
|
|
53006
|
+
return value;
|
|
53007
|
+
}
|
|
53008
|
+
function cursorToolInput(rawInput) {
|
|
53009
|
+
if (!isRecord4(rawInput))
|
|
53010
|
+
return;
|
|
53011
|
+
if (isRecord4(rawInput.args))
|
|
53012
|
+
return rawInput.args;
|
|
53013
|
+
return rawInput;
|
|
53014
|
+
}
|
|
53015
|
+
function normalizeCursorToolName(title) {
|
|
53016
|
+
return (title ?? "").trim().toLowerCase().replace(/[\s_-]+/g, "");
|
|
53017
|
+
}
|
|
53018
|
+
function cursorToolIdentity(update) {
|
|
53019
|
+
const input = cursorToolInput(update.rawInput);
|
|
53020
|
+
const declared = typeof input?.[CURSOR_TOOL_NAME_KEY] === "string" ? input[CURSOR_TOOL_NAME_KEY] : undefined;
|
|
53021
|
+
return normalizeCursorToolName(declared ?? update.title);
|
|
53022
|
+
}
|
|
53023
|
+
function normalizeToolKind(update, driver) {
|
|
53024
|
+
const kindRaw = update?.kind?.trim().toLowerCase() ?? "";
|
|
53025
|
+
switch (kindRaw) {
|
|
53026
|
+
case "read":
|
|
53027
|
+
case "search":
|
|
53028
|
+
case "execute":
|
|
53029
|
+
case "edit":
|
|
53030
|
+
case "think":
|
|
53031
|
+
return kindRaw;
|
|
53032
|
+
}
|
|
53033
|
+
if (driver !== "cursor")
|
|
53034
|
+
return "other";
|
|
53035
|
+
switch (cursorToolIdentity(update ?? {})) {
|
|
53036
|
+
case "read":
|
|
53037
|
+
case "readfile":
|
|
53038
|
+
return "read";
|
|
53039
|
+
case "grep":
|
|
53040
|
+
case "glob":
|
|
53041
|
+
case "find":
|
|
53042
|
+
case "codebasesearch":
|
|
53043
|
+
case "search":
|
|
53044
|
+
return "search";
|
|
53045
|
+
case "shell":
|
|
53046
|
+
case "bash":
|
|
53047
|
+
case "terminal":
|
|
53048
|
+
return "execute";
|
|
53049
|
+
case "strreplace":
|
|
53050
|
+
case "replace":
|
|
53051
|
+
case "edit":
|
|
53052
|
+
case "write":
|
|
53053
|
+
case "delete":
|
|
53054
|
+
return "edit";
|
|
53055
|
+
case "task":
|
|
53056
|
+
case "delegate":
|
|
53057
|
+
case "runsubagent":
|
|
53058
|
+
case "switchmode":
|
|
53059
|
+
case "todowrite":
|
|
53060
|
+
case "updatetodos":
|
|
53061
|
+
case "todoread":
|
|
53062
|
+
case "createplan":
|
|
53063
|
+
case "updateplan":
|
|
53064
|
+
case "plan":
|
|
53065
|
+
return "think";
|
|
53066
|
+
default:
|
|
53067
|
+
return "other";
|
|
53068
|
+
}
|
|
53069
|
+
}
|
|
53070
|
+
function isCursorSubagentInput(rawInput, title) {
|
|
53071
|
+
if (!CURSOR_SUBAGENT_TOOL_NAMES.has(cursorToolIdentity({ title, rawInput })))
|
|
53072
|
+
return false;
|
|
53073
|
+
const input = cursorToolInput(rawInput);
|
|
53074
|
+
return input !== undefined && readFirstString(input, ["subagent_type", "subagentType", "agent", "agentType", "prompt", "instructions"]) !== undefined;
|
|
53075
|
+
}
|
|
52924
53076
|
function isKimiSubagentInput(rawInput) {
|
|
52925
53077
|
return isRecord4(rawInput) && readFirstString(rawInput, ["prompt"]) !== undefined && readFirstString(rawInput, ["subagent_type", "subagentType"]) !== undefined;
|
|
52926
53078
|
}
|
|
@@ -52935,6 +53087,12 @@ function summarizeToolInput(rawInput, title = "") {
|
|
|
52935
53087
|
}
|
|
52936
53088
|
if (!isRecord4(rawInput))
|
|
52937
53089
|
return;
|
|
53090
|
+
const nestedInput = cursorToolInput(rawInput);
|
|
53091
|
+
if (nestedInput !== rawInput) {
|
|
53092
|
+
const nestedSummary = summarizeToolInput(nestedInput, title);
|
|
53093
|
+
if (nestedSummary)
|
|
53094
|
+
return nestedSummary;
|
|
53095
|
+
}
|
|
52938
53096
|
const taskSummary = summarizeTaskInput(rawInput, title);
|
|
52939
53097
|
if (taskSummary)
|
|
52940
53098
|
return taskSummary;
|
|
@@ -52955,6 +53113,16 @@ function summarizeToolInput(rawInput, title = "") {
|
|
|
52955
53113
|
return parts.join(" ");
|
|
52956
53114
|
}
|
|
52957
53115
|
}
|
|
53116
|
+
const globPattern = readFirstString(rawInput, ["glob_pattern"]);
|
|
53117
|
+
if (globPattern) {
|
|
53118
|
+
const targetDirectory = readFirstString(rawInput, ["target_directory"]);
|
|
53119
|
+
return targetDirectory ? `${globPattern} in ${targetDirectory}` : globPattern;
|
|
53120
|
+
}
|
|
53121
|
+
const mode = readFirstString(rawInput, ["target_mode_id", "mode_id"]);
|
|
53122
|
+
const explanation = readFirstString(rawInput, ["explanation"]);
|
|
53123
|
+
if (mode || explanation) {
|
|
53124
|
+
return mode && explanation ? `${mode}: ${explanation}` : mode ?? explanation;
|
|
53125
|
+
}
|
|
52958
53126
|
return readFirstString(rawInput, [
|
|
52959
53127
|
"path",
|
|
52960
53128
|
"file",
|
|
@@ -52968,6 +53136,7 @@ function summarizeToolInput(rawInput, title = "") {
|
|
|
52968
53136
|
"pattern",
|
|
52969
53137
|
"text",
|
|
52970
53138
|
"search",
|
|
53139
|
+
"working_directory",
|
|
52971
53140
|
"name",
|
|
52972
53141
|
"description"
|
|
52973
53142
|
]);
|
|
@@ -53074,7 +53243,7 @@ function isGenericToolTitle(kind, title) {
|
|
|
53074
53243
|
}
|
|
53075
53244
|
return false;
|
|
53076
53245
|
}
|
|
53077
|
-
var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END, USAGE_BREAKDOWN_FIELDS;
|
|
53246
|
+
var SENTENCE_TERMINAL_AT_END, PARAGRAPH_BOUNDARY_AT_END, PARAGRAPH_BOUNDARY_AT_START, LINE_BREAK_AT_END, LINE_BREAK_AT_START, PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END, CURSOR_TOOL_NAME_KEY = "_toolName", CURSOR_PLAN_TOOL_NAMES, CURSOR_SUBAGENT_TOOL_NAMES, USAGE_BREAKDOWN_FIELDS;
|
|
53078
53247
|
var init_streaming_prompt = __esm(() => {
|
|
53079
53248
|
init_background_followup();
|
|
53080
53249
|
init_tool_kind_emoji();
|
|
@@ -53084,6 +53253,15 @@ var init_streaming_prompt = __esm(() => {
|
|
|
53084
53253
|
LINE_BREAK_AT_END = /\r?\n[\t ]*$/;
|
|
53085
53254
|
LINE_BREAK_AT_START = /^[\t ]*\r?\n/;
|
|
53086
53255
|
PARTIAL_CRLF_PARAGRAPH_BOUNDARY_AT_END = /\r?\n[\t ]*\r$/;
|
|
53256
|
+
CURSOR_PLAN_TOOL_NAMES = new Set([
|
|
53257
|
+
"todowrite",
|
|
53258
|
+
"createplan",
|
|
53259
|
+
"updateplan",
|
|
53260
|
+
"plan",
|
|
53261
|
+
"updatetodos",
|
|
53262
|
+
"todoread"
|
|
53263
|
+
]);
|
|
53264
|
+
CURSOR_SUBAGENT_TOOL_NAMES = new Set(["task", "delegate", "runsubagent", "subagent"]);
|
|
53087
53265
|
USAGE_BREAKDOWN_FIELDS = [
|
|
53088
53266
|
["inputTokens", ["inputTokens", "input_tokens"]],
|
|
53089
53267
|
["outputTokens", ["outputTokens", "output_tokens"]],
|