Commit Graph
110 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 4.6 a22bbfbe8d move icon rails to bottom strip row aligned with status bar
Icon rails pulled out of _SidebarSlot and _ContextSlot into the
bottom row alongside StatusbarHost. All three strips — left icon
rail, app strip, right icon rail — now sit on one continuous
horizontal line per D-047. Sidebar and context panels render
content only; their bottom rails share the status bar row with
matched widths. Collapsed spines get a matching-width spacer.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:44:09 +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 Opus 4.6 b581ed3fe8 center welcome content, bump font sizes, hide debug banner
Welcome content block is now centered in the viewport with a
720px max-width constraint. Status line pinned to the bottom.
Font sizes bumped across the board: title 52px, subtitle 16px,
section headers 12px, action labels 15px, recent project names
15px. Debug banner disabled via debugShowCheckedModeBanner.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:38:44 +02:00
jpmschweitzerandClaude Opus 4.6 16ecf51091 redesign welcome as full-screen overlay with recent projects
Welcome screen is now a full-window overlay that covers the IDE
when no project is open. Two-column layout: START actions (open
folder, clone from git, start Claude session) with keyboard
shortcut hints, and RECENT projects list showing name, path,
branch, and relative timestamp. Status line shows version, daemon
connection state, and active theme.

ProjectManager tracks up to 10 recent projects with path, branch
name, and last-opened time, persisted as JSON in app.recentProjects.
Boot chain: try last project → try cwd → show welcome. Clicking a
recent project opens it directly into Claude.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:35:21 +02:00
jpmschweitzerandClaude Opus 4.6 eedeaec05a persist last-opened project and wire welcome open dialog
ProjectManager.open() now saves app.lastProject to user settings.
Boot calls openLast() instead of opening cwd — first launch shows
the welcome screen, subsequent launches restore the last project
directly into Claude. The welcome "Open project" button shows a
modal path-entry dialog that validates against git and activates
the Claude tab on success. Removed the dead "New Claude session"
button since secondary sessions are spawned via command palette.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:29:40 +02:00
jpmschweitzerandClaude Opus 4.6 f07a7b55a2 auto-open project from cwd and show Claude as primary
On desktop boot, main.dart calls project.open(cwd) to resolve the
git root. If a project opens successfully, the workspace activates
claude.primary instead of welcome. The _WorkspaceSlot now listens
to ProjectManager: when isOpen, Claude is always the visible
primary surface; when no project, welcome shows. This closes the
gap where the app loaded the project root but still displayed the
welcome screen as if no choice had been made.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:26:35 +02:00
jpmschweitzerandClaude Opus 4.6 257bb0cd94 fix tooltip stacking on fast mouse movement
The delayed show callback fired even after the mouse had already
exited, causing tooltips to stack. Track hover state with a bool
and check it after the delay before showing.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:19:32 +02:00
jpmschweitzerandClaude Opus 4.6 8a94fd07a7 wire decisions, tickets, markdown viewer, and graph extensions
Four stub extensions now contribute real tabs with views:

- Decisions panel (sidebar, priority -20): lists confirmed D-records
  from pql decisions list with ID, title, and domain.
- Tickets panel (sidebar, priority -10): lists tickets with status
  dot color-coded by state (done=green, in_progress=blue,
  cancelled=red).
- Markdown viewer (context, priority -100): shows raw content of
  the active .md file, listens for editor.buffer_activated events.
- Graph view (context, priority -80): lists files with inbound and
  outbound link counts from pql search --connections.

