@clawos-dev/clawd 0.2.180-beta.360.ee0a26c → 0.2.181-beta.361.269b0f5
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 +73 -133
- package/dist/shift/mcp-server.cjs +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -253,7 +253,11 @@ var init_events = __esm({
|
|
|
253
253
|
"skill-hint",
|
|
254
254
|
"meta-text",
|
|
255
255
|
"attachment-skills",
|
|
256
|
-
"attachment-deferred-tools"
|
|
256
|
+
"attachment-deferred-tools",
|
|
257
|
+
// clawd shift v1:scheduler fire 时 daemon 给新 cc 的首条 user message 用
|
|
258
|
+
// <clawd-shift-fire> wrap 起头;classifyUserMessage 识别后路由到 UserMetaLine 折叠渲染,
|
|
259
|
+
// 不显示成 user 气泡(避免 instruction 文本被当 owner 实时对话)。
|
|
260
|
+
"clawd-shift-fire"
|
|
257
261
|
];
|
|
258
262
|
SKILL_SOURCE_VALUES = ["builtin", "global", "project", "plugin"];
|
|
259
263
|
AGENT_SOURCE_VALUES = [
|
|
@@ -11240,6 +11244,7 @@ function classifyUserMessage(input) {
|
|
|
11240
11244
|
if (SYSTEM_REMINDER_RE.test(text) || OPENSPEC_BLOCK_RE.test(text)) {
|
|
11241
11245
|
return { meta: "system-reminder" };
|
|
11242
11246
|
}
|
|
11247
|
+
if (CLAWD_SHIFT_FIRE_RE.test(text)) return { meta: "clawd-shift-fire" };
|
|
11243
11248
|
if (SKILL_HINT_RE.test(text)) return { meta: "skill-hint" };
|
|
11244
11249
|
const flags = raw;
|
|
11245
11250
|
if (flags.isMeta === true || flags.isSynthetic === true) return { meta: "meta-text" };
|
|
@@ -11454,7 +11459,7 @@ function readCurrentContent(filePath) {
|
|
|
11454
11459
|
return null;
|
|
11455
11460
|
}
|
|
11456
11461
|
}
|
|
11457
|
-
var import_node_fs10, import_node_os5, import_node_path9, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
|
|
11462
|
+
var import_node_fs10, import_node_os5, import_node_path9, TASK_NOTIFICATION_RE, TASK_ID_RE, TOOL_USE_ID_RE, SLASH_COMMAND_RE, LOCAL_COMMAND_RE, SYSTEM_REMINDER_RE, OPENSPEC_BLOCK_RE, SKILL_HINT_RE, CLAWD_SHIFT_FIRE_RE, ATTACHMENT_SILENT_SUBTYPES, ClaudeHistoryReader;
|
|
11458
11463
|
var init_claude_history = __esm({
|
|
11459
11464
|
"src/tools/claude-history.ts"() {
|
|
11460
11465
|
"use strict";
|
|
@@ -11471,6 +11476,7 @@ var init_claude_history = __esm({
|
|
|
11471
11476
|
SYSTEM_REMINDER_RE = /^\s*<system-reminder\b/i;
|
|
11472
11477
|
OPENSPEC_BLOCK_RE = /^\s*<!--\s*OPENSPEC\b/i;
|
|
11473
11478
|
SKILL_HINT_RE = /^\s*Base directory for this skill:\s/;
|
|
11479
|
+
CLAWD_SHIFT_FIRE_RE = /^\s*<clawd-shift-fire\b/i;
|
|
11474
11480
|
ATTACHMENT_SILENT_SUBTYPES = /* @__PURE__ */ new Set([
|
|
11475
11481
|
"hook_additional_context",
|
|
11476
11482
|
"hook_success",
|
|
@@ -41344,29 +41350,6 @@ function buildConnectionPrompt(args) {
|
|
|
41344
41350
|
return result;
|
|
41345
41351
|
}
|
|
41346
41352
|
|
|
41347
|
-
// src/persona/sharing-prompt.ts
|
|
41348
|
-
var ATTACHMENT_SHARING_HINT = `## \u628A\u4EA7\u51FA\u6587\u4EF6\u5206\u4EAB\u7ED9\u5BF9\u65B9\uFF08attachment\uFF09
|
|
41349
|
-
|
|
41350
|
-
\u5F53\u4F60\u4EA7\u51FA\u4E86\u6587\u4EF6\u3001\u9700\u8981\u8BA9\u5BF9\u65B9\u62FF\u5230\u65F6\uFF08\u5C24\u5176 Bash \u89E3\u538B/\u751F\u6210\u7684\u6587\u4EF6\uFF0C\u6216\u8DE8\u8BBE\u5907\u88AB\u59D4\u6D3E\u65F6\u5BF9\u65B9\u5728\u53E6\u4E00\u53F0\u673A\u5668\u3001\u770B\u4E0D\u5230\u4F60\u7684\u672C\u5730\u8DEF\u5F84\uFF09\uFF0C\u7528 daemon \u7684 HTTP RPC \u628A\u6587\u4EF6\u8F6C\u6210\u4E00\u4E2A\u5E26\u7B7E\u540D\u7684\u4E0B\u8F7D URL\uFF1A
|
|
41351
|
-
|
|
41352
|
-
1. \u5165\u7FA4\uFF08\u767B\u8BB0\u5230\u672C session \u7684\u5171\u4EAB\u6E05\u5355\uFF09\uFF1A
|
|
41353
|
-
\`\`\`bash
|
|
41354
|
-
curl -sS -X POST "$CLAWD_DAEMON_URL/api/rpc/attachment.groupAdd" \\
|
|
41355
|
-
-H "X-Clawd-Session-Id: $CLAWD_SESSION_ID" -H 'Content-Type: application/json' \\
|
|
41356
|
-
-d '{"relPath":"<\u6587\u4EF6\u7684\u7EDD\u5BF9\u8DEF\u5F84>"}'
|
|
41357
|
-
\`\`\`
|
|
41358
|
-
2. \u7B7E\u540D\u62FF URL\uFF1A
|
|
41359
|
-
\`\`\`bash
|
|
41360
|
-
curl -sS -X POST "$CLAWD_DAEMON_URL/api/rpc/attachment.signUrl" \\
|
|
41361
|
-
-H "X-Clawd-Session-Id: $CLAWD_SESSION_ID" -H 'Content-Type: application/json' \\
|
|
41362
|
-
-d '{"relPath":"<\u540C\u4E00\u4E2A\u7EDD\u5BF9\u8DEF\u5F84>"}'
|
|
41363
|
-
\`\`\`
|
|
41364
|
-
\u8FD4\u56DE\u7684 \`url\` \u5C31\u662F\u5BF9\u65B9\u53EF\u76F4\u63A5\u6253\u5F00/\u4E0B\u8F7D\u7684\u94FE\u63A5\u3002
|
|
41365
|
-
|
|
41366
|
-
- \`relPath\` \u5FC5\u987B\u4F20**\u7EDD\u5BF9\u8DEF\u5F84**\uFF08\u4F60\u4EA7\u51FA\u6587\u4EF6\u7684\u771F\u5B9E\u8DEF\u5F84\uFF09\uFF0C\u4E0D\u8981\u4F20\u76F8\u5BF9\u8DEF\u5F84\u3002
|
|
41367
|
-
- \u53EA\u80FD\u5206\u4EAB\u4F60\u81EA\u5DF1\u5DE5\u4F5C\u76EE\u5F55\u5185\u7684\u6587\u4EF6\uFF0C\u8D8A\u754C\u4F1A\u88AB\u62D2\u3002
|
|
41368
|
-
- \u88AB dispatch \u63A5\u5230\u4EFB\u52A1\u3001\u8981\u56DE\u4F20\u4EA7\u7269\u65F6\uFF1A\u628A\u7B7E\u540D URL \u5199\u8FDB \`personaDispatchComplete\` \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`;
|
|
41369
|
-
|
|
41370
41353
|
// src/dispatch/system-prompt.ts
|
|
41371
41354
|
var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
|
|
41372
41355
|
|
|
@@ -41532,9 +41515,6 @@ function buildSpawnContext(state, deps) {
|
|
|
41532
41515
|
if (dispatchMcpConfigPath2) {
|
|
41533
41516
|
ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + DISPATCH_SYSTEM_PROMPT_HINT;
|
|
41534
41517
|
}
|
|
41535
|
-
if (daemonUrl) {
|
|
41536
|
-
ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + ATTACHMENT_SHARING_HINT;
|
|
41537
|
-
}
|
|
41538
41518
|
if (meta?.extraSettings) {
|
|
41539
41519
|
ctx.extraSettings = meta.extraSettings;
|
|
41540
41520
|
}
|
|
@@ -47343,7 +47323,7 @@ var import_node_crypto4 = require("crypto");
|
|
|
47343
47323
|
var MAX_RUNS_PER_SHIFT = 30;
|
|
47344
47324
|
var DEFAULT_TIMEOUT_MS = 30 * 6e4;
|
|
47345
47325
|
var CONSECUTIVE_ERROR_THRESHOLD = 5;
|
|
47346
|
-
var TICK_INTERVAL_MS =
|
|
47326
|
+
var TICK_INTERVAL_MS = 1e3;
|
|
47347
47327
|
var STORE_FLUSH_DEBOUNCE_MS = 500;
|
|
47348
47328
|
var CLOCK_JUMP_THRESHOLD_MS = 5 * 6e4;
|
|
47349
47329
|
|
|
@@ -49269,67 +49249,6 @@ function removeSubscription(client, sessionId) {
|
|
|
49269
49249
|
else client.subscribedSessions.set(sessionId, next);
|
|
49270
49250
|
}
|
|
49271
49251
|
|
|
49272
|
-
// src/transport/rpc-adapter.ts
|
|
49273
|
-
var EXPOSED_RPC_METHODS = [
|
|
49274
|
-
"appBuilder.createProject",
|
|
49275
|
-
"appBuilder.listProjects",
|
|
49276
|
-
"appBuilder.updateProjectPort",
|
|
49277
|
-
"appBuilder.setProdUrl",
|
|
49278
|
-
// 单栏 refactor §5.6.2 stage fix:scaffold + install 完成调 startDevServer 起 dev server;
|
|
49279
|
-
// 中间用 reportStage 上报阶段(scaffolding / installing / failed),UI 据 stage 推帧切 PreviewPane。
|
|
49280
|
-
"appBuilder.startDevServer",
|
|
49281
|
-
"appBuilder.reportStage",
|
|
49282
|
-
// 单栏 §5.6.5 fix: UI 切 session 时调(assistant 不需要主动调,但暴露白名单避免误猜成 forbidden)
|
|
49283
|
-
"appBuilder.setActiveSession",
|
|
49284
|
-
// dataclaw-builder:persona 建页时取建页人身份(含 union_id)写进生成 app 的配置。
|
|
49285
|
-
// 路由到 handlers['auth:getIdentity'],只返 identity、绝不带 ttcToken(见 handlers/feishu-auth.ts)。
|
|
49286
|
-
"auth.getIdentity",
|
|
49287
|
-
// Persona dispatch (Task 4): A 端 dispatch MCP server 调 run(hold-and-wait 一次);
|
|
49288
|
-
// B 端 dispatch MCP server 调 complete(带 outcome 触发 run 端 resolve)。详见
|
|
49289
|
-
// protocol/src/dispatch.ts。
|
|
49290
|
-
"personaDispatch.run",
|
|
49291
|
-
"personaDispatch.complete",
|
|
49292
|
-
// clawd-shift v1 (spec 2026-06-24-clawd-shift):cc 子进程内的 shift MCP server 调
|
|
49293
|
-
// 这 5 个 method 管理 owner 的 shift(fire-and-forget 排班)。鉴权靠 body.personaId
|
|
49294
|
-
// (mcp-server 从 process.env.CLAWD_PERSONA_ID 读,源 = SessionFile.ownerPersonaId)。
|
|
49295
|
-
// handler 内 cancel/update/history 校验 createdByPersona === personaId 防越权。
|
|
49296
|
-
"shift-internal.add",
|
|
49297
|
-
"shift-internal.list",
|
|
49298
|
-
"shift-internal.cancel",
|
|
49299
|
-
"shift-internal.update",
|
|
49300
|
-
"shift-internal.history",
|
|
49301
|
-
// file-sharing:persona guest agent 把自己工作目录内的产物入群+签名分享。
|
|
49302
|
-
// 路径越界由 handlers/attachment.ts guardAttachmentPath(scope-based)拦截。
|
|
49303
|
-
"attachment.groupAdd",
|
|
49304
|
-
"attachment.signUrl"
|
|
49305
|
-
];
|
|
49306
|
-
async function handleRpcRequest(input) {
|
|
49307
|
-
const { method, body, sessionId, dispatcher } = input;
|
|
49308
|
-
if (!sessionId) {
|
|
49309
|
-
return { status: 400, body: { ok: false, error: "MISSING_SESSION_ID", message: "X-Clawd-Session-Id header required" } };
|
|
49310
|
-
}
|
|
49311
|
-
if (!EXPOSED_RPC_METHODS.includes(method)) {
|
|
49312
|
-
return { status: 403, body: { ok: false, error: "METHOD_NOT_EXPOSED", message: `method "${method}" not exposed via HTTP RPC` } };
|
|
49313
|
-
}
|
|
49314
|
-
const internalMethod = method.replace(".", ":");
|
|
49315
|
-
const augmentedBody = {
|
|
49316
|
-
...typeof body === "object" && body != null ? body : {},
|
|
49317
|
-
sessionId
|
|
49318
|
-
};
|
|
49319
|
-
try {
|
|
49320
|
-
const result = await dispatcher.dispatch(internalMethod, augmentedBody, { sessionId });
|
|
49321
|
-
return { status: 200, body: { ok: true, result } };
|
|
49322
|
-
} catch (err) {
|
|
49323
|
-
const e = err;
|
|
49324
|
-
const code = e?.code ?? "INTERNAL";
|
|
49325
|
-
const message = e?.message ?? String(err);
|
|
49326
|
-
return { status: 400, body: { ok: false, error: code, message } };
|
|
49327
|
-
}
|
|
49328
|
-
}
|
|
49329
|
-
function resolveExposedHandler(handlers, internalMethod) {
|
|
49330
|
-
return handlers[internalMethod] ?? handlers[internalMethod.replace(":", ".")];
|
|
49331
|
-
}
|
|
49332
|
-
|
|
49333
49252
|
// src/transport/auth.ts
|
|
49334
49253
|
init_protocol();
|
|
49335
49254
|
var AuthGate = class {
|
|
@@ -50572,6 +50491,60 @@ async function importZip(buf, root) {
|
|
|
50572
50491
|
}
|
|
50573
50492
|
}
|
|
50574
50493
|
|
|
50494
|
+
// src/transport/rpc-adapter.ts
|
|
50495
|
+
var EXPOSED_RPC_METHODS = [
|
|
50496
|
+
"appBuilder.createProject",
|
|
50497
|
+
"appBuilder.listProjects",
|
|
50498
|
+
"appBuilder.updateProjectPort",
|
|
50499
|
+
"appBuilder.setProdUrl",
|
|
50500
|
+
// 单栏 refactor §5.6.2 stage fix:scaffold + install 完成调 startDevServer 起 dev server;
|
|
50501
|
+
// 中间用 reportStage 上报阶段(scaffolding / installing / failed),UI 据 stage 推帧切 PreviewPane。
|
|
50502
|
+
"appBuilder.startDevServer",
|
|
50503
|
+
"appBuilder.reportStage",
|
|
50504
|
+
// 单栏 §5.6.5 fix: UI 切 session 时调(assistant 不需要主动调,但暴露白名单避免误猜成 forbidden)
|
|
50505
|
+
"appBuilder.setActiveSession",
|
|
50506
|
+
// dataclaw-builder:persona 建页时取建页人身份(含 union_id)写进生成 app 的配置。
|
|
50507
|
+
// 路由到 handlers['auth:getIdentity'],只返 identity、绝不带 ttcToken(见 handlers/feishu-auth.ts)。
|
|
50508
|
+
"auth.getIdentity",
|
|
50509
|
+
// Persona dispatch (Task 4): A 端 dispatch MCP server 调 run(hold-and-wait 一次);
|
|
50510
|
+
// B 端 dispatch MCP server 调 complete(带 outcome 触发 run 端 resolve)。详见
|
|
50511
|
+
// protocol/src/dispatch.ts。
|
|
50512
|
+
"personaDispatch.run",
|
|
50513
|
+
"personaDispatch.complete",
|
|
50514
|
+
// clawd-shift v1 (spec 2026-06-24-clawd-shift):cc 子进程内的 shift MCP server 调
|
|
50515
|
+
// 这 5 个 method 管理 owner 的 shift(fire-and-forget 排班)。鉴权靠 body.personaId
|
|
50516
|
+
// (mcp-server 从 process.env.CLAWD_PERSONA_ID 读,源 = SessionFile.ownerPersonaId)。
|
|
50517
|
+
// handler 内 cancel/update/history 校验 createdByPersona === personaId 防越权。
|
|
50518
|
+
"shift-internal.add",
|
|
50519
|
+
"shift-internal.list",
|
|
50520
|
+
"shift-internal.cancel",
|
|
50521
|
+
"shift-internal.update",
|
|
50522
|
+
"shift-internal.history"
|
|
50523
|
+
];
|
|
50524
|
+
async function handleRpcRequest(input) {
|
|
50525
|
+
const { method, body, sessionId, dispatcher } = input;
|
|
50526
|
+
if (!sessionId) {
|
|
50527
|
+
return { status: 400, body: { ok: false, error: "MISSING_SESSION_ID", message: "X-Clawd-Session-Id header required" } };
|
|
50528
|
+
}
|
|
50529
|
+
if (!EXPOSED_RPC_METHODS.includes(method)) {
|
|
50530
|
+
return { status: 403, body: { ok: false, error: "METHOD_NOT_EXPOSED", message: `method "${method}" not exposed via HTTP RPC` } };
|
|
50531
|
+
}
|
|
50532
|
+
const internalMethod = method.replace(".", ":");
|
|
50533
|
+
const augmentedBody = {
|
|
50534
|
+
...typeof body === "object" && body != null ? body : {},
|
|
50535
|
+
sessionId
|
|
50536
|
+
};
|
|
50537
|
+
try {
|
|
50538
|
+
const result = await dispatcher.dispatch(internalMethod, augmentedBody, { sessionId });
|
|
50539
|
+
return { status: 200, body: { ok: true, result } };
|
|
50540
|
+
} catch (err) {
|
|
50541
|
+
const e = err;
|
|
50542
|
+
const code = e?.code ?? "INTERNAL";
|
|
50543
|
+
const message = e?.message ?? String(err);
|
|
50544
|
+
return { status: 400, body: { ok: false, error: code, message } };
|
|
50545
|
+
}
|
|
50546
|
+
}
|
|
50547
|
+
|
|
50575
50548
|
// src/transport/http-router.ts
|
|
50576
50549
|
var RPC_ROUTE_PREFIX = "/api/rpc/";
|
|
50577
50550
|
var RPC_BODY_MAX_BYTES = 1 * 1024 * 1024;
|
|
@@ -52962,16 +52935,6 @@ function personaIdFromPath(absPath, personaRoot) {
|
|
|
52962
52935
|
const id = rel.split(path44.sep)[0];
|
|
52963
52936
|
return id || null;
|
|
52964
52937
|
}
|
|
52965
|
-
function isPathWithin(dir, absPath) {
|
|
52966
|
-
const d = path44.resolve(dir);
|
|
52967
|
-
const t = path44.resolve(absPath);
|
|
52968
|
-
const sep3 = d.endsWith(path44.sep) ? "" : path44.sep;
|
|
52969
|
-
return t === d || t.startsWith(d + sep3);
|
|
52970
|
-
}
|
|
52971
|
-
function isPathInGuestBoundary(personaRoot, personaId, userWorkDir, absPath) {
|
|
52972
|
-
if (userWorkDir && isPathWithin(userWorkDir, absPath)) return true;
|
|
52973
|
-
return personaIdFromPath(path44.resolve(absPath), personaRoot) === personaId;
|
|
52974
|
-
}
|
|
52975
52938
|
|
|
52976
52939
|
// src/handlers/history.ts
|
|
52977
52940
|
init_protocol();
|
|
@@ -53783,31 +53746,6 @@ function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot)
|
|
|
53783
53746
|
}
|
|
53784
53747
|
}
|
|
53785
53748
|
function buildAttachmentHandlers(deps) {
|
|
53786
|
-
function guardAttachmentPath(ctx, sessionId, candidateAbs, method, nonGuestPolicy) {
|
|
53787
|
-
if (ctx?.principal.kind === "owner") return;
|
|
53788
|
-
const scope = deps.getSessionScope?.(sessionId);
|
|
53789
|
-
if (!scope) return;
|
|
53790
|
-
if (scope.kind === "persona" && scope.mode === "guest") {
|
|
53791
|
-
if (!deps.personaRoot) return;
|
|
53792
|
-
const userWorkDir = deps.usersRoot ? deriveUserWorkDir(scope.capId, deps.usersRoot) : void 0;
|
|
53793
|
-
if (!isPathInGuestBoundary(deps.personaRoot, scope.personaId, userWorkDir, candidateAbs)) {
|
|
53794
|
-
throw new ClawdError(
|
|
53795
|
-
ERROR_CODES.UNAUTHORIZED,
|
|
53796
|
-
`${method}: path outside guest work dir: ${candidateAbs}`
|
|
53797
|
-
);
|
|
53798
|
-
}
|
|
53799
|
-
return;
|
|
53800
|
-
}
|
|
53801
|
-
if (nonGuestPolicy === "group-acl") return;
|
|
53802
|
-
const cwd = deps.sessionStore?.read(sessionId)?.cwd;
|
|
53803
|
-
if (!cwd) return;
|
|
53804
|
-
if (!isPathWithin(cwd, candidateAbs)) {
|
|
53805
|
-
throw new ClawdError(
|
|
53806
|
-
ERROR_CODES.UNAUTHORIZED,
|
|
53807
|
-
`${method}: path outside session work dir: ${candidateAbs}`
|
|
53808
|
-
);
|
|
53809
|
-
}
|
|
53810
|
-
}
|
|
53811
53749
|
const signUrl = async (frame, _client, ctx) => {
|
|
53812
53750
|
const parsed = AttachmentSignUrlArgs.safeParse(frame);
|
|
53813
53751
|
if (!parsed.success) {
|
|
@@ -53850,7 +53788,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
53850
53788
|
}
|
|
53851
53789
|
const cwdAbs = import_node_path36.default.resolve(sessionFile.cwd);
|
|
53852
53790
|
const candidateAbs = import_node_path36.default.isAbsolute(args.relPath) ? import_node_path36.default.resolve(args.relPath) : import_node_path36.default.resolve(cwdAbs, args.relPath);
|
|
53853
|
-
|
|
53791
|
+
assertGuestAttachmentPath(ctx, candidateAbs, deps.personaRoot, "attachment.signUrl", deps.usersRoot);
|
|
53854
53792
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
53855
53793
|
const entry = entries.find((e) => {
|
|
53856
53794
|
const storedAbs = import_node_path36.default.isAbsolute(e.relPath) ? import_node_path36.default.resolve(e.relPath) : import_node_path36.default.resolve(cwdAbs, e.relPath);
|
|
@@ -53889,18 +53827,15 @@ function buildAttachmentHandlers(deps) {
|
|
|
53889
53827
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, parsed.error.message);
|
|
53890
53828
|
}
|
|
53891
53829
|
const args = parsed.data;
|
|
53830
|
+
guardGuestBySessionCwd(ctx, args.sessionId, "attachment.groupAdd");
|
|
53892
53831
|
const scope = deps.getSessionScope(args.sessionId);
|
|
53893
53832
|
if (!scope) {
|
|
53894
53833
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
53895
53834
|
}
|
|
53896
|
-
const cwdAbs = import_node_path36.default.resolve(deps.sessionStore?.read(args.sessionId)?.cwd ?? ".");
|
|
53897
|
-
const candidateAbs = import_node_path36.default.isAbsolute(args.relPath) ? import_node_path36.default.resolve(args.relPath) : import_node_path36.default.resolve(cwdAbs, args.relPath);
|
|
53898
|
-
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.groupAdd", "cwd-subtree");
|
|
53899
|
-
const from = ctx?.principal.kind === "owner" ? "owner" : "agent";
|
|
53900
53835
|
const size = 0;
|
|
53901
53836
|
const entry = deps.groupFileStore.upsert(scope, args.sessionId, {
|
|
53902
53837
|
relPath: args.relPath,
|
|
53903
|
-
from,
|
|
53838
|
+
from: "owner",
|
|
53904
53839
|
label: args.label,
|
|
53905
53840
|
size,
|
|
53906
53841
|
mime: lookupMime(args.relPath)
|
|
@@ -55737,11 +55672,16 @@ function daemonShiftToUiShift(d, _nowMs) {
|
|
|
55737
55672
|
}
|
|
55738
55673
|
if (!d.enabled) noteParts.push("(disabled)");
|
|
55739
55674
|
const note = noteParts.join(" \u2014 ");
|
|
55675
|
+
const runs = d.runs.map((r) => ({
|
|
55676
|
+
startedAtMs: r.startedAtMs,
|
|
55677
|
+
...r.sessionId ? { sessionId: r.sessionId } : {}
|
|
55678
|
+
}));
|
|
55740
55679
|
return {
|
|
55741
55680
|
id: d.id,
|
|
55742
55681
|
agentId: d.targetPersona,
|
|
55743
55682
|
schedule: d.schedule,
|
|
55744
|
-
note
|
|
55683
|
+
note,
|
|
55684
|
+
...runs.length > 0 ? { runs } : {}
|
|
55745
55685
|
};
|
|
55746
55686
|
}
|
|
55747
55687
|
function buildShiftHandlers(deps) {
|
|
@@ -57470,7 +57410,7 @@ async function startDaemon(config) {
|
|
|
57470
57410
|
});
|
|
57471
57411
|
const rpcDispatcher = {
|
|
57472
57412
|
async dispatch(method, args, _ctx) {
|
|
57473
|
-
const handler =
|
|
57413
|
+
const handler = handlers[method];
|
|
57474
57414
|
if (!handler) {
|
|
57475
57415
|
throw Object.assign(new Error(`unknown RPC method "${method}"`), { code: "METHOD_NOT_IMPLEMENTED" });
|
|
57476
57416
|
}
|
|
@@ -21252,7 +21252,7 @@ async function main() {
|
|
|
21252
21252
|
name: external_exports.string().describe("short label shown in shift.json + future UI"),
|
|
21253
21253
|
schedule: ScheduleSchema,
|
|
21254
21254
|
prompt: external_exports.string().describe(
|
|
21255
|
-
"instruction the spawned cc executes on startup (NOT a chat message from the owner). Write what you want the persona to DO or SAY at fire time, in instruction form \u2014 daemon wraps it in a
|
|
21255
|
+
"instruction the spawned cc executes on startup (NOT a chat message from the owner). Write what you want the persona to DO or SAY at fire time, in instruction form \u2014 daemon wraps it in a <clawd-shift-fire> tag so the spawned cc treats it as a scheduled action and responds as an assistant turn (no user-bubble appears in the owner's UI)."
|
|
21256
21256
|
),
|
|
21257
21257
|
targetPersona: external_exports.string().optional().describe("which persona to spawn; defaults to the calling persona"),
|
|
21258
21258
|
timeoutMs: external_exports.number().optional().describe("hard timeout per fire; default 30 minutes")
|
package/package.json
CHANGED