Memory-only "if you encounter a failure, fix it first" advice keeps losing to the model's default scope-protection behaviour: when a test is red or analyze warns on entry, the safer-feeling option is to flag and continue rather than fix and continue. Promoting the rule into the load-bearing guardrails list makes it sit in the same register as "Flutter desktop is the host" — non-negotiable, not advisory. Pairs with the .githooks/pre-push gate landed alongside: that prevents broken state from being pushed in the first place; this prevents the next session from building on broken state if it slips through. Co-Authored-By: Claude <noreply@anthropic.com>
7.3 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
What clide is
An IDE for Claude Code CLI. Single Flutter package at the repo root, plus small native supporter tools where Dart can't reach.
lib/— all Dart code. Subsystem handlers (lib/src/daemon/,lib/src/pty/,lib/src/ipc/,lib/src/git/,lib/src/pql/), kernel services (lib/kernel/), UI widgets (lib/widgets/), built-in extensions (lib/builtin/), and the extension framework (lib/extension/). The Flutter app hosts the IPC server in-process (D-56).pql— external supporter tool. Clide wraps it for every query surface; never re-implements it.ptyc/— small C supporter tool, peer of pql. Spawns a PTY + child and hands the master fd back overSCM_RIGHTS. Clide shells out to it for every pane (shell, tmux, claude, LSP, debug adapter).
tmux owns Claude session persistence (D-41) — the app re-attaches on restart via tmux new-session -A. Native rendering — markdown, canvas, graph — is Dart/Flutter (CustomPaint + widgets), not third-party packages.
Design doc: docs/initial-plan.md. Decisions: decisions/ (D-NNN confirmed, Q-NNN open, R-NNN rejected — see decisions/README.md). Python Textual predecessor under legacy/.
Guardrails
These are load-bearing. Violating any means the design is wrong, not the rule.
- Flutter desktop is the host. No Electron, ever. Web target may work as a happy accident — don't compromise desktop fidelity for it. If we ship a web build at all, prefer Flutter's WebAssembly (CanvasKit/Skwasm) compile over the JS/HTML renderer.
xterm.dartis the terminal renderer; markdown, canvas, graph are customCustomPaint/widget components. - Single process. The Flutter app hosts everything in-process: IPC server, subsystem handlers (pane, files, editor, git, pql), extensions. No separate daemon binary (D-56 dissolved it). The CLI surface for Claude is a thin C client (ptyc peer).
- CLI-first, not MCP. Claude talks via Bash (
clide ...), matching pql's contract. SeeD-1. - Dart is the core; native supporter tools fill specific gaps.
ptyc(C) for PTY spawning.pql(Go) for queries. No second "core language." SeeD-5(amended by D-56). - Own the rendering stack. PTY (via
ptyc), markdown renderer, graph, canvas — all clide-owned, not pulled from opinionated packages. - User/Claude parity. Every CLI subcommand has a UI affordance, and every UI action has a CLI. See
D-6. - pql: wrap, don't duplicate. Pql logic only lives in
lib/src/pql/(pure shell-outs). Clide owns pql'signore_files:config key; it never touches pql's.pql/index/cache data. SeeD-3. - Repo-is-the-workspace. The git repo root is the workspace — no parallel "vault" concept.
- Ignore discipline. Single knob:
ignore_files:in.pql/config.yaml, ordered layering. SeeD-4. - Decision discipline. All architectural choices live in
decisions/<domain>.mdasD-NNNrecords. Open questions asQ-NNN. Rejected alternatives asR-NNN. Claim new IDs viapql decisions claim D <domain> "title". Seedecisions/README.md. - No pre-existing excuse. Solo-dev repo — every failure encountered is yours to fix, regardless of who introduced it. If
make testis red, a golden is broken, orflutter analyzeshows a warning when you start working, the order is: fix it first, then your work. If you genuinely can't fix it in scope (separate ticket, large sweep, missing context), stop and surface it before continuing — don't push on top of broken state. "It was already broken" is not a reason to add more on top.
Repo layout
lib/
main.dart # Flutter app entry point
app.dart # Root layout, workspace, panels
clide.dart # Barrel: shared types (IPC envelope, pane kinds, etc.)
src/ # Core subsystems (IPC server, PTY, git, files, pql, panes, editor)
kernel/ # Kernel services (theme, i18n, settings, panels, commands, focus)
builtin/ # Built-in extensions (claude, editor, files, git, terminal, etc.)
widgets/ # Custom widget primitives (no Material/Cupertino)
extension/ # Extension contract and registration
lua/ # Lua runtime support (Tier 6)
test/ # All tests (core subsystems + widgets + goldens + a11y)
assets/ # Fonts, themes, grammars, licenses, logo
linux/, macos/, web/ # Flutter platform directories
ptyc/ # C PTY helper
native/ # Vendored native libs (libtree-sitter.so)
decisions/ # D/Q/R records
docs/ # Design docs, wireframes
legacy/ # Python Textual clide v1.2 (frozen)
Dependencies & supply chain
- Prefer-zero-deps. Flutter-SDK widgets first; third-party packages need justification. What stays is exact-pinned in
pubspec.yaml(no caret ranges). Advisories reviewed before every bump;pubspec.lockcommitted. - Document every bundled dependency. Listed in
assets/licenses.yamlwith name, kind, version, homepage, license, and purpose. Adding a dep is a two-step commit: add the artefact and thelicenses.yamlentry. SeeD-42. ptycand any future native supporter tool: no dep graph by design (libc-only forptyc). "Audit" is reading the source before each bump.
Commands
make run # launch Flutter desktop app
make analyze # flutter analyze
make format # dart format --set-exit-if-changed
make test # fast test suite (analyze + format + unit + widget + golden)
make test-core # core subsystem tests (IPC, PTY, git, pane registry)
make test-a11y # accessibility contract tests
make test-integration# real app boot integration tests
make build-linux # flutter build linux
make build-macos # flutter build macos
make ptyc-build # build the ptyc PTY-spawn helper
make push-check # pre-push gate: decisions + core + fast tests + a11y
make hooks # install the repo's git hooks (one-time setup)
make clean # remove build artefacts
One-time setup on a fresh clone: make hooks && flutter pub get once Flutter is installed.
Changelog discipline
Keep a Changelog 1.1.0. Every user-visible commit adds an entry under ## [Unreleased] in CHANGELOG.md. Cutting a release means moving Unreleased entries under a new dated version heading and bumping pubspec.yaml version: in the same commit — see .claude/skills/git-commit/SKILL.md for the full rule.
Open questions
Open questions live under decisions/questions-*.md.