@clawos-dev/clawd 0.2.195-beta.393.e8d2aa5 → 0.2.196-beta.394.2f2689d
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 +69 -20
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -44287,15 +44287,27 @@ var SessionManager = class {
|
|
|
44287
44287
|
this.lastObserverEventAt.set(sessionId, (this.deps.now ?? Date.now)());
|
|
44288
44288
|
let feedEvents = outEvents;
|
|
44289
44289
|
if (outEvents.some((e) => e.kind === "turn_end")) {
|
|
44290
|
-
const
|
|
44291
|
-
|
|
44292
|
-
|
|
44293
|
-
|
|
44290
|
+
const runnerState = runner.getState();
|
|
44291
|
+
const toolSessionId = runnerState.file.toolSessionId;
|
|
44292
|
+
const adapter = this.deps.getAdapter(runnerState.file.tool ?? "claude");
|
|
44293
|
+
const gateOpen = !adapter.canAcceptTurnEnd || !toolSessionId ? true : adapter.canAcceptTurnEnd(toolSessionId);
|
|
44294
|
+
if (!gateOpen) {
|
|
44295
|
+
this.deps.logger?.info("drop turn_end (adapter gate closed)", {
|
|
44294
44296
|
sessionId,
|
|
44295
|
-
|
|
44296
|
-
|
|
44297
|
-
batchKinds: outEvents.map((e) => e.kind)
|
|
44297
|
+
toolSessionId,
|
|
44298
|
+
reason: "tui-screen-not-idle"
|
|
44298
44299
|
});
|
|
44300
|
+
feedEvents = outEvents.filter((e) => e.kind !== "turn_end");
|
|
44301
|
+
} else {
|
|
44302
|
+
const ev = this.peekTurnEvidence(runner);
|
|
44303
|
+
if (!ev.turnHasContent) {
|
|
44304
|
+
this.deps.logger?.info("drop turn_end (empty turn, observer replay)", {
|
|
44305
|
+
sessionId,
|
|
44306
|
+
...ev,
|
|
44307
|
+
batchKinds: outEvents.map((e) => e.kind)
|
|
44308
|
+
});
|
|
44309
|
+
feedEvents = outEvents.filter((e) => e.kind !== "turn_end");
|
|
44310
|
+
}
|
|
44299
44311
|
}
|
|
44300
44312
|
}
|
|
44301
44313
|
if (feedEvents.length === 0) return;
|
|
@@ -44576,22 +44588,24 @@ var SessionManager = class {
|
|
|
44576
44588
|
const runner = sid ? this.runners.get(sid) : void 0;
|
|
44577
44589
|
if (!runner) return;
|
|
44578
44590
|
const ev = this.peekTurnEvidence(runner);
|
|
44579
|
-
|
|
44580
|
-
|
|
44581
|
-
|
|
44582
|
-
|
|
44583
|
-
|
|
44584
|
-
|
|
44585
|
-
}
|
|
44586
|
-
if (!willInject) return;
|
|
44591
|
+
if (!ev.turnEndSeenThisTurn) {
|
|
44592
|
+
this.deps.logger?.debug("screen-idle compensation skipped (no prior turn_end this turn)", {
|
|
44593
|
+
sessionId: sid,
|
|
44594
|
+
...ev
|
|
44595
|
+
});
|
|
44596
|
+
return;
|
|
44597
|
+
}
|
|
44587
44598
|
runner.input({ kind: "inject-events", events: [{ kind: "turn_end" }] });
|
|
44588
44599
|
}
|
|
44589
44600
|
/**
|
|
44590
|
-
* 读 runner 当前 turn
|
|
44591
|
-
*
|
|
44592
|
-
*
|
|
44593
|
-
*
|
|
44594
|
-
* turnHasContent
|
|
44601
|
+
* 读 runner 当前 turn 态快照,供 turn_end 判定使用:
|
|
44602
|
+
* `turnEndSeenThisTurn`:从 buffer 末尾回扫到最近 user_text 期间是否已出现过 turn_end
|
|
44603
|
+
* (已出现=本轮真结束过、合法尾随;未出现=本轮还没结束过)→ 屏幕静止补偿的复发闸
|
|
44604
|
+
* (`dispatchTurnIdle`)。
|
|
44605
|
+
* `turnHasContent`:末条是否 assistant 产出(非 user_text/turn_end/空)→ observer 回灌
|
|
44606
|
+
* turn_end 的空 turn 守卫闸(`feedObserverEvents`)。
|
|
44607
|
+
* 权威 gate(TUI 屏幕是否 idle + 弹框态)在 `adapter.canAcceptTurnEnd` 里,这两条只覆盖
|
|
44608
|
+
* "buffer 完整性"独立维度。
|
|
44595
44609
|
*/
|
|
44596
44610
|
peekTurnEvidence(runner) {
|
|
44597
44611
|
const st = runner.getState();
|
|
@@ -47201,6 +47215,12 @@ function observeScreenIdle(surface, opts) {
|
|
|
47201
47215
|
disposed = true;
|
|
47202
47216
|
unsub();
|
|
47203
47217
|
clear();
|
|
47218
|
+
},
|
|
47219
|
+
isIdle() {
|
|
47220
|
+
if (!armed) return false;
|
|
47221
|
+
if (opts.getPopupVisible()) return false;
|
|
47222
|
+
const obsWait = opts.getObserverWaitMs?.() ?? 0;
|
|
47223
|
+
return obsWait <= 0;
|
|
47204
47224
|
}
|
|
47205
47225
|
};
|
|
47206
47226
|
}
|
|
@@ -47278,11 +47298,31 @@ var ClaudeTuiAdapter = class extends ClaudeAdapter {
|
|
|
47278
47298
|
// 用于 spawn / PtyChildProcess 链路打日志
|
|
47279
47299
|
tuiLogger;
|
|
47280
47300
|
tuiOpts;
|
|
47301
|
+
/**
|
|
47302
|
+
* per-toolSessionId 的 tui 观察者句柄,仅用于 turn_end gate 查询(`canAcceptTurnEnd`)。
|
|
47303
|
+
* onIdle / onPopupTransition 等回调仍走原有闭包(不复用这份 map),本 map 只承担
|
|
47304
|
+
* "manager 需要跨模块查屏幕/弹框状态"这单一职责。
|
|
47305
|
+
*/
|
|
47306
|
+
tuiStates = /* @__PURE__ */ new Map();
|
|
47281
47307
|
constructor(opts = {}) {
|
|
47282
47308
|
super(opts);
|
|
47283
47309
|
this.tuiLogger = opts.logger;
|
|
47284
47310
|
this.tuiOpts = opts;
|
|
47285
47311
|
}
|
|
47312
|
+
/**
|
|
47313
|
+
* TUI adapter 的 turn_end 权威判定:屏幕已 idle 且非弹框态才放行。
|
|
47314
|
+
*
|
|
47315
|
+
* `feedObserverEvents` 收到 observer 回灌 `turn_end` 时调用。屏幕仍在变(如后台 agent 在跑)
|
|
47316
|
+
* 时 drop 掉 turn_end,避免 `system/turn_duration` JSONL 帧误触发 running-idle 状态转换。
|
|
47317
|
+
*
|
|
47318
|
+
* 未跟踪的 toolSessionId(spawn 前 / spawn 失败 / 已 dispose)视为 pass —— gate 只 drop
|
|
47319
|
+
* "有证据判定为伪信号"的场景,不做 unknown → block。
|
|
47320
|
+
*/
|
|
47321
|
+
canAcceptTurnEnd(toolSessionId) {
|
|
47322
|
+
const state = this.tuiStates.get(toolSessionId);
|
|
47323
|
+
if (!state) return true;
|
|
47324
|
+
return state.screenIdle.isIdle();
|
|
47325
|
+
}
|
|
47286
47326
|
spawn(ctx) {
|
|
47287
47327
|
const args = buildTuiSpawnArgs(ctx, jsonlExistsForCtx(ctx));
|
|
47288
47328
|
const cmd = process.env.CLAUDE_BIN ?? "claude";
|
|
@@ -47352,6 +47392,12 @@ var ClaudeTuiAdapter = class extends ClaudeAdapter {
|
|
|
47352
47392
|
if (ctx.toolSessionId && this.tuiOpts.onSurfaceRegister) {
|
|
47353
47393
|
this.tuiOpts.onSurfaceRegister(ctx.toolSessionId, surface);
|
|
47354
47394
|
}
|
|
47395
|
+
if (ctx.toolSessionId) {
|
|
47396
|
+
this.tuiStates.set(ctx.toolSessionId, {
|
|
47397
|
+
screenIdle: screenIdleObserver,
|
|
47398
|
+
popup: popupObserver
|
|
47399
|
+
});
|
|
47400
|
+
}
|
|
47355
47401
|
let chunkSeq = 0;
|
|
47356
47402
|
if (ctx.toolSessionId && this.tuiOpts.onPtyReplayRegister) {
|
|
47357
47403
|
this.tuiOpts.onPtyReplayRegister(ctx.toolSessionId, async () => {
|
|
@@ -47397,6 +47443,9 @@ var ClaudeTuiAdapter = class extends ClaudeAdapter {
|
|
|
47397
47443
|
readyObserver.dispose();
|
|
47398
47444
|
popupObserver.dispose();
|
|
47399
47445
|
screenIdleObserver.dispose();
|
|
47446
|
+
if (ctx.toolSessionId) {
|
|
47447
|
+
this.tuiStates.delete(ctx.toolSessionId);
|
|
47448
|
+
}
|
|
47400
47449
|
if (ctx.toolSessionId && this.tuiOpts.onSurfaceUnregister) {
|
|
47401
47450
|
this.tuiOpts.onSurfaceUnregister(ctx.toolSessionId);
|
|
47402
47451
|
}
|
package/package.json
CHANGED