Skip to content

feat(coding-agent): add SQLite session search index - #266

Merged
liuedcson merged 2 commits into
mainfrom
feat/session-search-main
Oct 19, 2026
Merged

liuedcson merged 2 commits into
mainfrom
feat/session-search-main

Conversation

@liuedcson

@liuedcson liuedcson commented Oct 19, 2026 •

Copy link
Copy Markdown
Collaborator

背景

Web 端要支持按内容搜索会话,前提是有一个可查询的本地索引。这一步先把索引本身落到 main:JSONL 仍是权威数据,索引是派生数据,可随时重建。

node:sqlite + FTS5 trigram 建在 <agentDir>/index/session-search.v1.db。3 个字符以上的查询走 FTS,更短的查询走最近 200 个会话的 LIKE。查询入口是 sessions.search / sessions.list / index.status;CLI 不打开索引。

实现

  1. 索引核心:packages/coding-agent/src/core/session-index/(schema、store、fallback、projector、reader、attach、client、command、worker)。降级路径(SQLite 不可用)改为直接扫 JSONL,行为与索引一致。packages/coding-agent/src/server/session-search-service.ts 提供进程内服务,apps/cli/src/main.ts 接入。

  2. 子会话规则:packages/coding-agent/src/core/child-session.ts 的 isChildAgentSession 以结构标记判定——header 的 origin === "subagent",或 id 前缀为 subagent- / workflow-(兼容旧数据),不解析文本。子 agent 通过 childSessionHeader() 在 header 里写入 origin 和 parentSessionId。

  3. 索引排除子会话:schema minor 2 增加 sessions.origin 列并按 id 前缀回填;所有 search / list SQL 与降级扫描都过滤 origin IS NULL;CLI 的 resume 选择器使用同一条规则。子会话仍然写入索引,只是不可搜索、不列出。

  4. 文档:packages/coding-agent/docs/session-index.md、session-format.md。

验证

  • pnpm run check 通过。
  • packages/coding-agent 的 session-index、子会话 env、会话分支读取、subagent 链路共 62 个测试通过。

Add a derived, rebuildable SQLite index over session JSONL files for
session lists and full-text search, for Web and Desktop hosts. JSONL stays
the only authoritative data: the index only reads session files and can be
deleted at any time.

Index:
- node:sqlite with FTS5 trigram at <agentDir>/index/session-search.v1.db;
  application_id STCX, schema major in the file name, minor in user_version.
- One worker thread owns the connection. Opening never rejects: a foreign
  file, missing SQLite/FTS5, or a dead worker falls back to a JSONL scan
  with session-level hits and status "degraded".
- Incremental sync verifies header and tail hashes before appending;
  rewritten, shrunk, v1, or older-projector files are rebuilt in one
  BEGIN IMMEDIATE transaction with a snapshot check.
- Queries of 3+ characters use FTS with bm25; shorter ones use LIKE over
  the 200 most recent sessions, at most 50 hits.
- Before each search or list, a 30 ms freshness pass re-syncs the 20 most
  recent files and lists directories whose mtime changed, so sessions
  written by other processes appear without notifications.

Integration:
- SessionManager.setFilePersistedListener() reports create/append/rewrite.
- attachSessionIndex() and withSessionIndex() wire managers and factories.
- createSessionSearchService() exposes search.query, sessions.list, and
  index.status without choosing a transport, validating untrusted params.
- `step session-index status | reindex [--full] | clear`.
- The CLI does not open the index during interactive or print sessions.
- The worker ships beside client.js in dist and the Node bundle, and as an
  extra entry point in compiled Bun binaries.

docs/session-index.md describes storage, upgrades, and the steps for a
host to adopt the index.
…arch

Child agents (subagent lanes, workflow agents) now stamp origin: "subagent"
and parentSessionId in their session header. isChildAgentSession recognizes
the header marker or the subagent-/workflow- id prefix of older sessions.

The session index (schema minor 2) stores sessions.origin, backfills it from
the id prefix, and excludes child sessions from every search and list path,
including the degraded JSONL scan. The CLI resume picker uses the same rule.
@liuedcson
liuedcson merged commit 91dbfd9 into main Oct 19, 2026
2 checks passed
@liuedcson
liuedcson deleted the feat/session-search-main branch October 19, 2026 11:55
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.

1 participant