@clawos-dev/clawd 0.2.255 → 0.2.257
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 +72 -27
- package/dist/dispatch/mcp-server.cjs +18 -2
- package/dist/share-md-viewer-error.html +1 -1
- package/dist/share-md-viewer.html +1 -1
- package/dist/share-ui/assets/{guest-BnunifuX.js → guest-D7iXbNdh.js} +1 -1
- package/dist/share-ui/assets/{guest-53QJqRhe.css → guest-DTAqwGDc.css} +1 -1
- package/dist/share-ui/guest.html +2 -2
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -6238,7 +6238,13 @@ var init_dispatch = __esm({
|
|
|
6238
6238
|
// 合法值集与 claude adapter capabilities.models[].id 一致(见 daemon
|
|
6239
6239
|
// tools/claude.ts CLAUDE_MODEL_IDS);handler 层做二次校验,非法值 fail-fast。
|
|
6240
6240
|
// protocol 层保持 string 便于未来跨 tool 扩展(届时 union 收合法字面量)。
|
|
6241
|
-
model: external_exports.string().min(1).optional()
|
|
6241
|
+
model: external_exports.string().min(1).optional(),
|
|
6242
|
+
// 可选:给新 worker session 起 label(写入 SessionFile.label,sidebar 显示)。
|
|
6243
|
+
// 仅在**新开 dispatch**(dispatchId 缺席)时生效;续派(dispatchId 非空)
|
|
6244
|
+
// 时 daemon 层静默丢弃(避免半途改 label 造成 sidebar 抖动)。
|
|
6245
|
+
// 上限 60 字符——sidebar 显示 tolerance,卡在 dispatch 入口即可。
|
|
6246
|
+
// 协议层不硬拒 sessionLabel + dispatchId 同传,保留 forward-compat。
|
|
6247
|
+
sessionLabel: external_exports.string().min(1).max(60).optional()
|
|
6242
6248
|
}).refine((v2) => v2.targetPersona !== void 0 || v2.dispatchId !== void 0, {
|
|
6243
6249
|
message: "either targetPersona (new dispatch) or dispatchId (follow-up) is required"
|
|
6244
6250
|
}).refine((v2) => !(v2.dispatchId !== void 0 && v2.targetDeviceId !== void 0), {
|
|
@@ -40768,6 +40774,7 @@ init_protocol();
|
|
|
40768
40774
|
var DEFAULT_PORT = 18790;
|
|
40769
40775
|
var DEFAULT_HOST = "127.0.0.1";
|
|
40770
40776
|
var DEFAULT_CLAWOS_API = "https://api.clawos.chat";
|
|
40777
|
+
var DEFAULT_OWNER_IDLE_KILL_DELAY_MS = 6 * 60 * 60 * 1e3;
|
|
40771
40778
|
var DEFAULT_LOG_ENDPOINT = "https://clawd-prod.cn-hangzhou.log.aliyuncs.com/logstores/app-logs/track";
|
|
40772
40779
|
function resolveLogShipping(raw, cliNoShipping) {
|
|
40773
40780
|
if (cliNoShipping) {
|
|
@@ -40782,6 +40789,12 @@ function resolveLogShipping(raw, cliNoShipping) {
|
|
|
40782
40789
|
const sampling = mode === "errors-only" ? { debug: 0, info: 0, warn: 1, error: 1 } : isPlainSamplingMap(raw?.sampling) ? raw.sampling : {};
|
|
40783
40790
|
return { mode, endpoint, sampling };
|
|
40784
40791
|
}
|
|
40792
|
+
function resolveIdleKillMs(raw) {
|
|
40793
|
+
if (raw === void 0 || raw === null || raw === "") return null;
|
|
40794
|
+
const n = typeof raw === "number" ? raw : Number(raw);
|
|
40795
|
+
if (!Number.isFinite(n) || n < 0) return null;
|
|
40796
|
+
return n;
|
|
40797
|
+
}
|
|
40785
40798
|
function isPlainSamplingMap(v2) {
|
|
40786
40799
|
if (!v2 || typeof v2 !== "object") return false;
|
|
40787
40800
|
return Object.values(v2).every((n) => typeof n === "number");
|
|
@@ -40879,6 +40892,7 @@ function resolveConfig(opts) {
|
|
|
40879
40892
|
const mode = DAEMON_MODE_VALUES.includes(rawMode ?? "") ? rawMode : "sdk";
|
|
40880
40893
|
const filePreviewPorts = Array.isArray(fileCfg.previewPorts) ? fileCfg.previewPorts.map((n) => Number(n)).filter((n) => Number.isInteger(n) && n > 0) : null;
|
|
40881
40894
|
const previewPorts = env.CLAWD_PREVIEW_PORTS ? env.CLAWD_PREVIEW_PORTS.split(",").map((s) => Number(s.trim())).filter((n) => Number.isInteger(n) && n > 0) : filePreviewPorts && filePreviewPorts.length > 0 ? filePreviewPorts : null;
|
|
40895
|
+
const ownerIdleKillDelayMs = resolveIdleKillMs(env.CLAWD_OWNER_IDLE_KILL_DELAY_MS) ?? resolveIdleKillMs(fileCfg.ownerIdleKillDelayMs) ?? DEFAULT_OWNER_IDLE_KILL_DELAY_MS;
|
|
40882
40896
|
const logShipping = resolveLogShipping(
|
|
40883
40897
|
fileCfg.logShipping,
|
|
40884
40898
|
args.noLogShipping ?? false
|
|
@@ -40896,7 +40910,8 @@ function resolveConfig(opts) {
|
|
|
40896
40910
|
frpcBinary,
|
|
40897
40911
|
mode,
|
|
40898
40912
|
previewPorts,
|
|
40899
|
-
logShipping
|
|
40913
|
+
logShipping,
|
|
40914
|
+
ownerIdleKillDelayMs
|
|
40900
40915
|
};
|
|
40901
40916
|
}
|
|
40902
40917
|
var HELP_TEXT = `clawd [options]
|
|
@@ -40923,6 +40938,10 @@ Env (advanced):
|
|
|
40923
40938
|
CLAWD_CC_MODE CC \u5B50\u8FDB\u7A0B\u4EA4\u4E92\u6A21\u5F0F\uFF1A'sdk'\uFF08\u9ED8\u8BA4\uFF0C--print stream-json\uFF09/ 'tui'\uFF08pty \u4EA4\u4E92\u5F0F\uFF09\uFF1B
|
|
40924
40939
|
\u503C\u975E\u5408\u6CD5\u5B57\u9762\u91CF\u65F6\u9759\u9ED8\u56DE\u9000 'sdk'\u3002ready \u5E27 mode \u5B57\u6BB5\u900F\u4F20\u7ED9 UI\uFF1B
|
|
40925
40940
|
'tui' \u6A21\u5F0F\u989D\u5916\u63A8 session:control + session:pty \u4E24\u4E2A\u5E27\uFF08\u4E1A\u52A1\u5E27\u540D\u4E0D\u53D8\uFF09
|
|
40941
|
+
CLAWD_OWNER_IDLE_KILL_DELAY_MS
|
|
40942
|
+
owner persona session \u95F2\u7F6E\u56DE\u6536\u515C\u5E95\u4E0A\u9650\uFF08ms\uFF0C\u9ED8\u8BA4 21600000 = 6h\uFF09\uFF1B
|
|
40943
|
+
\u8BBE 0 \u5173\u95ED\u56DE\u6536\u3002\u4E5F\u53EF\u5199 config.json \u7684 ownerIdleKillDelayMs\u3002
|
|
40944
|
+
guest session \u7684 10min \u662F\u72EC\u7ACB\u5EF6\u8FDF\uFF0C\u4E0D\u53D7\u6B64\u9879\u5F71\u54CD
|
|
40926
40945
|
`;
|
|
40927
40946
|
|
|
40928
40947
|
// src/index.ts
|
|
@@ -41406,12 +41425,14 @@ function scopeSubPath(scope) {
|
|
|
41406
41425
|
if (scope.mode === "guest") return [scope.personaId, "guests", scope.capId];
|
|
41407
41426
|
return [scope.personaId, scope.mode];
|
|
41408
41427
|
}
|
|
41409
|
-
|
|
41428
|
+
var GUEST_IDLE_KILL_DELAY_MS = 6e5;
|
|
41429
|
+
function metaFromScope(scope, personaRoot, usersRoot, ownerPrincipalId, callerDisplayName, callerFeishuUnionId, opts) {
|
|
41410
41430
|
if (scope.kind === "default") return void 0;
|
|
41431
|
+
const ownerDelay = opts?.ownerIdleKillDelayMs !== void 0 && opts.ownerIdleKillDelayMs > 0 ? opts.ownerIdleKillDelayMs : void 0;
|
|
41411
41432
|
if (scope.mode === "owner") {
|
|
41412
41433
|
if (!ownerPrincipalId || !usersRoot) {
|
|
41413
41434
|
return {
|
|
41414
|
-
|
|
41435
|
+
idleKillDelayMs: ownerDelay,
|
|
41415
41436
|
personaMode: "owner",
|
|
41416
41437
|
callerDisplayName,
|
|
41417
41438
|
callerDeviceId: ownerPrincipalId,
|
|
@@ -41420,7 +41441,7 @@ function metaFromScope(scope, personaRoot, usersRoot, ownerPrincipalId, callerDi
|
|
|
41420
41441
|
}
|
|
41421
41442
|
const userWorkDir2 = deriveUserWorkDir(ownerPrincipalId, usersRoot);
|
|
41422
41443
|
return {
|
|
41423
|
-
|
|
41444
|
+
idleKillDelayMs: ownerDelay,
|
|
41424
41445
|
personaMode: "owner",
|
|
41425
41446
|
userWorkDir: userWorkDir2,
|
|
41426
41447
|
addDirs: [userWorkDir2],
|
|
@@ -41431,7 +41452,7 @@ function metaFromScope(scope, personaRoot, usersRoot, ownerPrincipalId, callerDi
|
|
|
41431
41452
|
}
|
|
41432
41453
|
const userWorkDir = deriveUserWorkDir(scope.capId, usersRoot);
|
|
41433
41454
|
return {
|
|
41434
|
-
|
|
41455
|
+
idleKillDelayMs: GUEST_IDLE_KILL_DELAY_MS,
|
|
41435
41456
|
personaMode: "guest",
|
|
41436
41457
|
userWorkDir,
|
|
41437
41458
|
addDirs: [userWorkDir],
|
|
@@ -41932,20 +41953,23 @@ var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7E
|
|
|
41932
41953
|
- \u53EA\u80FD\u5206\u4EAB\u4F60\u81EA\u5DF1\u5DE5\u4F5C\u76EE\u5F55\u5185\u7684\u6587\u4EF6\uFF0C\u8D8A\u754C\u4F1A\u88AB\u62D2\u3002
|
|
41933
41954
|
- \u88AB dispatch \u63A5\u5230\u4EFB\u52A1\u3001\u8981\u56DE\u4F20\u4EA7\u7269\u65F6\uFF1A\u628A\u7B7E\u540D URL \u5199\u8FDB \`personaDispatchComplete\` tool\uFF08\`clawd-dispatch\` MCP\uFF09\u7684 \`text\` \u91CC\uFF08\`filePaths\` \u53EA\u662F\u4F60\u672C\u673A\u7684\u7EDD\u5BF9\u8DEF\u5F84\uFF0C\u8DE8\u8BBE\u5907\u5BF9\u65B9\u6253\u4E0D\u5F00\uFF0CURL \u624D\u80FD\u6253\u5F00\uFF09\u3002`;
|
|
41934
41955
|
|
|
41956
|
+
// src/persona/no-ask-user-question-prompt.ts
|
|
41957
|
+
var NO_ASK_USER_QUESTION_HINT = `## \u9700\u8981\u8001\u677F\u62CD\u677F\u65F6\u600E\u4E48\u95EE
|
|
41958
|
+
|
|
41959
|
+
\u8981\u8001\u677F\u9009\u62E9 / \u786E\u8BA4 / \u62CD\u677F\u65F6\uFF0C\u76F4\u63A5\u6B63\u6587\u5199\u95EE\u9898 + \u5217 A/B/C \u9009\u9879\u3002\u4E0D\u8981\u8C03 AskUserQuestion tool\u3002`;
|
|
41960
|
+
|
|
41935
41961
|
// src/dispatch/system-prompt.ts
|
|
41936
41962
|
var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
|
|
41937
41963
|
|
|
41938
|
-
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-app-builder\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 \`clawd-dispatch\` MCP
|
|
41964
|
+
\u5F53\u7528\u6237\u6D88\u606F\u91CC\u542B \`@persona/<id>\`\uFF08\u5982 \`@persona/persona-app-builder\`\uFF09\u65F6\uFF0C**\u4F60\u5FC5\u987B**\u7ACB\u5373\u8C03 \`clawd-dispatch\` MCP \u7684 \`personaDispatch\` tool \u59D4\u6D3E\uFF1A
|
|
41939
41965
|
|
|
41940
41966
|
- \`targetPersona = <id>\`\uFF08@ token \u91CC\u7684 persona id\uFF09
|
|
41941
41967
|
- \`prompt = \u53BB\u6389 @persona/<id> token \u7684\u7528\u6237\u539F\u6587\`
|
|
41942
41968
|
|
|
41943
|
-
|
|
41969
|
+
\u544A\u8BC9\u7528\u6237"\u4EFB\u52A1\u5DF2\u4EA4\u529E"\u5373\u53EF\u7ED3\u675F\u672C\u8F6E\u3002\u7ED3\u679C\u4F1A\u4F5C\u4E3A\u4E00\u6761\u65B0\u6D88\u606F\u81EA\u52A8\u6CE8\u5165\u56DE\u4F60\u7684 session\uFF0C\u5C4A\u65F6\u518D\u7EFC\u5408\u8F6C\u8FBE\u7ED9\u7528\u6237\u3002\u60F3\u67E5\u8FDB\u5C55\u65F6\uFF08\u7528\u6237\u95EE\u8D77\uFF09\u8C03\u540C\u4E00 MCP \u7684 \`personaDispatchList\`\u3002
|
|
41944
41970
|
|
|
41945
|
-
- **\u4E0D\u8981**\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF08\u4F60\u4E0D\u662F\u90A3\u4E2A persona\uFF09
|
|
41946
|
-
- **\u4E0D\u8981** in-place \u6A21\u4EFF\u5BF9\u65B9\u4EBA\u683C \u2014\u2014 dispatch \u662F\u771F\u5207\u5230\u53E6\u4E00\u4E2A\u72EC\u7ACB session
|
|
41971
|
+
- **\u4E0D\u8981**\u5C1D\u8BD5\u81EA\u5DF1\u6267\u884C\uFF08\u4F60\u4E0D\u662F\u90A3\u4E2A persona\uFF09\uFF0C\u4E5F\u4E0D\u8981 in-place \u6A21\u4EFF\u5BF9\u65B9\u4EBA\u683C \u2014\u2014 dispatch \u662F\u771F\u5207\u5230\u53E6\u4E00\u4E2A\u72EC\u7ACB session
|
|
41947
41972
|
- \u4E00\u53E5\u8BDD\u91CC\u591A\u4E2A \`@persona/<id>\` \u65F6\u9009\u7B2C\u4E00\u4E2A\uFF08tool \u4E00\u6B21\u53EA\u5904\u7406\u4E00\u4E2A target\uFF09
|
|
41948
|
-
- \u59D4\u6D3E\u5931\u8D25\uFF08tool_result.is_error=true\uFF09\u65F6\u5982\u5B9E\u544A\u8BC9\u7528\u6237\u539F\u56E0\uFF0C**\u4E0D\u8981\u91CD\u8BD5**
|
|
41949
41973
|
|
|
41950
41974
|
### \u7EED\u6D3E\uFF08\u540C\u4E00\u4EF6\u4E8B\u7684\u540E\u7EED\u6307\u4EE4\uFF09
|
|
41951
41975
|
|
|
@@ -41953,15 +41977,15 @@ tool \u4F1A**\u7ACB\u5373\u8FD4\u56DE** dispatchId\uFF08\u5F02\u6B65\u59D4\u6D3E
|
|
|
41953
41977
|
|
|
41954
41978
|
### \u8DE8\u8BBE\u5907\u59D4\u6D3E\uFF08remote persona\uFF09
|
|
41955
41979
|
|
|
41956
|
-
\u5F53 @ token \u5F62\u5982 \`@persona/<id>@<deviceId>\`\uFF08\u7B2C\u4E8C\u6BB5\u662F\u8054\u7CFB\u4EBA**\u8BBE\u5907\u7684 deviceId**\uFF0CUI \u9009\u8054\u7CFB\u4EBA\u65F6\u5DF2\u89E3\u6790\u597D\u586B\u5165\uFF09\u65F6\uFF0C\u662F\u628A\u4EFB\u52A1\u59D4\u6D3E\u7ED9\u90A3\u53F0\u8BBE\u5907\u4E0A\u7684 persona\u3002\u9664 targetPersona / prompt \u5916\u518D\u5E26\
|
|
41980
|
+
\u5F53 @ token \u5F62\u5982 \`@persona/<id>@<deviceId>\`\uFF08\u7B2C\u4E8C\u6BB5\u662F\u8054\u7CFB\u4EBA**\u8BBE\u5907\u7684 deviceId**\uFF0CUI \u9009\u8054\u7CFB\u4EBA\u65F6\u5DF2\u89E3\u6790\u597D\u586B\u5165\uFF09\u65F6\uFF0C\u662F\u628A\u4EFB\u52A1\u59D4\u6D3E\u7ED9\u90A3\u53F0\u8BBE\u5907\u4E0A\u7684 persona\u3002\u9664 targetPersona / prompt \u5916\u518D\u5E26\uFF1A
|
|
41957
41981
|
|
|
41958
41982
|
- \`targetDeviceId = <token \u7B2C\u4E8C\u6BB5\u7684 deviceId\uFF0C\u539F\u6837\u586B>\`
|
|
41959
41983
|
|
|
41960
|
-
deviceId \u76F4\u63A5\u53D6\u81EA token\uFF0C\u4E0D\u8981\u6539\u5199\u6216\u731C\u6D4B\u3002
|
|
41984
|
+
deviceId \u76F4\u63A5\u53D6\u81EA token\uFF0C\u4E0D\u8981\u6539\u5199\u6216\u731C\u6D4B\u3002
|
|
41961
41985
|
|
|
41962
41986
|
## \u88AB dispatch \u63A5\u5230\u4EFB\u52A1
|
|
41963
41987
|
|
|
41964
|
-
\u5982\u679C\u4F60\u7684 session \u7B2C\u4E00\u6761 user message \u662F\u4EE5 \`[Dispatched from owner \u2014 another persona session\u59D4\u6D3E\u7ED9\u4F60\u6267\u884C\u4EFB\u52A1]\` \u8D77\u5934\u7684 plain text \u4EFB\u52A1\u5305\uFF0C\u4F60\u662F\u88AB\u53E6\u4E00\u4E2A persona \u59D4\u6D3E\u6765\u5E72\u6D3B\u7684\
|
|
41988
|
+
\u5982\u679C\u4F60\u7684 session \u7B2C\u4E00\u6761 user message \u662F\u4EE5 \`[Dispatched from owner \u2014 another persona session\u59D4\u6D3E\u7ED9\u4F60\u6267\u884C\u4EFB\u52A1]\` \u8D77\u5934\u7684 plain text \u4EFB\u52A1\u5305\uFF0C\u4F60\u662F\u88AB\u53E6\u4E00\u4E2A persona \u59D4\u6D3E\u6765\u5E72\u6D3B\u7684\uFF1A
|
|
41965
41989
|
|
|
41966
41990
|
- \u4EFB\u52A1\u5728 \`Task:\` \u6BB5
|
|
41967
41991
|
- \u539F\u4F1A\u8BDD\u7684\u5BF9\u8BDD\u5386\u53F2\u5728 \`Source conversation\` \u6BB5\u7ED9\u7684 jsonl \u8DEF\u5F84\u4E0B\uFF1B\u6309\u9700 Read \u5B83\u4E86\u89E3\u4E0A\u4E0B\u6587\uFF08\u4E0D\u5FC5\u8BFB\u5B8C\uFF09
|
|
@@ -42012,7 +42036,10 @@ function cloneState(s) {
|
|
|
42012
42036
|
currentTurnSender: s.currentTurnSender
|
|
42013
42037
|
};
|
|
42014
42038
|
}
|
|
42015
|
-
|
|
42039
|
+
function idleKillDelayOf(state) {
|
|
42040
|
+
const ms = state.subSessionMeta?.idleKillDelayMs;
|
|
42041
|
+
return ms !== void 0 && ms > 0 ? ms : void 0;
|
|
42042
|
+
}
|
|
42016
42043
|
function tryFlushPending(state, deps) {
|
|
42017
42044
|
if (!state.readyForSend || state.pendingSend.length === 0) return [];
|
|
42018
42045
|
const text = state.pendingSend.shift();
|
|
@@ -42126,6 +42153,9 @@ function buildSpawnContext(state, deps) {
|
|
|
42126
42153
|
if (daemonUrl) {
|
|
42127
42154
|
ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + ATTACHMENT_SHARING_HINT;
|
|
42128
42155
|
}
|
|
42156
|
+
if (meta?.personaMode && (file.tool ?? "claude") === "claude") {
|
|
42157
|
+
ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + NO_ASK_USER_QUESTION_HINT;
|
|
42158
|
+
}
|
|
42129
42159
|
if (meta?.extraSettings) {
|
|
42130
42160
|
ctx.extraSettings = meta.extraSettings;
|
|
42131
42161
|
}
|
|
@@ -42284,11 +42314,12 @@ function pushEventToBuffer(state, event, deps) {
|
|
|
42284
42314
|
status: "running-idle"
|
|
42285
42315
|
}
|
|
42286
42316
|
});
|
|
42287
|
-
|
|
42317
|
+
const idleKillMs = idleKillDelayOf(next);
|
|
42318
|
+
if (idleKillMs !== void 0) {
|
|
42288
42319
|
effects.push({
|
|
42289
42320
|
kind: "schedule-idle-kill",
|
|
42290
42321
|
sessionId: next.file.sessionId,
|
|
42291
|
-
ms:
|
|
42322
|
+
ms: idleKillMs
|
|
42292
42323
|
});
|
|
42293
42324
|
}
|
|
42294
42325
|
}
|
|
@@ -42725,14 +42756,15 @@ function reduceSessionInner(state, input, deps) {
|
|
|
42725
42756
|
if (state.status !== "running-idle") {
|
|
42726
42757
|
return { state, effects: [] };
|
|
42727
42758
|
}
|
|
42728
|
-
|
|
42759
|
+
const rescheduleMs = idleKillDelayOf(state);
|
|
42760
|
+
if (input.subagentActive && rescheduleMs !== void 0) {
|
|
42729
42761
|
return {
|
|
42730
42762
|
state,
|
|
42731
42763
|
effects: [
|
|
42732
42764
|
{
|
|
42733
42765
|
kind: "schedule-idle-kill",
|
|
42734
42766
|
sessionId: state.file.sessionId,
|
|
42735
|
-
ms:
|
|
42767
|
+
ms: rescheduleMs
|
|
42736
42768
|
}
|
|
42737
42769
|
]
|
|
42738
42770
|
};
|
|
@@ -43652,8 +43684,8 @@ var SessionManager = class {
|
|
|
43652
43684
|
// 经过 compressFrameForWire 后决定是 push collector 还是走 deps.broadcastFrame。
|
|
43653
43685
|
// scope 决定两件事:SessionStore 路由 + SubSessionMeta 派生(metaFromScope)。
|
|
43654
43686
|
// - default → 复用 deps.store,无 subSessionMeta(普通 session)
|
|
43655
|
-
// - persona/owner → personas/<pid>/.clawd/sessions/owner/,meta={
|
|
43656
|
-
// - persona/guest → personas/<pid>/.clawd/sessions/guests/<capId>/,meta={
|
|
43687
|
+
// - persona/owner → personas/<pid>/.clawd/sessions/owner/,meta={idleKillDelayMs:<config 默认 6h>, personaMode:'owner'}
|
|
43688
|
+
// - persona/guest → personas/<pid>/.clawd/sessions/guests/<capId>/,meta={idleKillDelayMs:10min, personaMode:'guest', extraSettings:<sandbox>}
|
|
43657
43689
|
newRunner(file, scope) {
|
|
43658
43690
|
const adapter = this.deps.getAdapter(file.tool ?? "claude");
|
|
43659
43691
|
const store = this.storeFor(scope);
|
|
@@ -43665,7 +43697,8 @@ var SessionManager = class {
|
|
|
43665
43697
|
this.deps.usersRoot ?? "",
|
|
43666
43698
|
this.deps.ownerPrincipalId,
|
|
43667
43699
|
callerDisplayName,
|
|
43668
|
-
callerFeishuUnionId
|
|
43700
|
+
callerFeishuUnionId,
|
|
43701
|
+
{ ownerIdleKillDelayMs: this.deps.ownerIdleKillDelayMs }
|
|
43669
43702
|
);
|
|
43670
43703
|
if (subSessionMeta?.userWorkDir) {
|
|
43671
43704
|
import_node_fs9.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
|
|
@@ -44503,8 +44536,8 @@ var SessionManager = class {
|
|
|
44503
44536
|
//
|
|
44504
44537
|
// 区别于 owner / default 单 sessionId 入口,这些 API 接 SessionScope 参数 ——
|
|
44505
44538
|
// 调用方(PersonaManager / observer 等)明确传 scope,由 storeFor 路由到正确目录:
|
|
44506
|
-
// - {kind:'persona', personaId, mode:'guest', capId} → guests/<capId>/,meta={idleKill:
|
|
44507
|
-
// - {kind:'persona', personaId, mode:'owner'} → owner/,meta={idleKill
|
|
44539
|
+
// - {kind:'persona', personaId, mode:'guest', capId} → guests/<capId>/,meta={idleKill:10min, sandbox}
|
|
44540
|
+
// - {kind:'persona', personaId, mode:'owner'} → owner/,meta={idleKill:<config 默认 6h>}
|
|
44508
44541
|
//
|
|
44509
44542
|
// SubSessionMeta 由 scope → metaFromScope 派生,不进 SessionFile schema。
|
|
44510
44543
|
/** 按 scope 读取 SessionFile;不存在返回 null */
|
|
@@ -44758,6 +44791,8 @@ var SessionManager = class {
|
|
|
44758
44791
|
} : {},
|
|
44759
44792
|
// T-20:dispatch model override 落盘(reducer spawn 路径读 SessionFile.model 生成 --model flag)
|
|
44760
44793
|
...args.model ? { model: args.model } : {},
|
|
44794
|
+
// butler 顶部入口:dispatch 传下来的 label 落盘,sidebar 显示(否则兜底 cwd-basename)
|
|
44795
|
+
...args.label ? { label: args.label } : {},
|
|
44761
44796
|
createdAt: now,
|
|
44762
44797
|
updatedAt: now
|
|
44763
44798
|
};
|
|
@@ -49415,7 +49450,10 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
49415
49450
|
guestDisplayName: ctx.principal.displayName,
|
|
49416
49451
|
// T-31: 把 A 的飞书 union_id 透传给 B(connectGuestContext 已把它挂在 principal.feishuUnionId)
|
|
49417
49452
|
...ctx.principal.feishuUnionId ? { guestFeishuUnionId: ctx.principal.feishuUnionId } : {},
|
|
49418
|
-
...args.model ? { model: args.model } : {}
|
|
49453
|
+
...args.model ? { model: args.model } : {},
|
|
49454
|
+
// butler 顶部入口:peer daemon 若在 forwardToPeer 里传了 sessionLabel(当前
|
|
49455
|
+
// 未接线,作 forward-compat 预留),这里也透给 spawnB
|
|
49456
|
+
...args.sessionLabel ? { label: args.sessionLabel } : {}
|
|
49419
49457
|
}).then(() => logger?.info("dispatch.spawnB.ok", { dispatchId: dispatchId2 })).catch((err) => {
|
|
49420
49458
|
const reason = err instanceof Error ? err.message : String(err);
|
|
49421
49459
|
logger?.warn("dispatch.spawnB.failed", { dispatchId: dispatchId2, reason });
|
|
@@ -49450,7 +49488,9 @@ function buildPersonaDispatchHandlers(deps) {
|
|
|
49450
49488
|
sourceSessionId,
|
|
49451
49489
|
targetPersona,
|
|
49452
49490
|
prompt: args.prompt,
|
|
49453
|
-
...args.model ? { model: args.model } : {}
|
|
49491
|
+
...args.model ? { model: args.model } : {},
|
|
49492
|
+
// butler 顶部入口(spec 2026-07-27):sessionLabel 落到 SessionFile.label 让 sidebar 显示
|
|
49493
|
+
...args.sessionLabel ? { label: args.sessionLabel } : {}
|
|
49454
49494
|
}).then(() => {
|
|
49455
49495
|
logger?.info("dispatch.spawnB.ok", { dispatchId });
|
|
49456
49496
|
}).catch((err) => {
|
|
@@ -59292,6 +59332,9 @@ async function startDaemon(config) {
|
|
|
59292
59332
|
ownerDisplayName,
|
|
59293
59333
|
ownerPrincipalId,
|
|
59294
59334
|
ownerFeishuUnionId,
|
|
59335
|
+
// T-37 owner session 闲置回收兜底上限(默认 6h,config.json / env 可调,设 0 关闭)。
|
|
59336
|
+
// guest 的 10min 不走这条——它是 session/scope.ts 的固定常量。
|
|
59337
|
+
ownerIdleKillDelayMs: config.ownerIdleKillDelayMs,
|
|
59295
59338
|
contactStore,
|
|
59296
59339
|
mode: config.mode,
|
|
59297
59340
|
// 单栏 refactor (spec 2026-06-02 §5.1):cc 子进程 env CLAWD_DAEMON_URL 闭包来源。
|
|
@@ -59773,7 +59816,9 @@ async function startDaemon(config) {
|
|
|
59773
59816
|
// T-31: 把 A 的飞书 union_id stamp 到 B SessionFile,供 cc prompt 身份卡 union_id 行
|
|
59774
59817
|
guestFeishuUnionId: args.guestFeishuUnionId,
|
|
59775
59818
|
// T-20: 可选 model override 透到 SessionFile.model
|
|
59776
|
-
...args.model ? { model: args.model } : {}
|
|
59819
|
+
...args.model ? { model: args.model } : {},
|
|
59820
|
+
// butler 顶部入口(spec 2026-07-27):可选 label 透到 SessionFile.label(sidebar 显示)
|
|
59821
|
+
...args.label ? { label: args.label } : {}
|
|
59777
59822
|
});
|
|
59778
59823
|
},
|
|
59779
59824
|
// A 角色:从 ContactStore 取 peer 可达 URL + connect token,转发到对端 daemon /rpc。
|
|
@@ -22734,7 +22734,13 @@ var DispatchRunArgsSchema = external_exports.object({
|
|
|
22734
22734
|
// 合法值集与 claude adapter capabilities.models[].id 一致(见 daemon
|
|
22735
22735
|
// tools/claude.ts CLAUDE_MODEL_IDS);handler 层做二次校验,非法值 fail-fast。
|
|
22736
22736
|
// protocol 层保持 string 便于未来跨 tool 扩展(届时 union 收合法字面量)。
|
|
22737
|
-
model: external_exports.string().min(1).optional()
|
|
22737
|
+
model: external_exports.string().min(1).optional(),
|
|
22738
|
+
// 可选:给新 worker session 起 label(写入 SessionFile.label,sidebar 显示)。
|
|
22739
|
+
// 仅在**新开 dispatch**(dispatchId 缺席)时生效;续派(dispatchId 非空)
|
|
22740
|
+
// 时 daemon 层静默丢弃(避免半途改 label 造成 sidebar 抖动)。
|
|
22741
|
+
// 上限 60 字符——sidebar 显示 tolerance,卡在 dispatch 入口即可。
|
|
22742
|
+
// 协议层不硬拒 sessionLabel + dispatchId 同传,保留 forward-compat。
|
|
22743
|
+
sessionLabel: external_exports.string().min(1).max(60).optional()
|
|
22738
22744
|
}).refine((v) => v.targetPersona !== void 0 || v.dispatchId !== void 0, {
|
|
22739
22745
|
message: "either targetPersona (new dispatch) or dispatchId (follow-up) is required"
|
|
22740
22746
|
}).refine((v) => !(v.dispatchId !== void 0 && v.targetDeviceId !== void 0), {
|
|
@@ -23557,7 +23563,10 @@ async function handlePersonaDispatchToolCall(input, ctx) {
|
|
|
23557
23563
|
...input.targetDeviceId ? { targetDeviceId: input.targetDeviceId } : {},
|
|
23558
23564
|
// T-20: 可选 override B session 使用的 claude 模型;MCP tool 层已 enum 校验,
|
|
23559
23565
|
// daemon handler 层还会再校验一次(fail-fast)。
|
|
23560
|
-
...input.model ? { model: input.model } : {}
|
|
23566
|
+
...input.model ? { model: input.model } : {},
|
|
23567
|
+
// butler 顶部入口:可选 sessionLabel 落到新 worker SessionFile.label。
|
|
23568
|
+
// 长度 1-60 由 protocol schema 强约束;续派场景(dispatchId 非空)daemon 层静默丢弃。
|
|
23569
|
+
...input.sessionLabel ? { sessionLabel: input.sessionLabel } : {}
|
|
23561
23570
|
})
|
|
23562
23571
|
});
|
|
23563
23572
|
} catch (err) {
|
|
@@ -23738,6 +23747,13 @@ async function main() {
|
|
|
23738
23747
|
// 精确校验(按 target persona tool 选表)在 daemon handler 层做(fail-fast)。
|
|
23739
23748
|
model: external_exports.enum([...CLAUDE_MODEL_IDS, ...CODEX_MODEL_IDS]).optional().describe(
|
|
23740
23749
|
"override the target persona's default model. Omit to use the persona default. Claude personas: " + CLAUDE_MODEL_IDS.join(" / ") + ". Codex personas: " + CODEX_MODEL_IDS.join(" / ") + "."
|
|
23750
|
+
),
|
|
23751
|
+
// butler 顶部入口 (spec 2026-07-27):butler 给新 worker session 起 label 用。
|
|
23752
|
+
// Sidebar 直接显示这个 label(否则兜底 cwd-basename 都是 persona 目录名,同一
|
|
23753
|
+
// persona 的 dispatched session 长得都一样)。仅新开 dispatch 生效;续派
|
|
23754
|
+
// (dispatchId set) 时 daemon 静默丢弃,保 worker session 稳定命名。
|
|
23755
|
+
sessionLabel: external_exports.string().optional().describe(
|
|
23756
|
+
'short human-readable label for the new worker session (shown in sidebar, e.g. "\u4FEE sidebar \u9876\u90E8\u5165\u53E3" / "\u67E5\u6628\u665A SLS \u767B\u5F55\u5931\u8D25"). aim for 8-14 chars, verb-led. ignored when continuing an existing dispatch via dispatchId (worker session keeps its original label).'
|
|
23741
23757
|
)
|
|
23742
23758
|
}
|
|
23743
23759
|
},
|