@clawos-dev/clawd 0.2.179-beta.359.7bf1eca → 0.2.179
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 +141 -118
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -41339,11 +41339,34 @@ function buildConnectionPrompt(args) {
|
|
|
41339
41339
|
}
|
|
41340
41340
|
if (args.workDir) {
|
|
41341
41341
|
result += `
|
|
41342
|
-
\u4F60\u7684\u6587\u4EF6\u5DE5\u4F5C\u76EE\u5F55\u662F ${args.workDir}\uFF0C\
|
|
41342
|
+
\u4F60\u7684\u6587\u4EF6\u5DE5\u4F5C\u76EE\u5F55\u662F ${args.workDir}\uFF0C\u8FD9\u4E2A\u76EE\u5F55\u5BF9\u4F60\u53EF\u8BFB\u53EF\u5199\uFF0C\u6587\u4EF6\u7684\u8BFB\u53D6/\u521B\u5EFA/\u4FEE\u6539\u90FD\u5728\u8FD9\u91CC\u8FDB\u884C\u3002persona \u76EE\u5F55\u5BF9\u4F60\u53EA\u8BFB\uFF0C\u4E0D\u8981\u5F80\u91CC\u5199\u3002`;
|
|
41343
41343
|
}
|
|
41344
41344
|
return result;
|
|
41345
41345
|
}
|
|
41346
41346
|
|
|
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
|
+
|
|
41347
41370
|
// src/dispatch/system-prompt.ts
|
|
41348
41371
|
var DISPATCH_SYSTEM_PROMPT_HINT = `## \u59D4\u6D3E\u7ED9\u53E6\u4E00\u4E2A persona\uFF08dispatch\uFF09
|
|
41349
41372
|
|
|
@@ -41509,6 +41532,9 @@ function buildSpawnContext(state, deps) {
|
|
|
41509
41532
|
if (dispatchMcpConfigPath2) {
|
|
41510
41533
|
ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + DISPATCH_SYSTEM_PROMPT_HINT;
|
|
41511
41534
|
}
|
|
41535
|
+
if (daemonUrl) {
|
|
41536
|
+
ctx.extraSystemPrompt = (ctx.extraSystemPrompt ? ctx.extraSystemPrompt + "\n\n" : "") + ATTACHMENT_SHARING_HINT;
|
|
41537
|
+
}
|
|
41512
41538
|
if (meta?.extraSettings) {
|
|
41513
41539
|
ctx.extraSettings = meta.extraSettings;
|
|
41514
41540
|
}
|
|
@@ -49243,6 +49269,67 @@ function removeSubscription(client, sessionId) {
|
|
|
49243
49269
|
else client.subscribedSessions.set(sessionId, next);
|
|
49244
49270
|
}
|
|
49245
49271
|
|
|
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
|
+
|
|
49246
49333
|
// src/transport/auth.ts
|
|
49247
49334
|
init_protocol();
|
|
49248
49335
|
var AuthGate = class {
|
|
@@ -50485,60 +50572,6 @@ async function importZip(buf, root) {
|
|
|
50485
50572
|
}
|
|
50486
50573
|
}
|
|
50487
50574
|
|
|
50488
|
-
// src/transport/rpc-adapter.ts
|
|
50489
|
-
var EXPOSED_RPC_METHODS = [
|
|
50490
|
-
"appBuilder.createProject",
|
|
50491
|
-
"appBuilder.listProjects",
|
|
50492
|
-
"appBuilder.updateProjectPort",
|
|
50493
|
-
"appBuilder.setProdUrl",
|
|
50494
|
-
// 单栏 refactor §5.6.2 stage fix:scaffold + install 完成调 startDevServer 起 dev server;
|
|
50495
|
-
// 中间用 reportStage 上报阶段(scaffolding / installing / failed),UI 据 stage 推帧切 PreviewPane。
|
|
50496
|
-
"appBuilder.startDevServer",
|
|
50497
|
-
"appBuilder.reportStage",
|
|
50498
|
-
// 单栏 §5.6.5 fix: UI 切 session 时调(assistant 不需要主动调,但暴露白名单避免误猜成 forbidden)
|
|
50499
|
-
"appBuilder.setActiveSession",
|
|
50500
|
-
// dataclaw-builder:persona 建页时取建页人身份(含 union_id)写进生成 app 的配置。
|
|
50501
|
-
// 路由到 handlers['auth:getIdentity'],只返 identity、绝不带 ttcToken(见 handlers/feishu-auth.ts)。
|
|
50502
|
-
"auth.getIdentity",
|
|
50503
|
-
// Persona dispatch (Task 4): A 端 dispatch MCP server 调 run(hold-and-wait 一次);
|
|
50504
|
-
// B 端 dispatch MCP server 调 complete(带 outcome 触发 run 端 resolve)。详见
|
|
50505
|
-
// protocol/src/dispatch.ts。
|
|
50506
|
-
"personaDispatch.run",
|
|
50507
|
-
"personaDispatch.complete",
|
|
50508
|
-
// clawd-shift v1 (spec 2026-06-24-clawd-shift):cc 子进程内的 shift MCP server 调
|
|
50509
|
-
// 这 5 个 method 管理 owner 的 shift(fire-and-forget 排班)。鉴权靠 body.personaId
|
|
50510
|
-
// (mcp-server 从 process.env.CLAWD_PERSONA_ID 读,源 = SessionFile.ownerPersonaId)。
|
|
50511
|
-
// handler 内 cancel/update/history 校验 createdByPersona === personaId 防越权。
|
|
50512
|
-
"shift-internal.add",
|
|
50513
|
-
"shift-internal.list",
|
|
50514
|
-
"shift-internal.cancel",
|
|
50515
|
-
"shift-internal.update",
|
|
50516
|
-
"shift-internal.history"
|
|
50517
|
-
];
|
|
50518
|
-
async function handleRpcRequest(input) {
|
|
50519
|
-
const { method, body, sessionId, dispatcher } = input;
|
|
50520
|
-
if (!sessionId) {
|
|
50521
|
-
return { status: 400, body: { ok: false, error: "MISSING_SESSION_ID", message: "X-Clawd-Session-Id header required" } };
|
|
50522
|
-
}
|
|
50523
|
-
if (!EXPOSED_RPC_METHODS.includes(method)) {
|
|
50524
|
-
return { status: 403, body: { ok: false, error: "METHOD_NOT_EXPOSED", message: `method "${method}" not exposed via HTTP RPC` } };
|
|
50525
|
-
}
|
|
50526
|
-
const internalMethod = method.replace(".", ":");
|
|
50527
|
-
const augmentedBody = {
|
|
50528
|
-
...typeof body === "object" && body != null ? body : {},
|
|
50529
|
-
sessionId
|
|
50530
|
-
};
|
|
50531
|
-
try {
|
|
50532
|
-
const result = await dispatcher.dispatch(internalMethod, augmentedBody, { sessionId });
|
|
50533
|
-
return { status: 200, body: { ok: true, result } };
|
|
50534
|
-
} catch (err) {
|
|
50535
|
-
const e = err;
|
|
50536
|
-
const code = e?.code ?? "INTERNAL";
|
|
50537
|
-
const message = e?.message ?? String(err);
|
|
50538
|
-
return { status: 400, body: { ok: false, error: code, message } };
|
|
50539
|
-
}
|
|
50540
|
-
}
|
|
50541
|
-
|
|
50542
50575
|
// src/transport/http-router.ts
|
|
50543
50576
|
var RPC_ROUTE_PREFIX = "/api/rpc/";
|
|
50544
50577
|
var RPC_BODY_MAX_BYTES = 1 * 1024 * 1024;
|
|
@@ -52929,6 +52962,16 @@ function personaIdFromPath(absPath, personaRoot) {
|
|
|
52929
52962
|
const id = rel.split(path44.sep)[0];
|
|
52930
52963
|
return id || null;
|
|
52931
52964
|
}
|
|
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
|
+
}
|
|
52932
52975
|
|
|
52933
52976
|
// src/handlers/history.ts
|
|
52934
52977
|
init_protocol();
|
|
@@ -53740,6 +53783,31 @@ function assertGuestAttachmentPath(ctx, absPath, personaRoot, method, usersRoot)
|
|
|
53740
53783
|
}
|
|
53741
53784
|
}
|
|
53742
53785
|
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
|
+
}
|
|
53743
53811
|
const signUrl = async (frame, _client, ctx) => {
|
|
53744
53812
|
const parsed = AttachmentSignUrlArgs.safeParse(frame);
|
|
53745
53813
|
if (!parsed.success) {
|
|
@@ -53782,7 +53850,7 @@ function buildAttachmentHandlers(deps) {
|
|
|
53782
53850
|
}
|
|
53783
53851
|
const cwdAbs = import_node_path36.default.resolve(sessionFile.cwd);
|
|
53784
53852
|
const candidateAbs = import_node_path36.default.isAbsolute(args.relPath) ? import_node_path36.default.resolve(args.relPath) : import_node_path36.default.resolve(cwdAbs, args.relPath);
|
|
53785
|
-
|
|
53853
|
+
guardAttachmentPath(ctx, args.sessionId, candidateAbs, "attachment.signUrl", "group-acl");
|
|
53786
53854
|
const entries = deps.groupFileStore.list(scope, args.sessionId);
|
|
53787
53855
|
const entry = entries.find((e) => {
|
|
53788
53856
|
const storedAbs = import_node_path36.default.isAbsolute(e.relPath) ? import_node_path36.default.resolve(e.relPath) : import_node_path36.default.resolve(cwdAbs, e.relPath);
|
|
@@ -53821,15 +53889,18 @@ function buildAttachmentHandlers(deps) {
|
|
|
53821
53889
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, parsed.error.message);
|
|
53822
53890
|
}
|
|
53823
53891
|
const args = parsed.data;
|
|
53824
|
-
guardGuestBySessionCwd(ctx, args.sessionId, "attachment.groupAdd");
|
|
53825
53892
|
const scope = deps.getSessionScope(args.sessionId);
|
|
53826
53893
|
if (!scope) {
|
|
53827
53894
|
throw new ClawdError(ERROR_CODES.VALIDATION_ERROR, `session ${args.sessionId} not found`);
|
|
53828
53895
|
}
|
|
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";
|
|
53829
53900
|
const size = 0;
|
|
53830
53901
|
const entry = deps.groupFileStore.upsert(scope, args.sessionId, {
|
|
53831
53902
|
relPath: args.relPath,
|
|
53832
|
-
from
|
|
53903
|
+
from,
|
|
53833
53904
|
label: args.label,
|
|
53834
53905
|
size,
|
|
53835
53906
|
mime: lookupMime(args.relPath)
|
|
@@ -55654,22 +55725,11 @@ function buildAppBuilderHandlers(deps) {
|
|
|
55654
55725
|
}
|
|
55655
55726
|
|
|
55656
55727
|
// src/handlers/shift.ts
|
|
55657
|
-
|
|
55658
|
-
|
|
55659
|
-
|
|
55660
|
-
|
|
55661
|
-
}
|
|
55662
|
-
function everyMsToCron(everyMs) {
|
|
55663
|
-
if (everyMs <= 6e4) return "* * * * *";
|
|
55664
|
-
const minutes = Math.floor(everyMs / 6e4);
|
|
55665
|
-
if (minutes < 60) return `*/${minutes} * * * *`;
|
|
55666
|
-
const hours = Math.floor(minutes / 60);
|
|
55667
|
-
if (hours < 24) return `0 */${hours} * * *`;
|
|
55668
|
-
const days = Math.max(1, Math.floor(hours / 24));
|
|
55669
|
-
return `0 0 */${days} * *`;
|
|
55670
|
-
}
|
|
55671
|
-
function daemonShiftToUiShift(d, nowMs) {
|
|
55672
|
-
const durationMs = pickUiDurationMs(d.timeoutMs);
|
|
55728
|
+
function daemonShiftToUiShift(d, _nowMs) {
|
|
55729
|
+
if (d.schedule.kind === "at") {
|
|
55730
|
+
const atMs = Date.parse(d.schedule.at);
|
|
55731
|
+
if (Number.isNaN(atMs)) return null;
|
|
55732
|
+
}
|
|
55673
55733
|
const noteParts = [d.name];
|
|
55674
55734
|
if (d.prompt && d.prompt.length > 0) {
|
|
55675
55735
|
const promptPreview = d.prompt.length > 120 ? `${d.prompt.slice(0, 117)}\u2026` : d.prompt;
|
|
@@ -55677,49 +55737,12 @@ function daemonShiftToUiShift(d, nowMs) {
|
|
|
55677
55737
|
}
|
|
55678
55738
|
if (!d.enabled) noteParts.push("(disabled)");
|
|
55679
55739
|
const note = noteParts.join(" \u2014 ");
|
|
55680
|
-
|
|
55681
|
-
|
|
55682
|
-
|
|
55683
|
-
|
|
55684
|
-
|
|
55685
|
-
|
|
55686
|
-
id: d.id,
|
|
55687
|
-
agentId: d.targetPersona,
|
|
55688
|
-
schedule: {
|
|
55689
|
-
kind: "single",
|
|
55690
|
-
start: new Date(startMs).toISOString(),
|
|
55691
|
-
end: new Date(startMs + durationMs).toISOString()
|
|
55692
|
-
},
|
|
55693
|
-
note
|
|
55694
|
-
};
|
|
55695
|
-
}
|
|
55696
|
-
case "cron": {
|
|
55697
|
-
return {
|
|
55698
|
-
id: d.id,
|
|
55699
|
-
agentId: d.targetPersona,
|
|
55700
|
-
schedule: {
|
|
55701
|
-
kind: "recurring",
|
|
55702
|
-
cron: d.schedule.expr,
|
|
55703
|
-
...d.schedule.tz ? { tz: d.schedule.tz } : {},
|
|
55704
|
-
durationMs
|
|
55705
|
-
},
|
|
55706
|
-
note
|
|
55707
|
-
};
|
|
55708
|
-
}
|
|
55709
|
-
case "every": {
|
|
55710
|
-
const cron = everyMsToCron(d.schedule.everyMs);
|
|
55711
|
-
return {
|
|
55712
|
-
id: d.id,
|
|
55713
|
-
agentId: d.targetPersona,
|
|
55714
|
-
schedule: {
|
|
55715
|
-
kind: "recurring",
|
|
55716
|
-
cron,
|
|
55717
|
-
durationMs
|
|
55718
|
-
},
|
|
55719
|
-
note
|
|
55720
|
-
};
|
|
55721
|
-
}
|
|
55722
|
-
}
|
|
55740
|
+
return {
|
|
55741
|
+
id: d.id,
|
|
55742
|
+
agentId: d.targetPersona,
|
|
55743
|
+
schedule: d.schedule,
|
|
55744
|
+
note
|
|
55745
|
+
};
|
|
55723
55746
|
}
|
|
55724
55747
|
function buildShiftHandlers(deps) {
|
|
55725
55748
|
return {
|
|
@@ -57447,7 +57470,7 @@ async function startDaemon(config) {
|
|
|
57447
57470
|
});
|
|
57448
57471
|
const rpcDispatcher = {
|
|
57449
57472
|
async dispatch(method, args, _ctx) {
|
|
57450
|
-
const handler = handlers
|
|
57473
|
+
const handler = resolveExposedHandler(handlers, method);
|
|
57451
57474
|
if (!handler) {
|
|
57452
57475
|
throw Object.assign(new Error(`unknown RPC method "${method}"`), { code: "METHOD_NOT_IMPLEMENTED" });
|
|
57453
57476
|
}
|
package/package.json
CHANGED