All four fetch data via the daemon's pql.exec IPC surface.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:17:03 +02:00
jpmschweitzerandClaude Opus 4.6 cab92b0c6e add Phosphor Icons font and wire into icon rails
Phosphor Icons v2.0.8 (MIT) — regular, bold, and fill weights
bundled under assets/fonts/phosphor/. PhosphorIconPainter bridges
the font glyphs into the existing ClideIconPainter interface via
Paragraph API so icon rails, pane headers, and any widget using
ClideIcon can consume them. Sidebar and context panel icon rails
now use Phosphor glyphs instead of hand-painted CustomPaint icons.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:10:40 +02:00
jpmschweitzerandClaude Opus 4.6 82c63da3ad persist layout state across sessions
Collapse state, panel sizes, active sidebar/context tabs, and
editor split ratio save to .clide/settings.yaml on every layout
change and restore on boot. Guards against missing projectDir
so tests and no-project scenarios degrade gracefully.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:02:48 +02:00
jpmschweitzerandClaude Opus 4.6 43901bc387 implement editor-above-Claude split in workspace
Editor opens above Claude via Ctrl+E with a draggable divider at
35% height (clamped 15-70%). Ctrl+W or Escape closes it. The
workspace no longer renders a tab bar — Claude is the always-visible
primary surface per D-047/D-048; the editor is a split overlay
per D-049, not a tab. The _WorkspaceSlot separates editor from
primary content tabs and renders them as a vertical split when the
editor is open.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 23:01:02 +02:00
jpmschweitzerandClaude Opus 4.6 3f19eca059 remove bazzite-flutter-setup.sh
One-time setup script no longer needed.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 22:48:17 +02:00
jpmschweitzerandClaude Opus 4.6 11eb91effe implement collapse spine, focus mode, keyboard shortcuts, context rail
Collapsed side panels render as a 12px vertical spine with rotated
label, hover highlight, and badge dot (D-051). Focus mode snapshots
and restores the full layout arrangement (D-052). Fourteen new
commands in the default-layout extension: collapse toggles
(Ctrl+Shift+1/3), panel focus (Ctrl+1/2/3), focus mode (Ctrl+.),
sidebar section switching (Alt+1-5), Escape dismiss (D-054). Right
panel gets a bottom icon rail matching the sidebar pattern (D-047).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 22:47:45 +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 Opus 4.6 c61d2a23e4 add interaction model spec from wireframe flows v3
Extracted shell spec for Claude Code implementation: three-column
layout, prompt bar Y-invariance, collapse spine, focus mode, chrome
budget, editor mode, context auto-behavior, keyboard map, responsive
breakpoints, and state persistence. Source: Wireframe - Flows v3.html.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-22 22:47:17 +02:00
jpmschweitzerandClaude 02814b35f3 add POLICY.md and set line length to 160
POLICY.md codifies runtime behavior rules (no network on default
launch path), dependency vetting, vendored binary rebuild process,
telemetry prohibition, and licensing requirements. Binding on all
contributors including agents.

Line length 160 in .editorconfig (all files) and
analysis_options.yaml (dart formatter).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 22:20:42 +02:00
jpmschweitzerandClaude 50bd3012bd add wasmtime Apache-2.0 license file per POLICY.md
Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 22:13:58 +02:00
jpmschweitzerandClaude ce8529e424 add tree-sitter syntax highlighting via dart:ffi
Vendor libtree-sitter.so (v0.26.8, wasmtime 44.0 statically linked)
and call its C API through dart:ffi. Grammar WASM files are loaded by
tree-sitter's embedded wasmtime engine via ts_wasm_store_load_language.

48 grammars compiled with tree-sitter build --wasm, 48 highlight
queries (42 from upstream repos, 6 written in-house for comment,
erlang, gdscript, gitignore, hcl, hlsl, swift). SQLite grammar
replaces full SQL (974K-line parser exhausted RAM at compile time).

Removes wasm_run and wasm_run_flutter — they downloaded a 22 MB
binary from GitHub at first launch, violating the no-network-on-
default-launch-path policy.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 22:08:00 +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 5aa153334d update welcome screen per hi-fi design
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
Larger wordmark (48px), START section header, icon-prefixed
action rows for Open project and New Claude session. Semantics
hint preserved for a11y.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 17:31:10 +02:00
jpmschweitzerandClaude ad3e35709e require confirmation before discarding unstaged changes
The discard button in the git panel now opens a dialog warning
that changes will be permanently lost. Prevents accidental data
loss from a misclick.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 17:30:55 +02:00
jpmschweitzerandClaude 45054f7aec add git branch picker + status bar indicator
git.branches and git.checkout IPC verbs. Status bar shows current
branch with ahead/behind count; clicking opens a branch picker
dialog for checkout.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 17:30:37 +02:00
jpmschweitzerandClaude 6592a88695 add command palette widget + layout keybindings
ClidePalette renders as a floating overlay with fuzzy-filtered
command list. Ctrl+Shift+P toggles it. Ctrl+B toggles sidebar,
Ctrl+J toggles context panel. All wired through CommandRegistry
via the default layout extension.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 17:30:21 +02:00
jpmschweitzerandClaude eda3b30382 add sidebar icon rail replacing top tab bar
Four new icon painters (git branch, search, terminal, warning).
ClideIconRail widget with parent-owned hover state so only one
icon highlights at a time. Sidebar slot renders content above +
icon rail below; workspace and context slots keep the tab bar.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 17:29:00 +02:00
jpmschweitzerandClaude 1f23ba40f2 fix make run — use PID file, add make stop
test / unit + widget + golden + a11y (push) Failing after 40s
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
PID file at /tmp/clide-daemon-<uid>.pid replaces pkill pattern
matching. make run depends on stop so stale daemons are killed
before build. Flutter exit via ctrl-C no longer aborts Make.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:54:18 +02:00
jpmschweitzerandClaude 8b5615426a wire design palette through resolver with fallback chains
Surface map now tries palette keys (bgSunken, surfaceHi, textHi,
etc.) first, falling back to semantic refs for legacy themes.
Sidebar/panel bg differentiates from workspace bg. Buttons use
accent colour with onAccent text. Four-level text gradient flows
to widgets.

WCAG-AA contrast fixes: clide textDim lightened, midnight
onAccent darkened, paper textDim darkened. Contrast test updated
to cover all four themes. Resolver tests updated for the new
palette shape. Goldens regenerated.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:54:11 +02:00
jpmschweitzerandClaude 861fa6652a fix make run daemon lifecycle
test / unit + widget + golden + a11y (push) Failing after 40s
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
Kill stale daemon before build to prevent "Text file busy". Trap
EXIT + INT + TERM for reliable cleanup on ctrl-C. Add make stop
for standalone daemon kill.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:32:11 +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 de9a7b9745 update design handoff with framework-free token exports
New tokens/ directory with YAML palette + syntax files for all
four themes, plus a pure dart:ui Dart file (no Material). README
updated to reflect the no-Material constraint and open typography
question.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:29:17 +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 ae1c3d8a34 add claude.ai/design handoff under docs/claude-design/
Four self-contained HTML mockups (wireframe, flows, hi-fi, design
system), four Dart theme files (clide, midnight, paper, terminal),
and flat PNG renders. Reference material for the UI build — not
runtime assets.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:11:22 +02:00
jpmschweitzerandClaude 1a5e682dc8 brand all build targets with the clide logo
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
Replace Flutter default icons across Linux (GTK window icon via
bundled asset), macOS (AppIcon.appiconset all sizes), and web
(favicon, PWA icons, manifest, meta description). Logo PNGs at
16–1024px generated from the SVG source. Window title set to
"clide" everywhere. Web manifest colours match summer-night.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 16:02:08 +02:00
jpmschweitzerandClaude d4f5f7c09f add clide logo SVG
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
Angle-bracket chevrons with teal accent underline, matching the
summer-night palette.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 15:18:54 +02:00
jpmschweitzerandClaude 303e449ef4 add make run target
Builds the daemon binary if stale, starts it in the background,
launches flutter run -d linux, and cleans up the daemon on exit.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 15:18:40 +02:00
jpmschweitzerandClaude 4f8840ccd2 add type scale constants; remove scattered font size overrides
Sidebar and panel text was too small — dozens of bare fontSize:
10/11/12 values fighting the ambient DefaultTextStyle. Root font
bumped from 13 to 14. Three semantic constants replace the magic
numbers: clideFontBody (14), clideFontCaption (12), clideFontMono
(13). Widgets that render body text now inherit instead of
overriding.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 15:18:30 +02:00
jpmschweitzerandClaude e290ae6dbd wire builtin.pql + builtin.problems panels
test / unit + widget + golden + a11y (push) Failing after 40s
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
PqlExtension contributes a sidebar tab (files, query, decisions,
tickets views) and a context-panel tab (backlinks + outlinks for
the active file, auto-refreshing on editor.active-changed).

ProblemsExtension contributes a sidebar tab aggregating pql.doctor
and decisions.sync diagnostics with actionable hints.

Both upgraded from stubs to 0.1.0.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 14:03:32 +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 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 7164ec11d6 install pql skill and add pql permissions
pql init --with-skill=yes installs .claude/skills/pql/SKILL.md
covering vault queries and the planning surface (decisions +
tickets). Lock file tracks version + SHA-256 for drift detection.

Bash(pql) and Bash(pql *) added to .claude/settings.json so
pql commands run without permission prompts.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 13:39:11 +02:00
jpmschweitzerandClaude 6bce2621b7 wire builtin.git sidebar panel + builtin.diff workspace tab
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
GitController hydrates from git.status IPC and auto-refreshes on
git.changed events. Panel shows staged/unstaged/untracked/conflict
groups with per-file actions and an inline commit field.

DiffController renders unified diffs with line numbers, addition/
removal colouring, and a staged/unstaged toggle. Both extensions
upgraded from stubs to 0.1.0.

ClideText gains an optional fontFamily parameter so diff lines can
render in JetBrainsMono without breaking golden tests (font still
inherits from ambient DefaultTextStyle by default).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 11:09:48 +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 f619760e7b add git subsystem — daemon-side status, diff, operations + IPC
Shell-outs to git for status (porcelain v1/v2), unified-diff
parsing, and operations (stage, unstage, hunk-apply, discard,
commit, stash, log, pull, push). IPC verbs git.* registered on
the daemon dispatcher with git.changed event emission on
mutations. 42 new core tests.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 11:09:16 +02:00
jpmschweitzerandClaude 681ce3b447 wire builtin.editor to the active buffer + open files from the tree
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
EditorController mirrors the daemon's active buffer into the Flutter
UI. Hydrates on mount (editor.active → editor.read), subscribes to
editor.opened / active-changed / edited / saved / closed, and pushes
local edits back via editor.set-content. A one-shot echo-suppression
flag keeps the daemon's authoritative edit echo from clobbering the
caret the user just moved.

Text surface is EditableText directly — no TextField / Material
import, so D-007's "bare WidgetsApp" guardrail carries into the
editor tab. JetBrainsMono via the shared mono-family constants;
cursor + selection colours come from the theme tokens.

File-tree click now calls ipc.request('editor.open', {path}) instead
of the kernel command registry (which wouldn't have reached the
daemon). The opened file becomes active, the editor tab's controller
sees editor.active-changed, and the text content reconciles.

Linux release bundle still builds; 174 app tests + 74 core tests
stay green.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 10:31:01 +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 b9fbcd43a2 implement builtin.claude per D-041
test / unit + widget + golden + a11y (push) Failing after 45s
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
Tier-0 stub flipped to the real Claude pane. Primary-per-repo
semantics: session name is `clide-claude-<hash>` where <hash> is
FNV-1a over the workspace root path, so reopening clide attaches
to the same `claude` process through `tmux new-session -A`.

Primary has no close button — closing the tab disposes the widget
but deliberately does NOT call pane.close, so the tmux session
survives until the user actually exits claude or clide is shut
down. Secondary sessions (spawned via the claude.new-secondary
command registered here, UI wiring lands next) close normally and
the pane.close cascades into tmux kill-session.

Graceful fallback when tmux isn't on PATH: retries the spawn with
argv=['claude'], surfaces "no-tmux · fresh every launch" in the
header subtitle so the user knows persistence is off.

Session-naming unit tests cover determinism + uniqueness per repo.
Full app suite: 174 tests passing.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:40:30 +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 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 e1ea52c5e4 implement builtin.terminal — general-purpose shell pane
Flips the Tier-0 stub into a real extension. Contributes a Terminal
tab in the workspace slot that spawns $SHELL -l via IPC pane.spawn,
feeds pane.output events into xterm.dart's Terminal, and routes user
input back through pane.write. Viewport resize propagates via
pane.resize. Surface for disconnected-daemon / exited-shell states so
there's no silent dead tab.

Knows nothing about Claude deliberately — the Claude-specific pane
(primary-per-repo, tmux-backed, D-041) lives under builtin.claude in
the next steps.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-04-22 09:23:44 +02:00