Files
clide/CLAUDE.md
T
jpmschweitzerandClaude 301322a6b0 promote no-pre-existing-excuse to a CLAUDE.md guardrail
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>
2026-05-06 22:28:25 +02:00

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 over SCM_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.dart is the terminal renderer; markdown, canvas, graph are custom CustomPaint/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. See D-1.
  • Dart is the core; native supporter tools fill specific gaps. ptyc (C) for PTY spawning. pql (Go) for queries. No second "core language." See D-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's ignore_files: config key; it never touches pql's .pql/ index/cache data. See D-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. See D-4.
  • Decision discipline. All architectural choices live in decisions/<domain>.md as D-NNN records. Open questions as Q-NNN. Rejected alternatives as R-NNN. Claim new IDs via pql decisions claim D <domain> "title". See decisions/README.md.
  • No pre-existing excuse. Solo-dev repo — every failure encountered is yours to fix, regardless of who introduced it. If make test is red, a golden is broken, or flutter analyze shows 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.lock committed.
  • Document every bundled dependency. Listed in assets/licenses.yaml with name, kind, version, homepage, license, and purpose. Adding a dep is a two-step commit: add the artefact and the licenses.yaml entry. See D-42.
  • ptyc and any future native supporter tool: no dep graph by design (libc-only for ptyc). "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.