Skip to content

feat: add ZCode session source - #513

Open
sinoon wants to merge 1 commit into
paperboytm:mainfrom
sinoon:feat/zcode-source
Open

feat: add ZCode session source#513
sinoon wants to merge 1 commit into
paperboytm:mainfrom
sinoon:feat/zcode-source

Conversation

@sinoon

@sinoon sinoon commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

What

Adds ZCode as a first-class session source, indexable on par with the existing OpenCode source.

ZCode is an AI coding agent CLI whose session store follows the OpenCode-style per-session SQLite model: one database at ~/.zcode/cli/db/db.sqlite with session/message/part tables and JSON payloads on the message/part rows. Until now these sessions were invisible to Spool because the source was not in the indexed set.

How

  • packages/core new zcode parser (parsers/zcode.ts): mirrors the OpenCode parser, adapted for ZCode's table shape — no model/agent columns on session (the model is derived from message data instead), and a task_type column separating session kinds:
    • interactive rows — primary conversations, indexed as standalone sessions.
    • subagent_child rows — folded into their parent conversation as sidechain messages under a ZCode subagent: <title> header (visible in the session detail view; like every other source, folded sidechains stay out of the fragment search index).
    • fork and selection_side_chat rows — these own a copied message history plus their own continuation, so folding them into the parent would duplicate the shared prefix into the index (on a real installation, ~30k duplicated messages out of ~130k total). They are indexed as standalone sessions carrying their own titles.
    • Recursive walks between roots and subagents only follow task_type = 'subagent_child' edges, bounded by a depth guard. Orphan subagents whose parent row is missing stay hidden, matching the OpenCode semantics.
  • Sync machinery: virtual <db>#session=<id> file paths, index-version pinning (zcode-v1-session-model), stale-row cleanup for archived/deleted sessions, WAL sidecar normalization in the watcher (db.sqlite-wal/-shm/-journaldb.sqlite), project grouping by the recorded cwd, doctor index counter, and root resolution via default ~/.zcode/cli/db plus SPOOL_ZCODE_DIR / ZCODE_HOME overrides.
  • Surfaces: @spool-lab/session-kit provider list + label; hub SID validation (backend + web); source badge colors (ui tokens/theme/styles + web session feed). ZCode sits in the same capability bucket as Gemini/OpenCode/Pi: local preparation + Hub Share via provider-neutral portable records, not natively resumable, not published to Discovery (Link-only by default).
  • Docs: README, bundled skill, web docs (quick-start, data-sources matrix, configuration table, CLI reference, agent integration).

Out of scope (mirroring the pi precedent): native Resume support, Discovery/Explore publication, and the archived Electron app.

Verification

  • pnpm check — lint clean across the repo; pnpm build; pnpm typecheck — all green.
  • pnpm test — workspace green; packages/core alone 470/470, including 14 new parser tests (fold semantics, fork standalone indexing, orphan/archived-parent/cycle guards, model derivation, part-type filtering, WAL sidecar mapping, mtime versioning) and 1 new syncer test (database indexing + fold + fork + idempotent re-sync through syncAll/syncFile).
  • Real-world smoke test with the repo-local CLI against a live ~/.zcode/cli/db/db.sqlite (1023 rows: 320 interactive, 684 subagent_child, 17 fork, 2 selection_side_chat):
    • spool sync indexes exactly 340 root sessions (0 archives, subagents folded).
    • spool sessions list -s zcode, spool sessions search … -s zcode, and spool sessions show <uuid> (message timeline + folded ZCode subagent: sections) all work as expected.

Compatibility

Existing indexes are untouched: the sources seed row is added idempotently via the existing INSERT OR IGNORE block on next launch, and no schema version bump is required (no DDL). Users without ZCode see no behavioral change; on machines without ~/.zcode/cli/db/db.sqlite the source quietly yields nothing, same as an absent Gemini or Pi install.

Index ZCode (an AI coding agent CLI whose session store follows the
OpenCode-style per-session SQLite model) as a first-class session source,
on par with the existing OpenCode source:

- packages/core: new zcode parser reading ~/.zcode/cli/db/db.sqlite
  (session/message/part tables; JSON message/part payloads). ZCode marks
  rows with task_type: subagent_child rows fold into their parent
  conversation as sidechain messages (visible in the session detail view,
  staying out of fragment search like other sources), while fork and
  selection_side_chat rows own a copied history and are indexed as
  standalone sessions to avoid duplicating large shared prefixes.
- Sync machinery: virtual #session= paths, index-version pinning,
  stale-row cleanup, watcher WAL sidecar normalization, project grouping
  by recorded cwd, doctor index counter, SPOOL_ZCODE_DIR / ZCODE_HOME
  root resolution.
- Surfaces: session-kit provider list + label (Link-only, portable
  records, not natively resumable — same bucket as gemini/opencode/pi),
  hub SID validation (backend + web), source badge colors in ui and web.
- Docs: README, bundled skill, web docs (quick-start, data-sources
  matrix, configuration table, CLI reference, agent integration).

Verified: pnpm check lint-clean, pnpm build, pnpm typecheck, pnpm test
(core 470/470 incl. 14 new parser tests + 1 syncer test; workspace
564/564). Also smoke-tested the repo-local CLI against a real
~/.zcode/cli/db/db.sqlite (1023 source rows): indexes 340 root sessions
(forks standalone, subagents folded), and full-text search, sessions
list, and sessions show (with folded ZCode subagent section) all work.

Claude Code and Codex remain the only Native Resume and Discovery
providers; ZCode shares are Link-only until Discovery supports the
portable sources.
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