Commit Graph
22 Commits
Author SHA1 Message Date
Jeroen SchweitzerandClaude Opus 4.6 a6eca2561b remove dissolved daemon, retire ptyc, fix golden cross-platform
Complete three overdue cleanups discovered during macOS health check:

D-56 daemon dissolution: delete bin/clide.dart, DaemonServer,
and orphaned tests (test/cli/, subprocess_test, in_process_test).
Update stale "clide --daemon" references in i18n catalogs, error
messages, editor_commands, CI scripts, and decision records.

ptyc retirement: delete ptyc/ source tree, PtySession, scm_rights.
Remove from Toolchain resolution, ToolCheck gate, backend
serialization, testmode harness, Makefile, CI, and sandbox
entitlements. PTY spawning uses NativePty (Dart FFI forkpty) since
the terminal was absorbed in-tree. D-5 amended.

Golden tests: wire the existing but never-applied clideGoldenConfig
via flutter_test_config.dart. Disable CI goldens (Skia anti-aliasing
differs between macOS/Linux even with Ahem). Keep platform-keyed
goldens only — goldens/linux/ and goldens/macos/ each run on their
own OS.

Test suite: 826 pass, 0 fail on macOS (was 829 pass, 11 fail).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-05-07 18:40:01 +02:00
jpmschweitzerandClaude 1151a0ce80 install ratcheting line-coverage gate at 34% floor (T-90)
First child of T-89. Codifies "don't make coverage worse" as a
durable pre-push contract before any test-writing children land.

- pubspec.yaml: new `coverage_floor: 34` key. Single source of
  truth for the floor; ratchets up only.
- ci/coverage_gate.sh: parses coverage/lcov.info (LH/LF), reads
  the floor from pubspec.yaml, exits non-zero if integer-truncated
  measured % drops below it. Self-contained awk parser — no `lcov`
  CLI dependency.
- ci/test.sh: flutter test now runs with --coverage, so the gate
  reads fresh data without an extra test invocation. Wall time
  delta is small and stays inside the < 90 s pre-push budget
  (D-29).
- Makefile: new `coverage-gate` target wires the script in;
  `push-check` adds it as a dependency. The .githooks/pre-push
  hook (already wired) picks this up automatically.
- .gitignore: ignore /coverage/ wholesale; the floor lives in
  pubspec.yaml, nothing under coverage/ is committed.

Decision recorded as D-66 (decisions/testing.md). End target is
95%; reaching it is tracked as the rest of T-89's children.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-06 22:44:43 +02:00
jpmschweitzerandClaude 6e6546fe32 clean-house sweep: anchor drift, app/-prefix paths, D-59 sunset
Fixes 3 substring-truncated cross-reference anchors so they match
the full heading slug:
- D-3 link in architecture.md
- D-40 link in process.md (heading gained the [SUPERSEDED] tag)
- Q-15 link in questions-process.md

Strips the legacy `app/` prefix from path references in 5 files —
the dirs were flattened to repo root in the Flutter rebuild
(D-56). Three "was `app/...`" historical references in D-5 and
D-56 are deliberately preserved as record of the dissolution.

Adds an inline (tracked in T-88) note to D-59 so the
"must track dugite-native releases for security updates" intent
is wired to a backlog item — RULE-SUNSET-WITHOUT-TICKET would
otherwise keep flagging it on every sweep.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-06 16:40:38 +02:00
jpmschweitzerandClaude d4369aabc3 add D-60 through D-65: POLICY.md rules as decision records
Six new D-records codify rules that lived only in POLICY.md:
D-60 no network on default launch path, D-61 dependency vetting
checklist, D-62 dependency removal process, D-63 vendored binary
rebuild process, D-64 no telemetry (architecture), D-65 license
compatibility matrix. Closes T-28.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-05 08:49:53 +02:00
Jeroen SchweitzerandClaude Opus 4.6 b0d9fab0c6 bundle git via dugite-native (D-59)
macOS sandbox blocks Homebrew git execution (symlinks resolve to Cellar
paths that SBPL cannot match). Bundled dugite-native — the same
relocatable Git distribution GitHub Desktop ships.

