Skip to content
Open
Show file tree
Hide file tree
Changes from 19 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
d313e91
docs(interaction): document the exit sweep and correct the Ctrl+X des…
baobaolaodie Oct 8, 2026
d793249
chore(deps): add zod for the session-list projection schema
baobaolaodie Oct 8, 2026
983c167
feat(adapter): sweep never-spoken sessions on a normal exit
baobaolaodie Oct 8, 2026
90ee4ba
feat(adapter): mirror the session-list metadata projection
baobaolaodie Oct 8, 2026
0a9eb9c
feat(adapter): sweep never-spoken sessions on a clean exit
baobaolaodie Oct 8, 2026
e02fadb
test(ci): register the session-list metadata and sweep regressions
baobaolaodie Oct 8, 2026
1718a19
docs(interaction): drop the Ctrl+X correction and scope the sweep notice
baobaolaodie Oct 8, 2026
0f2f838
fix(adapter): register the projection wire and guard the sweep by hea…
baobaolaodie Oct 8, 2026
d20eb5b
test(adapter): make the exit-sweep regression self-verifying
baobaolaodie Oct 8, 2026
56a72b6
fix(adapter): register the session-list projection before the boot agent
baobaolaodie Oct 9, 2026
f323c69
merge: bring in origin/main (incl. #1395 deferred session persistence)
baobaolaodie Oct 9, 2026
32d9f75
test(adapter): drop stale plugin.ts line pins from the sweep regression
baobaolaodie Oct 9, 2026
0b5085a
test(adapter): describe the DATA_DIR constant instead of pinning its …
baobaolaodie Oct 9, 2026
efb63aa
fix(session): keep never-used fresh sessions out of JSONL despite cre…
baobaolaodie Oct 9, 2026
127d193
fix(session): do not seed a child from a never-used source session
baobaolaodie Oct 9, 2026
bccc7d8
fix(session): stop advertising a resume id for an unstored fork and w…
baobaolaodie Oct 9, 2026
dc9aebf
fix(session): judge the inherited cut, not the source session, for se…
baobaolaodie Oct 9, 2026
19512e9
docs(session): align two comments with the code and pin the gate-inst…
baobaolaodie Oct 9, 2026
7bb1d7b
test(session): label the new persistence probes for the fixed-window …
baobaolaodie Oct 9, 2026
819c47b
test(session): assert the unseeded child for a never-used source
baobaolaodie Oct 9, 2026
13f9cd1
refactor(session): keep the conversation criterion in one place
baobaolaodie Oct 9, 2026
565325d
docs(readme): state that an explicit flush no longer publishes an act…
baobaolaodie Oct 9, 2026
c081df1
fix(session): replay the cut's policy facts into an unseeded child
baobaolaodie Oct 9, 2026
4cfd0bc
fix(session): keep sessions another process write-leases
baobaolaodie Oct 9, 2026
1045d51
merge: bring in origin/main (08c8107a)
baobaolaodie Oct 10, 2026
041635a
fix(session): hold the policy plane back from the fresh-session gate
baobaolaodie Oct 10, 2026
c1e770d
merge: bring in origin/main (3961b3c9)
baobaolaodie Oct 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions docs/interaction.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,15 @@ those sessions as usual — "no registration" is not "no history".

- The group lives only inside this screen and is never written back to the registry.

On a normal exit (`/exit`, `/quit`, `/q`, a double `Ctrl+C` while idle, `Ctrl+D`), the TUI
removes sessions **no human has ever spoken in** — leftovers from earlier runs included —
and, when anything was cleaned, reports the count in its exit notice.

- Only that path sweeps: hand-offs (`/update`, kernel switch, `/restart`), crashes and
signal-driven exits leave sessions alone.
- A session with any human message (even if its turn never started) and any sub-agent are
**never removed**.

**Behaviour changes versus the old screens** (deliberately removed, and no longer covered by regressions):

- Session-level right-click menu (rename/delete one session).
Expand Down
5 changes: 5 additions & 0 deletions docs/interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ Bracketed paste(右键或终端原生粘贴)保留普通文本与换行。
- 这些会话照常列出并可恢复——"没有登记"不等于"没有历史"。
- 该分组只在本界面内存活,不会写回登记。

正常退出时(`/exit`、`/quit`、`/q`、空闲时连按两次 `Ctrl+C`、`Ctrl+D`),TUI 会清理**从未被人类发言**的会话(含历史遗留),并在有清理时于退出提示里报出数量。

- 只在正常退出这一条路径上清理:`/update`、内核切换、`/restart` 等交接,以及崩溃与信号退出都不清理。
- 有人类发言的会话(哪怕回合没起来)与子代理**永不删除**。

**旧界面相较之下的行为变更**(有意移除,不再回归):

- 会话级右键菜单(重命名/删除单个会话)。
Expand Down
9 changes: 9 additions & 0 deletions guide/dsh-tui-guide/interaction.en.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,15 @@ those sessions as usual — "no registration" is not "no history".

- The group lives only inside this screen and is never written back to the registry.

On a normal exit (`/exit`, `/quit`, `/q`, a double `Ctrl+C` while idle, `Ctrl+D`), the TUI
removes sessions **no human has ever spoken in** — leftovers from earlier runs included —
and, when anything was cleaned, reports the count in its exit notice.

- Only that path sweeps: hand-offs (`/update`, kernel switch, `/restart`), crashes and
signal-driven exits leave sessions alone.
- A session with any human message (even if its turn never started) and any sub-agent are
**never removed**.

**Behaviour changes versus the old screens** (deliberately removed, and no longer covered by regressions):

- Session-level right-click menu (rename/delete one session).
Expand Down
5 changes: 5 additions & 0 deletions guide/dsh-tui-guide/interaction.md
Original file line number Diff line number Diff line change
Expand Up @@ -404,6 +404,11 @@ Bracketed paste(右键或终端原生粘贴)保留普通文本与换行。
- 这些会话照常列出并可恢复——"没有登记"不等于"没有历史"。
- 该分组只在本界面内存活,不会写回登记。

正常退出时(`/exit`、`/quit`、`/q`、空闲时连按两次 `Ctrl+C`、`Ctrl+D`),TUI 会清理**从未被人类发言**的会话(含历史遗留),并在有清理时于退出提示里报出数量。

- 只在正常退出这一条路径上清理:`/update`、内核切换、`/restart` 等交接,以及崩溃与信号退出都不清理。
- 有人类发言的会话(哪怕回合没起来)与子代理**永不删除**。

**旧界面相较之下的行为变更**(有意移除,不再回归):

- 会话级右键菜单(重命名/删除单个会话)。
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,8 @@
"usehooks-ts": "^3.1.0",
"wrap-ansi": "^10.0.1",
"ws": "^8.21.3",
"yaml": "^2.9.0"
"yaml": "^2.9.0",
"zod": "^4.4.3"
},
"optionalDependencies": {
"sharp": "0.35.4"
Expand Down
3 changes: 3 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 30 additions & 0 deletions scripts/run-ci-group.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,15 @@ const GROUPS = {
// 字节、不得拉回 raw mode——在途回复与鼠标事件由清理后的 re-drain
// 吞掉,不再落入 shell。
["verify-exit-mouse-residue", ['node', '--import', 'tsx/esm', 'scripts/verify-exit-mouse-residue.tsx']],
// 正常退出分支的清理接线回归(ADR-0012 决策 3/5 · AC-5/AC-6):未发言
// 会话的 sweep 必须在回合结束后折进 finishExit 的通知(await 的 sweep
// 永远到不了那里),崩溃 / `/update` / 内核切换 / `/restart` / 启动失败
// 分支一律不 sweep;恶意依赖只损失回合不损失关机(终端恢复序列与进程
// 交接原位、fail-soft);③ 层吃本进程真实视图(绑定会话、注册表活
// agent、清单血缘),有人类消息无 turn/start 的会话存活,非本进程产出
// 的清单整份放过而不猜血缘。清退分支是 apply() 内的闭包,其接线按源码
// 断言(与 verify-shutdown-fallback 同形),被调用的 helper 直接驱动。
["verify-session-cleanup-exit", ['node', '--import', 'tsx/esm', 'scripts/verify-session-cleanup-exit.tsx']],
// 组件级拖拽协议回归:无修饰左键 press 捕获 drag target,首动 dragstart、
// 连续 dragmove、release/focus-out/reset 收尾 dragend;未移动仍走 click,
// 无 handler 与修饰键区域保留基线文本选择;真实 SGR 管线 + 最小滑块消费者。
Expand Down Expand Up @@ -605,9 +614,30 @@ const GROUPS = {
["verify-session-artifact-cache", ['node', 'scripts/verify-session-artifact-cache.mjs']],
// 跨进程首屏快照:不等慢枚举、来源隔离、失败保留、空库清空与迟到守卫。
["verify-session-list-snapshot", ['node', 'scripts/verify-session-list-snapshot.mjs']],
// 会话清单投影镜像回归(issue #1342 的可见性面):TUI 必须注册与 web 宿主
// **同名同版本**的 sessionListMetadata 投影——定义(键/stateVersion/字段
// 类型/init)逐项对字面量钉死(宿主侧改动要让本脚本红、而不是静默重开
// issue),legacy 拼写 schema/viewSchema/view 必须缺席;fold 矩阵含两条
// 只看值看不到的性质(无变化事件返回同一引用、blank 不回落);
// 跨运行时读取按对方等价形状解析并驱动真实 registry 的 restore;同键双
// 注册的版本判定(首个定义生效、行仍写入);服务缺失/无 register/版本
// 冲突必须降级不崩;宿主包可定位时跑真实实现的漂移探针,定位不到则响亮
// SKIP(含搜索路径与原因),绝不静默通过。
["verify-session-list-metadata", ['node', '--import', 'tsx/esm', 'scripts/verify-session-list-metadata.ts']],
// 空会话须完整读取后才能判定:截断/损坏、帧数上限、纯图片输入与旧缓存
// 不得隐藏真实历史或进入清理名单;真实 JSONL 重开验证落盘后的可见性。
['verify-session-emptiness', ['node', '--import', 'tsx/esm', 'scripts/verify-session-emptiness.ts']],
// 未发言会话清理回归(ADR-0012 / 三层判据):真实临时 sessions 根 + 真 TUI
// 会话索引,走的是出货实现(store.readIndex、sessionLog 的有界读与删除原语、
// sessionHistory 的每会话记录)而不是替身——启动壳(含本次运行之前就存在的
// 「历史」条目)被回收,人类 user/message 无 turn/start 必须保留(宿主自身
// blank 规则会删的反例),turn/start 与受委托运行及其后代保留,本进程仍持有
// 的会话(绑定 / 活后台)保留,缺失/悬空/损坏/预算截断的日志只跳过不删并
// 报出是哪层放过的;对抗用例「索引说 hasPrompt:false 而日志有人类消息」;
// 恒删/恒留/抽掉日志规则的负控(正例不能被常量满足);候选上限与每日志事件
// 预算、依赖抛错不中止本轮(fail-soft);分区恰好覆盖索引一次(不静默丢),
// 真 sweep 只删收集到的 id、索引不动、last-used/agent-view/resume 记录被遗忘。
["verify-unspoken-session-sweep", ['node', '--import', 'tsx/esm', 'scripts/verify-unspoken-session-sweep.tsx']],
// /resume 会话浏览器按键流回归:子运行折叠/展开、空会话不列出、搜索、
// Esc 先清查询再退出、rename 后光标按 id 跟随目标(不是按行号)、
// confirm-delete 只认无修饰 Enter、Esc 取消。真实 Chat 渲染驱动。
Expand Down
Loading
Loading