@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.
- package/dist/cli.cjs +92 -1
- 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