@clawos-dev/clawd 0.2.364 → 0.2.366
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/cli.cjs
CHANGED
|
@@ -14498,19 +14498,19 @@ var init_claude_history = __esm({
|
|
|
14498
14498
|
const backups = snapshot?.trackedFileBackups;
|
|
14499
14499
|
const anchorId = snapshot?.messageId;
|
|
14500
14500
|
if (typeof anchorId !== "string" || !backups || typeof backups !== "object") continue;
|
|
14501
|
-
const
|
|
14501
|
+
const record3 = {};
|
|
14502
14502
|
for (const [filePath, raw] of Object.entries(backups)) {
|
|
14503
14503
|
if (!raw || typeof raw !== "object") continue;
|
|
14504
14504
|
const b2 = raw;
|
|
14505
14505
|
const name = b2.backupFileName;
|
|
14506
14506
|
const version2 = b2.version;
|
|
14507
14507
|
if (typeof version2 !== "number") continue;
|
|
14508
|
-
|
|
14508
|
+
record3[filePath] = {
|
|
14509
14509
|
backupFileName: typeof name === "string" ? name : null,
|
|
14510
14510
|
version: version2
|
|
14511
14511
|
};
|
|
14512
14512
|
}
|
|
14513
|
-
out.set(anchorId,
|
|
14513
|
+
out.set(anchorId, record3);
|
|
14514
14514
|
}
|
|
14515
14515
|
return out;
|
|
14516
14516
|
}
|
|
@@ -41569,9 +41569,9 @@ var require_ZipFileWorker = __commonJS({
|
|
|
41569
41569
|
this.currentFile = streamInfo["file"].name;
|
|
41570
41570
|
var streamedContent = this.streamFiles && !streamInfo["file"].dir;
|
|
41571
41571
|
if (streamedContent) {
|
|
41572
|
-
var
|
|
41572
|
+
var record3 = generateZipParts(streamInfo, streamedContent, false, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
|
|
41573
41573
|
this.push({
|
|
41574
|
-
data:
|
|
41574
|
+
data: record3.fileRecord,
|
|
41575
41575
|
meta: { percent: 0 }
|
|
41576
41576
|
});
|
|
41577
41577
|
} else {
|
|
@@ -41581,8 +41581,8 @@ var require_ZipFileWorker = __commonJS({
|
|
|
41581
41581
|
ZipFileWorker.prototype.closedSource = function(streamInfo) {
|
|
41582
41582
|
this.accumulate = false;
|
|
41583
41583
|
var streamedContent = this.streamFiles && !streamInfo["file"].dir;
|
|
41584
|
-
var
|
|
41585
|
-
this.dirRecords.push(
|
|
41584
|
+
var record3 = generateZipParts(streamInfo, streamedContent, true, this.currentSourceOffset, this.zipPlatform, this.encodeFileName);
|
|
41585
|
+
this.dirRecords.push(record3.dirRecord);
|
|
41586
41586
|
if (streamedContent) {
|
|
41587
41587
|
this.push({
|
|
41588
41588
|
data: generateDataDescriptors(streamInfo),
|
|
@@ -41590,7 +41590,7 @@ var require_ZipFileWorker = __commonJS({
|
|
|
41590
41590
|
});
|
|
41591
41591
|
} else {
|
|
41592
41592
|
this.push({
|
|
41593
|
-
data:
|
|
41593
|
+
data: record3.fileRecord,
|
|
41594
41594
|
meta: { percent: 0 }
|
|
41595
41595
|
});
|
|
41596
41596
|
while (this.contentBuffer.length) {
|
|
@@ -43630,14 +43630,14 @@ var Batcher = class {
|
|
|
43630
43630
|
timer = null;
|
|
43631
43631
|
disposed = false;
|
|
43632
43632
|
pendingSends = [];
|
|
43633
|
-
enqueue(
|
|
43633
|
+
enqueue(record3) {
|
|
43634
43634
|
if (this.disposed) return;
|
|
43635
|
-
const sz = approxSize(
|
|
43635
|
+
const sz = approxSize(record3);
|
|
43636
43636
|
while (this.queue.length >= this.deps.bufferCap) {
|
|
43637
43637
|
this.queue.shift();
|
|
43638
43638
|
this.droppedSinceFlush++;
|
|
43639
43639
|
}
|
|
43640
|
-
this.queue.push(
|
|
43640
|
+
this.queue.push(record3);
|
|
43641
43641
|
this.bytes += sz;
|
|
43642
43642
|
if (!this.identityReady) return;
|
|
43643
43643
|
this.maybeTrigger();
|
|
@@ -43699,8 +43699,8 @@ var Batcher = class {
|
|
|
43699
43699
|
});
|
|
43700
43700
|
}
|
|
43701
43701
|
};
|
|
43702
|
-
function approxSize(
|
|
43703
|
-
return (
|
|
43702
|
+
function approxSize(record3) {
|
|
43703
|
+
return (record3.msg?.length ?? 0) + (record3.meta_json?.length ?? 0) + 200;
|
|
43704
43704
|
}
|
|
43705
43705
|
var BACKOFF_MS = [1e3, 2e3, 4e3];
|
|
43706
43706
|
async function sendBatch(deps, batch) {
|
|
@@ -43788,8 +43788,8 @@ function createLogClient(opts) {
|
|
|
43788
43788
|
stats.dropped++;
|
|
43789
43789
|
return;
|
|
43790
43790
|
}
|
|
43791
|
-
const
|
|
43792
|
-
batcher.enqueue(
|
|
43791
|
+
const record3 = buildRecord(input, identity, opts.source, homeDir, now);
|
|
43792
|
+
batcher.enqueue(record3);
|
|
43793
43793
|
} catch {
|
|
43794
43794
|
}
|
|
43795
43795
|
},
|
|
@@ -44786,6 +44786,7 @@ function pushEventToBufferInPlace(next, event, deps) {
|
|
|
44786
44786
|
if (newBuffer.length === 1) next.bufferStartSeq = seq;
|
|
44787
44787
|
const isTurnEnd = withSeq.kind === "turn_end";
|
|
44788
44788
|
const isUserText = withSeq.kind === "user_text";
|
|
44789
|
+
const isBackgroundEvent = withSeq.kind === "subagent_progress";
|
|
44789
44790
|
if (isTurnEnd && next.turnOpen && isLateTurnEnd(withSeq, next.turnStartedAt, deps.now())) {
|
|
44790
44791
|
return [emitSessionEvent(next.file.sessionId, withSeq)];
|
|
44791
44792
|
}
|
|
@@ -44796,7 +44797,7 @@ function pushEventToBufferInPlace(next, event, deps) {
|
|
|
44796
44797
|
}
|
|
44797
44798
|
next.turnOpen = false;
|
|
44798
44799
|
next.turnStartedAt = null;
|
|
44799
|
-
} else if (!next.turnOpen) {
|
|
44800
|
+
} else if (!isBackgroundEvent && !next.turnOpen) {
|
|
44800
44801
|
next.turnOpen = true;
|
|
44801
44802
|
next.turnStartedAt = deps.now();
|
|
44802
44803
|
}
|
|
@@ -49855,6 +49856,195 @@ function num(v2) {
|
|
|
49855
49856
|
return typeof v2 === "number" ? v2 : void 0;
|
|
49856
49857
|
}
|
|
49857
49858
|
|
|
49859
|
+
// src/tools/codex-subagent-tracker.ts
|
|
49860
|
+
var CodexSubagentTracker = class {
|
|
49861
|
+
agents = /* @__PURE__ */ new Map();
|
|
49862
|
+
handleParentNotification(method, params) {
|
|
49863
|
+
if (method !== "item/started" && method !== "item/completed") return [];
|
|
49864
|
+
const item = record(record(params)?.item);
|
|
49865
|
+
if (!item) return [];
|
|
49866
|
+
if (item.type === "subAgentActivity") return this.handleActivity(item);
|
|
49867
|
+
if (item.type === "collabAgentToolCall") return this.handleCollabToolCall(item);
|
|
49868
|
+
return [];
|
|
49869
|
+
}
|
|
49870
|
+
handleChildNotification(threadId, method, params) {
|
|
49871
|
+
const state = this.state(threadId);
|
|
49872
|
+
const p2 = record(params);
|
|
49873
|
+
if (method === "item/started") {
|
|
49874
|
+
const itemType = stringValue(record(p2?.item)?.type);
|
|
49875
|
+
return this.updateStatus(state, "running", itemType ? { lastToolName: itemType } : {});
|
|
49876
|
+
}
|
|
49877
|
+
if (method === "turn/completed") {
|
|
49878
|
+
const turnStatus = stringValue(record(p2?.turn)?.status);
|
|
49879
|
+
if (turnStatus === "completed") return this.updateStatus(state, "completed");
|
|
49880
|
+
if (turnStatus === "failed" || turnStatus === "interrupted") {
|
|
49881
|
+
return this.updateStatus(state, "failed");
|
|
49882
|
+
}
|
|
49883
|
+
return [];
|
|
49884
|
+
}
|
|
49885
|
+
if (method === "error") {
|
|
49886
|
+
if (p2?.willRetry === true) return [];
|
|
49887
|
+
return this.updateStatus(state, "failed");
|
|
49888
|
+
}
|
|
49889
|
+
if (method === "thread/status/changed") {
|
|
49890
|
+
const rawStatus = p2?.status;
|
|
49891
|
+
const statusType = stringValue(record(rawStatus)?.type) ?? stringValue(rawStatus);
|
|
49892
|
+
if (statusType === "systemError") return this.updateStatus(state, "failed");
|
|
49893
|
+
}
|
|
49894
|
+
return [];
|
|
49895
|
+
}
|
|
49896
|
+
handleActivity(item) {
|
|
49897
|
+
const agentId = stringValue(item.agentThreadId);
|
|
49898
|
+
if (!agentId) return [];
|
|
49899
|
+
const state = this.state(agentId);
|
|
49900
|
+
const agentPath = stringValue(item.agentPath);
|
|
49901
|
+
if (agentPath) {
|
|
49902
|
+
state.agentPath = agentPath;
|
|
49903
|
+
state.description = agentPathLabel(agentPath);
|
|
49904
|
+
}
|
|
49905
|
+
const events = [];
|
|
49906
|
+
const toolUseId = stringValue(item.id);
|
|
49907
|
+
const kind = stringValue(item.kind);
|
|
49908
|
+
if (toolUseId && (kind === "started" || kind === "interacted" || kind === "interrupted")) {
|
|
49909
|
+
events.push(...this.bind(state, toolUseId));
|
|
49910
|
+
}
|
|
49911
|
+
if (kind === "interacted") events.push(...this.updateStatus(state, "running"));
|
|
49912
|
+
if (kind === "interrupted") events.push(...this.updateStatus(state, "failed"));
|
|
49913
|
+
return events;
|
|
49914
|
+
}
|
|
49915
|
+
handleCollabToolCall(item) {
|
|
49916
|
+
const prompt = stringValue(item.prompt);
|
|
49917
|
+
const agentStates = record(item.agentsStates);
|
|
49918
|
+
const agentIds = /* @__PURE__ */ new Set();
|
|
49919
|
+
if (Array.isArray(item.receiverThreadIds)) {
|
|
49920
|
+
for (const value of item.receiverThreadIds) {
|
|
49921
|
+
const id = stringValue(value);
|
|
49922
|
+
if (id) agentIds.add(id);
|
|
49923
|
+
}
|
|
49924
|
+
}
|
|
49925
|
+
if (agentStates) {
|
|
49926
|
+
for (const id of Object.keys(agentStates)) agentIds.add(id);
|
|
49927
|
+
}
|
|
49928
|
+
const events = [];
|
|
49929
|
+
for (const agentId of agentIds) {
|
|
49930
|
+
const state = this.state(agentId);
|
|
49931
|
+
const codexStatus = stringValue(record(agentStates?.[agentId])?.status);
|
|
49932
|
+
const status = collabStatus(codexStatus);
|
|
49933
|
+
if (status) {
|
|
49934
|
+
events.push(...this.updateStatus(state, status, prompt ? { prompt } : {}));
|
|
49935
|
+
} else if (!state.terminal && prompt) {
|
|
49936
|
+
state.prompt = prompt;
|
|
49937
|
+
}
|
|
49938
|
+
if (!codexStatus && item.status === "failed") {
|
|
49939
|
+
events.push(...this.updateStatus(state, "failed", prompt ? { prompt } : {}));
|
|
49940
|
+
}
|
|
49941
|
+
}
|
|
49942
|
+
return events;
|
|
49943
|
+
}
|
|
49944
|
+
state(agentId) {
|
|
49945
|
+
let state = this.agents.get(agentId);
|
|
49946
|
+
if (!state) {
|
|
49947
|
+
state = {
|
|
49948
|
+
agentId,
|
|
49949
|
+
toolCallEmitted: false,
|
|
49950
|
+
startedEmitted: false,
|
|
49951
|
+
terminalEmitted: false
|
|
49952
|
+
};
|
|
49953
|
+
this.agents.set(agentId, state);
|
|
49954
|
+
}
|
|
49955
|
+
return state;
|
|
49956
|
+
}
|
|
49957
|
+
bind(state, toolUseId) {
|
|
49958
|
+
if (!state.toolUseId) state.toolUseId = toolUseId;
|
|
49959
|
+
if (state.toolUseId !== toolUseId) return [];
|
|
49960
|
+
const pendingStatus = state.status;
|
|
49961
|
+
const events = [];
|
|
49962
|
+
if (!state.toolCallEmitted) {
|
|
49963
|
+
state.toolCallEmitted = true;
|
|
49964
|
+
const input = { agentId: state.agentId };
|
|
49965
|
+
if (state.description) input.description = state.description;
|
|
49966
|
+
if (state.agentPath) input.agentPath = state.agentPath;
|
|
49967
|
+
if (state.prompt) input.prompt = state.prompt;
|
|
49968
|
+
events.push({
|
|
49969
|
+
kind: "tool_call",
|
|
49970
|
+
toolUseId,
|
|
49971
|
+
tool: "Agent",
|
|
49972
|
+
toolKind: "codex",
|
|
49973
|
+
input
|
|
49974
|
+
});
|
|
49975
|
+
}
|
|
49976
|
+
events.push(...this.emitProgress(state, "started"));
|
|
49977
|
+
if (pendingStatus && pendingStatus !== "started") {
|
|
49978
|
+
events.push(...this.emitProgress(state, pendingStatus));
|
|
49979
|
+
} else if (!state.status) {
|
|
49980
|
+
state.status = "started";
|
|
49981
|
+
}
|
|
49982
|
+
return events;
|
|
49983
|
+
}
|
|
49984
|
+
updateStatus(state, status, patch = {}) {
|
|
49985
|
+
if (state.terminal) return [];
|
|
49986
|
+
if (patch.prompt) state.prompt = patch.prompt;
|
|
49987
|
+
if (patch.lastToolName) state.lastToolName = patch.lastToolName;
|
|
49988
|
+
if (status === "started") {
|
|
49989
|
+
if (!state.status) state.status = status;
|
|
49990
|
+
} else {
|
|
49991
|
+
state.status = status;
|
|
49992
|
+
}
|
|
49993
|
+
if (status === "completed" || status === "failed") state.terminal = status;
|
|
49994
|
+
return this.emitProgress(state, status);
|
|
49995
|
+
}
|
|
49996
|
+
emitProgress(state, status) {
|
|
49997
|
+
if (!state.toolUseId) return [];
|
|
49998
|
+
if (status === "started") {
|
|
49999
|
+
if (state.startedEmitted) return [];
|
|
50000
|
+
state.startedEmitted = true;
|
|
50001
|
+
} else if (status === "running") {
|
|
50002
|
+
const signature = JSON.stringify([state.description, state.lastToolName, state.prompt]);
|
|
50003
|
+
if (state.lastRunningSignature === signature) return [];
|
|
50004
|
+
state.lastRunningSignature = signature;
|
|
50005
|
+
} else {
|
|
50006
|
+
if (state.terminalEmitted) return [];
|
|
50007
|
+
state.terminalEmitted = true;
|
|
50008
|
+
}
|
|
50009
|
+
const event = {
|
|
50010
|
+
kind: "subagent_progress",
|
|
50011
|
+
toolUseId: state.toolUseId,
|
|
50012
|
+
agentId: state.agentId,
|
|
50013
|
+
status
|
|
50014
|
+
};
|
|
50015
|
+
if (state.description) event.description = state.description;
|
|
50016
|
+
if (state.prompt) event.prompt = state.prompt;
|
|
50017
|
+
if (status !== "started" && state.lastToolName) event.lastToolName = state.lastToolName;
|
|
50018
|
+
return [event];
|
|
50019
|
+
}
|
|
50020
|
+
};
|
|
50021
|
+
function notificationThreadId(method, params) {
|
|
50022
|
+
const p2 = record(params);
|
|
50023
|
+
const direct = stringValue(p2?.threadId);
|
|
50024
|
+
if (direct) return direct;
|
|
50025
|
+
if (method === "thread/started") return stringValue(record(p2?.thread)?.id);
|
|
50026
|
+
return void 0;
|
|
50027
|
+
}
|
|
50028
|
+
function collabStatus(value) {
|
|
50029
|
+
if (value === "pendingInit") return "started";
|
|
50030
|
+
if (value === "running") return "running";
|
|
50031
|
+
if (value === "completed") return "completed";
|
|
50032
|
+
if (value === "errored" || value === "interrupted" || value === "shutdown" || value === "notFound") {
|
|
50033
|
+
return "failed";
|
|
50034
|
+
}
|
|
50035
|
+
return void 0;
|
|
50036
|
+
}
|
|
50037
|
+
function agentPathLabel(agentPath) {
|
|
50038
|
+
const segments = agentPath.split("/").filter(Boolean);
|
|
50039
|
+
return segments[segments.length - 1];
|
|
50040
|
+
}
|
|
50041
|
+
function record(value) {
|
|
50042
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
50043
|
+
}
|
|
50044
|
+
function stringValue(value) {
|
|
50045
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
50046
|
+
}
|
|
50047
|
+
|
|
49858
50048
|
// src/tools/codex-app-server-params.ts
|
|
49859
50049
|
function resolveApprovalPolicy(ctx) {
|
|
49860
50050
|
if (ctx.personaMode === "owner" || ctx.personaMode === "guest") return "never";
|
|
@@ -50076,6 +50266,7 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
50076
50266
|
let threadId = ctx.toolSessionId;
|
|
50077
50267
|
let turnId;
|
|
50078
50268
|
const approvalIds = /* @__PURE__ */ new Map();
|
|
50269
|
+
const subagents = new CodexSubagentTracker();
|
|
50079
50270
|
const effort = ctx.effort;
|
|
50080
50271
|
let exited = false;
|
|
50081
50272
|
const finish = (code) => {
|
|
@@ -50085,11 +50276,26 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
50085
50276
|
};
|
|
50086
50277
|
const client = new CodexAppServerClient(proc, {
|
|
50087
50278
|
onNotification: (method, params) => {
|
|
50088
|
-
|
|
50279
|
+
const ownerThreadId = notificationThreadId(method, params);
|
|
50280
|
+
const route = threadId && ownerThreadId === threadId ? "foreground" : threadId && ownerThreadId ? "subagent" : !threadId && method === "thread/started" && ownerThreadId ? "foreground" : "ignored";
|
|
50281
|
+
const p2 = record2(params);
|
|
50282
|
+
const item = record2(p2?.item);
|
|
50283
|
+
deps.logger?.debug("codex notification routed", {
|
|
50284
|
+
method,
|
|
50285
|
+
rootThreadId: threadId,
|
|
50286
|
+
threadId: ownerThreadId,
|
|
50287
|
+
turnId: stringValue2(p2?.turnId) ?? stringValue2(record2(p2?.turn)?.id),
|
|
50288
|
+
itemType: stringValue2(item?.type),
|
|
50289
|
+
route
|
|
50290
|
+
});
|
|
50291
|
+
if (threadId !== void 0 && ownerThreadId === threadId && method === "turn/started") {
|
|
50089
50292
|
const id = params?.turn?.id;
|
|
50090
50293
|
if (id) turnId = id;
|
|
50091
50294
|
}
|
|
50092
|
-
const events =
|
|
50295
|
+
const events = route === "subagent" && ownerThreadId ? subagents.handleChildNotification(ownerThreadId, method, params) : route === "foreground" ? [
|
|
50296
|
+
...subagents.handleParentNotification(method, params),
|
|
50297
|
+
...translateNotification(method, params)
|
|
50298
|
+
] : [];
|
|
50093
50299
|
if (events.length) sink.pushEvents(events);
|
|
50094
50300
|
},
|
|
50095
50301
|
onServerRequest: (id, method, params) => {
|
|
@@ -50174,6 +50380,12 @@ function createCodexSession(ctx, sink, deps = {}) {
|
|
|
50174
50380
|
}
|
|
50175
50381
|
};
|
|
50176
50382
|
}
|
|
50383
|
+
function record2(value) {
|
|
50384
|
+
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
50385
|
+
}
|
|
50386
|
+
function stringValue2(value) {
|
|
50387
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
50388
|
+
}
|
|
50177
50389
|
|
|
50178
50390
|
// src/tools/codex-app-server-query.ts
|
|
50179
50391
|
var import_node_child_process5 = require("child_process");
|
|
@@ -50285,9 +50497,9 @@ var CODEX_CAPABILITIES_BASE = {
|
|
|
50285
50497
|
tool: "codex",
|
|
50286
50498
|
toolSessionIdLabel: "Codex Thread ID",
|
|
50287
50499
|
permissionModes: CODEX_APPROVAL_PRESETS,
|
|
50288
|
-
//
|
|
50289
|
-
|
|
50290
|
-
features: { rewind: false, subagents:
|
|
50500
|
+
// Codex 原生 child thread 已经映射到现有 Agent 卡 + history drawer;其余功能仍不支持
|
|
50501
|
+
//(rewind 无 file-snapshot / 无 TUI pty / 无 observe 推送 / 无文件分享 / fork 是 claude jsonl 专用)。
|
|
50502
|
+
features: { rewind: false, subagents: true, tui: false, observe: false, fileSharing: false, fork: false },
|
|
50291
50503
|
configSchema: [
|
|
50292
50504
|
{
|
|
50293
50505
|
name: "model",
|
|
@@ -53753,6 +53965,34 @@ function str2(v2) {
|
|
|
53753
53965
|
function num2(v2) {
|
|
53754
53966
|
return typeof v2 === "number" && Number.isFinite(v2) ? v2 : void 0;
|
|
53755
53967
|
}
|
|
53968
|
+
function nativeSubagentStart(item) {
|
|
53969
|
+
if (item.type !== "subAgentActivity" || item.kind !== "started") return void 0;
|
|
53970
|
+
const toolUseId = str2(item.id);
|
|
53971
|
+
const agentId = str2(item.agentThreadId);
|
|
53972
|
+
const agentPath = str2(item.agentPath);
|
|
53973
|
+
if (!toolUseId || !agentId || !agentPath) return void 0;
|
|
53974
|
+
const segments = agentPath.split("/").filter(Boolean);
|
|
53975
|
+
return {
|
|
53976
|
+
toolUseId,
|
|
53977
|
+
agentId,
|
|
53978
|
+
agentPath,
|
|
53979
|
+
description: segments[segments.length - 1] ?? agentId
|
|
53980
|
+
};
|
|
53981
|
+
}
|
|
53982
|
+
function threadItems(thread) {
|
|
53983
|
+
const turns = thread && Array.isArray(thread.turns) ? thread.turns : [];
|
|
53984
|
+
const items = [];
|
|
53985
|
+
for (const turn of turns) {
|
|
53986
|
+
const value = rec2(turn);
|
|
53987
|
+
if (value && Array.isArray(value.items)) items.push(...value.items);
|
|
53988
|
+
}
|
|
53989
|
+
return items;
|
|
53990
|
+
}
|
|
53991
|
+
function threadMessages(thread) {
|
|
53992
|
+
const messages = [];
|
|
53993
|
+
for (const item of threadItems(thread)) messages.push(...threadItemToHistoryMessages(item));
|
|
53994
|
+
return messages;
|
|
53995
|
+
}
|
|
53756
53996
|
function userInputText(content) {
|
|
53757
53997
|
if (!Array.isArray(content)) return "";
|
|
53758
53998
|
return content.map((c) => {
|
|
@@ -53763,6 +54003,22 @@ function userInputText(content) {
|
|
|
53763
54003
|
function threadItemToHistoryMessages(item) {
|
|
53764
54004
|
const it = rec2(item);
|
|
53765
54005
|
if (!it) return [];
|
|
54006
|
+
const subagent = nativeSubagentStart(it);
|
|
54007
|
+
if (subagent) {
|
|
54008
|
+
return [
|
|
54009
|
+
{
|
|
54010
|
+
kind: "tool_call",
|
|
54011
|
+
tool: "Agent",
|
|
54012
|
+
toolUseId: subagent.toolUseId,
|
|
54013
|
+
input: {
|
|
54014
|
+
agentId: subagent.agentId,
|
|
54015
|
+
description: subagent.description,
|
|
54016
|
+
agentPath: subagent.agentPath
|
|
54017
|
+
},
|
|
54018
|
+
raw: item
|
|
54019
|
+
}
|
|
54020
|
+
];
|
|
54021
|
+
}
|
|
53766
54022
|
switch (it.type) {
|
|
53767
54023
|
case "userMessage": {
|
|
53768
54024
|
const text = userInputText(it.content);
|
|
@@ -53846,33 +54102,41 @@ var CodexHistoryReader = class {
|
|
|
53846
54102
|
return out;
|
|
53847
54103
|
}
|
|
53848
54104
|
async read(args) {
|
|
53849
|
-
const
|
|
53850
|
-
|
|
53851
|
-
args.cwd,
|
|
53852
|
-
"thread/read",
|
|
53853
|
-
{ threadId: args.toolSessionId, includeTurns: true },
|
|
53854
|
-
this.deps
|
|
53855
|
-
)
|
|
53856
|
-
);
|
|
53857
|
-
const thread = res && rec2(res.thread);
|
|
53858
|
-
const turns = thread && Array.isArray(thread.turns) ? thread.turns : [];
|
|
53859
|
-
const messages = [];
|
|
53860
|
-
for (const turn of turns) {
|
|
53861
|
-
const t = rec2(turn);
|
|
53862
|
-
const items = t && Array.isArray(t.items) ? t.items : [];
|
|
53863
|
-
for (const item of items) messages.push(...threadItemToHistoryMessages(item));
|
|
53864
|
-
}
|
|
54105
|
+
const thread = await this.readThread(args.cwd, args.toolSessionId);
|
|
54106
|
+
const messages = threadMessages(thread);
|
|
53865
54107
|
const total = messages.length;
|
|
53866
54108
|
const limit = args.limit ?? total;
|
|
53867
54109
|
const offset = typeof args.offset === "number" ? Math.min(Math.max(0, args.offset), total) : Math.max(0, total - limit);
|
|
53868
54110
|
return { messages: messages.slice(offset, offset + limit), total, offset };
|
|
53869
54111
|
}
|
|
53870
|
-
|
|
53871
|
-
|
|
53872
|
-
|
|
54112
|
+
async listSubagents(args) {
|
|
54113
|
+
const thread = await this.readThread(args.cwd, args.toolSessionId);
|
|
54114
|
+
const seen = /* @__PURE__ */ new Set();
|
|
54115
|
+
const subagents = [];
|
|
54116
|
+
for (const item of threadItems(thread)) {
|
|
54117
|
+
const value = rec2(item);
|
|
54118
|
+
const started = value && nativeSubagentStart(value);
|
|
54119
|
+
if (!started || seen.has(started.agentId)) continue;
|
|
54120
|
+
seen.add(started.agentId);
|
|
54121
|
+
subagents.push({
|
|
54122
|
+
subagentId: started.agentId,
|
|
54123
|
+
summary: started.description,
|
|
54124
|
+
// 列表只读 parent 一次,避免为每个 child 再开 app-server 做 N+1 查询。
|
|
54125
|
+
messageCount: 0
|
|
54126
|
+
});
|
|
54127
|
+
}
|
|
54128
|
+
return subagents;
|
|
53873
54129
|
}
|
|
53874
|
-
async readSubagent() {
|
|
53875
|
-
|
|
54130
|
+
async readSubagent(args) {
|
|
54131
|
+
const thread = await this.readThread(args.cwd, args.subagentId);
|
|
54132
|
+
const actualId = str2(thread.id);
|
|
54133
|
+
const parentThreadId = str2(thread.parentThreadId);
|
|
54134
|
+
if (actualId !== args.subagentId || parentThreadId !== args.toolSessionId) {
|
|
54135
|
+
throw new Error(
|
|
54136
|
+
`Codex subagent thread ${args.subagentId} does not belong to parent thread ${args.toolSessionId}`
|
|
54137
|
+
);
|
|
54138
|
+
}
|
|
54139
|
+
return { messages: threadMessages(thread) };
|
|
53876
54140
|
}
|
|
53877
54141
|
computeRewindDiff() {
|
|
53878
54142
|
return { canRewind: false, files: [], totalInsertions: 0, totalDeletions: 0 };
|
|
@@ -53880,6 +54144,19 @@ var CodexHistoryReader = class {
|
|
|
53880
54144
|
listRewindableUserMessageIds() {
|
|
53881
54145
|
return [];
|
|
53882
54146
|
}
|
|
54147
|
+
async readThread(cwd, threadId) {
|
|
54148
|
+
const res = rec2(
|
|
54149
|
+
await queryCodexAppServer(
|
|
54150
|
+
cwd,
|
|
54151
|
+
"thread/read",
|
|
54152
|
+
{ threadId, includeTurns: true },
|
|
54153
|
+
this.deps
|
|
54154
|
+
)
|
|
54155
|
+
);
|
|
54156
|
+
const thread = res && rec2(res.thread);
|
|
54157
|
+
if (!thread) throw new Error(`Codex thread/read returned no thread for ${threadId}`);
|
|
54158
|
+
return thread;
|
|
54159
|
+
}
|
|
53883
54160
|
};
|
|
53884
54161
|
|
|
53885
54162
|
// src/tools/codex-skills.ts
|
|
@@ -55226,9 +55503,9 @@ var LocalWsServer = class {
|
|
|
55226
55503
|
Promise.resolve(this.frameHandler(client, frame)).catch((err) => {
|
|
55227
55504
|
const e = err;
|
|
55228
55505
|
const requestId = typeof frame.requestId === "string" ? frame.requestId : void 0;
|
|
55229
|
-
const
|
|
55230
|
-
if (!
|
|
55231
|
-
this.safeSend(
|
|
55506
|
+
const record3 = this.clients.get(client.id);
|
|
55507
|
+
if (!record3) return;
|
|
55508
|
+
this.safeSend(record3.ws, {
|
|
55232
55509
|
type: "error",
|
|
55233
55510
|
requestId,
|
|
55234
55511
|
code: e.code ?? "INTERNAL",
|
|
@@ -58016,9 +58293,9 @@ var OwnerIdentityStore = class {
|
|
|
58016
58293
|
loginAt: typeof r.loginAt === "string" ? r.loginAt : (/* @__PURE__ */ new Date(0)).toISOString()
|
|
58017
58294
|
};
|
|
58018
58295
|
}
|
|
58019
|
-
write(
|
|
58296
|
+
write(record3) {
|
|
58020
58297
|
import_node_fs44.default.mkdirSync(import_node_path49.default.dirname(this.file), { recursive: true });
|
|
58021
|
-
import_node_fs44.default.writeFileSync(this.file, JSON.stringify(
|
|
58298
|
+
import_node_fs44.default.writeFileSync(this.file, JSON.stringify(record3, null, 2), { mode: 384 });
|
|
58022
58299
|
try {
|
|
58023
58300
|
import_node_fs44.default.chmodSync(this.file, 384);
|
|
58024
58301
|
} catch {
|
|
@@ -59465,18 +59742,22 @@ function buildHistoryHandlers(deps) {
|
|
|
59465
59742
|
);
|
|
59466
59743
|
}
|
|
59467
59744
|
};
|
|
59745
|
+
const historyReaderForToolSession = (toolSessionId) => {
|
|
59746
|
+
const file = store.list().find((session) => session.toolSessionId === toolSessionId);
|
|
59747
|
+
return file ? getHistoryReader(file.tool ?? "claude") : history;
|
|
59748
|
+
};
|
|
59468
59749
|
const subagents = async (frame, _client, ctx) => {
|
|
59469
59750
|
const args = HistorySubagentsArgs.parse(frame);
|
|
59470
59751
|
assertGuestPath(ctx, path64.resolve(args.cwd), personaRoot, "history:subagents", usersRoot);
|
|
59471
59752
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagents");
|
|
59472
|
-
const subs = await
|
|
59753
|
+
const subs = await historyReaderForToolSession(args.toolSessionId).listSubagents(args);
|
|
59473
59754
|
return { response: { type: "history:subagents", subagents: subs } };
|
|
59474
59755
|
};
|
|
59475
59756
|
const subagentRead = async (frame, _client, ctx) => {
|
|
59476
59757
|
const args = HistorySubagentReadArgs.parse(frame);
|
|
59477
59758
|
assertGuestPath(ctx, path64.resolve(args.cwd), personaRoot, "history:subagent-read", usersRoot);
|
|
59478
59759
|
assertGuestOwnsToolSession(ctx, args.toolSessionId, "history:subagent-read");
|
|
59479
|
-
const res = await
|
|
59760
|
+
const res = await historyReaderForToolSession(args.toolSessionId).readSubagent(args);
|
|
59480
59761
|
return { response: { type: "history:subagent-read", ...res } };
|
|
59481
59762
|
};
|
|
59482
59763
|
const recentDirs = async (_frame, _client, ctx) => {
|
|
@@ -60196,15 +60477,15 @@ function buildFeishuAuthHandlers(deps) {
|
|
|
60196
60477
|
};
|
|
60197
60478
|
};
|
|
60198
60479
|
const getIdentity = async () => {
|
|
60199
|
-
const
|
|
60480
|
+
const record3 = deps.ownerIdentityStore.read();
|
|
60200
60481
|
return {
|
|
60201
60482
|
response: {
|
|
60202
60483
|
type: "auth:getIdentity:ok",
|
|
60203
|
-
identity:
|
|
60484
|
+
identity: record3 ? record3.identity : null,
|
|
60204
60485
|
// 决策 #15:设备属性,与登录态无关——UI"分享我的 Hub 标识"用
|
|
60205
60486
|
deviceId: deps.deviceId,
|
|
60206
60487
|
// 过期时间戳(仅时间戳,token 本体永不出 ws)——UI 派生 过期/临期 提示
|
|
60207
|
-
ttcTokenExpiresAt:
|
|
60488
|
+
ttcTokenExpiresAt: record3 ? record3.ttcTokenExpiresAt : null
|
|
60208
60489
|
}
|
|
60209
60490
|
};
|
|
60210
60491
|
};
|
|
@@ -60613,7 +60894,7 @@ function computeMethodAccess(args) {
|
|
|
60613
60894
|
}
|
|
60614
60895
|
|
|
60615
60896
|
// src/version.ts
|
|
60616
|
-
var version = "0.2.
|
|
60897
|
+
var version = "0.2.366".length > 0 ? "0.2.366" : "dev";
|
|
60617
60898
|
|
|
60618
60899
|
// src/cli-probe/probe.ts
|
|
60619
60900
|
var fs62 = __toESM(require("fs"), 1);
|
|
@@ -64631,13 +64912,13 @@ async function startDaemon(config) {
|
|
|
64631
64912
|
};
|
|
64632
64913
|
const reportDevice = async () => {
|
|
64633
64914
|
if (!feishuActive) return;
|
|
64634
|
-
const
|
|
64635
|
-
if (!
|
|
64915
|
+
const record3 = ownerIdentityStore.read();
|
|
64916
|
+
if (!record3) return;
|
|
64636
64917
|
try {
|
|
64637
64918
|
await centralUpsertDevice({
|
|
64638
64919
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
64639
|
-
ttcJwt:
|
|
64640
|
-
provider:
|
|
64920
|
+
ttcJwt: record3.ttcToken,
|
|
64921
|
+
provider: record3.identity.provider,
|
|
64641
64922
|
deviceId: authFile.deviceId,
|
|
64642
64923
|
url: currentTunnelUrl ?? void 0,
|
|
64643
64924
|
name: ownerDisplayName
|
|
@@ -64812,13 +65093,13 @@ async function startDaemon(config) {
|
|
|
64812
65093
|
// 契约(ContactHandlerDeps.exchangeToken):null = 本机登录问题(未登录 / JWT 过期),
|
|
64813
65094
|
// 其他失败原样抛给 handler——两种都会让握手硬失败,只是给对端的错误文案不同。
|
|
64814
65095
|
exchangeToken: async (targetDeviceId) => {
|
|
64815
|
-
const
|
|
64816
|
-
if (!
|
|
65096
|
+
const record3 = ownerIdentityStore.read();
|
|
65097
|
+
if (!record3) return null;
|
|
64817
65098
|
try {
|
|
64818
65099
|
const r = await centralExchange({
|
|
64819
65100
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
64820
|
-
jwt:
|
|
64821
|
-
provider:
|
|
65101
|
+
jwt: record3.ttcToken,
|
|
65102
|
+
provider: record3.identity.provider,
|
|
64822
65103
|
deviceId: targetDeviceId,
|
|
64823
65104
|
selfDeviceId: authFile.deviceId,
|
|
64824
65105
|
// 换票在握手关键路径上(硬失败),对端 connect-remote RPC_TIMEOUT_MS=5s:
|
|
@@ -64873,27 +65154,27 @@ async function startDaemon(config) {
|
|
|
64873
65154
|
feishuDevice: {
|
|
64874
65155
|
store: contactStore,
|
|
64875
65156
|
exchange: async (deviceId) => {
|
|
64876
|
-
const
|
|
64877
|
-
if (!
|
|
65157
|
+
const record3 = ownerIdentityStore.read();
|
|
65158
|
+
if (!record3) {
|
|
64878
65159
|
throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "device:connect requires feishu login");
|
|
64879
65160
|
}
|
|
64880
65161
|
return centralExchange({
|
|
64881
65162
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
64882
|
-
jwt:
|
|
64883
|
-
provider:
|
|
65163
|
+
jwt: record3.ttcToken,
|
|
65164
|
+
provider: record3.identity.provider,
|
|
64884
65165
|
deviceId,
|
|
64885
65166
|
selfDeviceId: authFile.deviceId
|
|
64886
65167
|
});
|
|
64887
65168
|
},
|
|
64888
65169
|
listDevices: async () => {
|
|
64889
|
-
const
|
|
64890
|
-
if (!
|
|
65170
|
+
const record3 = ownerIdentityStore.read();
|
|
65171
|
+
if (!record3) {
|
|
64891
65172
|
throw new ClawdError(ERROR_CODES.FEISHU_LOGIN_REQUIRED, "device:list requires feishu login");
|
|
64892
65173
|
}
|
|
64893
65174
|
return centralListDevices({
|
|
64894
65175
|
api: config.clawosApi ?? DEFAULT_CLAWOS_API,
|
|
64895
|
-
ttcJwt:
|
|
64896
|
-
provider:
|
|
65176
|
+
ttcJwt: record3.ttcToken,
|
|
65177
|
+
provider: record3.identity.provider
|
|
64897
65178
|
});
|
|
64898
65179
|
},
|
|
64899
65180
|
connectRemote,
|