Skip to content

feat(cli): thread rename, pin, and title search — headless 会话管理对齐(补齐 HTTP 面已有的能力) - #519

Merged
Qiyuanqiii merged 2 commits into
mainfrom
Qiyuanqiii/thread-cli-metadata
Nov 2, 2026
Merged

Qiyuanqiii merged 2 commits into
mainfrom
Qiyuanqiii/thread-cli-metadata

Conversation

@Qiyuanqiii

Copy link
Copy Markdown
Member

动机 / Motivation

继续对照 Claude Code 与 Codex CLI 的功能盘点:两者的主界面都支持重命名会话、置顶会话与按标题搜索(Claude Code 的 sessions 与 Codex 的 thread 管理)。Universal-Code 的存储层与 HTTP 面早已完整具备这三件事——internal/store/thread_metadata.go 的 RenameThread/PinThread + internal/httpapi/thread_metadata.go 的 PUT /threads/{id}/name|pin,桌面聊天列表也在使用——但 CLI(文档明确的一等 headless/NDJSON 入口)一个都没有:thread 子命令只有 create/list/show/send/compact/compactions/history/archive/restore/delete/export。

对无人值守脚本来说,跑完一个 NDJSON 任务后无法给它起一个可识别的名字、无法置顶重点会话、也无法按标题找回历史任务,只能靠完整的 thread ID。本 PR 把这条不对称补齐。

变更 / Changes

  • cyberagent thread rename <thread-id> "new title":复用 store.RenameThread(4096 字符上限、拒绝控制字符、trim;同值 no-op 幂等;已删除线程按标准 not-found),与 HTTP 面语义逐字对齐。
  • cyberagent thread pin <thread-id> [--pinned true|false](默认 true):复用 store.PinThread;--pinned 为 String 旗标并严格校验 true|false(Go flag.Bool 不消费下一参数,--pinned false 会把值当位置参数,因此与 thread list --pinned 一致采用 String)。
  • cyberagent thread list --title-query <text> --pinned true|false:透传 domain.ThreadFilter 已有的 TitleQuery/Pinned(ASCII 大小写不敏感字面子串、≤256 字符,其余 Unicode 精确比较);文本列表每行新增 pinned= 标记,--json 走既有 domain.Thread 投影。
  • 帮助文本与 docs/usage.md(中英)同步;docs/reviews/thread-cli-metadata/ 按仓库惯例记录 OCR delegate 复审(F1/F2 两条 P3 文档措辞问题,均已修复)与覆盖明细。

不涉及 schema 迁移、不新增权限、不改 HTTP/Web 行为。

验证 / Verification

  • gofmt -l internal/app/ 无输出;go vet ./internal/app/ 无告警。
  • go test ./internal/app/ -run TestThreadCLI -count=1 通过(含两个新测试:rename/show 传播/大小写命中与未命中/空标题/控制字符/不存在线程;pin 默认值/双向过滤的 JSON 精确断言/unpin/非法值拒绝)。
  • 完整 go test ./internal/app/ 中仅有的两个失败均与本 PR 无关且在干净 main 上同样复现:TestRunCommandExecuteIsConfirmedAuditedAndExactlyOnce 依赖本机不可用的 approved executable;词表测试需要检出 docs/openapi.json(稀疏检出产物,补齐后通过)。
  • 真实构建 cmd/cyberagent 端到端冒烟:rename 多词标题(含不带引号裸多词)、--pinned=false 与 --pinned false、--pinned maybe 报错、纯空白 --title-query 不过滤、大小写混合查询命中、--pinned false 过滤正确、每次实际变更 version 递增。

差距说明 / Gap context

与 Claude Code / Codex 对照仍在的差距(供后续规划,本 PR 不涉及):聊天内"编辑历史消息并重发"(Esc-Esc / 点击编辑)、侧问通道(/btw、/side)、语音听写、输出风格定制。上一次同类对比已通过 PR #518 补齐项目指令脚手架(/init 对应物)。

The HTTP surface and Desktop chat list already support renaming, pinning,
and title search for conversations (store/thread_metadata.go +
httpapi/thread_metadata.go); the CLI — the documented first-class surface
for headless and NDJSON workflows — had no access to any of them.

Add 'cyberagent thread rename <id> <title>', 'cyberagent thread pin <id>
[--pinned true|false]', and 'thread list --title-query/--pinned' with the
same store semantics (no authority, not-found for deleted threads,
monotonic versions). The text listing now shows pinned state per row.

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Claude <noreply@anthropic.com>
@Qiyuanqiii
Qiyuanqiii merged commit 4e6118b into main Nov 2, 2026
23 checks passed
@Qiyuanqiii
Qiyuanqiii deleted the Qiyuanqiii/thread-cli-metadata branch November 2, 2026 07:17
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