@clawos-dev/clawd 0.2.177-beta.355.6443d50 → 0.2.177-beta.357.f436213

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
@@ -255,8 +255,9 @@ var init_events = __esm({
255
255
  "attachment-skills",
256
256
  "attachment-deferred-tools",
257
257
  // clawd shift v1:scheduler fire 时 daemon 给新 cc 的首条 user message 用
258
- // <clawd-shift-fire> wrap 起头;classifyUserMessage 识别后路由到 UserMetaLine 折叠渲染,
259
- // 不显示成 user 气泡(避免 instruction 文本被当 owner 实时对话)。
258
+ // `[clawd-shift-fire ...]` plain text marker 起头任务包(不是 XML 标签,避开
259
+ // reducer 双源 dedup 失效雷,见 daemon shift/wrap.ts 注释);classifyUserMessage
260
+ // 识别后路由到 UserMetaLine 折叠渲染,不显示成 user 气泡。
260
261
  "clawd-shift-fire"
261
262
  ];
262
263
  SKILL_SOURCE_VALUES = ["builtin", "global", "project", "plugin"];
@@ -11476,7 +11477,7 @@ var init_claude_history = __esm({
11476
11477
  SYSTEM_REMINDER_RE = /^\s*<system-reminder\b/i;
11477
11478
  OPENSPEC_BLOCK_RE = /^\s*<!--\s*OPENSPEC\b/i;
11478
11479
  SKILL_HINT_RE = /^\s*Base directory for this skill:\s/;
11479
- CLAWD_SHIFT_FIRE_RE = /^\s*<clawd-shift-fire\b/i;
11480
+ CLAWD_SHIFT_FIRE_RE = /^\s*\[clawd-shift-fire\b/i;
11480
11481
  ATTACHMENT_SILENT_SUBTYPES = /* @__PURE__ */ new Set([
11481
11482
  "hook_additional_context",
11482
11483
  "hook_success",
@@ -41279,18 +41280,18 @@ function composeGuestSandbox(base, userWorkDir, spawnCwd) {
41279
41280
 
41280
41281
  // src/shift/wrap.ts
41281
41282
  function wrapShiftFirePrompt(args) {
41283
+ const personaLabel = sanitizeMarkerValue(args.targetPersona);
41282
41284
  return [
41283
- `<clawd-shift-fire target-persona="${escapeAttr(args.targetPersona)}">`,
41284
- "This is a scheduled shift fire \u2014 not a live user message.",
41285
+ `[clawd-shift-fire target-persona=${personaLabel} \u2014 scheduled shift fire, not a live user message from the owner]`,
41286
+ "",
41285
41287
  "Respond as an assistant turn (start your output directly).",
41286
41288
  "",
41287
41289
  "Instruction:",
41288
- args.prompt,
41289
- "</clawd-shift-fire>"
41290
+ args.prompt
41290
41291
  ].join("\n");
41291
41292
  }
41292
- function escapeAttr(v2) {
41293
- return v2.replace(/&/g, "&amp;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
41293
+ function sanitizeMarkerValue(v2) {
41294
+ return v2.replace(/[\]\r\n\t]/g, "_");
41294
41295
  }
41295
41296
 
41296
41297
  // src/session/reducer.ts
@@ -41345,7 +41346,7 @@ function buildConnectionPrompt(args) {
41345
41346
  }
41346
41347
  if (args.workDir) {
41347
41348
  result += `
41348
- \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`;
41349
+ \u4F60\u7684\u6587\u4EF6\u5DE5\u4F5C\u76EE\u5F55\u662F ${args.workDir}\uFF0C\u6240\u6709\u6587\u4EF6\u8BFB\u5199\u90FD\u653E\u5728\u8FD9\u4E2A\u76EE\u5F55\u4E0B\u3002persona \u76EE\u5F55\u5BF9\u4F60\u53EA\u8BFB\uFF0C\u4E0D\u8981\u5F80\u91CC\u5199\u3002`;
41349
41350
  }
41350
41351
  return result;
41351
41352
  }
@@ -55660,11 +55661,22 @@ function buildAppBuilderHandlers(deps) {
55660
55661
  }
55661
55662
 
55662
55663
  // src/handlers/shift.ts
55664
+ var UI_DEFAULT_DURATION_MS = 30 * 6e4;
55665
+ var UI_MAX_DURATION_MS = 60 * 6e4;
55666
+ function pickUiDurationMs(timeoutMs) {
55667
+ return Math.min(timeoutMs ?? UI_DEFAULT_DURATION_MS, UI_MAX_DURATION_MS);
55668
+ }
55669
+ function everyMsToCron(everyMs) {
55670
+ if (everyMs <= 6e4) return "* * * * *";
55671
+ const minutes = Math.floor(everyMs / 6e4);
55672
+ if (minutes < 60) return `*/${minutes} * * * *`;
55673
+ const hours = Math.floor(minutes / 60);
55674
+ if (hours < 24) return `0 */${hours} * * *`;
55675
+ const days = Math.max(1, Math.floor(hours / 24));
55676
+ return `0 0 */${days} * *`;
55677
+ }
55663
55678
  function daemonShiftToUiShift(d, nowMs) {
55664
- if (d.schedule.kind === "at") {
55665
- const atMs = Date.parse(d.schedule.at);
55666
- if (Number.isNaN(atMs) || atMs <= nowMs) return null;
55667
- }
55679
+ const durationMs = pickUiDurationMs(d.timeoutMs);
55668
55680
  const noteParts = [d.name];
55669
55681
  if (d.prompt && d.prompt.length > 0) {
55670
55682
  const promptPreview = d.prompt.length > 120 ? `${d.prompt.slice(0, 117)}\u2026` : d.prompt;
@@ -55672,12 +55684,49 @@ function daemonShiftToUiShift(d, nowMs) {
55672
55684
  }
55673
55685
  if (!d.enabled) noteParts.push("(disabled)");
55674
55686
  const note = noteParts.join(" \u2014 ");
55675
- return {
55676
- id: d.id,
55677
- agentId: d.targetPersona,
55678
- schedule: d.schedule,
55679
- note
55680
- };
55687
+ switch (d.schedule.kind) {
55688
+ case "at": {
55689
+ const startMs = Date.parse(d.schedule.at);
55690
+ if (Number.isNaN(startMs)) return null;
55691
+ if (startMs + durationMs <= nowMs) return null;
55692
+ return {
55693
+ id: d.id,
55694
+ agentId: d.targetPersona,
55695
+ schedule: {
55696
+ kind: "single",
55697
+ start: new Date(startMs).toISOString(),
55698
+ end: new Date(startMs + durationMs).toISOString()
55699
+ },
55700
+ note
55701
+ };
55702
+ }
55703
+ case "cron": {
55704
+ return {
55705
+ id: d.id,
55706
+ agentId: d.targetPersona,
55707
+ schedule: {
55708
+ kind: "recurring",
55709
+ cron: d.schedule.expr,
55710
+ ...d.schedule.tz ? { tz: d.schedule.tz } : {},
55711
+ durationMs
55712
+ },
55713
+ note
55714
+ };
55715
+ }
55716
+ case "every": {
55717
+ const cron = everyMsToCron(d.schedule.everyMs);
55718
+ return {
55719
+ id: d.id,
55720
+ agentId: d.targetPersona,
55721
+ schedule: {
55722
+ kind: "recurring",
55723
+ cron,
55724
+ durationMs
55725
+ },
55726
+ note
55727
+ };
55728
+ }
55729
+ }
55681
55730
  }
55682
55731
  function buildShiftHandlers(deps) {
55683
55732
  return {
@@ -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 <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)."
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 \u2014 ...]` task pack 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.177-beta.355.6443d50",
3
+ "version": "0.2.177-beta.357.f436213",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",