@clawos-dev/clawd 0.2.162 → 0.2.163
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 +36 -4
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -4933,7 +4933,8 @@ var init_schemas = __esm({
|
|
|
4933
4933
|
// ① SDK 模式 stream-json `result` 帧(claude.ts)—— stdout 最后一帧,可靠
|
|
4934
4934
|
// ② TUI 模式 observer 读 JSONL `system/turn_duration` 行(claude-tui.ts parseLine)
|
|
4935
4935
|
// ⚠️ CC 写此行早于该轮尾段正文落盘,可能被尾随 text 覆盖 lastEventKind(③ 存在的原因)
|
|
4936
|
-
// ③ TUI
|
|
4936
|
+
// ③ TUI 模式屏幕静止 AND observer 静止(observeScreenIdle + manager.observerIdleWaitMs 复合闸 →
|
|
4937
|
+
// dispatchTurnIdle inject)—— 兜 ② 的覆盖;等尾随 text 全部 poll 落盘后补,排在 buffer 末条
|
|
4937
4938
|
external_exports.object({
|
|
4938
4939
|
...ParsedEventBase,
|
|
4939
4940
|
kind: external_exports.literal("turn_end")
|
|
@@ -33535,6 +33536,9 @@ var SessionManager = class {
|
|
|
33535
33536
|
// 由 observer 监听 jsonl user 行后调 recordRealUserUuid 建立映射;rewind 系列 RPC 在
|
|
33536
33537
|
// 入参 / 出参做转译,保证 UI 看到的 uuid 始终是 events 流里的 synth uuid
|
|
33537
33538
|
realUuidBySynth = /* @__PURE__ */ new Map();
|
|
33539
|
+
// observeScreenIdle 复合条件闸用:sessionId → observer 上次喂出业务事件的时刻(deps.now())。
|
|
33540
|
+
// observerIdleWaitMs 据此判 observer 是否也静止 ≥ idleMs(屏幕静止 AND observer 静止才补 turn_end)。
|
|
33541
|
+
lastObserverEventAt = /* @__PURE__ */ new Map();
|
|
33538
33542
|
// SessionStore 按 scope 派生(root = <dataDir>/sessions/<scopeSubPath>/)。
|
|
33539
33543
|
// default scope 直接复用 deps.store;persona scope(owner / listener)第一次访问时按需创建并缓存。
|
|
33540
33544
|
// 取代旧的 storesByAgent —— agentId 概念由 SessionScope 取代,路径即身份,
|
|
@@ -34126,6 +34130,7 @@ var SessionManager = class {
|
|
|
34126
34130
|
this.runners.delete(args.sessionId);
|
|
34127
34131
|
this.realUuidBySynth.delete(args.sessionId);
|
|
34128
34132
|
this.lastUiSizeBySessionId.delete(args.sessionId);
|
|
34133
|
+
this.lastObserverEventAt.delete(args.sessionId);
|
|
34129
34134
|
return { response: { sessionId: args.sessionId }, broadcast };
|
|
34130
34135
|
}
|
|
34131
34136
|
this.deleteOwned(args.sessionId);
|
|
@@ -34604,6 +34609,7 @@ var SessionManager = class {
|
|
|
34604
34609
|
this.runners.delete(args.sessionId);
|
|
34605
34610
|
this.realUuidBySynth.delete(args.sessionId);
|
|
34606
34611
|
this.lastUiSizeBySessionId.delete(args.sessionId);
|
|
34612
|
+
this.lastObserverEventAt.delete(args.sessionId);
|
|
34607
34613
|
return { response: { sessionId: args.sessionId }, broadcast };
|
|
34608
34614
|
}
|
|
34609
34615
|
this.storeFor(args.scope).delete(args.sessionId);
|
|
@@ -34755,6 +34761,7 @@ var SessionManager = class {
|
|
|
34755
34761
|
return;
|
|
34756
34762
|
}
|
|
34757
34763
|
}
|
|
34764
|
+
this.lastObserverEventAt.set(sessionId, (this.deps.now ?? Date.now)());
|
|
34758
34765
|
runner.feedObserverEvents(outEvents);
|
|
34759
34766
|
}
|
|
34760
34767
|
// AskUserQuestion 表单回写(plan: clawd-ask-user-question):UI 答完所有 question 后调用。
|
|
@@ -35030,6 +35037,20 @@ var SessionManager = class {
|
|
|
35030
35037
|
if (!runner) return;
|
|
35031
35038
|
runner.input({ kind: "inject-events", events: [{ kind: "turn_end" }] });
|
|
35032
35039
|
}
|
|
35040
|
+
/**
|
|
35041
|
+
* observer 还需静止多久(ms)才满 idleMs,0 = 已满。observeScreenIdle 复合条件闸:屏幕静止后
|
|
35042
|
+
* 精确等这段剩余再补 turn_end —— turn_duration 写盘早于尾段正文,observer 把尾随 text poll 落盘
|
|
35043
|
+
* 期间屏幕可能已静止,仅看屏幕会早 fire(补的 turn_end 盖不到尾随 text 之后)。
|
|
35044
|
+
* 找不到 runner / 从无事件 → 0(不阻塞 fire)。idleMs 由装配处传 SCREEN_IDLE_MS。
|
|
35045
|
+
*/
|
|
35046
|
+
observerIdleWaitMs(toolSessionId, idleMs) {
|
|
35047
|
+
const sid = this.sessionIdByToolSid(toolSessionId);
|
|
35048
|
+
if (!sid) return 0;
|
|
35049
|
+
const last = this.lastObserverEventAt.get(sid);
|
|
35050
|
+
if (last === void 0) return 0;
|
|
35051
|
+
const elapsed = (this.deps.now ?? Date.now)() - last;
|
|
35052
|
+
return Math.max(0, idleMs - elapsed);
|
|
35053
|
+
}
|
|
35033
35054
|
/** toolSessionId → sessionId 反查(遍历 runners);session 数典型 < 10,O(n) 可接受 */
|
|
35034
35055
|
sessionIdByToolSid(toolSessionId) {
|
|
35035
35056
|
for (const [sid, runner] of this.runners) {
|
|
@@ -37396,6 +37417,7 @@ function observeReady(surface, opts) {
|
|
|
37396
37417
|
}
|
|
37397
37418
|
function observeScreenIdle(surface, opts) {
|
|
37398
37419
|
const visibleRows = opts.visibleRows ?? 44;
|
|
37420
|
+
const REWAIT_MIN_MS = 50;
|
|
37399
37421
|
let lastSnap = null;
|
|
37400
37422
|
let armed = false;
|
|
37401
37423
|
let timer = null;
|
|
@@ -37414,6 +37436,11 @@ function observeScreenIdle(surface, opts) {
|
|
|
37414
37436
|
timer = setTimeout(fire, opts.idleMs);
|
|
37415
37437
|
return;
|
|
37416
37438
|
}
|
|
37439
|
+
const obsWait = opts.getObserverWaitMs?.() ?? 0;
|
|
37440
|
+
if (obsWait > 0) {
|
|
37441
|
+
timer = setTimeout(fire, Math.max(obsWait, REWAIT_MIN_MS));
|
|
37442
|
+
return;
|
|
37443
|
+
}
|
|
37417
37444
|
if (armed) return;
|
|
37418
37445
|
armed = true;
|
|
37419
37446
|
opts.onIdle();
|
|
@@ -37436,7 +37463,7 @@ function observeScreenIdle(surface, opts) {
|
|
|
37436
37463
|
};
|
|
37437
37464
|
}
|
|
37438
37465
|
var BYPASS_SETTLE_MS = 300;
|
|
37439
|
-
var SCREEN_IDLE_MS =
|
|
37466
|
+
var SCREEN_IDLE_MS = 5e3;
|
|
37440
37467
|
function createBootGate(pty, logger) {
|
|
37441
37468
|
const stripAnsi = (s) => s.replace(/\x1b\[[0-9;?]*C/g, " ").replace(/\x1b\[[0-9;?]*[a-zA-Z]/g, "").replace(/\x1b\][^\x07]*\x07/g, "").replace(/\x1b[NOPM=>78]/g, "").replace(/[\x00-\x1f\x7f]/g, " ");
|
|
37442
37469
|
const popups = {
|
|
@@ -37575,7 +37602,10 @@ var ClaudeTuiAdapter = class extends ClaudeAdapter {
|
|
|
37575
37602
|
this.tuiLogger?.debug("screen-idle \u2192 turn_end", { toolSessionId: ctx.toolSessionId });
|
|
37576
37603
|
this.tuiOpts.onTurnIdle(ctx.toolSessionId);
|
|
37577
37604
|
},
|
|
37578
|
-
getPopupVisible: () => popupObserver.visibleKind !== null
|
|
37605
|
+
getPopupVisible: () => popupObserver.visibleKind !== null,
|
|
37606
|
+
// observer 还需静止多久才满 SCREEN_IDLE_MS(复合条件 AND):屏幕静止后精确等这段剩余再补
|
|
37607
|
+
// turn_end,确保它排在尾段 text + turn_duration 全部 poll 落盘之后 = buffer 末条。
|
|
37608
|
+
getObserverWaitMs: () => ctx.toolSessionId ? this.tuiOpts.getObserverWaitMs?.(ctx.toolSessionId, SCREEN_IDLE_MS) ?? 0 : 0
|
|
37579
37609
|
});
|
|
37580
37610
|
if (ctx.toolSessionId && this.tuiOpts.onSurfaceRegister) {
|
|
37581
37611
|
this.tuiOpts.onSurfaceRegister(ctx.toolSessionId, surface);
|
|
@@ -46896,7 +46926,9 @@ async function startDaemon(config) {
|
|
|
46896
46926
|
// ReadyGate v2:ReadyDetector emit ready 时投递 reducer 'ready-detected' input
|
|
46897
46927
|
onReady: (tsid) => manager.dispatchReadyDetected(tsid),
|
|
46898
46928
|
// 屏幕静止 → 补权威 turn_end(修 turn_duration 尾随 text 覆盖 lastEventKind)
|
|
46899
|
-
onTurnIdle: (tsid) => manager.dispatchTurnIdle(tsid)
|
|
46929
|
+
onTurnIdle: (tsid) => manager.dispatchTurnIdle(tsid),
|
|
46930
|
+
// 复合条件闸:observer 还需静止多久才满 idleMs(屏幕静止后精确等这段剩余再补 turn_end)
|
|
46931
|
+
getObserverWaitMs: (tsid, idleMs) => manager.observerIdleWaitMs(tsid, idleMs)
|
|
46900
46932
|
}) : new ClaudeAdapter({ logger, historyReader: new ClaudeHistoryReader() });
|
|
46901
46933
|
registerAdapter("claude", claudeAdapter);
|
|
46902
46934
|
registerAdapter("codex", new CodexAdapter({ logger, historyReader: new CodexHistoryReader() }));
|