Commit Graph
15 Commits
Author SHA1 Message Date
jpmschweitzerandClaude c744c8ce4b test sweep: cover BufferLine + CellAnchor (T-91)
Adds test/terminal/buffer/line_test.dart — 51 unit tests covering
BufferLine and CellAnchor, hitting every reachable line in
lib/src/terminal/src/core/buffer/line.dart (192 / 192).

Coverage delta:
- line.dart: 0 / 194 → 192 / 192 (file shrank by two lines after
  the prior commit's iteration fix folded two for-loop heads into
  for-each-toList).
- Total project: 36.39% → 39.12%.
- pubspec.yaml `coverage_floor:` bumped 36 → 39 in lockstep.

Highlights:
- All packed-cell encodings (foreground/background/attrs/content
  channels, codepoint+width packing, CellData round-trips).
- `eraseRange` wide-char neighbor extension on both ends.
- `removeCells` / `insertCells` shift logic, anchor reposition, and
  the wide-tail-erase branch (insertCells case where the post-shift
  last cell carries a wide marker).
- `resize` exercising the [64, 256) capacity-doubling branch and
  the >=256 +32 branch separately.
- `getTrimmedLength` cols-clamp behaviour for null/over-capacity.
- `getText` skip-trailing-wide-char branch.
- `CellAnchor` lifecycle: detached construction, `reposition`,
  `reparent` (both detached→attached and between owners), `dispose`,
  attached y/offset via a real IndexAwareCircularBuffer.

Also cleans up five `unrelated_type_equality_checks` analyze infos
in test/terminal/buffer/range_test.dart by typing the RHS as Object
when intentionally probing the type-mismatch branch of operator==.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-06 23:03:21 +02:00
jpmschweitzerandClaude eb32396bd4 test sweep: cover BufferRange family (T-91)
Adds test/terminal/buffer/range_test.dart — 38 unit tests covering
the small pure-Dart files in lib/src/terminal/src/core/buffer/:

- cell_offset.dart       23 / 23  (was 0 / 23)
- range.dart             13 / 13  (was 0 / 13)
- segment.dart           13 / 13  (was 0 / 13)
- range_line.dart        30 / 30  (was 0 / 30)
- range_block.dart       48 / 48  (was 0 / 48)

Total project line coverage 34.90% → 36.39%; coverage_floor in
pubspec.yaml bumped 34 → 36 in lockstep.

Tests exercise the abstract BufferRange operator==/hashCode/toString
via a local _StubRange (BufferRangeLine and BufferRangeBlock both
override those, so the base versions are otherwise unreachable —
worth a stub rather than carving the lines out of coverage). The
denormalized-input branches in Block contain/toSegments/extend get
explicit cases too.

Pure Dart, no Flutter dependency — uses package:test/test.dart and
runs in <100ms.

First batch under T-91; line.dart and buffer.dart land in subsequent
commits with their own floor bumps.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-06 22:55:15 +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 a67a768592 restore semantic bold rendering in terminal panes (T-73)
Bold attributes from terminal escapes now render in a real bold
weight instead of being silently flattened.

- pubspec.yaml: register JetBrainsMono Bold + BoldItalic at
  weight 700 under family JetBrainsMono. Files already shipped on
  disk; only the registration was missing.
- assets/licenses.yaml: bump JetBrainsMono weights_bundled to
  [Regular, Italic, Bold, BoldItalic] per D-42 (the entry must
  match what is actually wired into the family).
- lib/src/terminal/src/ui/painter.dart: revert the `bold: false`
  override and drop the workaround comment. Bold now flows from
  CellFlags.bold to TextStyle.fontWeight.
- test/terminal/painter_bold_metrics_test.dart: load Regular and
  Bold via FontLoader and assert paragraph maxIntrinsicWidth is
  identical (cell-grid drift = 0). JetBrainsMono Bold's monospace
  by spec; this test is the canary for the day someone swaps the
  font.
- test/goldens/goldens/{ci,linux}/clide_button.png: regenerate.
  ClideButton's label renders slightly heavier on the bold variant
  (expected — 0.28% pixel diff before regen).

Earlier perception of over-bolding in the Claude pane was
synthetic-bold smearing (Flutter overpaints when no Bold.ttf is
registered for the family), not legitimate bold rendering. Visual
A/B confirms a real Bold face renders crisp emphasis without the
smear, so no per-pane renderer config is needed.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-06 22:29:23 +02:00
jpmschweitzerandClaude 5f162a6668 rename tagline to "IDE for Claude Code CLI"
clide is an IDE for the Claude Code CLI. The previous tagline
"Flutter desktop IDE for Claude Code" overemphasized the host
toolkit (Flutter is implementation detail, immediately obvious to
contributors) and was ambiguous about whether the integration
target is the CLI specifically.