make dugite-fetch downloads the platform tarball to native/dugite/.
Toolchain checks the bundled binary first, sets GIT_EXEC_PATH and
GIT_TEMPLATE_DIR automatically. native/dugite/ is gitignored (57 MB
compressed).

Decision D-59 in tooling.md, dependency entry in licenses.yaml
(GPL-2.0 for the git binary, MIT for dugite-native build scripts).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 13:18:39 +02:00
jpmschweitzerandClaude Opus 4.6 2235cc4c19 drop leading zeros from all D/Q/R/T IDs
pql 1.2.0 changed its record format to drop leading zeros. All
262 references across 18 files renumbered (D-001→D-1, T-043→T-43,
etc.). pql-plan.json export updated as the git source of truth
for the planning database. DB rebuilt via pql plan import.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 12:16:52 +02:00
jpmschweitzerandClaude Opus 4.6 a44a2efae7 add format engine packages: jovial_svg, markdown, html_core (D-058)
Three format engines adopted per the new D-058 rule (format
engines clear the dependency bar; UI chrome stays in-house):

- jovial_svg 1.1.26 (BSD-3) — SVG renderer via CustomPaint
- markdown 7.2.2 (BSD-3) — GFM parser; renderer is ours
- flutter_widget_from_html_core 0.17.2 (MIT) — HTML renderer

Welcome screen now loads logo.svg via jovial_svg instead of a
raster PNG. POLICY.md updated with format engine rule. All three
documented in licenses.yaml.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 10:28:46 +02:00
jpmschweitzerandClaude Opus 4.6 8938a0d502 add Q-031: XWayland fallback, proper Wayland protocol roadmap
Documents the workaround (GDK_BACKEND=x11), rollback instructions,
the proper fix (libwayland-client + xdg-decoration protocol), and
the alternative timeline (Flutter GTK4 migration).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 09:09:16 +02:00
jpmschweitzerandClaude Opus 4.6 538472f7ec replace OS title bar with per-column 24px hats (D-057)
Hide GTK title bar via gtk_window_set_decorated(FALSE). Add
MethodChannel('clide/window') for drag/minimize/maximize/close
wired to GTK window functions. Dart WindowControls service wraps
the channel. Three per-column hats in RootLayout: left (macOS
traffic lights or plain drag), center (project > branch label),
right (minimize/maximize/close glyph buttons on Linux). Resolves
Q-006.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 08:16:28 +02:00
jpmschweitzerandClaude Opus 4.6 1fdd35706e fold project.yaml into pubspec.yaml
pubspec.yaml is now the single source of truth for version and
project metadata. Makefile reads version from pubspec.yaml. All
references to project.yaml across CLAUDE.md, CHANGELOG.md,
decisions, and skills updated.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 00:45:36 +02:00
jpmschweitzerandClaude Opus 4.6 46329700d5 dissolve app/ into repo root (D-056)
Single Flutter package at the repo root. All code, tests, assets,
and platform directories moved from app/ to root. Package renamed
from clide_app to clide — all imports rewritten. Merged pubspec
combines core (ffi) and app (flutter, yaml, xterm) dependencies.
Makefile simplified: no APP_PRESENT conditionals, no cd, no daemon
lifecycle. 317 tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 00:37:20 +02:00
jpmschweitzerandClaude Opus 4.6 a526c5b9b7 add D-055 Claude internal tabs, readable session name slugs
D-055: multiple Claude sessions share the workspace as internal
tabs inside the Claude pane header. Primary has no close; secondaries
show ×. Tab row hidden when only primary exists. + button and
double-click-empty spawn new secondaries.

