@clawos-dev/clawd 0.2.761 → 0.2.763
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 +157 -21
- package/dist/cloud-persona-conversations.html +1 -1
- package/dist/cloud-persona-metrics.html +1 -1
- package/dist/cloud-persona-schedules.html +1 -1
- package/dist/owner-ui/assets/owner-DhFLEcSc.css +32 -0
- package/dist/owner-ui/assets/{owner-vl8mMol4.js → owner-O1mLoqLY.js} +230 -225
- package/dist/owner-ui/owner.html +2 -2
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/guest-B_ZYW2CL.css +32 -0
- package/dist/share-ui/assets/{guest-DOIr732g.js → guest-DQyie0wU.js} +153 -148
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
- package/dist/owner-ui/assets/owner-aAdXxGaN.css +0 -32
- package/dist/share-ui/assets/guest-BTg2GvCX.css +0 -32
package/dist/cli.cjs
CHANGED
|
@@ -47897,6 +47897,115 @@ function extractLarkReplyText(events) {
|
|
|
47897
47897
|
return order.map((k3) => (chunks.get(k3) ?? []).join("")).filter((t2) => t2.length > 0).join("\n").trim();
|
|
47898
47898
|
}
|
|
47899
47899
|
|
|
47900
|
+
// src/session/lark-tool-send.ts
|
|
47901
|
+
var LARK_RESUME_MARKER = "\u300C\u7EE7\u7EED\u300D\u7531\u7CFB\u7EDF\u4EE3\u53D1";
|
|
47902
|
+
var isResumePrompt = (text) => text.includes(LARK_RESUME_MARKER);
|
|
47903
|
+
var SEND_COMMAND_RES = [
|
|
47904
|
+
/\bim\s+\+messages-send\b/,
|
|
47905
|
+
/\bim\s+messages\s+(?:create|reply)\b/,
|
|
47906
|
+
/\bapi\s+POST\s+\/open-apis\/im\/v1\/messages(?:[\/\s'"`?#]|$)/
|
|
47907
|
+
];
|
|
47908
|
+
var DRY_RUN_RE = /--dry-run\b|\bdry_run\b/;
|
|
47909
|
+
var TARGET_CHAT_RES = [
|
|
47910
|
+
/--chat-id[= ]+['"]?(oc_[A-Za-z0-9_-]+)/,
|
|
47911
|
+
/--receive-id[= ]+['"]?(oc_[A-Za-z0-9_-]+)/,
|
|
47912
|
+
/"receive_id"\s*:\s*"(oc_[A-Za-z0-9_-]+)"/,
|
|
47913
|
+
/'receive_id'\s*:\s*'(oc_[A-Za-z0-9_-]+)'/
|
|
47914
|
+
];
|
|
47915
|
+
var FAILED_CODE_RE = /"code"\s*:\s*[1-9]/;
|
|
47916
|
+
var OK_CODE_RE = /"code"\s*:\s*0\b/;
|
|
47917
|
+
var MESSAGE_ID_RE = /"?(?:message_id|messageId)"?\s*[:=]\s*"?om_[A-Za-z0-9_-]+/;
|
|
47918
|
+
var textOf = (value) => {
|
|
47919
|
+
if (typeof value === "string") return value;
|
|
47920
|
+
if (value == null) return "";
|
|
47921
|
+
try {
|
|
47922
|
+
return JSON.stringify(value);
|
|
47923
|
+
} catch {
|
|
47924
|
+
return "";
|
|
47925
|
+
}
|
|
47926
|
+
};
|
|
47927
|
+
var commandOf = (input) => {
|
|
47928
|
+
if (typeof input === "string") return input;
|
|
47929
|
+
if (!input || typeof input !== "object") return "";
|
|
47930
|
+
const parts = [];
|
|
47931
|
+
const walk2 = (v3, depth) => {
|
|
47932
|
+
if (depth > 4 || v3 == null) return;
|
|
47933
|
+
if (typeof v3 === "string") parts.push(v3);
|
|
47934
|
+
else if (Array.isArray(v3)) for (const item of v3) walk2(item, depth + 1);
|
|
47935
|
+
else if (typeof v3 === "object") for (const item of Object.values(v3)) walk2(item, depth + 1);
|
|
47936
|
+
};
|
|
47937
|
+
walk2(input, 0);
|
|
47938
|
+
return parts.join("\n");
|
|
47939
|
+
};
|
|
47940
|
+
var targetChatOf = (command) => {
|
|
47941
|
+
for (const re2 of TARGET_CHAT_RES) {
|
|
47942
|
+
const m3 = re2.exec(command);
|
|
47943
|
+
if (m3) return m3[1];
|
|
47944
|
+
}
|
|
47945
|
+
return void 0;
|
|
47946
|
+
};
|
|
47947
|
+
var targetChatInOutput = (output) => {
|
|
47948
|
+
const text = textOf(output);
|
|
47949
|
+
const m3 = /"?chat_id"?\s*:\s*"?(oc_[A-Za-z0-9_-]+)/.exec(text);
|
|
47950
|
+
return m3?.[1];
|
|
47951
|
+
};
|
|
47952
|
+
var isSendCommand = (command) => command.includes("lark-cli") && !DRY_RUN_RE.test(command) && SEND_COMMAND_RES.some((re2) => re2.test(command));
|
|
47953
|
+
var isSentResult = (output, error) => {
|
|
47954
|
+
if (error != null) return false;
|
|
47955
|
+
const text = textOf(output);
|
|
47956
|
+
if (!text) return false;
|
|
47957
|
+
if (FAILED_CODE_RE.test(text)) return false;
|
|
47958
|
+
return OK_CODE_RE.test(text) || MESSAGE_ID_RE.test(text);
|
|
47959
|
+
};
|
|
47960
|
+
var realChatIdOf = (chatId) => chatId.split(":")[0] ?? chatId;
|
|
47961
|
+
function detectLarkToolSend(events, chatId) {
|
|
47962
|
+
const expected = realChatIdOf(chatId);
|
|
47963
|
+
if (!expected) return false;
|
|
47964
|
+
let start = 0;
|
|
47965
|
+
for (let i2 = events.length - 1; i2 >= 0; i2--) {
|
|
47966
|
+
const ev = events[i2];
|
|
47967
|
+
if (ev.kind !== "user_text") continue;
|
|
47968
|
+
if (!isResumePrompt(ev.text)) {
|
|
47969
|
+
start = i2 + 1;
|
|
47970
|
+
break;
|
|
47971
|
+
}
|
|
47972
|
+
}
|
|
47973
|
+
const calls = /* @__PURE__ */ new Map();
|
|
47974
|
+
for (const ev of events.slice(start)) {
|
|
47975
|
+
if (ev.kind === "tool_call") {
|
|
47976
|
+
const command2 = commandOf(ev.input);
|
|
47977
|
+
if (isSendCommand(command2)) calls.set(ev.toolUseId, command2);
|
|
47978
|
+
continue;
|
|
47979
|
+
}
|
|
47980
|
+
if (ev.kind !== "tool_result") continue;
|
|
47981
|
+
const command = calls.get(ev.toolUseId);
|
|
47982
|
+
if (!command) continue;
|
|
47983
|
+
if (!isSentResult(ev.output, ev.error)) continue;
|
|
47984
|
+
if (targetChatOf(command) === expected) return true;
|
|
47985
|
+
if (targetChatInOutput(ev.output) === expected) return true;
|
|
47986
|
+
}
|
|
47987
|
+
return false;
|
|
47988
|
+
}
|
|
47989
|
+
function createLarkSendWatch(chatId) {
|
|
47990
|
+
const expected = realChatIdOf(chatId);
|
|
47991
|
+
let fired = false;
|
|
47992
|
+
const calls = /* @__PURE__ */ new Map();
|
|
47993
|
+
return (event) => {
|
|
47994
|
+
if (fired || !expected) return fired;
|
|
47995
|
+
if (event.kind === "tool_call") {
|
|
47996
|
+
const command2 = commandOf(event.input);
|
|
47997
|
+
if (isSendCommand(command2)) calls.set(event.toolUseId, command2);
|
|
47998
|
+
return fired;
|
|
47999
|
+
}
|
|
48000
|
+
if (event.kind !== "tool_result") return fired;
|
|
48001
|
+
const command = calls.get(event.toolUseId);
|
|
48002
|
+
if (!command) return fired;
|
|
48003
|
+
if (!isSentResult(event.output, event.error)) return fired;
|
|
48004
|
+
if (targetChatOf(command) === expected || targetChatInOutput(event.output) === expected) fired = true;
|
|
48005
|
+
return fired;
|
|
48006
|
+
};
|
|
48007
|
+
}
|
|
48008
|
+
|
|
47900
48009
|
// src/session/runner.ts
|
|
47901
48010
|
var import_node_os9 = __toESM(require("os"), 1);
|
|
47902
48011
|
var import_node_path15 = __toESM(require("path"), 1);
|
|
@@ -51703,29 +51812,49 @@ var SessionManager = class {
|
|
|
51703
51812
|
r2.input({ kind: "command", command: { kind: "stop" } });
|
|
51704
51813
|
};
|
|
51705
51814
|
const settleDelayMs = args.settleDelayMs ?? (this.deps.mode === "tui" ? 500 : 0);
|
|
51815
|
+
const sendWatch = createLarkSendWatch(args.chatId);
|
|
51816
|
+
let sentDuringTurn = false;
|
|
51817
|
+
const observeFrame = (frame) => {
|
|
51818
|
+
if (sentDuringTurn || frame?.type !== "session:event" || !frame.event) return;
|
|
51819
|
+
if (!sendWatch(frame.event)) return;
|
|
51820
|
+
sentDuringTurn = true;
|
|
51821
|
+
};
|
|
51822
|
+
const repliedByToolOf = (events) => sentDuringTurn || detectLarkToolSend(events, args.chatId);
|
|
51706
51823
|
const extractAndSettle = () => {
|
|
51707
51824
|
try {
|
|
51708
51825
|
const events = this.readHistoryEventsForScope(sessionId, scope);
|
|
51709
51826
|
const replyText = extractLarkReplyText(events);
|
|
51710
|
-
|
|
51827
|
+
const repliedByTool = repliedByToolOf(events);
|
|
51828
|
+
settle(replyText ? { ok: true, replyText, ...repliedByTool ? { repliedByTool: true } : {} } : repliedByTool ? { ok: true, replyText: "", repliedByTool: true } : { error: "empty reply" });
|
|
51711
51829
|
} catch (err) {
|
|
51712
51830
|
settle({ error: err.message });
|
|
51713
51831
|
}
|
|
51714
51832
|
};
|
|
51715
|
-
|
|
51716
|
-
|
|
51717
|
-
|
|
51718
|
-
|
|
51719
|
-
|
|
51720
|
-
|
|
51721
|
-
|
|
51722
|
-
|
|
51723
|
-
|
|
51724
|
-
|
|
51725
|
-
|
|
51726
|
-
|
|
51727
|
-
|
|
51728
|
-
|
|
51833
|
+
const sentByTool = () => {
|
|
51834
|
+
if (sentDuringTurn) return true;
|
|
51835
|
+
try {
|
|
51836
|
+
return detectLarkToolSend(this.readHistoryEventsForScope(sessionId, scope), args.chatId);
|
|
51837
|
+
} catch {
|
|
51838
|
+
return false;
|
|
51839
|
+
}
|
|
51840
|
+
};
|
|
51841
|
+
const settleError = (message) => {
|
|
51842
|
+
settle(sentByTool() ? { ok: true, replyText: "", repliedByTool: true } : { error: message });
|
|
51843
|
+
};
|
|
51844
|
+
const onEndFrame = makeEndFrameHandler(sessionId, (info) => {
|
|
51845
|
+
if (info.kind === "idle") {
|
|
51846
|
+
if (settleDelayMs === 0) extractAndSettle();
|
|
51847
|
+
else setTimeout(extractAndSettle, settleDelayMs);
|
|
51848
|
+
} else if (info.kind === "stopped") {
|
|
51849
|
+
settleError("session stopped before reply");
|
|
51850
|
+
} else {
|
|
51851
|
+
settleError(info.message || "session error");
|
|
51852
|
+
}
|
|
51853
|
+
});
|
|
51854
|
+
unsubscribe = this.subscribe(sessionId, scope, (frame) => {
|
|
51855
|
+
observeFrame(frame);
|
|
51856
|
+
onEndFrame(frame);
|
|
51857
|
+
});
|
|
51729
51858
|
const runner = this.ensureRunnerForScope(file, scope);
|
|
51730
51859
|
runner.input({
|
|
51731
51860
|
kind: "command",
|
|
@@ -57371,7 +57500,7 @@ function ledgerOf(t2) {
|
|
|
57371
57500
|
function stateOf(t2) {
|
|
57372
57501
|
return t2.status.state.replace(/^TASK_STATE_/, "").toLowerCase();
|
|
57373
57502
|
}
|
|
57374
|
-
var
|
|
57503
|
+
var textOf2 = (m3) => (m3?.parts ?? []).map((p3) => typeof p3.text === "string" ? p3.text : "").filter(Boolean).join("\n");
|
|
57375
57504
|
function firstUserMessage(t2) {
|
|
57376
57505
|
return t2.history?.find((m3) => m3.role === "ROLE_USER");
|
|
57377
57506
|
}
|
|
@@ -57407,9 +57536,9 @@ function toTaskView(t2, workerSessionId) {
|
|
|
57407
57536
|
executorThreadId: l2.executor.threadId,
|
|
57408
57537
|
...workerSessionId ? { workerSessionId } : {},
|
|
57409
57538
|
...sessionLabel ? { sessionLabel } : {},
|
|
57410
|
-
taskText:
|
|
57539
|
+
taskText: textOf2(firstUserMessage(t2)),
|
|
57411
57540
|
brief: typeof brief === "string" && brief ? brief : null,
|
|
57412
|
-
resultText: (resultArtifact ?
|
|
57541
|
+
resultText: (resultArtifact ? textOf2({ messageId: "", role: "ROLE_AGENT", parts: resultArtifact.parts }) : "") || textOf2(lastAgent) || null,
|
|
57413
57542
|
filePaths: Array.isArray(filePaths) ? filePaths.filter((p3) => typeof p3 === "string") : [],
|
|
57414
57543
|
line: t2.metadata[A2A_LINE_EXTENSION] ?? {},
|
|
57415
57544
|
deliveredAt: l2.deliveredAt,
|
|
@@ -57441,7 +57570,7 @@ You may read this file with your Read tool to understand context. You do not hav
|
|
|
57441
57570
|
const detail = `${head}
|
|
57442
57571
|
|
|
57443
57572
|
Task:
|
|
57444
|
-
${
|
|
57573
|
+
${textOf2(msg)}${source}
|
|
57445
57574
|
|
|
57446
57575
|
When done, call \`a2aReport\` from the \`clawd-a2a\` MCP server (e.g. \`mcp__clawd-a2a__a2aReport\` in claude):
|
|
57447
57576
|
- done: { state: "completed", text, brief, filePaths? }
|
|
@@ -67536,6 +67665,11 @@ ${formatLarkSpeakerReminder(speaker)}`
|
|
|
67536
67665
|
deps.logger?.warn(`larkBot turn error (${last.chatId}): ${result.error}`);
|
|
67537
67666
|
}
|
|
67538
67667
|
const absorbed = envs.slice(0, -1).map((e) => e.eventId);
|
|
67668
|
+
const repliedByTool = "ok" in result && result.repliedByTool === true;
|
|
67669
|
+
if (repliedByTool) {
|
|
67670
|
+
deps.logger?.info(`larkBot already replied by tool (${last.chatId}), suppressing auto reply`);
|
|
67671
|
+
}
|
|
67672
|
+
const replyBody = repliedByTool ? replyText || "[replied-by-tool]" : replyText;
|
|
67539
67673
|
for (let attempt = 0; attempt <= replyDelays.length; attempt++) {
|
|
67540
67674
|
if (attempt > 0) await sleep2(replyDelays[attempt - 1]);
|
|
67541
67675
|
try {
|
|
@@ -67544,8 +67678,10 @@ ${formatLarkSpeakerReminder(speaker)}`
|
|
|
67544
67678
|
// 回复走真身:chatId 自 spec 2026-09-10 起是虚拟三段式,只作会话 key 用
|
|
67545
67679
|
chatId: last.realChatId ?? last.chatId,
|
|
67546
67680
|
replyToMessageId: replyAnchorOf(last),
|
|
67547
|
-
text:
|
|
67681
|
+
text: replyBody,
|
|
67548
67682
|
eventId: last.eventId,
|
|
67683
|
+
// 工具已代发:中心只销账不发送(台账仍要关,否则重启认领会重跑同一事件)
|
|
67684
|
+
...repliedByTool ? { repliedByTool: true } : {},
|
|
67549
67685
|
// 文档评论:云端据此走评论回复接口而非 IM(显式字段,不靠 chatId 前缀猜)
|
|
67550
67686
|
...last.type === "doc_comment" ? { docComment: { fileToken: last.fileToken, fileType: last.fileType ?? "docx" } } : {},
|
|
67551
67687
|
...absorbed.length > 0 ? { absorbedEventIds: absorbed } : {}
|
|
@@ -76541,7 +76677,7 @@ function computeMethodAccess(args) {
|
|
|
76541
76677
|
}
|
|
76542
76678
|
|
|
76543
76679
|
// src/version.ts
|
|
76544
|
-
var version = "0.2.
|
|
76680
|
+
var version = "0.2.763".length > 0 ? "0.2.763" : "dev";
|
|
76545
76681
|
|
|
76546
76682
|
// src/cli-probe/probe.ts
|
|
76547
76683
|
var fs87 = __toESM(require("fs"), 1);
|