@ganglion/xacpx 0.18.0 → 0.19.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 +617 -61
- package/dist/cli.js +2029 -1959
- package/dist/control/control-service.d.ts +2 -0
- package/dist/control/workspace-git.d.ts +3 -0
- package/package.json +1 -1
|
@@ -2633,6 +2633,561 @@ var init_prompt_media = __esm(() => {
|
|
|
2633
2633
|
};
|
|
2634
2634
|
});
|
|
2635
2635
|
|
|
2636
|
+
// src/transport/background-followup.ts
|
|
2637
|
+
import { access, open as open2, readFile, readdir, stat } from "node:fs/promises";
|
|
2638
|
+
import { constants as fsConstants } from "node:fs";
|
|
2639
|
+
import { homedir as homedir2 } from "node:os";
|
|
2640
|
+
import { basename, dirname as dirname2, join as join2 } from "node:path";
|
|
2641
|
+
function isAsyncAgentLaunch(event) {
|
|
2642
|
+
return isAsyncAgentLaunchOutput(event.rawOutput);
|
|
2643
|
+
}
|
|
2644
|
+
function isAsyncAgentLaunchOutput(rawOutput) {
|
|
2645
|
+
const candidate = typeof rawOutput === "string" ? tryParseJsonObject(rawOutput) ?? rawOutput : rawOutput;
|
|
2646
|
+
if (candidate && typeof candidate === "object" && !Array.isArray(candidate)) {
|
|
2647
|
+
const status = candidate.status;
|
|
2648
|
+
if (status !== undefined)
|
|
2649
|
+
return status === "async_launched";
|
|
2650
|
+
}
|
|
2651
|
+
return ASYNC_AGENT_LAUNCH.test(textOfUnknown(rawOutput));
|
|
2652
|
+
}
|
|
2653
|
+
function tryParseJsonObject(text) {
|
|
2654
|
+
if (!text.trimStart().startsWith("{"))
|
|
2655
|
+
return;
|
|
2656
|
+
try {
|
|
2657
|
+
const parsed = JSON.parse(text);
|
|
2658
|
+
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : undefined;
|
|
2659
|
+
} catch {
|
|
2660
|
+
return;
|
|
2661
|
+
}
|
|
2662
|
+
}
|
|
2663
|
+
function asyncAgentId(event) {
|
|
2664
|
+
const fromObject = findStringField(event.rawOutput, new Set(["agentId", "agent_id"]));
|
|
2665
|
+
if (fromObject)
|
|
2666
|
+
return fromObject;
|
|
2667
|
+
return /\bagent(?:Id|_id)["']?\s*[:=]\s*["']?([A-Za-z0-9_-]+)/i.exec(textOfUnknown(event.rawOutput))?.[1];
|
|
2668
|
+
}
|
|
2669
|
+
async function findNativeTranscriptPath(input) {
|
|
2670
|
+
const configDirName = input.driver === "qoder" ? ".qoder" : ".claude";
|
|
2671
|
+
const projectsDir = join2(input.homeDir ?? homedir2(), configDirName, "projects");
|
|
2672
|
+
const direct = join2(projectsDir, encodeClaudeProjectDirectory(input.cwd), `${input.sessionId}.jsonl`);
|
|
2673
|
+
if (await exists(direct))
|
|
2674
|
+
return direct;
|
|
2675
|
+
try {
|
|
2676
|
+
const entries = await readdir(projectsDir, { withFileTypes: true });
|
|
2677
|
+
for (const entry of entries) {
|
|
2678
|
+
if (!entry.isDirectory())
|
|
2679
|
+
continue;
|
|
2680
|
+
const candidate = join2(projectsDir, entry.name, `${input.sessionId}.jsonl`);
|
|
2681
|
+
if (await exists(candidate))
|
|
2682
|
+
return candidate;
|
|
2683
|
+
}
|
|
2684
|
+
} catch {
|
|
2685
|
+
return;
|
|
2686
|
+
}
|
|
2687
|
+
return;
|
|
2688
|
+
}
|
|
2689
|
+
async function followBackgroundTurn(options) {
|
|
2690
|
+
const transcriptPath = options.transcriptPath ?? await findNativeTranscriptPath(options);
|
|
2691
|
+
if (!transcriptPath) {
|
|
2692
|
+
return { status: "unavailable", completedToolCallIds: [], failedToolCallIds: [] };
|
|
2693
|
+
}
|
|
2694
|
+
let initial;
|
|
2695
|
+
try {
|
|
2696
|
+
initial = await readFile(transcriptPath);
|
|
2697
|
+
} catch {
|
|
2698
|
+
return { status: "unavailable", transcriptPath, completedToolCallIds: [], failedToolCallIds: [] };
|
|
2699
|
+
}
|
|
2700
|
+
const initialCompleteEnd = initial.lastIndexOf(10);
|
|
2701
|
+
const initialComplete = initial.subarray(0, initialCompleteEnd >= 0 ? initialCompleteEnd : 0).toString("utf8");
|
|
2702
|
+
const mainCursor = {
|
|
2703
|
+
offset: initial.length,
|
|
2704
|
+
partial: initialCompleteEnd >= 0 ? initial.subarray(initialCompleteEnd + 1).toString("utf8") : initial.toString("utf8")
|
|
2705
|
+
};
|
|
2706
|
+
const initialRecords = initialComplete.split(`
|
|
2707
|
+
`).map(parseRecord);
|
|
2708
|
+
const launched = new Set([...options.launchedToolCallIds].filter(Boolean));
|
|
2709
|
+
const completed = new Set;
|
|
2710
|
+
const failed = new Set;
|
|
2711
|
+
const toolEvents = new Map;
|
|
2712
|
+
for (const event of options.initialToolEvents ?? [])
|
|
2713
|
+
toolEvents.set(event.toolCallId, event);
|
|
2714
|
+
const parentToolCallIdByAgentId = new Map;
|
|
2715
|
+
for (const [toolCallId, agentId] of options.subagentIdsByToolCallId ?? []) {
|
|
2716
|
+
if (toolCallId && agentId)
|
|
2717
|
+
parentToolCallIdByAgentId.set(agentId, toolCallId);
|
|
2718
|
+
}
|
|
2719
|
+
const boundary = findPromptBoundary(initialRecords, launched);
|
|
2720
|
+
let launchSeen = boundary >= 0 || initialRecords.some((record) => hasTrackedLaunch(record, launched));
|
|
2721
|
+
let boundarySeen = boundary >= 0;
|
|
2722
|
+
let sequence = 0;
|
|
2723
|
+
let lastNotificationSequence = -1;
|
|
2724
|
+
let done = false;
|
|
2725
|
+
const emitTool = async (event) => {
|
|
2726
|
+
toolEvents.set(event.toolCallId, event);
|
|
2727
|
+
await options.onToolEvent?.(event);
|
|
2728
|
+
};
|
|
2729
|
+
const processRecord = async (record) => {
|
|
2730
|
+
if (!record)
|
|
2731
|
+
return;
|
|
2732
|
+
sequence += 1;
|
|
2733
|
+
const blocks = contentBlocks(record.message?.content);
|
|
2734
|
+
if (record.type === "user") {
|
|
2735
|
+
const userText = blocks.map(blockText).filter(Boolean).join(`
|
|
2736
|
+
`);
|
|
2737
|
+
for (const notification of taskNotifications(userText)) {
|
|
2738
|
+
if (launched.has(notification.toolCallId)) {
|
|
2739
|
+
completed.add(notification.toolCallId);
|
|
2740
|
+
if (notification.failed)
|
|
2741
|
+
failed.add(notification.toolCallId);
|
|
2742
|
+
lastNotificationSequence = sequence;
|
|
2743
|
+
const previous = toolEvents.get(notification.toolCallId);
|
|
2744
|
+
if (previous) {
|
|
2745
|
+
await emitTool({
|
|
2746
|
+
...previous,
|
|
2747
|
+
status: notification.failed ? "error" : "success",
|
|
2748
|
+
...notification.failed ? { rawOutput: { message: "background Agent failed" } } : {}
|
|
2749
|
+
});
|
|
2750
|
+
}
|
|
2751
|
+
}
|
|
2752
|
+
}
|
|
2753
|
+
for (const block of blocks) {
|
|
2754
|
+
if (readString(block, "type") !== "tool_result")
|
|
2755
|
+
continue;
|
|
2756
|
+
const toolCallId = readString(block, "tool_use_id");
|
|
2757
|
+
if (!toolCallId)
|
|
2758
|
+
continue;
|
|
2759
|
+
const output = blockText(block);
|
|
2760
|
+
if (ASYNC_AGENT_LAUNCH.test(output))
|
|
2761
|
+
launched.add(toolCallId);
|
|
2762
|
+
const previous = toolEvents.get(toolCallId);
|
|
2763
|
+
await emitTool({
|
|
2764
|
+
toolCallId,
|
|
2765
|
+
toolName: previous?.toolName ?? "Tool",
|
|
2766
|
+
kind: previous?.kind ?? "other",
|
|
2767
|
+
...previous?.parentToolCallId ? { parentToolCallId: previous.parentToolCallId } : {},
|
|
2768
|
+
...previous?.isSubagent ? { isSubagent: true } : {},
|
|
2769
|
+
...previous?.summary ? { summary: previous.summary } : {},
|
|
2770
|
+
...previous?.rawInput !== undefined ? { rawInput: previous.rawInput } : {},
|
|
2771
|
+
...output ? { rawOutput: output } : {},
|
|
2772
|
+
status: readBoolean(block, "is_error") ? "error" : "success"
|
|
2773
|
+
});
|
|
2774
|
+
}
|
|
2775
|
+
return;
|
|
2776
|
+
}
|
|
2777
|
+
if (record.type !== "assistant" || record.isSidechain === true)
|
|
2778
|
+
return;
|
|
2779
|
+
for (const block of blocks) {
|
|
2780
|
+
const type = readString(block, "type");
|
|
2781
|
+
if (type === "text") {
|
|
2782
|
+
const text = readString(block, "text");
|
|
2783
|
+
if (text)
|
|
2784
|
+
await options.onText?.(text);
|
|
2785
|
+
} else if (type === "thinking") {
|
|
2786
|
+
const thought = readString(block, "thinking");
|
|
2787
|
+
if (thought)
|
|
2788
|
+
await options.onThought?.(thought);
|
|
2789
|
+
} else if (type === "tool_use") {
|
|
2790
|
+
const toolCallId = readString(block, "id");
|
|
2791
|
+
if (!toolCallId)
|
|
2792
|
+
continue;
|
|
2793
|
+
const name = readString(block, "name") ?? "Tool";
|
|
2794
|
+
const rawInput = block.input;
|
|
2795
|
+
const event = {
|
|
2796
|
+
toolCallId,
|
|
2797
|
+
toolName: name,
|
|
2798
|
+
kind: classifyToolKind(name),
|
|
2799
|
+
...toolSummary(rawInput) ? { summary: toolSummary(rawInput) } : {},
|
|
2800
|
+
...rawInput !== undefined ? { rawInput } : {},
|
|
2801
|
+
status: "running"
|
|
2802
|
+
};
|
|
2803
|
+
await emitTool(event);
|
|
2804
|
+
}
|
|
2805
|
+
}
|
|
2806
|
+
if (record.message?.stop_reason === "end_turn" && launched.size > 0 && [...launched].every((id) => completed.has(id)) && lastNotificationSequence >= 0 && sequence > lastNotificationSequence) {
|
|
2807
|
+
done = true;
|
|
2808
|
+
}
|
|
2809
|
+
};
|
|
2810
|
+
const processAfterBoundary = async (record) => {
|
|
2811
|
+
if (!record)
|
|
2812
|
+
return;
|
|
2813
|
+
if (!boundarySeen) {
|
|
2814
|
+
if (hasTrackedLaunch(record, launched))
|
|
2815
|
+
launchSeen = true;
|
|
2816
|
+
if (launchSeen && isMainEndTurn(record))
|
|
2817
|
+
boundarySeen = true;
|
|
2818
|
+
return;
|
|
2819
|
+
}
|
|
2820
|
+
await processRecord(record);
|
|
2821
|
+
};
|
|
2822
|
+
const processSubagentRecord = async (record, parentToolCallId) => {
|
|
2823
|
+
if (!record)
|
|
2824
|
+
return;
|
|
2825
|
+
const blocks = contentBlocks(record.message?.content);
|
|
2826
|
+
if (record.type === "assistant") {
|
|
2827
|
+
for (const block of blocks) {
|
|
2828
|
+
if (readString(block, "type") !== "tool_use")
|
|
2829
|
+
continue;
|
|
2830
|
+
const toolCallId = readString(block, "id");
|
|
2831
|
+
if (!toolCallId)
|
|
2832
|
+
continue;
|
|
2833
|
+
const name = readString(block, "name") ?? "Tool";
|
|
2834
|
+
const rawInput = block.input;
|
|
2835
|
+
const previous = toolEvents.get(toolCallId);
|
|
2836
|
+
await emitTool({
|
|
2837
|
+
...previous,
|
|
2838
|
+
toolCallId,
|
|
2839
|
+
parentToolCallId: previous?.parentToolCallId ?? parentToolCallId,
|
|
2840
|
+
...previous?.isSubagent || isAgentToolName(name) ? { isSubagent: true } : {},
|
|
2841
|
+
toolName: previous?.toolName ?? name,
|
|
2842
|
+
kind: previous?.kind ?? classifyToolKind(name),
|
|
2843
|
+
...previous?.summary ? { summary: previous.summary } : toolSummary(rawInput) ? { summary: toolSummary(rawInput) } : {},
|
|
2844
|
+
...previous?.rawInput !== undefined ? { rawInput: previous.rawInput } : rawInput !== undefined ? { rawInput } : {},
|
|
2845
|
+
status: previous?.status === "success" || previous?.status === "error" ? previous.status : "running"
|
|
2846
|
+
});
|
|
2847
|
+
}
|
|
2848
|
+
return;
|
|
2849
|
+
}
|
|
2850
|
+
if (record.type !== "user")
|
|
2851
|
+
return;
|
|
2852
|
+
for (const block of blocks) {
|
|
2853
|
+
if (readString(block, "type") !== "tool_result")
|
|
2854
|
+
continue;
|
|
2855
|
+
const toolCallId = readString(block, "tool_use_id");
|
|
2856
|
+
if (!toolCallId)
|
|
2857
|
+
continue;
|
|
2858
|
+
const previous = toolEvents.get(toolCallId);
|
|
2859
|
+
const output = blockText(block);
|
|
2860
|
+
const event = {
|
|
2861
|
+
...previous,
|
|
2862
|
+
toolCallId,
|
|
2863
|
+
parentToolCallId: previous?.parentToolCallId ?? parentToolCallId,
|
|
2864
|
+
...previous?.isSubagent ? { isSubagent: true } : {},
|
|
2865
|
+
toolName: previous?.toolName ?? "Tool",
|
|
2866
|
+
kind: previous?.kind ?? "other",
|
|
2867
|
+
...previous?.summary ? { summary: previous.summary } : {},
|
|
2868
|
+
...previous?.rawInput !== undefined ? { rawInput: previous.rawInput } : {},
|
|
2869
|
+
...previous?.rawOutput !== undefined ? { rawOutput: previous.rawOutput } : output ? { rawOutput: output } : {},
|
|
2870
|
+
status: readBoolean(block, "is_error") || previous?.status === "error" ? "error" : "success"
|
|
2871
|
+
};
|
|
2872
|
+
if (event.isSubagent && isAsyncAgentLaunch(event)) {
|
|
2873
|
+
const agentId = asyncAgentId(event);
|
|
2874
|
+
if (agentId)
|
|
2875
|
+
parentToolCallIdByAgentId.set(agentId, event.toolCallId);
|
|
2876
|
+
}
|
|
2877
|
+
await emitTool(event);
|
|
2878
|
+
}
|
|
2879
|
+
};
|
|
2880
|
+
const subagentCursors = new Map;
|
|
2881
|
+
const processSubagentTranscripts = async () => {
|
|
2882
|
+
const transcripts = await findSubagentTranscripts(transcriptPath);
|
|
2883
|
+
let advanced = false;
|
|
2884
|
+
let discoveredNestedAgent = true;
|
|
2885
|
+
while (discoveredNestedAgent) {
|
|
2886
|
+
const mappedAgentCount = parentToolCallIdByAgentId.size;
|
|
2887
|
+
for (const subagent of transcripts) {
|
|
2888
|
+
const parentToolCallId = parentToolCallIdByAgentId.get(subagent.agentId);
|
|
2889
|
+
if (!parentToolCallId)
|
|
2890
|
+
continue;
|
|
2891
|
+
const cursor = subagentCursors.get(subagent.path) ?? { offset: 0, partial: "" };
|
|
2892
|
+
const previousOffset = cursor.offset;
|
|
2893
|
+
const lines = await readJsonlDelta(subagent.path, cursor);
|
|
2894
|
+
if (cursor.offset !== previousOffset)
|
|
2895
|
+
advanced = true;
|
|
2896
|
+
subagentCursors.set(subagent.path, cursor);
|
|
2897
|
+
for (const line of lines)
|
|
2898
|
+
await processSubagentRecord(parseRecord(line), parentToolCallId);
|
|
2899
|
+
}
|
|
2900
|
+
discoveredNestedAgent = parentToolCallIdByAgentId.size > mappedAgentCount;
|
|
2901
|
+
}
|
|
2902
|
+
return advanced;
|
|
2903
|
+
};
|
|
2904
|
+
await processSubagentTranscripts();
|
|
2905
|
+
if (boundary >= 0) {
|
|
2906
|
+
for (const record of initialRecords.slice(boundary + 1)) {
|
|
2907
|
+
await processRecord(record);
|
|
2908
|
+
if (done)
|
|
2909
|
+
break;
|
|
2910
|
+
}
|
|
2911
|
+
}
|
|
2912
|
+
const startedAt = Date.now();
|
|
2913
|
+
const pollIntervalMs = options.pollIntervalMs ?? DEFAULT_POLL_INTERVAL_MS;
|
|
2914
|
+
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
2915
|
+
while (!done) {
|
|
2916
|
+
throwIfAborted(options.signal);
|
|
2917
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
2918
|
+
return {
|
|
2919
|
+
status: "timeout",
|
|
2920
|
+
transcriptPath,
|
|
2921
|
+
completedToolCallIds: [...completed],
|
|
2922
|
+
failedToolCallIds: [...failed]
|
|
2923
|
+
};
|
|
2924
|
+
}
|
|
2925
|
+
await waitForPoll(pollIntervalMs, options.signal);
|
|
2926
|
+
await processSubagentTranscripts();
|
|
2927
|
+
const lines = await readJsonlDelta(transcriptPath, mainCursor);
|
|
2928
|
+
for (const line of lines) {
|
|
2929
|
+
await processAfterBoundary(parseRecord(line));
|
|
2930
|
+
if (done)
|
|
2931
|
+
break;
|
|
2932
|
+
}
|
|
2933
|
+
}
|
|
2934
|
+
if (parentToolCallIdByAgentId.size > 0) {
|
|
2935
|
+
let stablePolls = 0;
|
|
2936
|
+
for (let poll = 0;poll < FINAL_SUBAGENT_DRAIN_MAX_POLLS && stablePolls < FINAL_SUBAGENT_DRAIN_STABLE_POLLS; poll += 1) {
|
|
2937
|
+
await waitForPoll(pollIntervalMs, options.signal);
|
|
2938
|
+
stablePolls = await processSubagentTranscripts() ? 0 : stablePolls + 1;
|
|
2939
|
+
}
|
|
2940
|
+
}
|
|
2941
|
+
return {
|
|
2942
|
+
status: "completed",
|
|
2943
|
+
transcriptPath,
|
|
2944
|
+
completedToolCallIds: [...completed],
|
|
2945
|
+
failedToolCallIds: [...failed]
|
|
2946
|
+
};
|
|
2947
|
+
}
|
|
2948
|
+
async function readJsonlDelta(path2, cursor) {
|
|
2949
|
+
let size;
|
|
2950
|
+
try {
|
|
2951
|
+
size = (await stat(path2)).size;
|
|
2952
|
+
} catch {
|
|
2953
|
+
return [];
|
|
2954
|
+
}
|
|
2955
|
+
if (size < cursor.offset) {
|
|
2956
|
+
cursor.offset = 0;
|
|
2957
|
+
cursor.partial = "";
|
|
2958
|
+
}
|
|
2959
|
+
if (size <= cursor.offset)
|
|
2960
|
+
return [];
|
|
2961
|
+
let chunk;
|
|
2962
|
+
try {
|
|
2963
|
+
const handle = await open2(path2, "r");
|
|
2964
|
+
try {
|
|
2965
|
+
chunk = Buffer.alloc(size - cursor.offset);
|
|
2966
|
+
const result = await handle.read(chunk, 0, chunk.length, cursor.offset);
|
|
2967
|
+
chunk = chunk.subarray(0, result.bytesRead);
|
|
2968
|
+
} finally {
|
|
2969
|
+
await handle.close();
|
|
2970
|
+
}
|
|
2971
|
+
} catch {
|
|
2972
|
+
return [];
|
|
2973
|
+
}
|
|
2974
|
+
cursor.offset += chunk.length;
|
|
2975
|
+
cursor.partial += chunk.toString("utf8");
|
|
2976
|
+
const lines = cursor.partial.split(`
|
|
2977
|
+
`);
|
|
2978
|
+
cursor.partial = lines.pop() ?? "";
|
|
2979
|
+
return lines;
|
|
2980
|
+
}
|
|
2981
|
+
function findPromptBoundary(records, launched) {
|
|
2982
|
+
let launchIndex = -1;
|
|
2983
|
+
for (let index = 0;index < records.length; index += 1) {
|
|
2984
|
+
const record = records[index];
|
|
2985
|
+
if (record?.type !== "assistant" || record.isSidechain === true)
|
|
2986
|
+
continue;
|
|
2987
|
+
for (const block of contentBlocks(record.message?.content)) {
|
|
2988
|
+
if (readString(block, "type") === "tool_use" && launched.has(readString(block, "id") ?? "")) {
|
|
2989
|
+
launchIndex = index;
|
|
2990
|
+
}
|
|
2991
|
+
}
|
|
2992
|
+
}
|
|
2993
|
+
if (launchIndex < 0)
|
|
2994
|
+
return -1;
|
|
2995
|
+
for (let index = launchIndex + 1;index < records.length; index += 1) {
|
|
2996
|
+
const record = records[index];
|
|
2997
|
+
if (record?.type === "assistant" && record.isSidechain !== true && record.message?.stop_reason === "end_turn") {
|
|
2998
|
+
return index;
|
|
2999
|
+
}
|
|
3000
|
+
}
|
|
3001
|
+
return -1;
|
|
3002
|
+
}
|
|
3003
|
+
function hasTrackedLaunch(record, launched) {
|
|
3004
|
+
if (record?.type !== "assistant" || record.isSidechain === true)
|
|
3005
|
+
return false;
|
|
3006
|
+
return contentBlocks(record.message?.content).some((block) => readString(block, "type") === "tool_use" && launched.has(readString(block, "id") ?? ""));
|
|
3007
|
+
}
|
|
3008
|
+
function isMainEndTurn(record) {
|
|
3009
|
+
return record.type === "assistant" && record.isSidechain !== true && record.message?.stop_reason === "end_turn";
|
|
3010
|
+
}
|
|
3011
|
+
function parseRecord(line) {
|
|
3012
|
+
if (!line.trim())
|
|
3013
|
+
return;
|
|
3014
|
+
try {
|
|
3015
|
+
return JSON.parse(line);
|
|
3016
|
+
} catch {
|
|
3017
|
+
return;
|
|
3018
|
+
}
|
|
3019
|
+
}
|
|
3020
|
+
function contentBlocks(content) {
|
|
3021
|
+
if (typeof content === "string")
|
|
3022
|
+
return [{ type: "text", text: content }];
|
|
3023
|
+
return Array.isArray(content) ? content.filter((block) => !!block && typeof block === "object") : [];
|
|
3024
|
+
}
|
|
3025
|
+
function blockText(block) {
|
|
3026
|
+
if (typeof block.text === "string")
|
|
3027
|
+
return block.text;
|
|
3028
|
+
if (typeof block.content === "string")
|
|
3029
|
+
return block.content;
|
|
3030
|
+
if (Array.isArray(block.content))
|
|
3031
|
+
return block.content.map((item) => textOfUnknown(item)).filter(Boolean).join(`
|
|
3032
|
+
`);
|
|
3033
|
+
return textOfUnknown(block.content);
|
|
3034
|
+
}
|
|
3035
|
+
function textOfUnknown(value) {
|
|
3036
|
+
if (typeof value === "string")
|
|
3037
|
+
return value;
|
|
3038
|
+
if (Array.isArray(value))
|
|
3039
|
+
return value.map(textOfUnknown).filter(Boolean).join(`
|
|
3040
|
+
`);
|
|
3041
|
+
if (!value || typeof value !== "object")
|
|
3042
|
+
return "";
|
|
3043
|
+
const object = value;
|
|
3044
|
+
if (typeof object.text === "string")
|
|
3045
|
+
return object.text;
|
|
3046
|
+
if (object.content !== undefined)
|
|
3047
|
+
return textOfUnknown(object.content);
|
|
3048
|
+
try {
|
|
3049
|
+
return JSON.stringify(value);
|
|
3050
|
+
} catch {
|
|
3051
|
+
return "";
|
|
3052
|
+
}
|
|
3053
|
+
}
|
|
3054
|
+
function findStringField(value, keys) {
|
|
3055
|
+
if (!value || typeof value !== "object")
|
|
3056
|
+
return;
|
|
3057
|
+
if (Array.isArray(value)) {
|
|
3058
|
+
for (const item of value) {
|
|
3059
|
+
const found = findStringField(item, keys);
|
|
3060
|
+
if (found)
|
|
3061
|
+
return found;
|
|
3062
|
+
}
|
|
3063
|
+
return;
|
|
3064
|
+
}
|
|
3065
|
+
const object = value;
|
|
3066
|
+
for (const key of keys) {
|
|
3067
|
+
const candidate = object[key];
|
|
3068
|
+
if (typeof candidate === "string" && candidate.trim())
|
|
3069
|
+
return candidate.trim();
|
|
3070
|
+
}
|
|
3071
|
+
for (const candidate of Object.values(object)) {
|
|
3072
|
+
const found = findStringField(candidate, keys);
|
|
3073
|
+
if (found)
|
|
3074
|
+
return found;
|
|
3075
|
+
}
|
|
3076
|
+
return;
|
|
3077
|
+
}
|
|
3078
|
+
function taskNotifications(text) {
|
|
3079
|
+
const notifications = [];
|
|
3080
|
+
const blocks = [...text.matchAll(/<task-notification>([\s\S]*?)<\/task-notification>/gi)].map((match) => match[1] ?? "");
|
|
3081
|
+
for (const block of blocks.length > 0 ? blocks : [text]) {
|
|
3082
|
+
const toolCallId = /<tool-use-id>([^<]+)<\/tool-use-id>/i.exec(block)?.[1]?.trim();
|
|
3083
|
+
if (!toolCallId)
|
|
3084
|
+
continue;
|
|
3085
|
+
const status = /<status>([^<]+)<\/status>/i.exec(block)?.[1]?.trim().toLowerCase();
|
|
3086
|
+
notifications.push({
|
|
3087
|
+
toolCallId,
|
|
3088
|
+
failed: status === "failed" || status === "error" || status === "cancelled" || status === "canceled"
|
|
3089
|
+
});
|
|
3090
|
+
}
|
|
3091
|
+
return notifications;
|
|
3092
|
+
}
|
|
3093
|
+
function classifyToolKind(name) {
|
|
3094
|
+
const normalized = name.toLowerCase();
|
|
3095
|
+
if (/(read|view|open)/.test(normalized))
|
|
3096
|
+
return "read";
|
|
3097
|
+
if (/(grep|search|find|glob)/.test(normalized))
|
|
3098
|
+
return "search";
|
|
3099
|
+
if (/(edit|write|patch|replace|create)/.test(normalized))
|
|
3100
|
+
return "edit";
|
|
3101
|
+
if (/(bash|shell|exec|run|terminal|command)/.test(normalized))
|
|
3102
|
+
return "execute";
|
|
3103
|
+
if (/(think|reason|plan|agent|task)/.test(normalized))
|
|
3104
|
+
return "think";
|
|
3105
|
+
return "other";
|
|
3106
|
+
}
|
|
3107
|
+
function isAgentToolName(name) {
|
|
3108
|
+
const normalized = name.trim().toLowerCase();
|
|
3109
|
+
return normalized === "agent" || normalized === "task";
|
|
3110
|
+
}
|
|
3111
|
+
async function findSubagentTranscripts(transcriptPath) {
|
|
3112
|
+
const sessionDir = join2(dirname2(transcriptPath), basename(transcriptPath, ".jsonl"), "subagents");
|
|
3113
|
+
const found = [];
|
|
3114
|
+
const visit = async (directory) => {
|
|
3115
|
+
let entries;
|
|
3116
|
+
try {
|
|
3117
|
+
entries = await readdir(directory, { withFileTypes: true });
|
|
3118
|
+
} catch {
|
|
3119
|
+
return;
|
|
3120
|
+
}
|
|
3121
|
+
for (const entry of entries) {
|
|
3122
|
+
const path2 = join2(directory, entry.name);
|
|
3123
|
+
if (entry.isDirectory()) {
|
|
3124
|
+
await visit(path2);
|
|
3125
|
+
} else if (entry.isFile() && entry.name.startsWith("agent-") && entry.name.endsWith(".jsonl")) {
|
|
3126
|
+
found.push({ agentId: entry.name.slice("agent-".length, -".jsonl".length), path: path2 });
|
|
3127
|
+
}
|
|
3128
|
+
}
|
|
3129
|
+
};
|
|
3130
|
+
await visit(sessionDir);
|
|
3131
|
+
return found;
|
|
3132
|
+
}
|
|
3133
|
+
function toolSummary(input) {
|
|
3134
|
+
if (!input || typeof input !== "object")
|
|
3135
|
+
return;
|
|
3136
|
+
const object = input;
|
|
3137
|
+
for (const key of ["description", "summary", "path", "file_path", "query", "pattern", "command"]) {
|
|
3138
|
+
if (typeof object[key] === "string" && object[key].trim())
|
|
3139
|
+
return object[key].trim();
|
|
3140
|
+
}
|
|
3141
|
+
return;
|
|
3142
|
+
}
|
|
3143
|
+
function readString(object, key) {
|
|
3144
|
+
if (!object || typeof object !== "object")
|
|
3145
|
+
return;
|
|
3146
|
+
const value = object[key];
|
|
3147
|
+
return typeof value === "string" ? value : undefined;
|
|
3148
|
+
}
|
|
3149
|
+
function readBoolean(object, key) {
|
|
3150
|
+
return !!object && typeof object === "object" && object[key] === true;
|
|
3151
|
+
}
|
|
3152
|
+
function encodeClaudeProjectDirectory(cwd) {
|
|
3153
|
+
return cwd.replace(/[:\\/]/g, "-");
|
|
3154
|
+
}
|
|
3155
|
+
async function exists(path2) {
|
|
3156
|
+
try {
|
|
3157
|
+
await access(path2, fsConstants.R_OK);
|
|
3158
|
+
return true;
|
|
3159
|
+
} catch {
|
|
3160
|
+
return false;
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
function throwIfAborted(signal) {
|
|
3164
|
+
if (signal?.aborted)
|
|
3165
|
+
throw new DOMException("background follow-up aborted", "AbortError");
|
|
3166
|
+
}
|
|
3167
|
+
async function waitForPoll(ms, signal) {
|
|
3168
|
+
if (!signal) {
|
|
3169
|
+
await new Promise((resolve2) => setTimeout(resolve2, ms));
|
|
3170
|
+
return;
|
|
3171
|
+
}
|
|
3172
|
+
throwIfAborted(signal);
|
|
3173
|
+
await new Promise((resolve2, reject) => {
|
|
3174
|
+
const timer = setTimeout(() => {
|
|
3175
|
+
signal.removeEventListener("abort", onAbort);
|
|
3176
|
+
resolve2();
|
|
3177
|
+
}, ms);
|
|
3178
|
+
const onAbort = () => {
|
|
3179
|
+
clearTimeout(timer);
|
|
3180
|
+
reject(new DOMException("background follow-up aborted", "AbortError"));
|
|
3181
|
+
};
|
|
3182
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
3183
|
+
});
|
|
3184
|
+
}
|
|
3185
|
+
var DEFAULT_POLL_INTERVAL_MS = 250, DEFAULT_TIMEOUT_MS, FINAL_SUBAGENT_DRAIN_MAX_POLLS = 4, FINAL_SUBAGENT_DRAIN_STABLE_POLLS = 2, ASYNC_AGENT_LAUNCH;
|
|
3186
|
+
var init_background_followup = __esm(() => {
|
|
3187
|
+
DEFAULT_TIMEOUT_MS = 30 * 60 * 1000;
|
|
3188
|
+
ASYNC_AGENT_LAUNCH = /Async agent launched successfully|["']?status["']?\s*:\s*["']async_launched["']/i;
|
|
3189
|
+
});
|
|
3190
|
+
|
|
2636
3191
|
// src/transport/tool-event-mode.ts
|
|
2637
3192
|
function resolveToolEventMode(input) {
|
|
2638
3193
|
if (input?.toolEventMode !== undefined) {
|
|
@@ -2822,7 +3377,7 @@ function formatToolCallEvent(update, sessionUpdate) {
|
|
|
2822
3377
|
return null;
|
|
2823
3378
|
const emoji = TOOL_KIND_EMOJI[kind] ?? DEFAULT_TOOL_EMOJI;
|
|
2824
3379
|
const inputSummary = summarizeToolInput(update.rawInput, title) || summarizeToolInput(update.rawOutput, title);
|
|
2825
|
-
const status =
|
|
3380
|
+
const status = readString2(update, "status");
|
|
2826
3381
|
if (!inputSummary && status === "pending")
|
|
2827
3382
|
return null;
|
|
2828
3383
|
if (!inputSummary && isGenericToolTitle(kind, title))
|
|
@@ -2894,13 +3449,13 @@ function buildToolUseEvent(update, driver) {
|
|
|
2894
3449
|
const toolName = title || "Tool";
|
|
2895
3450
|
const summaryRaw = summarizeToolInput(update.rawInput, title) || summarizeToolInput(update.rawOutput, title);
|
|
2896
3451
|
const summary = summaryRaw && summaryRaw !== title ? summaryRaw : undefined;
|
|
2897
|
-
const statusRaw =
|
|
3452
|
+
const statusRaw = readString2(update, "status");
|
|
2898
3453
|
const isClaudeDriver = driver === undefined || driver === "claude";
|
|
2899
3454
|
const claudeMeta = isClaudeDriver ? update._meta?.claudeCode : undefined;
|
|
2900
3455
|
const claudeToolResponse = claudeMeta?.toolResponse;
|
|
2901
3456
|
const hasClaudeToolResponse = !isEmptyToolField(claudeToolResponse);
|
|
2902
|
-
const
|
|
2903
|
-
const status =
|
|
3457
|
+
const isAsyncAgentLaunch2 = update._meta?.claudeCode?.toolName === "Agent" && isRecord2(claudeToolResponse) && claudeToolResponse.status === "async_launched" || driver === "qoder" && update._meta?.qoder?.toolName === "Agent" && isAsyncAgentLaunchOutput(update.rawOutput);
|
|
3458
|
+
const status = isAsyncAgentLaunch2 ? "running" : statusRaw === "completed" || statusRaw === "success" ? "success" : statusRaw === "failed" || statusRaw === "error" ? "error" : hasClaudeToolResponse ? "success" : "running";
|
|
2904
3459
|
const rawInput = update.rawInput;
|
|
2905
3460
|
const content = update.content;
|
|
2906
3461
|
const rawOutput = update.rawOutput ?? claudeToolResponse;
|
|
@@ -3029,7 +3584,7 @@ function normalizeUsageCost(value) {
|
|
|
3029
3584
|
if (!isRecord2(value))
|
|
3030
3585
|
return;
|
|
3031
3586
|
const amount = asFiniteNumber(value.amount);
|
|
3032
|
-
const currency =
|
|
3587
|
+
const currency = readString2(value, "currency");
|
|
3033
3588
|
if (amount === undefined && !currency)
|
|
3034
3589
|
return;
|
|
3035
3590
|
return { ...amount !== undefined ? { amount } : {}, ...currency ? { currency } : {} };
|
|
@@ -3041,10 +3596,10 @@ function normalizeAgentCommands(value) {
|
|
|
3041
3596
|
for (const entry of value) {
|
|
3042
3597
|
if (!isRecord2(entry))
|
|
3043
3598
|
continue;
|
|
3044
|
-
const name =
|
|
3599
|
+
const name = readString2(entry, "name");
|
|
3045
3600
|
if (!name)
|
|
3046
3601
|
continue;
|
|
3047
|
-
const description =
|
|
3602
|
+
const description = readString2(entry, "description");
|
|
3048
3603
|
out.push({ name, ...description ? { description } : {}, hasInput: entry.input != null });
|
|
3049
3604
|
}
|
|
3050
3605
|
return out;
|
|
@@ -3052,7 +3607,7 @@ function normalizeAgentCommands(value) {
|
|
|
3052
3607
|
function isRecord2(value) {
|
|
3053
3608
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
3054
3609
|
}
|
|
3055
|
-
function
|
|
3610
|
+
function readString2(rawInput, key) {
|
|
3056
3611
|
if (!isRecord2(rawInput))
|
|
3057
3612
|
return;
|
|
3058
3613
|
const value = rawInput[key];
|
|
@@ -3076,6 +3631,7 @@ function isGenericToolTitle(kind, title) {
|
|
|
3076
3631
|
}
|
|
3077
3632
|
var USAGE_BREAKDOWN_FIELDS;
|
|
3078
3633
|
var init_streaming_prompt = __esm(() => {
|
|
3634
|
+
init_background_followup();
|
|
3079
3635
|
init_tool_kind_emoji();
|
|
3080
3636
|
USAGE_BREAKDOWN_FIELDS = [
|
|
3081
3637
|
["inputTokens", ["inputTokens", "input_tokens"]],
|
|
@@ -3097,22 +3653,22 @@ function isModelNotAdvertisedError(text) {
|
|
|
3097
3653
|
// src/recovery/discover-parent-package-paths.ts
|
|
3098
3654
|
import { spawn as spawn2 } from "node:child_process";
|
|
3099
3655
|
import { createRequire as createRequire2 } from "node:module";
|
|
3100
|
-
import { access } from "node:fs/promises";
|
|
3101
|
-
import { homedir as
|
|
3102
|
-
import { dirname as
|
|
3656
|
+
import { access as access2 } from "node:fs/promises";
|
|
3657
|
+
import { homedir as homedir3 } from "node:os";
|
|
3658
|
+
import { dirname as dirname3, join as join3 } from "node:path";
|
|
3103
3659
|
function deriveParentPackageName(platformPackage) {
|
|
3104
3660
|
return platformPackage.replace(/-(?:linux|darwin|win32|windows|freebsd|openbsd|sunos|aix)(?:-(?:x64|arm64|ia32|arm|ppc64|s390x))?(?:-(?:baseline|musl|gnu|gnueabihf|musleabihf|msvc))?$/, "");
|
|
3105
3661
|
}
|
|
3106
3662
|
async function discoverParentPackagePaths(platformPackage, seedPath, deps = {}) {
|
|
3107
3663
|
const env = deps.env ?? process.env;
|
|
3108
|
-
const home = deps.home ??
|
|
3664
|
+
const home = deps.home ?? homedir3();
|
|
3109
3665
|
const cwd = deps.cwd ?? process.cwd();
|
|
3110
3666
|
const fsExists = deps.fsExists ?? defaultFsExists;
|
|
3111
3667
|
const resolveFromCwd = deps.resolveFromCwd ?? defaultResolveFromCwd;
|
|
3112
3668
|
const queryRoot = deps.queryPackageManagerRoot ?? defaultQueryPackageManagerRoot;
|
|
3113
3669
|
const parentName = deriveParentPackageName(platformPackage);
|
|
3114
3670
|
const rawCandidates = [];
|
|
3115
|
-
const bunGlobalRoot = env.BUN_INSTALL ?
|
|
3671
|
+
const bunGlobalRoot = env.BUN_INSTALL ? join3(env.BUN_INSTALL, "install", "global", "node_modules") : join3(home, ".bun", "install", "global", "node_modules");
|
|
3116
3672
|
const [npmRoot, pnpmRoot, yarnRoot] = await Promise.all([
|
|
3117
3673
|
queryRoot("npm"),
|
|
3118
3674
|
queryRoot("pnpm"),
|
|
@@ -3135,20 +3691,20 @@ async function discoverParentPackagePaths(platformPackage, seedPath, deps = {})
|
|
|
3135
3691
|
if (resolved)
|
|
3136
3692
|
rawCandidates.push({ path: resolved, manager: classify(resolved) });
|
|
3137
3693
|
}
|
|
3138
|
-
rawCandidates.push({ path:
|
|
3694
|
+
rawCandidates.push({ path: join3(bunGlobalRoot, parentName), manager: "bun" });
|
|
3139
3695
|
if (npmRoot)
|
|
3140
|
-
rawCandidates.push({ path:
|
|
3696
|
+
rawCandidates.push({ path: join3(npmRoot, parentName), manager: "npm" });
|
|
3141
3697
|
if (pnpmRoot)
|
|
3142
|
-
rawCandidates.push({ path:
|
|
3698
|
+
rawCandidates.push({ path: join3(pnpmRoot, parentName), manager: "pnpm" });
|
|
3143
3699
|
if (yarnRoot)
|
|
3144
|
-
rawCandidates.push({ path:
|
|
3700
|
+
rawCandidates.push({ path: join3(yarnRoot, parentName), manager: "yarn" });
|
|
3145
3701
|
const seen = new Set;
|
|
3146
3702
|
const verified = [];
|
|
3147
3703
|
for (const candidate of rawCandidates) {
|
|
3148
3704
|
if (seen.has(candidate.path))
|
|
3149
3705
|
continue;
|
|
3150
3706
|
seen.add(candidate.path);
|
|
3151
|
-
if (await fsExists(
|
|
3707
|
+
if (await fsExists(join3(candidate.path, "package.json"))) {
|
|
3152
3708
|
verified.push(candidate);
|
|
3153
3709
|
}
|
|
3154
3710
|
}
|
|
@@ -3161,7 +3717,7 @@ function isUnder(child, parent) {
|
|
|
3161
3717
|
}
|
|
3162
3718
|
async function defaultFsExists(path2) {
|
|
3163
3719
|
try {
|
|
3164
|
-
await
|
|
3720
|
+
await access2(path2);
|
|
3165
3721
|
return true;
|
|
3166
3722
|
} catch {
|
|
3167
3723
|
return false;
|
|
@@ -3172,7 +3728,7 @@ function defaultResolveFromCwd(name, cwd) {
|
|
|
3172
3728
|
const pkgJson = require2.resolve(`${name}/package.json`, {
|
|
3173
3729
|
paths: [cwd, ...require2.resolve.paths(name) ?? []]
|
|
3174
3730
|
});
|
|
3175
|
-
return
|
|
3731
|
+
return dirname3(pkgJson);
|
|
3176
3732
|
} catch {
|
|
3177
3733
|
return null;
|
|
3178
3734
|
}
|
|
@@ -3219,7 +3775,7 @@ async function defaultQueryPackageManagerRoot(tool) {
|
|
|
3219
3775
|
const trimmed = stdout.trim().split(/\r?\n/).pop()?.trim() ?? "";
|
|
3220
3776
|
if (!trimmed)
|
|
3221
3777
|
return done(null);
|
|
3222
|
-
done(spec.postfix ?
|
|
3778
|
+
done(spec.postfix ? join3(trimmed, spec.postfix) : trimmed);
|
|
3223
3779
|
});
|
|
3224
3780
|
});
|
|
3225
3781
|
}
|
|
@@ -5537,9 +6093,9 @@ var PRIMARY_PREFIX = "XACPX_", LEGACY_PREFIX = "WEACPX_";
|
|
|
5537
6093
|
// src/transport/acpx-queue-owner-launcher.ts
|
|
5538
6094
|
import { createHash as createHash2 } from "node:crypto";
|
|
5539
6095
|
import { spawn as spawn3 } from "node:child_process";
|
|
5540
|
-
import { readFile, unlink } from "node:fs/promises";
|
|
5541
|
-
import { homedir as
|
|
5542
|
-
import { join as
|
|
6096
|
+
import { readFile as readFile2, unlink } from "node:fs/promises";
|
|
6097
|
+
import { homedir as homedir4 } from "node:os";
|
|
6098
|
+
import { join as join4 } from "node:path";
|
|
5543
6099
|
function buildXacpxMcpServerSpec(input) {
|
|
5544
6100
|
const { command, args } = splitCommandLine(input.xacpxCommand);
|
|
5545
6101
|
return {
|
|
@@ -5701,7 +6257,7 @@ function createDefaultQueueOwnerTerminator(_acpxCommand) {
|
|
|
5701
6257
|
async function readQueueOwnerPid(sessionId) {
|
|
5702
6258
|
let owner;
|
|
5703
6259
|
try {
|
|
5704
|
-
owner = JSON.parse(await
|
|
6260
|
+
owner = JSON.parse(await readFile2(queueLockFilePath(sessionId), "utf8"));
|
|
5705
6261
|
} catch {
|
|
5706
6262
|
return;
|
|
5707
6263
|
}
|
|
@@ -5714,7 +6270,7 @@ async function terminateAcpxQueueOwner(sessionId) {
|
|
|
5714
6270
|
const lockPath = queueLockFilePath(sessionId);
|
|
5715
6271
|
let owner;
|
|
5716
6272
|
try {
|
|
5717
|
-
owner = JSON.parse(await
|
|
6273
|
+
owner = JSON.parse(await readFile2(lockPath, "utf8"));
|
|
5718
6274
|
} catch {
|
|
5719
6275
|
return;
|
|
5720
6276
|
}
|
|
@@ -5724,7 +6280,7 @@ async function terminateAcpxQueueOwner(sessionId) {
|
|
|
5724
6280
|
await unlink(lockPath).catch(() => {});
|
|
5725
6281
|
}
|
|
5726
6282
|
function queueLockFilePath(sessionId) {
|
|
5727
|
-
return
|
|
6283
|
+
return join4(homedir4(), ".acpx", "queues", `${shortHash(sessionId, 24)}.lock`);
|
|
5728
6284
|
}
|
|
5729
6285
|
function shortHash(value, length) {
|
|
5730
6286
|
return createHash2("sha256").update(value).digest("hex").slice(0, length);
|
|
@@ -5754,12 +6310,12 @@ var init_acpx_queue_owner_launcher = __esm(() => {
|
|
|
5754
6310
|
|
|
5755
6311
|
// src/runtime/core-home.ts
|
|
5756
6312
|
import { existsSync as existsSync2 } from "node:fs";
|
|
5757
|
-
import { join as
|
|
6313
|
+
import { join as join5 } from "node:path";
|
|
5758
6314
|
function coreHomeDir(home) {
|
|
5759
|
-
const primary =
|
|
6315
|
+
const primary = join5(home, CORE_HOME_DIR_NAME);
|
|
5760
6316
|
if (existsSync2(primary))
|
|
5761
6317
|
return primary;
|
|
5762
|
-
const legacy =
|
|
6318
|
+
const legacy = join5(home, CORE_HOME_LEGACY_DIR_NAME);
|
|
5763
6319
|
if (existsSync2(legacy))
|
|
5764
6320
|
return legacy;
|
|
5765
6321
|
return primary;
|
|
@@ -5772,7 +6328,7 @@ var init_core_home = () => {};
|
|
|
5772
6328
|
|
|
5773
6329
|
// src/orchestration/orchestration-ipc.ts
|
|
5774
6330
|
import { createHash as createHash3 } from "node:crypto";
|
|
5775
|
-
import { join as
|
|
6331
|
+
import { join as join6 } from "node:path";
|
|
5776
6332
|
function resolveOrchestrationEndpoint(runtimeDir, platform = process.platform) {
|
|
5777
6333
|
if (platform === "win32") {
|
|
5778
6334
|
const suffix = createHash3("sha256").update(runtimeDir).digest("hex").slice(0, 12);
|
|
@@ -5783,7 +6339,7 @@ function resolveOrchestrationEndpoint(runtimeDir, platform = process.platform) {
|
|
|
5783
6339
|
}
|
|
5784
6340
|
return {
|
|
5785
6341
|
kind: "unix",
|
|
5786
|
-
path:
|
|
6342
|
+
path: join6(runtimeDir, "orchestration.sock")
|
|
5787
6343
|
};
|
|
5788
6344
|
}
|
|
5789
6345
|
function createOrchestrationEndpoint(path2, platform = process.platform) {
|
|
@@ -5803,20 +6359,20 @@ function encodeOrchestrationRpcResponse(response) {
|
|
|
5803
6359
|
var init_orchestration_ipc = () => {};
|
|
5804
6360
|
|
|
5805
6361
|
// src/daemon/daemon-files.ts
|
|
5806
|
-
import { dirname as
|
|
6362
|
+
import { dirname as dirname4, join as join7 } from "node:path";
|
|
5807
6363
|
function resolveDaemonPaths(options) {
|
|
5808
|
-
const runtimeDir = options.runtimeDir ?? (options.configPath ? resolveRuntimeDirFromConfigPath(options.configPath) :
|
|
6364
|
+
const runtimeDir = options.runtimeDir ?? (options.configPath ? resolveRuntimeDirFromConfigPath(options.configPath) : join7(coreHomeDir(options.home), "runtime"));
|
|
5809
6365
|
return {
|
|
5810
6366
|
runtimeDir,
|
|
5811
|
-
pidFile:
|
|
5812
|
-
statusFile:
|
|
5813
|
-
stdoutLog:
|
|
5814
|
-
stderrLog:
|
|
5815
|
-
appLog:
|
|
6367
|
+
pidFile: join7(runtimeDir, "daemon.pid"),
|
|
6368
|
+
statusFile: join7(runtimeDir, "status.json"),
|
|
6369
|
+
stdoutLog: join7(runtimeDir, "stdout.log"),
|
|
6370
|
+
stderrLog: join7(runtimeDir, "stderr.log"),
|
|
6371
|
+
appLog: join7(runtimeDir, "app.log")
|
|
5816
6372
|
};
|
|
5817
6373
|
}
|
|
5818
6374
|
function resolveRuntimeDirFromConfigPath(configPath) {
|
|
5819
|
-
return
|
|
6375
|
+
return join7(dirname4(configPath), "runtime");
|
|
5820
6376
|
}
|
|
5821
6377
|
function resolveDaemonOrchestrationSocketPath(runtimeDir, platform = process.platform) {
|
|
5822
6378
|
return resolveOrchestrationEndpoint(runtimeDir, platform).path;
|
|
@@ -5836,7 +6392,7 @@ var init_daemon_files = __esm(() => {
|
|
|
5836
6392
|
|
|
5837
6393
|
// src/util/path.ts
|
|
5838
6394
|
import path2 from "node:path";
|
|
5839
|
-
import { homedir as
|
|
6395
|
+
import { homedir as homedir5 } from "node:os";
|
|
5840
6396
|
function normalizePath(input) {
|
|
5841
6397
|
const expanded = expandHome(input);
|
|
5842
6398
|
if (isWindowsLikePath(expanded)) {
|
|
@@ -5864,7 +6420,7 @@ function isWindowsLikePath(input) {
|
|
|
5864
6420
|
return WINDOWS_DRIVE_PATH_RE.test(input) || WINDOWS_UNC_PATH_RE.test(input);
|
|
5865
6421
|
}
|
|
5866
6422
|
function expandHome(input) {
|
|
5867
|
-
return input.startsWith("~") ?
|
|
6423
|
+
return input.startsWith("~") ? homedir5() + input.slice(1) : input;
|
|
5868
6424
|
}
|
|
5869
6425
|
var WINDOWS_DRIVE_PATH_RE, WINDOWS_UNC_PATH_RE, ROOT_PATH_RE;
|
|
5870
6426
|
var init_path = __esm(() => {
|
|
@@ -5875,11 +6431,11 @@ var init_path = __esm(() => {
|
|
|
5875
6431
|
|
|
5876
6432
|
// src/transport/codex-subagent-filter.ts
|
|
5877
6433
|
import { closeSync, openSync, readdirSync, readSync, statSync } from "node:fs";
|
|
5878
|
-
import { homedir as
|
|
5879
|
-
import { join as
|
|
6434
|
+
import { homedir as homedir6 } from "node:os";
|
|
6435
|
+
import { join as join8 } from "node:path";
|
|
5880
6436
|
function resolveCodexHome(env = process.env) {
|
|
5881
6437
|
const fromEnv = env.CODEX_HOME?.trim();
|
|
5882
|
-
return fromEnv ? fromEnv :
|
|
6438
|
+
return fromEnv ? fromEnv : join8(homedir6(), ".codex");
|
|
5883
6439
|
}
|
|
5884
6440
|
function isPlainObject(value) {
|
|
5885
6441
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
@@ -5944,7 +6500,7 @@ function filterSubagentSessions(result, isSubagent) {
|
|
|
5944
6500
|
};
|
|
5945
6501
|
}
|
|
5946
6502
|
function nodeRolloutReader(home) {
|
|
5947
|
-
const root =
|
|
6503
|
+
const root = join8(home, "sessions");
|
|
5948
6504
|
return {
|
|
5949
6505
|
listRolloutPaths() {
|
|
5950
6506
|
const out = [];
|
|
@@ -5956,7 +6512,7 @@ function nodeRolloutReader(home) {
|
|
|
5956
6512
|
return;
|
|
5957
6513
|
}
|
|
5958
6514
|
for (const entry of entries) {
|
|
5959
|
-
const full =
|
|
6515
|
+
const full = join8(dir, entry.name);
|
|
5960
6516
|
if (entry.isDirectory())
|
|
5961
6517
|
walk(full);
|
|
5962
6518
|
else if (entry.isFile() && entry.name.startsWith("rollout-") && entry.name.endsWith(".jsonl"))
|
|
@@ -6070,24 +6626,24 @@ var init_agent_session_list = __esm(() => {
|
|
|
6070
6626
|
});
|
|
6071
6627
|
|
|
6072
6628
|
// src/transport/acpx-session-files.ts
|
|
6073
|
-
import { readdir, unlink as unlink2 } from "node:fs/promises";
|
|
6074
|
-
import { homedir as
|
|
6075
|
-
import { join as
|
|
6629
|
+
import { readdir as readdir2, unlink as unlink2 } from "node:fs/promises";
|
|
6630
|
+
import { homedir as homedir7 } from "node:os";
|
|
6631
|
+
import { join as join9 } from "node:path";
|
|
6076
6632
|
async function deleteAcpxSessionFiles(options) {
|
|
6077
|
-
const dir = options.sessionsDir ??
|
|
6633
|
+
const dir = options.sessionsDir ?? join9(homedir7(), ".acpx", "sessions");
|
|
6078
6634
|
const safeId = encodeURIComponent(options.acpxRecordId);
|
|
6079
|
-
await unlink2(
|
|
6635
|
+
await unlink2(join9(dir, `${safeId}.json`)).catch(() => {
|
|
6080
6636
|
return;
|
|
6081
6637
|
});
|
|
6082
6638
|
let entries;
|
|
6083
6639
|
try {
|
|
6084
|
-
entries = await
|
|
6640
|
+
entries = await readdir2(dir);
|
|
6085
6641
|
} catch {
|
|
6086
6642
|
return;
|
|
6087
6643
|
}
|
|
6088
6644
|
const streamFiles = entries.filter((name) => name.startsWith(`${safeId}.stream.`));
|
|
6089
6645
|
for (const name of streamFiles) {
|
|
6090
|
-
await unlink2(
|
|
6646
|
+
await unlink2(join9(dir, name)).catch(() => {
|
|
6091
6647
|
return;
|
|
6092
6648
|
});
|
|
6093
6649
|
}
|
|
@@ -6352,9 +6908,9 @@ init_terminate_process_tree();
|
|
|
6352
6908
|
init_prompt_output();
|
|
6353
6909
|
init_prompt_media();
|
|
6354
6910
|
init_streaming_prompt();
|
|
6355
|
-
import { copyFile, readdir as
|
|
6356
|
-
import { homedir as
|
|
6357
|
-
import { dirname as
|
|
6911
|
+
import { copyFile, readdir as readdir3 } from "node:fs/promises";
|
|
6912
|
+
import { homedir as homedir8 } from "node:os";
|
|
6913
|
+
import { dirname as dirname5, join as join10, win32 } from "node:path";
|
|
6358
6914
|
import { spawn as spawn4 } from "node:child_process";
|
|
6359
6915
|
|
|
6360
6916
|
// src/bridge/parse-missing-optional-dep.ts
|
|
@@ -6623,7 +7179,7 @@ class BridgeRuntime {
|
|
|
6623
7179
|
const resolved = __require.resolve(`${candidate}/package.json`, {
|
|
6624
7180
|
paths: [process.cwd(), ...__require.resolve.paths(candidate) ?? []]
|
|
6625
7181
|
});
|
|
6626
|
-
return
|
|
7182
|
+
return dirname5(resolved);
|
|
6627
7183
|
} catch {
|
|
6628
7184
|
continue;
|
|
6629
7185
|
}
|
|
@@ -7056,14 +7612,14 @@ async function tryRepairAcpxSessionIndex(deps = {}) {
|
|
|
7056
7612
|
if (platform !== "win32") {
|
|
7057
7613
|
return false;
|
|
7058
7614
|
}
|
|
7059
|
-
const home = deps.home ?? process.env.HOME ?? process.env.USERPROFILE ??
|
|
7615
|
+
const home = deps.home ?? process.env.HOME ?? process.env.USERPROFILE ?? homedir8();
|
|
7060
7616
|
if (!home) {
|
|
7061
7617
|
return false;
|
|
7062
7618
|
}
|
|
7063
|
-
const pathJoin = platform === "win32" ? win32.join :
|
|
7619
|
+
const pathJoin = platform === "win32" ? win32.join : join10;
|
|
7064
7620
|
const sessionsDir = pathJoin(home, ".acpx", "sessions");
|
|
7065
7621
|
const indexPath = pathJoin(sessionsDir, "index.json");
|
|
7066
|
-
const readdirFn = deps.readdirFn ??
|
|
7622
|
+
const readdirFn = deps.readdirFn ?? readdir3;
|
|
7067
7623
|
const copyFileFn = deps.copyFileFn ?? copyFile;
|
|
7068
7624
|
let files;
|
|
7069
7625
|
try {
|