Four layers under app/test/:
* kernel/, extension/ — unit tests for every kernel service and
the extension contract. i18n fallback chain gets the full
matrix (exact/lang/default/placeholder, namespace isolation,
unknown namespace, interpolation). Theme resolver and
extension-manager topo sort covered.
* widgets/, builtin/ — widget tests for every primitive and each
Tier 0 built-in. Assertions reach into the Semantics node so
a missing label fails structurally, not visually.
* goldens/ — Alchemist + Ahem font for cross-platform pixel
stability; primitives only (button, tab bar, icon set). No
goldens for compositions — they'd churn through every tier.
* a11y/ — contract-level gate: semantic coverage walks the
built-in catalogue, contrast walks every token pair in every
bundled theme against WCAG-AA thresholds (catches real
regressions: the first run caught `tab.inactive_text` at 2.81
in summer-night), i18n coverage asserts every referenced key
exists in its catalog (exists-in-map, not "key == value" — too
ambiguous for keys that happen to equal their translation).
Helpers under helpers/: `KernelFixture.create()` boots a
KernelServices with in-memory stores + a FakeDaemonClient (no
socket, drivable connected-state), `widget_harness` wraps a
widget in the minimum tree that resolves theme + i18n.
Co-Authored-By: Claude <noreply@anthropic.com>
12 KiB
Changelog
All notable changes to clide are documented in this file.
The format follows Keep a Changelog 1.1.0, and this project adheres to Semantic Versioning.
This changelog tracks the Flutter rebuild at the repo root. The Python
Textual implementation's changelog is preserved under
legacy/CHANGELOG.md.
Versions are tracked in project.yaml under version:,
which is the single source of truth. Cutting a release means (a) moving
the entries below from ## [Unreleased] under a new dated version
heading, and (b) bumping project.yaml version: in the same commit.
[Unreleased]
Removed
- Go sidecar skeleton under
sidecar/—cmd/clide/main.go,go.mod, and theinternal/*packages (cli,daemon,diag,git,ipc,pql,proc,pty,version). Deleted wholesale per ADR 0005: the "sidecar language: Go" premise no longer holds once the core is Dart. All functionality listed for those packages will be reimplemented underlib/as part of Tier 0. - Go-specific Makefile targets (
lint,vuln,test-race,fmt,tidy,snapshot,tools,installvia Go), thegovulncheck/goimports/golangci-lintversion pins, and the pre-push hook'sGOBINPATH injection. Replaced with Dart/Flutter equivalents (analyze,format,test,test-integration,buildviadart compile exe). module:andgo_version:fromproject.yaml— single-language core means no Go module path to track.
Changed
- ADR 0002 marked superseded by ADR 0005. The "sidecar language: Go" guardrail is retired. CLAUDE.md's guardrails, dependency notes, and command reference are updated to reflect the Dart-core direction.
.gitignoreretargeted: Flutter/Dart output at the repo root (.dart_tool/,build/, platform ephemeral dirs,bin/clide), plus aptyc/section for the C helper's build artefacts. Go-specific rules removed.ci/lint.sh,ci/test.sh,ci/security.sh, and.githooks/pre-pushrewritten for the Dart toolchain — no Go shell-outs, noGOBINPATH dance.
Added
-
App-level test suite under
app/test/— 168 tests across four layers:- Unit (
kernel/,extension/) — events bus, settings (scope + YAML round-trip), log, i18n fallback chain matrix, theme resolver + loader + controller, panel registry + arrangement, command registry + keybinding parser + palette filter, extension-manager dep-order / cycle detection / enable-disable, manifest loader, extension scanner. - Widget (
widgets/,builtin/) — every primitive's Semantics presence + token consumption + hover/press states; each Tier 0 built-in's contributions, view, and locale-switch re-render. - Golden (
goldens/) — widget primitives only, Alchemist + Ahem font; PNG fixtures checked in under_files/ci/and_files/linux/. - A11y (
a11y/) —semantic_coverage_test.dart(contract-level check that every built-in carries title + version + label-ready contributions),contrast_test.dart(WCAG-AA ratio gate on every bundled theme's canonical token pairs),i18n_coverage_test.dart(asserts every Tier-0-referenced key is present in itsen_UScatalog),keyboard_traversal_test.dart(focusability smoke).
- Unit (
-
Test helpers under
app/test/helpers/—KernelFixture(boots a KernelServices with in-memory defaults + a fake daemon for widget-level tests),FakeDaemonClient(subclasses the real client, no socket, drivable connected-state),golden_harness(Alchemist config with Ahem font for cross-platform pixel stability),widget_harness(wraps a widget in Directionality + ClideKernel + ClideTheme + MediaQuery). -
Flutter desktop app scaffold under
app/with a bareWidgetsApproot (no Material, no Cupertino) and the Tier 0 three-column layout.- Kernel (
app/lib/kernel/) — 18 services consumed by every extension:settings(scope-resolved get/set acrossapp.*/project.*/ext.*),project,extensions,theme,panels(slot registry + arrangement),events,ipc,commands(+ palette + keybinding resolver),clipboard,files,notify,dialog(single-at-a-time modal router),tray,secrets,os,net,focus, andlog. Unified in aClideKernelInheritedWidget. - i18n (
app/lib/kernel/src/i18n/) — text-driven lookup ported from fframe'sL10n: namespaced JSON catalogs,string()/interpolated()calls with caller-supplied placeholders, and a proper locale fallback chain (exact → language → default-country → default-language → placeholder). Improves on fframe's design by adding the chain, which fframe lacks. - A11y from Tier 0 —
Semantics(label:, hint:, button:)on every interactive primitive;SemanticsBinding.ensureSemantics()at boot; atheme/contrast.darthelper exposes token pairs that the a11y suite walks for WCAG-AA compliance. - Extension contract (
app/lib/extension/) — abstractClideExtension, sealedContributionPointhierarchy (TabContribution,StatusItemContribution,ToolbarButtonContribution,CommandContribution,TrayItemContribution,LayoutPresetContribution). Each extension ships one manifest contributing N atoms into kernel slots. Priority-based ordering within a slot, dependency-aware activation, YAML manifest loader + scanner for~/.clide/extensions/. - Three-tier theme pipeline — palette (named colors) → semantic roles → ~60 VS-Code-style surface tokens, each layer with defaults so palette-only themes ship. Ported
summer-nightas the first bundled theme; muted value calibrated for WCAG-AA contrast. - Widget primitives (
app/lib/widgets/) —ClideSurface,ClideText,ClideButton,ClideTabBar,ClideDivider,ClideScrollbar,ClideTooltip,ClideIcon+ eightCustomPainter-rendered icons (folder, gear, x, chevron-left/right, dot, check, plug). All token-consuming, all Semantics-wrapped. - Tier 0 built-in extensions —
builtin.default-layout(classic three-column preset + reset command),builtin.welcome(workspace placeholder),builtin.ipc-status(live-region statusbar indicator),builtin.theme-picker(command + modal, bound toctrl+k). Plus 17 id-reserving stubs (builtin.claude,builtin.terminal,builtin.files,builtin.editor,builtin.git, ...) so later tiers can fill in without rename churn. - Lua runtime boundary —
app/lib/lua/ships as typed stubs (host,adapter,capability_api,render_intent) so third-party Lua extensions can plug in at Tier 6 without retrofitting.
- Kernel (
-
.gitignoreextended to coverapp/sub-package artefacts (app/.dart_tool,app/build, per-platform ephemeral dirs,app/*.iml) and the Playwright harness undertools/ui/(node_modules,out, test-results). -
Dart core package at the repo root:
bin/clide.dart(one binary,--daemonand one-shot subcommand modes),lib/clide.dartbarrel exporting the shared IPC types,lib/src/ipc/(envelope.dart,server.dart,paths.dart,schema_v1.dart), andlib/src/daemon/dispatcher.dart.clide --daemonlistens on a unix socket;clide ping/clide versionround-trip through it with the ADR 0006 exit-code contract (0/1/2/3/4). Includestest/ipc/andtest/daemon/suites covering envelope parsing, the in-process server, and a subprocess smoke that verifies signal-driven shutdown + socket unlink. -
scripts/bazzite-flutter-setup.sh— one-shot installer for the Flutter SDK + desktop build deps on Bazzite / Fedora Silverblue. Drops the SDK under~/opt/flutter, wires PATH in the user's shell rc files, and layers the Linux desktop build deps viarpm-ostree install. -
ADR 0005 — Dart core; sidecar directory dissolved;
ptycas pql-peer. Establishes one Dart AOT binary for both CLI and daemon,lib/as the shared core, and promotes the C PTY helper to a standalone supporter tool on the same footing as pql. -
ADR 0006 — CLI and event surface contract. Defines the subsystem list (
pane,tab,editor,panel,tree,git,pql,canvas,graph,theme,settings,project), the command shape, the versioned JSON event schema, the pql-style exit-code contract, and the command↔event duality rule that operationalises user/Claude parity. -
Architectural decision records carried forward from the short-lived
claudianplugin project (discarded in favour of this Flutter rebuild): ADR 0001 — CLI-first, not MCP. ADR 0002 — Sidecar language: Go. ADR 0003 — pql as supporter tool; wrap, don't duplicate; pql is a Clide subsystem when present. ADR 0004 — Ignore file strategy (ignore_files:in.pql/config.yaml, layered). -
Pre-push quality gate:
.githooks/pre-pushrunsmake push-check(lint + test + test-race + test-integration + vuln + app-analyze + app-test) so bad pushes are caught locally before they hit Gitea. The app-side targets gracefully noop until Flutter is scaffolded. Install withmake hooks(setsgit config core.hooksPath .githooks); the hook prepends$GOBIN/$HOME/go/binto PATH so govulncheck resolves without the user touching their shell profile. -
Go sidecar/CLI skeleton under
sidecar/(modulegit.schweitz.net/jpmschweitzer/clide/sidecar):cmd/clide/main.go,internal/cliwith a stdlib-flag dispatch,internal/diagmirroring pql's exit-code + stderr-JSON contract,internal/versionwith ldflag-stamped build info, and placeholder packages fordaemon,pty,proc,git,ipc,pqlawaiting their tier.clide --versionemits JSON build-info today. -
Root
Makefiledrives both the Go sidecar and the Flutter app under one toolchain. Version is read fromproject.yamlvia awk and stamped into the sidecar via-ldflags -X. Flutter targets gracefully noop before the app is scaffolded so the Makefile is usable from day one. Pinned Go tooling (govulncheck, goimports, golangci-lint) installs viamake tools. -
ci/entry scripts:test.sh,lint.sh(includes the supply-chain gate — no green lint without a green CVE scan),security.sh,release.sh(stub). -
Project identity files for the Flutter rebuild at the repo root:
project.yaml(single source of truth for version + module path, version 2.0.0-dev), a freshREADME.md, MITLICENSE, and.editorconfig. The Python clide's manifest and README are preserved underlegacy/. -
docs/initial-plan.md— the north-star design document for the Flutter rebuild. Captures what we kept from Python Clide (pane model, git skills, Claude-always-visible), what we took from Obsidian (canvas and graph — no vault, no bases, no plugin inheritance), what Claudian's short experiment contributed (Go sidecar, CLI-first, pql-as-subsystem, ignore-file strategy), and the tier roadmap (Tier 0 app+sidecar handshake → Tier 5 canvas+graph). -
CLAUDE.mdorientation doc for future Claude Code instances: project identity, guardrails as one-liners, tier ordering, parent-project pointers, commands, dependencies & supply chain, open questions. Points at the design doc and ADRs rather than restating their content. -
Claude Code configuration under
.claude/: project-level allow/deny permissions and two skills —skill-create(generic skill authoring guidance) andgit-commit(this repo's commit conventions: no Conventional Commits, Keep a Changelog discipline,project.yaml-and-changelog-bumped-together rule, attribution trailer, safety reminders).