Session names now use a readable path slug (strip $HOME, replace /
with -) with fallback to FNV-1a hash when the slug exceeds 80 chars.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 00:13:24 +02:00
jpmschweitzerandClaude Opus 4.6 9e3a13e7f7 add D-047–D-054, Q-026–Q-030 for interaction model
Eight confirmed decisions: Claude-is-home layout (D-047), chrome
budget (D-048), editor mode (D-049), context auto-behavior (D-050),
collapse spine (D-051), focus mode (D-052), state persistence
(D-053), canonical keyboard map (D-054).

Five open questions: small screen layout (Q-026), two-editor split
(Q-027), terminal strip scope (Q-028), branch picker location
(Q-029), focus when editor dirty (Q-030).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 22:47:30 +02:00
jpmschweitzerandClaude 4f5d97ebc5 define core frame vs shipped extension boundary (D-046)
Core frame builtins are infrastructure the shell can't function
without. Content extensions (editor, claude, canvas, etc.) are
bundled but architecturally removable — users swap the surface,
not the data.

Removes builtin.jira stub: Jira belongs as a third-party
extension, not a frame builtin. Git is a split component —
daemon-side process stays in frame, UI surfaces are extensions.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 22:07:04 +02:00
jpmschweitzerandClaude 272b59e752 record design handoff decisions (D-043–D-045, Q-025, R-012)
test / unit + widget + golden + a11y (push) Failing after 41s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
D-043: adopt token palettes from design, reject Material wrapper.
D-044: four bundled themes replace summer-night.
D-045: syntax highlighting tokens in the theme pipeline.
Q-025: body text face — mono everywhere vs Josefin Sans + mono.
R-012: MaterialApp wrapper rejected (conflicts with D-007).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:11:40 +02:00
jpmschweitzerandClaude e43438d369 remove Python stopgap; rewire to pql 1.0
test / unit + widget + golden + a11y (push) Failing after 38s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
pql 1.0 ships full feature parity for decisions and tickets.
Sunset condition from D-040 met; deletion per R-011.

Removed: tools/scripts/plan entrypoint, tools/scripts/planning/
Python modules, tools/scripts/README.md, .gitignore pycache
entries.

Rewired: make decisions-validate now calls pql decisions validate.
CLAUDE.md decision discipline guardrail points at pql. Extension
stub comments updated. decisions/README.md examples use pql.
D-040 amended as superseded.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 13:39:28 +02:00
jpmschweitzerandClaude 0b451c133d record D-041: Claude panes — one primary per repo, tmux-backed
Captures the session-persistence + primary-vs-secondary policy
referenced from ptyc/README.md and deferred through the Tier 1
substrate work. Primary per repo (keyed on git root) survives app
restart via `tmux new-session -A`; secondaries are ephemeral and
collapse back to the primary on close; primary has no close
affordance. Daemon owns the session lifecycle, the UI just asks
pane.spawn / pane.close and observes events.

Required by the next commit (builtin.claude) which consumes this
policy.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:37:04 +02:00
jpmschweitzerandClaude 50d9e00ea5 add shared pane widgets + Q-023 ssh-remote question
ClidePtyView is a theme-bound wrapper around xterm.dart's TerminalView
— token-derived TerminalTheme, JetBrainsMono as the face, Semantics
live-region label so screen readers + Playwright both hear it. The
consumer (terminal / Claude extensions) owns the `Terminal` model and
wires IPC pane.write / pane.output → terminal.write() themselves; the
widget deliberately has no IPC dependency so it stays trivially
testable.

ClidePaneChrome is the shared pane header — title + subtitle + leading
icon + trailing widgets + optional close button. The close button is
null-conditional so primary Claude panes (D-041, landing in step 7)
can render without one.

xterm 4.0.0 added as a justified runtime dep + logged in
licenses.yaml per D-042. 3 new widget tests cover header rendering,
close-button presence, and the close-tap round-trip.

