@clawos-dev/clawd 0.2.17 → 0.2.18-beta.24.6c1b73d

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.
Files changed (2) hide show
  1. package/dist/cli.cjs +92 -1
  2. package/package.json +1 -1
package/dist/cli.cjs CHANGED
@@ -13336,6 +13336,11 @@ var SessionRunner = class {
13336
13336
  this.stopWaiters = [];
13337
13337
  for (const w of waiters) w();
13338
13338
  }
13339
+ try {
13340
+ this.hooks.onAfterInput?.(this.state, inputMsg);
13341
+ } catch (err) {
13342
+ this.hooks.logger?.warn("onAfterInput hook threw", { err: err.message });
13343
+ }
13339
13344
  }
13340
13345
  // 等子进程退出(procAlive=false)。manager.stop 在发完 SIGTERM 后调它确保
13341
13346
  // 真停下来再 ack 给前端,从而避免"删 worktree 时 CC 还活着持有文件锁"的 race。
@@ -13525,6 +13530,61 @@ var SessionRunner = class {
13525
13530
  }
13526
13531
  };
13527
13532
 
13533
+ // src/session/phase.ts
13534
+ var PHASE_DESCRIPTIONS = {
13535
+ idle: "\u8FD8\u6CA1\u542F\u52A8",
13536
+ spawning: "\u8FDB\u7A0B\u542F\u52A8\u4E2D",
13537
+ "turn-idle": "\u8FDB\u7A0B\u6D3B\u7740\uFF0C\u7B49\u8F93\u5165",
13538
+ "turn-running": "\u6B63\u5728 run \u4E2D",
13539
+ stopping: "\u6B63\u5728\u6740\u8FDB\u7A0B",
13540
+ exited: "\u8FDB\u7A0B\u5DF2\u9000\u51FA",
13541
+ crashed: "\u542F\u52A8\u5931\u8D25 / \u5F02\u5E38\u9000\u51FA",
13542
+ observing: "\u5916\u90E8 CC \u5728\u8DD1\uFF0Cdaemon \u65C1\u89C2"
13543
+ };
13544
+ function derivePhase(state) {
13545
+ switch (state.status) {
13546
+ case "idle":
13547
+ return "idle";
13548
+ case "spawning":
13549
+ return "spawning";
13550
+ case "running":
13551
+ return state.turnOpen ? "turn-running" : "turn-idle";
13552
+ case "stopping":
13553
+ return "stopping";
13554
+ case "stopped":
13555
+ return "exited";
13556
+ case "error":
13557
+ return "crashed";
13558
+ }
13559
+ }
13560
+ function deriveReason(input) {
13561
+ switch (input.kind) {
13562
+ case "command":
13563
+ return `cmd:${input.command.kind}`;
13564
+ case "proc-exit":
13565
+ return "proc-exit";
13566
+ case "proc-error":
13567
+ return "proc-error";
13568
+ case "inject-events":
13569
+ return "observer-events";
13570
+ case "stdout-line":
13571
+ return "stdout";
13572
+ case "permission-decision":
13573
+ return "permission";
13574
+ case "tick":
13575
+ return "tick";
13576
+ }
13577
+ }
13578
+ function buildPhaseLogFields(args) {
13579
+ return {
13580
+ sessionId: args.sessionId,
13581
+ phase: args.phase,
13582
+ prev: args.prev,
13583
+ desc: PHASE_DESCRIPTIONS[args.phase],
13584
+ ...args.reason ? { reason: args.reason } : {}
13585
+ };
13586
+ }
13587
+
13528
13588
  // src/session/manager.ts
