Files
1jehuang--jcode/docs/dev/crate-splitting-plan.md
wehub-resource-sync a789495a98
FreeBSD Smoke / FreeBSD Smoke (x86_64) (push) Has been cancelled
CI / Quality Guardrails (push) Has been cancelled
CI / Build & Test (macos-latest) (push) Has been cancelled
CI / Build & Test (ubuntu-latest) (push) Has been cancelled
CI / Build & Test (windows-latest) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / PowerShell Syntax (push) Has been cancelled
CI / Windows Cross-Target Check (Linux) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:10:34 +08:00

2.8 KiB

Compile-time crate splitting plan

Goal

Minimize the amount of code that must be rechecked or rebuilt when iterating on Jcode. The root jcode crate is still the integration shell, but stable leaf code should live in small crates with one-way dependencies.

Principles

  1. Extract stable leaves first: filesystem/storage, protocol/types, parsers, provider request/stream codecs, and TUI render primitives.
  2. Avoid cyclic domain crates. Root jcode may depend on leaf crates, but leaf crates must not call back into root logging/config/runtime directly. Use data types, callbacks, or explicit events at boundaries.
  3. Split by recompilation volatility, not by directory names. Code edited often should not force heavy provider/TUI/server modules to rebuild unless needed.
  4. Keep heavy optional dependencies behind crates/features. Embeddings, PDF, desktop/mobile, browser, and image/render pipelines should remain isolated.
  5. Preserve compatibility facades during migration. crate::storage::* can re-export jcode-storage::* while callers move gradually.

Current first step

jcode-storage is now a leaf crate for app paths, permission hardening, atomic JSON writes, and append-only JSONL helpers. The root src/storage.rs module is a thin compatibility facade that preserves existing logging behavior for backup recovery.

Measured after extraction on this machine:

  • cargo check -p jcode-storage: ~0.9s after initial dependencies were built.
  • cargo check -p jcode --lib: ~14s in the current warm-cache state.
  1. jcode-provider-anthropic: move Anthropic request/stream translation out of root src/provider/anthropic.rs and depend only on jcode-provider-core, jcode-message-types, and serde/reqwest primitives.
  2. jcode-provider-openai: same for OpenAI request/stream handling. This reduces rebuilds when editing server/TUI code and makes provider tests cheap.
  3. jcode-session-core: move session storage paths, journal metadata, and memory-profile pure transforms once dependencies on root prompt/logging are cut behind callbacks.
  4. jcode-tui-app-state: split key/input/navigation state transitions from rendering. Keep ratatui rendering in jcode-tui-render/root while state tests compile without the whole root crate.
  5. jcode-server-protocol-runtime: split websocket/client event fanout glue from agent execution so server tests do not rebuild TUI/provider internals.

Anti-patterns to avoid

  • Extracting crates that depend on root jcode. That preserves the compile-time bottleneck and creates dependency cycles.
  • Tiny crates for every file. Too many crates increase metadata overhead and make refactors painful.
  • Moving only type aliases while leaving implementations in root. The expensive compile units remain expensive.