Q-023 records the SSH-remote-development question so the daemon + IPC
seams don't accrete local-only assumptions during Tier 1-5.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:19:24 +02:00
jpmschweitzerandClaude c94ad2c05b restructure licenses.yaml: self + runtime deps + dev deps
test / unit + widget + golden + a11y (push) Successful in 1m30s
test / integration_test (xvfb) (push) Failing after 1m14s
test / bundle smoke (xvfb 5s) (push) Failing after 1m3s
test / daemon subprocess + web WASM smoke (push) Successful in 1m42s
Three sections instead of one flat list. `self:` carries clide's own
MIT license (rendered first in the About screen so the user knows
what they're running before the dependency list). `dependencies:`
covers artefacts that actually ship in the binary — JetBrainsMono,
JosefinSans, yaml. `dev_dependencies:` tracks build-time tooling
(mocktail, alchemist, flutter_lints, lints, test) for audit
completeness without polluting the user-facing About panel.

Also backfilled the two root-package dev deps that were missed the
first pass: `lints: 5.0.0` and `test: 1.25.8` (root pubspec, not
app/). Root LICENSE mirrored into app/assets/LICENSE + declared as
a bundled asset so the About screen can read it at runtime (Flutter
can't reference paths above the package root).

D-042 updated to describe the three-section split and the dev-vs-
runtime distinction.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 08:26:36 +02:00
jpmschweitzerandClaude 1b00d88a0d document bundled deps in licenses.yaml; record D-042
Every third-party artefact shipping in the clide binary — fonts,
Dart packages, native tools, bundled assets — now has an entry in
app/assets/licenses.yaml with name, kind, version, homepage, license
identifier, relative path to the bundled license text, and a
one-line purpose. The About screen (Tier 6) will render this file
verbatim. Seeded with the current set: JetBrainsMono, JosefinSans,
yaml, mocktail, alchemist, flutter_lints.

D-042 captures the two-step-commit rule (artefact + licenses.yaml
entry in the same changeset) alongside D-031's prefer-zero-deps
budget: preferring zero deps is the budget; licenses.yaml is the
visible consequence when the budget grows.

CLAUDE.md "Dependencies & supply chain" gains a matching guardrail
line. The per-dep license text files (OFL.txt for both fonts) are
declared as pubspec assets too so the About screen has something to
display, not just a manifest.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 08:18:39 +02:00
jpmschweitzerandClaude cede971646 migrate ADRs into D/R records; delete docs/ADRs/
Lift docs/ADRs/0001-0006 into decisions/:
  0001 → D-001 (CLI-first, not MCP)
  0002 → R-002 (Go sidecar; superseded by D-005)
  0003 → D-003 (pql as supporter tool; wrap, don't duplicate)
  0004 → D-004 (ignore file strategy)
  0005 → D-005 (Dart core; sidecar dissolved; ptyc as pql-peer)
  0006 → D-006 (CLI and event surface contract)

ADR 0006's trailing open-questions footer migrates to
questions-architecture.md as Q-001 / Q-002 / Q-003 (already landed
in the scaffold commit). Titles preserved verbatim; cross-references
updated to the new anchor-link style.

docs/ADRs/ deleted — originals remain in git history.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 17:13:37 +02:00
jpmschweitzerandClaude 4d515ce51e scaffold decisions/ with backlog from planning sessions
Adopt settled-reach's Q&D record convention. Confirmed decisions
live under decisions/<domain>.md as D-NNN; open questions under
questions-<domain>.md as Q-NNN; rejected alternatives in rejected.md
as R-NNN. Markdown is source of truth; .pql/pql.db (added later) is a
query index.

Backlog captured from the Tier-0 Flutter planning sessions: bare
WidgetsApp, theme pipeline, kernel admission rule, feature-first
layout, a11y + i18n as Tier-0 contracts, test pyramid, kanban over
Scrum, pql-owns-planning, Python stopgap sunset clause.

ADR migration (D-001, D-003-D-006 confirmed, R-002 rejected) is
staged for the next commit so the diff stays readable.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 17:10:42 +02:00