Commit Graph
14 Commits
Author SHA1 Message Date
jpmschweitzerandClaude 26cc1b3154 drop redundant single-symbol imports across the tree
12 imports flagged by `unnecessary_import` because the symbols
they bring in are also re-exported by the umbrella import already
present in the same file:

- bin/clide.dart: src/git/client.dart, src/pql/client.dart
  (covered by package:clide/clide.dart).
- lib/builtin/decisions/, lib/builtin/tickets/ (4 files):
  kernel/src/events/message_bus.dart (covered by kernel.dart).
- lib/kernel/src/ipc/in_process.dart: src/daemon/dispatcher.dart
  (covered by clide.dart).
- lib/main.dart: kernel/src/toolchain.dart (covered by kernel.dart).
- test/builtin/ipc_status/widget_test.dart:
  builtin/ipc_status/src/status_item.dart (covered by
  ipc_status.dart).
- test/daemon/{git,pql}_commands_test.dart: src/git/client.dart and
  src/pql/client.dart (covered by clide.dart).
- test/widgets/multitab_pane_test.dart: widgets/src/icons/x.dart
  (covered by widgets.dart).

Mechanical change — every removed line was already a no-op for
symbol resolution; the umbrella imports define the public surface
each file is actually using.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-06 23:46:24 +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 864a1062a6 remove dead code and fix analyzer warnings
Unused _resolvePtycPath (bin/clide.dart), _TrafficDot (app.dart
and clide_column_hat.dart), stale @override on _spawned field
(claude_pane.dart), duplicate import and unused local in
test_app.dart, unnecessary non-null assertions in project.dart.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 21:52:26 +02:00
Jeroen SchweitzerandClaude Opus 4.6 5aa0eb46e4 replace ptyc with forkpty() via Dart FFI
test / unit + widget + golden + a11y (push) Failing after 3m13s
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
NativePty calls forkpty() directly — no helper binary, no socketpair,
no SCM_RIGHTS. The master fd stays in-process. Reader isolate uses
poll() for clean shutdown.

Based on the pty-spike proof-of-concept. Platform-aware: macOS uses
libSystem (DynamicLibrary.process), Linux needs libutil.so.1.
TIOCSWINSZ platform-detected.

PaneRegistry updated to use NativePty. registerPaneCommands no longer
needs a Toolchain parameter. All ptyc references removed from the
daemon layer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-30 20:30:15 +02:00
Jeroen SchweitzerandClaude Opus 4.6 73e80a55a6 add Toolchain, GitClient, native directory picker
Toolchain centralizes binary resolution — replaces five ad-hoc
mechanisms (expandedPath, _resolveGit, _resolve, _resolvePtyc,
_existsOnPath). Resolves via Future.delayed after runApp to avoid
blocking the merged UI/platform thread on macOS.

GitClient wraps all git operations with a typed API. Every subprocess
call goes through _run() using toolchain.git + toolchain.gitEnv.
Replaces free functions in operations.dart.

Native directory picker: NSOpenPanel on macOS (method channel in
AppDelegate), GtkFileChooserDialog on Linux. Falls back to text-input
dialog on web or MissingPluginException. Shows "No git repo found"
dialog when the selected directory is not a git repository.

PqlClient and pane commands updated to use Toolchain. ToolCheck
replaced by Toolchain.missing/allOk. All IPC handlers now catch
GitException to prevent unhandled exceptions on the merged thread.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-25 13:18:39 +02:00
jpmschweitzerandClaude Opus 4.6 f71f2bce7c resolve ptyc path relative to daemon binary
The daemon now checks for ptyc at ../ptyc/bin/ptyc relative to its
own binary location before falling back to PATH lookup. Fixes
"ProcessException: No such file or directory. Command: ptyc" when
ptyc is built but not on PATH.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:44:00 +02:00
jpmschweitzerandClaude 93ab6ea3bd add pql subsystem — daemon-side client + IPC handlers
PqlClient wraps pql CLI per D-003 (shell-out, never duplicate).
IPC verbs: pql.files, pql.meta, pql.backlinks, pql.outlinks,
pql.tags, pql.schema, pql.query, pql.doctor, pql.decisions.*,
pql.tickets.*, pql.plan.status. 15 new core tests.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 14:02:47 +02:00
jpmschweitzerandClaude 17936bf215 add clide git CLI shortcuts
Maps clide git status|diff|stage|unstage|discard|commit|log|stash|
pull|push to the git.* IPC verbs. Updates --help to list the new
tier-3 subcommands.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 11:09:25 +02:00
jpmschweitzerandClaude 50d0143afc add tier-2 CLI shortcuts and clide tail --events
`bin/clide` gains the single-word shortcuts CLAUDE.md's tier 2 spells
out: open, active, insert, replace-selection, save. Each maps the
flat positional argv into the canonical editor.* IPC shape. Insert
and replace-selection accept a lone `-` to read text from stdin so
piping works (`pbpaste | clide replace-selection -`).

`clide tail --events` is the subscribe mode. Same socket as the
request side; the client just reads + filters events. --filter
SUBSYSTEM or SUBSYSTEM:ID narrows the stream. Exits cleanly on
SIGINT.

defaultSocketPath() now respects CLIDE_SOCKET_PATH before XDG — the
existing override callers always had this up their sleeve (via
XDG_RUNTIME_DIR manipulation) but making it explicit unblocks
parallel test runs where each test needs its own daemon socket. The
new end-to-end CLI suite does exactly that: 5 tests spin up real
daemon subprocesses and exercise the shortcut surface through the
live IPC stack.

74 core tests pass; round-trip verified by hand (open README.md →
insert → tail --events captures editor.opened / edited /
selection-changed / saved).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 10:21:03 +02:00
jpmschweitzerandClaude d32e8fdc17 add editor subsystem — daemon state + editor.* IPC
EditorBuffer + Selection + EditorRegistry hold the daemon-side
active-file model (D-006 subsystem 'editor'). Active buffer
tracking means `clide insert "…"` and `clide replace-selection
"…"` target the UI's focused file without the caller supplying an
id. Mutations mark buffers dirty; editor.save writes back to disk
through the workspace root; events fire on every state change so
subscribers can mirror.

IPC surface matches CLAUDE.md's tier-2 list + the natural extras
(list, read, activate, set-selection, set-content, close). Tests
cover open-idempotence, insert at caret, replace-selection range
swap, dirty→save→clean round-trip, close picks a new active
buffer, out-of-range selection clamping.

69 core tests pass.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 10:10:42 +02:00
jpmschweitzerandClaude 37108230f2 decouple Pane from PtySession so the web build compiles
test / unit + widget + golden + a11y (push) Failing after 37s
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
Pane is now a pure data class — id, kind, pid, argv, cwd, title,
isClosed. The daemon-side PaneRegistry holds a parallel map of
PtySession keyed on id; registry methods look up both sides when
writing / resizing / closing.

The `clide.dart` barrel no longer re-exports `src/pty/*`,
`src/panes/registry.dart`, or the `*_commands.dart` modules — all
three transitively import `dart:ffi` which isn't available when
compiling to WebAssembly. The daemon entrypoint (bin/clide.dart) +
core tests import them via deep paths now. Pane / PaneKind /
DaemonEventSink / RecordingEventSink stay in the barrel since
they're pure data the Flutter app references over IPC.

Verified: `dart analyze` clean, 53 core tests green, 174 app tests
green, `make ui-smoke` compiles + serves + Playwright smoke passes,
daemon boots + ping round-trips + SIGTERMs cleanly.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 10:01:06 +02:00
jpmschweitzerandClaude 4ff5556896 implement builtin.files — workspace file tree with live watcher
Flutter sidebar tab that lazy-loads the workspace tree via IPC
files.ls and refreshes subtrees on files.changed events. Click-to-
open routes through a future editor.open command; until Tier 2
registers it, the execute call no-ops gracefully.

Daemon side adds a new files subsystem:
  - files.root returns the resolved workspace root (git root if
    present, otherwise cwd)
  - files.ls lists a directory with ignore filtering applied
  - files.watch starts a recursive Directory.watch and fans
    FileSystemEvents out as files.changed IPC events
  - FilesService owns the watcher + ignore set lifecycle

IgnoreSet + IgnorePattern implement the common gitignore subset:
anchored (/foo), directory-only (foo/), negation (!foo), **
crossing dirs, ** at trailing position. Built-in layer hides clide-
owned dirs (.git, .pql, .clide, .dart_tool, build, node_modules);
.gitignore + .clideignore at the root layer on top per D-004. Full
multi-file ignore_files: layering from .pql/config.yaml is future
work.

11 new ignore-matcher tests + 5 files.* dispatcher tests.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:36:02 +02:00
jpmschweitzerandClaude 3715a2e191 add pane subsystem to the daemon + IPC event broadcast
Implements the Tier-1 pane subsystem from D-006: spawn / list / focus /
close / write / resize / tail commands, plus pane.spawned / output /
exit / resized / focused / closed events. PaneRegistry owns per-pane
PtySession lifecycles and id generation (p_N); a DaemonEventSink seam
keeps pane code decoupled from the IPC server package.

DaemonServer.broadcast() fans events out to every connected client.
Per-client subsystem/id filtering (`tail --filter pane:p_7`) is
deferred — Tier 1 broadcasts everything and the subscriber discards.

Panes carry a `kind:` field (terminal | claude). Step 7 (builtin.claude)
adds the claude-specific pane flow on top of this generic substrate —
the subsystem itself stays neutral.

14 new core tests: registry unit coverage (spawn → pane.spawned event,
output → base64 events, write/resize/close round-trips, idempotent
close, claude kind on the wire) plus dispatcher coverage (argv
validation, unknown-id → not-found, text vs bytes_b64, etc). All 37
core tests pass in ~3s under test-core.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:05:51 +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