Updates the welcome subtitle (i18n catalog + widget test + view),
the project description in pubspec.yaml, README and CLAUDE.md, the
CLI banner, and the web manifest/index.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-06 11:06:41 +02:00
jpmschweitzerandClaude 9c1597a450 inline terminal emulator, drop xterm.dart dependency
Replace the xterm pub.dev package with owned code under
lib/src/terminal/. Based on xterm.dart v4.0.0 by xuty (MIT).
Quiver LRU replaced with hand-rolled LinkedHashMap cache.
Scrollable removed from TerminalView — scroll events are forwarded
via Listener.onPointerSignal instead. zmodem, debugger, and
suggestion modules stripped as unused.

Also: bundle clide.tmux.conf (no status bar, 50k scrollback,
mouse on, zero escape delay, isolated -L clide socket), bump PTY
read buffer to 64KB, add 2px terminal padding, drop bold
JetBrains Mono registration.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-05 08:50:38 +02:00
jpmschweitzerandClaude 5301c4753c release v2.0.0
test / unit + widget + golden + a11y (push) Failing after 31s
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
Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 22:06:31 +02:00
jpmschweitzerandClaude 7911075107 move canonical upstream to GitHub
Gitea remote kept as secondary (`gitea`). Updated repository URLs
in pubspec.yaml, licenses.yaml, and initial-plan.md. README rewritten
to reflect the current single-process Flutter architecture.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-26 20:07:54 +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 fa0032d26d rename logo assets: logo-* and appicon-* sets
Two clean sets from their SVG sources:
  logo.svg    → logo-{16..1024}.png (bare, transparent)
  appicon.svg → appicon-{16..1024}.png (on dark circle)
All rendered from 2048px masters. References updated in
pubspec.yaml, welcome view, and native runner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-23 10:04:01 +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 5869697297 add four design themes + syntax tokens to theme pipeline
test / unit + widget + golden + a11y (push) Failing after 39s
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
SurfaceTokens gains seven syntax-role fields (keyword, type,
string, number, comment, method, punct). Theme loader parses
the syntax: YAML block and injects values into the surface
override layer. Resolver defaults map syntax roles to semantic
colours so themes without explicit syntax blocks still compile.

Four new theme YAMLs (clide, midnight, paper, terminal) replace
summer-night. Palette keys mapped to the existing semantic layer;
syntax values pass through directly. Goldens regenerated for the
14→font-size change.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:29:41 +02:00
jpmschweitzerandClaude edd8a20e0d add Dart PTY wrapper and test-core harness
PtySession wraps the ptyc helper: socketpair + Process.start + recvmsg
with SCM_RIGHTS for master-fd transfer, a background isolate that
loops on blocking read() and posts byte chunks, plus write/resize/
kill/close. close() SIGTERMs the child so the PTY's EOF wakes the
reader naturally; SIGKILL + fd close + isolate kill cover the edge
where the shell ignores SIGTERM — avoids the known Linux quirk where
closing an fd doesn't unblock an in-flight read() on it.

Env defaults stamp TERM=xterm-256color, COLORTERM=truecolor,
CLICOLOR_FORCE=1 so shells + tmux + Claude emit 24-bit sequences
that xterm.dart can render. User env (HOME / USER / SHELL) still
inherits via mergePtyEnv().

ffi: 2.1.3 added as a runtime dep — the FFI bindings for socketpair,
recvmsg, read/write, and ioctl(TIOCSWINSZ) need an allocator we're
not writing by hand. Justified in pubspec + listed in licenses.yaml
per D-042.

make test-core (ci/test_core.sh) runs the Flutter-free core tests
under a 120s hard timeout with setsid + process-group kill, wired
ahead of the fast app tests in push-check so a hung PTY test can't
wedge a pre-push. Current core suite: 24 tests in ~1s.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:01:01 +02:00
jpmschweitzerandClaude 235cbcc046 add Dart core package — IPC envelopes, daemon, ping round-trip
First real content for the `clide` Dart package at the repo root.
One AOT-compiled binary (ADR 0005) with two modes:

  * `clide --daemon`  long-running unix-socket server; listens on
    `$XDG_RUNTIME_DIR/clide-$USER.sock` with stale-socket
    reclaim, accepts JSON-lines request/response traffic, clean
    SIGTERM shutdown unlinks the socket file.
  * `clide <subcommand>`  one-shot; opens the socket, sends a
    request, writes the response JSON to stdout, exits with the
    dispatcher's error code per ADR 0006 (0/1/2/3/4). Unknown
    subcommands forward to the daemon so extensions can register
    their own without CLI changes.

Tier 0 handlers: `ping` (returns pong + version + UTC ts) and
`version`. Both are covered by `test/ipc/` + `test/daemon/`; the
subprocess test builds `bin/clide`, starts it, pings it, SIGTERMs
it, and asserts the socket file disappears.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-21 15:36:40 +02:00