@clawos-dev/clawd 0.2.256 → 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 CHANGED
@@ -40774,6 +40774,7 @@ init_protocol();
40774
40774
  var DEFAULT_PORT = 18790;
40775
40775
  var DEFAULT_HOST = "127.0.0.1";
40776
40776
  var DEFAULT_CLAWOS_API = "https://api.clawos.chat";
40777
+ var DEFAULT_OWNER_IDLE_KILL_DELAY_MS = 6 * 60 * 60 * 1e3;
40777
40778
  var DEFAULT_LOG_ENDPOINT = "https://clawd-prod.cn-hangzhou.log.aliyuncs.com/logstores/app-logs/track";
40778
40779
  function resolveLogShipping(raw, cliNoShipping) {
40779
40780
  if (cliNoShipping) {
@@ -40788,6 +40789,12 @@ function resolveLogShipping(raw, cliNoShipping) {
40788
40789
  const sampling = mode === "errors-only" ? { debug: 0, info: 0, warn: 1, error: 1 } : isPlainSamplingMap(raw?.sampling) ? raw.sampling : {};
40789
40790
  return { mode, endpoint, sampling };
40790
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
+ }
40791
40798
  function isPlainSamplingMap(v2) {
40792
40799
  if (!v2 || typeof v2 !== "object") return false;
40793
40800
  return Object.values(v2).every((n) => typeof n === "number");
@@ -40885,6 +40892,7 @@ function resolveConfig(opts) {
40885
40892
  const mode = DAEMON_MODE_VALUES.includes(rawMode ?? "") ? rawMode : "sdk";
40886
40893
  const filePreviewPorts = Array.isArray(fileCfg.previewPorts) ? fileCfg.previewPorts.map((n) => Number(n)).filter((n) => Number.isInteger(n) && n > 0) : null;
40887
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;
40888
40896
  const logShipping = resolveLogShipping(
40889
40897
  fileCfg.logShipping,
40890
40898
  args.noLogShipping ?? false
@@ -40902,7 +40910,8 @@ function resolveConfig(opts) {
40902
40910
  frpcBinary,
40903
40911
  mode,
40904
40912
  previewPorts,
40905
- logShipping
40913
+ logShipping,
40914
+ ownerIdleKillDelayMs
40906
40915
  };
40907
40916
  }
40908
40917
  var HELP_TEXT = `clawd [options]
@@ -40929,6 +40938,10 @@ Env (advanced):
40929
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
40930
40939
  \u503C\u975E\u5408\u6CD5\u5B57\u9762\u91CF\u65F6\u9759\u9ED8\u56DE\u9000 'sdk'\u3002ready \u5E27 mode \u5B57\u6BB5\u900F\u4F20\u7ED9 UI\uFF1B
40931
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
40932
40945
  `;
40933
40946
 
40934
40947
  // src/index.ts
@@ -41412,12 +41425,14 @@ function scopeSubPath(scope) {
41412
41425
  if (scope.mode === "guest") return [scope.personaId, "guests", scope.capId];
41413
41426
  return [scope.personaId, scope.mode];
41414
41427
  }
41415
- function metaFromScope(scope, personaRoot, usersRoot, ownerPrincipalId, callerDisplayName, callerFeishuUnionId) {
41428
+ var GUEST_IDLE_KILL_DELAY_MS = 6e5;
41429
+ function metaFromScope(scope, personaRoot, usersRoot, ownerPrincipalId, callerDisplayName, callerFeishuUnionId, opts) {
41416
41430
  if (scope.kind === "default") return void 0;
41431
+ const ownerDelay = opts?.ownerIdleKillDelayMs !== void 0 && opts.ownerIdleKillDelayMs > 0 ? opts.ownerIdleKillDelayMs : void 0;
41417
41432
  if (scope.mode === "owner") {
41418
41433
  if (!ownerPrincipalId || !usersRoot) {
41419
41434
  return {
41420
- idleKillEnabled: false,
41435
+ idleKillDelayMs: ownerDelay,
41421
41436
  personaMode: "owner",
41422
41437
  callerDisplayName,
41423
41438
  callerDeviceId: ownerPrincipalId,
@@ -41426,7 +41441,7 @@ function metaFromScope(scope, personaRoot, usersRoot, ownerPrincipalId, callerDi
41426
41441
  }
41427
41442
  const userWorkDir2 = deriveUserWorkDir(ownerPrincipalId, usersRoot);
41428
41443
  return {
41429
- idleKillEnabled: false,
41444
+ idleKillDelayMs: ownerDelay,
41430
41445
  personaMode: "owner",
41431
41446
  userWorkDir: userWorkDir2,
41432
41447
  addDirs: [userWorkDir2],
@@ -41437,7 +41452,7 @@ function metaFromScope(scope, personaRoot, usersRoot, ownerPrincipalId, callerDi
41437
41452
  }
41438
41453
  const userWorkDir = deriveUserWorkDir(scope.capId, usersRoot);
41439
41454
  return {
41440
- idleKillEnabled: true,
41455
+ idleKillDelayMs: GUEST_IDLE_KILL_DELAY_MS,
41441
41456
  personaMode: "guest",
41442
41457
  userWorkDir,
41443
41458
  addDirs: [userWorkDir],
@@ -42021,7 +42036,10 @@ function cloneState(s) {
42021
42036
  currentTurnSender: s.currentTurnSender
42022
42037
  };
42023
42038
  }
42024
- var IDLE_KILL_DELAY_MS = 6e5;
42039
+ function idleKillDelayOf(state) {
42040
+ const ms = state.subSessionMeta?.idleKillDelayMs;
42041
+ return ms !== void 0 && ms > 0 ? ms : void 0;
42042
+ }
42025
42043
  function tryFlushPending(state, deps) {
42026
42044
  if (!state.readyForSend || state.pendingSend.length === 0) return [];
42027
42045
  const text = state.pendingSend.shift();
@@ -42296,11 +42314,12 @@ function pushEventToBuffer(state, event, deps) {
42296
42314
  status: "running-idle"
42297
42315
  }
42298
42316
  });
42299
- if (next.subSessionMeta?.idleKillEnabled) {
42317
+ const idleKillMs = idleKillDelayOf(next);
42318
+ if (idleKillMs !== void 0) {
42300
42319
  effects.push({
42301
42320
  kind: "schedule-idle-kill",
42302
42321
  sessionId: next.file.sessionId,
42303
- ms: IDLE_KILL_DELAY_MS
42322
+ ms: idleKillMs
42304
42323
  });
42305
42324
  }
42306
42325
  }
@@ -42737,14 +42756,15 @@ function reduceSessionInner(state, input, deps) {
42737
42756
  if (state.status !== "running-idle") {
42738
42757
  return { state, effects: [] };
42739
42758
  }
42740
- if (input.subagentActive) {
42759
+ const rescheduleMs = idleKillDelayOf(state);
42760
+ if (input.subagentActive && rescheduleMs !== void 0) {
42741
42761
  return {
42742
42762
  state,
42743
42763
  effects: [
42744
42764
  {
42745
42765
  kind: "schedule-idle-kill",
42746
42766
  sessionId: state.file.sessionId,
42747
- ms: IDLE_KILL_DELAY_MS
42767
+ ms: rescheduleMs
42748
42768
  }
42749
42769
  ]
42750
42770
  };
@@ -43664,8 +43684,8 @@ var SessionManager = class {
43664
43684
  // 经过 compressFrameForWire 后决定是 push collector 还是走 deps.broadcastFrame。
43665
43685
  // scope 决定两件事:SessionStore 路由 + SubSessionMeta 派生(metaFromScope)。
43666
43686
  // - default → 复用 deps.store,无 subSessionMeta(普通 session)
43667
- // - persona/owner → personas/<pid>/.clawd/sessions/owner/,meta={idleKillEnabled:false, personaMode:'owner'}
43668
- // - persona/guest → personas/<pid>/.clawd/sessions/guests/<capId>/,meta={idleKillEnabled:true, personaMode:'guest', extraSettings:<sandbox>}
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>}
43669
43689
  newRunner(file, scope) {
43670
43690
  const adapter = this.deps.getAdapter(file.tool ?? "claude");
43671
43691
  const store = this.storeFor(scope);
@@ -43677,7 +43697,8 @@ var SessionManager = class {
43677
43697
  this.deps.usersRoot ?? "",
43678
43698
  this.deps.ownerPrincipalId,
43679
43699
  callerDisplayName,
43680
- callerFeishuUnionId
43700
+ callerFeishuUnionId,
43701
+ { ownerIdleKillDelayMs: this.deps.ownerIdleKillDelayMs }
43681
43702
  );
43682
43703
  if (subSessionMeta?.userWorkDir) {
43683
43704
  import_node_fs9.default.mkdirSync(subSessionMeta.userWorkDir, { recursive: true });
@@ -44515,8 +44536,8 @@ var SessionManager = class {
44515
44536
  //
44516
44537
  // 区别于 owner / default 单 sessionId 入口,这些 API 接 SessionScope 参数 ——
44517
44538
  // 调用方(PersonaManager / observer 等)明确传 scope,由 storeFor 路由到正确目录:
44518
- // - {kind:'persona', personaId, mode:'guest', capId} → guests/<capId>/,meta={idleKill:true, sandbox}
44519
- // - {kind:'persona', personaId, mode:'owner'} → owner/,meta={idleKill:false}
44539
+ // - {kind:'persona', personaId, mode:'guest', capId} → guests/<capId>/,meta={idleKill:10min, sandbox}
44540
+ // - {kind:'persona', personaId, mode:'owner'} → owner/,meta={idleKill:<config 默认 6h>}
44520
44541
  //
44521
44542
  // SubSessionMeta 由 scope → metaFromScope 派生,不进 SessionFile schema。
44522
44543
  /** 按 scope 读取 SessionFile;不存在返回 null */
@@ -59311,6 +59332,9 @@ async function startDaemon(config) {
59311
59332
  ownerDisplayName,
59312
59333
  ownerPrincipalId,
59313
59334
  ownerFeishuUnionId,
59335
+ // T-37 owner session 闲置回收兜底上限(默认 6h,config.json / env 可调,设 0 关闭)。
59336
+ // guest 的 10min 不走这条——它是 session/scope.ts 的固定常量。
59337
+ ownerIdleKillDelayMs: config.ownerIdleKillDelayMs,
59314
59338
  contactStore,
59315
59339
  mode: config.mode,
59316
59340
  // 单栏 refactor (spec 2026-06-02 §5.1):cc 子进程 env CLAWD_DAEMON_URL 闭包来源。