Skip to content

feat: add session delete command with backup and sqlite cleanup#8

Open
mayii2001 wants to merge 1 commit intoDailin521:mainfrom
mayii2001:feat/delete-session
Open

feat: add session delete command with backup and sqlite cleanup#8
mayii2001 wants to merge 1 commit intoDailin521:mainfrom
mayii2001:feat/delete-session

Conversation

@mayii2001
Copy link
Copy Markdown

背景

当前 Codex 桌面版不能删除 session。
需要一个可按 session id 精确删除的能力,避免手工删文件导致 rollout 与 SQLite 状态不一致。

目标

  • 支持按 session id 删除历史会话
  • 删除前自动备份
  • 删除后可回滚
  • 不影响现有 provider 同步语义

修改内容

CLI / Node

  • 新增命令:
  • codex-provider delete <session-id> [more-session-ids...] [--keep N] [--codex-home PATH]
  • 删除范围:
  • rollout 文件:~/.codex/sessions~/.codex/archived_sessions
  • SQLite:state_5.sqlitethreads 以及关联表引用
  • 保持不变:
  • status / sync / switch / restore / prune-backups 既有逻辑
  • 删除前备份:
  • 新增 deleted session 文件备份清单,支持 restore 回滚

文档

  • 更新:README.mdREADME_ZH.mdREADME_EN.mdAGENTS.md
  • 补充 delete 命令说明、示例、注意事项

验证

  • 自动测试:
  • npm test(通过,24 passed)
  • 手动测试:
  • 删除真实 session id:<填写>
  • 验证 rollout 文件已删除:<通过/失败>
  • 验证 SQLite threads.id 已删除:<通过/失败>
  • 原有命令正常:
    • codex-provider status
    • codex-provider sync --provider <provider>
    • codex-provider switch <provider>
    • codex-provider prune-backups --keep <n>

影响范围

  • 仅新增 delete 能力
  • 不改 provider 解析逻辑
  • 不改 backup 保留策略
  • 不改 SQLite provider 同步语义

回滚方案

  • 使用: codex-provider restore <backup-dir>

Copy link
Copy Markdown
Owner

@Dailin521 Dailin521 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this together. The feature is useful, but I found two blocking issues in the current implementation.

Blocking:

  • runDeleteSessions() deletes rollout files before deleting SQLite rows, but there is no rollback path if the SQLite delete fails. I reproduced this locally by holding a BEGIN IMMEDIATE lock on state_5.sqlite: the command throws a locked error, the rollout file is already gone, and the thread row is still present. That leaves the system in the exact partial state this command is supposed to avoid.
  • deleteSqliteThreadsByIds() only deletes from thread_dynamic_tools, thread_spawn_edges, and threads. The current real state_5.sqlite schema also includes stage1_outputs.thread_id, and PRAGMA foreign_keys is off by default. I reproduced this on a temp DB matching the current schema: after delete, threads=0 but stage1_outputs=1, so the command leaves orphaned rows behind.

Please make the delete path atomic/recoverable and cover all thread-linked tables that exist in the current schema before this can be merged.

@Dailin521 Dailin521 dismissed their stale review April 17, 2026 03:02

改为使用中文 review,结论不变。

Copy link
Copy Markdown
Owner

@Dailin521 Dailin521 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢提交,这个功能方向是对的,但当前实现里有两个阻塞问题。

阻塞问题:

  • runDeleteSessions() 现在是先删除 rollout 文件,再删除 SQLite 行;如果 SQLite 删除失败,没有回滚路径。我本地已经复现过:对 state_5.sqlite 持有 BEGIN IMMEDIATE 锁后执行删除,会抛出 locked 错误,但 rollout 文件已经删除,而 thread 行仍然还在。这样会留下这个命令本来想避免的半完成状态。
  • deleteSqliteThreadsByIds() 目前只删除了 thread_dynamic_toolsthread_spawn_edgesthreads。但当前真实 state_5.sqlite schema 里还有 stage1_outputs.thread_id,而且 PRAGMA foreign_keys 默认是关闭的。我按当前 schema 做了本地复现:删除后 threads=0,但 stage1_outputs=1,会留下孤儿数据。

建议在合并前至少补齐两件事:

  1. 让 delete 路径具备原子性或失败可恢复语义。
  2. 覆盖当前 schema 中所有与 thread 关联的表,并补对应集成测试。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants