feat: add ZCode session source - #513
Open
sinoon wants to merge 1 commit into
Open
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.sqlitewithsession/message/parttables 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/corenewzcodeparser (parsers/zcode.ts): mirrors the OpenCode parser, adapted for ZCode's table shape — nomodel/agentcolumns onsession(the model is derived from message data instead), and atask_typecolumn separating session kinds:interactiverows — primary conversations, indexed as standalone sessions.subagent_childrows — folded into their parent conversation as sidechain messages under aZCode subagent: <title>header (visible in the session detail view; like every other source, folded sidechains stay out of the fragment search index).forkandselection_side_chatrows — 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.task_type = 'subagent_child'edges, bounded by a depth guard. Orphan subagents whose parent row is missing stay hidden, matching the OpenCode semantics.<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/-journal→db.sqlite), project grouping by the recorded cwd, doctor index counter, and root resolution via default~/.zcode/cli/dbplusSPOOL_ZCODE_DIR/ZCODE_HOMEoverrides.@spool-lab/session-kitprovider list + label; hub SID validation (backend + web); source badge colors (uitokens/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).Out of scope (mirroring the
piprecedent): 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/corealone 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 throughsyncAll/syncFile).~/.zcode/cli/db/db.sqlite(1023 rows: 320 interactive, 684 subagent_child, 17 fork, 2 selection_side_chat):spoolsync indexes exactly 340 root sessions (0 archives, subagents folded).spool sessions list -s zcode,spool sessions search … -s zcode, andspool sessions show <uuid>(message timeline + foldedZCode subagent:sections) all work as expected.Compatibility
Existing indexes are untouched: the
sourcesseed row is added idempotently via the existingINSERT OR IGNOREblock 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.sqlitethe source quietly yields nothing, same as an absent Gemini or Pi install.