13529
13589
  function compressFrameForWire(frame) {
13530
13590
  if (frame.type !== "session:status") return frame;
@@ -13609,6 +13669,9 @@ var SessionManager = class {
13609
13669
  // 由 observer 监听 jsonl user 行后调 recordRealUserUuid 建立映射;rewind 系列 RPC 在
13610
13670
  // 入参 / 出参做转译,保证 UI 看到的 uuid 始终是 events 流里的 synth uuid
13611
13671
  realUuidBySynth = /* @__PURE__ */ new Map();
13672
+ // sessionId → 最近一次打过 log 的 phase;diff 命中才再打,避免每次 input 刷一行。
13673
+ // observer 路径的 'observing' 也写到这张表,跟 reducer 派生 phase 共享 last 值
13674
+ lastPhase = /* @__PURE__ */ new Map();
13612
13675
  async getCapabilities(tool) {
13613
13676
  const cached = this.capabilitiesCache.get(tool);
13614
13677
  if (cached) return cached;
@@ -13630,10 +13693,35 @@ var SessionManager = class {
13630
13693
  now: this.deps.now,
13631
13694
  bufferCap: this.deps.bufferCap,
13632
13695
  // adapter 自己持有模型表 + 兜底逻辑(contains / opus-1M / [1m] 等),manager 不再 cache 转发
13633
- resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId)
13696
+ resolveContextWindow: (tool, modelId) => this.deps.getAdapter(tool).resolveContextWindow(modelId),
13697
+ // phase 派生:每次 input 应用完后比对,变化才打一行 log。observer 路径的
13698
+ // 'observing' 由 onObserverPhase 单独写入 lastPhase 表,此处不会回退
13699
+ onAfterInput: (state, input) => this.recordPhaseFromState(file.sessionId, state, deriveReason(input))
13634
13700
  });
13635
13701
  return runner;
13636
13702
  }
13703
+ // 给 reducer state 派生当前 phase,跟上次 diff,变化时打一行带中文说明的 log
13704
+ recordPhaseFromState(sessionId, state, reason) {
13705
+ const next = derivePhase(state);
13706
+ const prev = this.lastPhase.get(sessionId) ?? null;
13707
+ if (prev === next) return;
13708
+ this.lastPhase.set(sessionId, next);
13709
+ this.deps.logger?.info(
13710
+ "session-phase",
13711
+ buildPhaseLogFields({ sessionId, phase: next, prev, reason })
13712
+ );
13713
+ }
13714
+ // observer 路径:外部 CC 在跑、daemon 只 tail JSONL;走单独的 'observing' phase
13715
+ recordObserverPhase(sessionId, status) {
13716
+ const next = status === "observing" ? "observing" : "exited";
13717
+ const prev = this.lastPhase.get(sessionId) ?? null;
13718
+ if (prev === next) return;
13719
+ this.lastPhase.set(sessionId, next);
13720
+ this.deps.logger?.info(
13721
+ "session-phase",
13722
+ buildPhaseLogFields({ sessionId, phase: next, prev, reason: "observer" })
13723
+ );
13724
+ }
13637
13725
  // 统一 runner 出口:先压 wire,然后按当前上下文路由
13638
13726
  // 同步命令路径(currentCollector 非空) → push 进 collector,命令方法返回给 dispatcher
13639
13727
  // 异步路径(stdout/exit/observer 主动调用) → 走 deps.broadcastFrame
@@ -13786,9 +13874,11 @@ var SessionManager = class {
13786
13874
  });
13787
13875
  this.runners.delete(args.sessionId);
13788
13876
  this.realUuidBySynth.delete(args.sessionId);
13877
+ this.lastPhase.delete(args.sessionId);
13789
13878
  return { response: { sessionId: args.sessionId }, broadcast };
13790
13879
  }
13791
13880
  this.deps.store.delete(args.sessionId);
13881
+ this.lastPhase.delete(args.sessionId);
13792
13882
  return {
13793
13883
  response: { sessionId: args.sessionId },
13794
13884
  broadcast: [
@@ -18142,6 +18232,7 @@ async function startDaemon(config) {
18142
18232
  hasRunner: !!r,
18143
18233
  runnerProcAlive: r ? r.getState().procAlive : null
18144
18234
  });
18235
+ manager.recordObserverPhase(sessionId, status);
18145
18236
  transport?.broadcastToSession(sessionId, { type: "session:status", sessionId, status });
18146
18237
  },
18147
18238
  // jsonl user 行的 real uuid 映射到 buffer 里 synth user_text,rewind 系列 RPC 在
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clawos-dev/clawd",
3
- "version": "0.2.17",
3
+ "version": "0.2.18-beta.24.6c1b73d",
4
4
  "description": "Standalone clawd daemon — Claude Code (and future Codex) session server over WebSocket",
5
5
  "type": "module",
6
6
  "license": "MIT",