Record that this solo-dev repo lands routine work straight on main and
does not use a branch-first flow, so the generic assistant default of
branching before committing on the default branch does not apply here.
Co-Authored-By: Claude <noreply@anthropic.com>
The pre-D-15 plan snapshot is no longer read — planning state lives in
.pql/changelog/ and is replayed into pql.db on clone/merge. pql plan
import only touches this file behind --legacy, so it is dead weight.
Co-Authored-By: Claude <noreply@anthropic.com>
These five were stuck in_progress locally while the source machine had
already closed them, but that machine's close never reached the
git-tracked changelog (no done-transition in .pql/changelog/, all remotes
in sync) — likely a write-through/hook gap in its pql bookkeeping.
Closed here after confirming the work is genuinely complete: each
ticket's acceptance criteria were verified against the code and the
backing tests run green (130 passing across the vim preset, Claude
sidebar sub-tabs, and the reader back/forward, pin, and edit-pencil
suites).
Co-Authored-By: Claude <noreply@anthropic.com>
Adds issue #7 — pql decisions sync regenerates governance/README.md and
relists resolved questions as open (dropping the Resolved section), which
also yields a persistent false-dirty diff.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sub-pixel rendering drift (~8px) from the committed goldens/macos/ baselines
for button, icon, and tab-bar. Regenerated on macOS.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two tests compared a raw Directory.systemTemp path against an OS-resolved
one, which diverge on macOS where /tmp is a symlink to /private/tmp:
FilesService.atCwd resolves the CWD, and the clide-cli e2e server must hash
the same canonical workspace the C client sees via getcwd. Resolve symlinks
on both sides.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
isIgnored only matched a directory path itself, not files beneath it, so
a recursive watch still surfaced changes inside .dart_tool/, build/, etc.
Linux usually hid this because inotify drops the nested creates; macOS
FSEvents delivers them, so the tree reacted to churn it should ignore.
Check each ancestor segment as a directory.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three analysis docs that were loose at the repo root: the 2026-05-26
codebase cleanliness audit, the dogfood self-analysis of whether Claude
can work inside clide, and the pql improvement notes for upstream.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Track the project-local Claude Code skills that were living untracked in
.claude/skills/.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Root-anchored ignores for Flutter build output (dist/), the Python venv
(.venv/), coverage and logs, the firebase debug log, and two stray
root-level Python trees (clide/, tests/) that aren't the Dart test/ dir.
Keeps git status clean without committing machine-local artefacts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The Activity / Team / Config sub-tabs were built on a raw GestureDetector,
so Tab traversal skipped them and Enter/Space did nothing — a gap against
the repo's a11y contract. Switch to ClideTappable (focusable, Enter/Space
activates) wrapped in button + selected semantics, and add a test that
drives the switch via ActivateIntent rather than a pointer tap.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The SDK's flutter_test pins test_api 0.7.11, but test 1.30.0 requires
0.7.10, so dependency resolution failed and make run/test aborted.
1.31.0 is the release whose test_api dep is exactly 0.7.11; 1.31.1 wants
0.7.12 and would re-conflict. Pulls in the transitive meta 1.18.0 and a
Dart >=3.10 lower bound.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Ticket changes land only in the gitignored .pql/pql.db; the post-checkout/post-merge hooks rebuild it from the committed changelog on every branch switch, so un-exported tickets vanish silently (this is how the T-208-T-225 tree was lost). Add an export-and-commit step to Step 3a and a matching anti-pattern, cross-linked to the pql skill.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A pql rebuild reset planning state to the committed changelog baseline
(max T-207), dropping the T-208–T-225 ticket tree sourced from
self-analysis.md. Re-created it deterministically (same order → same IDs)
and ran `pql plan export` so the changelog now carries the full tree:
- T-208 initiative "Give Claude hands"
- epics T-209 (PATH delivery), T-214 (bootstrap), T-218 (observability),
T-222 (events) + tasks T-224/T-225, with blockers and decision refs.
Committing the regenerated changelog makes the work durable: the next
`pql plan rebuild` replays it instead of resetting to T-207.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
pql 1.5 re-introduced .pql/pql-plan.json as the canonical planning-
state export (regenerated on every decisions/ticket mutation). Bring
the un-ignore back so the backup rides commits across clones —
add028e dropped it when the file was dead under pql 1.4, but the
export is live again. Hooks stay ignored (still per-clone, absolute
paths baked in).
Co-Authored-By: Claude <noreply@anthropic.com>
claude --resume keeps the model's prior context but emits no past
turns over stream-json, so the pane was visually empty until the
user sent a new prompt. The orchestrator now reads the last 256 KB
of the on-disk transcript JSONL when SpawnSpec.resume is true and
seeds the ConversationController with the parsed items before the
stream subscription starts. Best-effort: missing or unreadable file
just falls back to the previous empty-pane behaviour.
Co-Authored-By: Claude <noreply@anthropic.com>
Bash, Write, and Edit/MultiEdit each get a tool-appropriate body in
the permission card instead of the indented-JSON dump: Bash renders
the command as a shell code block with a background/timeout footer,
Write shows path + content syntax-highlighted from the extension, and
Edit shows path + before/after blocks. Unknown tools keep the JSON
fallback.
Co-Authored-By: Claude <noreply@anthropic.com>
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>
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
macos-pty-problem.md: diagnosis of the SCM_RIGHTS fd issue (resolved
by switching to forkpty via NativePty).
pty-proposition.md: Gemini's diagnostic plan (cmsg_len analysis,
ptyc instrumentation, async recvFd).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
tmux determines window size from its client, not the PTY winsize.
TIOCSWINSZ + SIGWINCH on the master fd has no effect on tmux's
internal dimensions. Use tmux resize-window -t <session> -x -y
to explicitly set the window size on resize.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 27s
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
tmux doesn't re-read the PTY winsize on SIGWINCH. After the ioctl
resize, call tmux refresh-client -C cols,rows to update tmux's
internal window dimensions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 27s
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
tmux running inside a PTY without a traditional terminal client
defaults to a huge window size (2000+ cols, 10000 rows). Pass
explicit -x and -y flags matching the TerminalView dimensions.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 34s
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
Reverts the bare-shell diagnostic. Spawns tmux new-session -A -s
<sessionName> for persistence. Claude command will be added back
after tmux + resize are stable.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
Missed in the workspace → project rename. Consistent with the
project.open / project.validate / ProjectOpened naming.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
top fails with "Error opening terminal: xterm-256color" because the
PTY child can't find terminfo. Set TERMINFO=/usr/share/terminfo
explicitly in the pane environment.
Output flush changed from 16ms Timer to Duration.zero (next event
loop turn) for tighter batching of escape sequences.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 29s
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
Split escape sequences caused rendering artifacts (visible % prompt
mark, garbled lines between commands). Two fixes from the legacy
Python implementation:
1. Read buffer increased from 4096 to 65536 bytes. Larger reads mean
fewer chunk boundaries that can split multi-byte escape sequences.
2. Output writes throttled to ~60fps via a 16ms Timer. Multiple PTY
reads within one frame window are batched into a single
terminal.write() call, so the xterm parser sees complete sequences
instead of fragments that render as garbage between frames.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 33s
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
Firing all tier ticks simultaneously on project open causes multiple
IPC calls (pql, git, files) to run in parallel, their responses
triggering rapid setState rebuilds that beachball the merged thread.
Stagger 500ms apart so each panel refreshes sequentially.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
Rapid resize during window drag sends many SIGWINCH signals causing
the shell to redraw repeatedly, corrupting xterm's render. Debounce
to 150ms so only the final size is sent.
NativePty.resize now explicitly sends SIGWINCH (signal 28) after
TIOCSWINSZ, matching the legacy Python implementation.
Removed 8px padding from ClidePtyView to eliminate potential
dimension mismatch between widget size and PTY cols/rows.
Default window size increased to 1600x900.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 1m57s
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
The PTY was spawning at 80x24 defaults before TerminalView had laid
out, then the real resize caused visual artifacts (ghost lines, broken
reflow). Now spawn triggers on the first onResize callback when real
dimensions are known — matching the pty-spike's proven pattern.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
execve doesn't search PATH — bare names like 'tmux' or 'claude' fail
silently. Resolve via the environment's PATH in Dart before passing
to the child. This matches ptyc's old execvp behavior.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
test / unit + widget + golden + a11y (push) Failing after 28s
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.4.4+ restores the 'decisions read' subcommand which returns
metadata + body + refs in one call. Reverts the temporary 'show
--with-refs' workaround.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
Remove debug print statements. Pass --with-refs to pql decisions show
so cross-references render in the detail view.
The decision body text is not available from pql — it indexes metadata
only. The body section of the D-record lives in the markdown file.
Rendering it requires either a pql --with-context flag or direct file
read + section extraction.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
The pql CLI command is 'decisions show', not 'decisions read'.
The client was sending the wrong subcommand.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
The context panel was hidden or collapsed when a decision or ticket
was selected. activateTab alone doesn't make the panel visible.
Now both extensions explicitly setVisible + setCollapsed before
activating the detail tab.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
The IsolateClient and KernelServices now share the same DaemonBus.
Previously, backend events (pane.output, git.changed) went to a
separate bus that widgets couldn't see.
ClaudePane._spawnWhenReady waits for ProjectOpened before sending
pane.spawn, preventing "No project active" errors.
Recents loaded before runApp so the welcome screen shows them.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
macOS cmsghdr uses socklen_t (4 bytes) for cmsg_len, not size_t
(8 bytes like Linux). The Dart FFI struct was reading at wrong offsets
causing SCM_RIGHTS fd transfer to fail. Added CmsghdrDarwin with
Uint32 cmsg_len alongside the existing Linux layout.
SOL_SOCKET is 0xffff on macOS (was hardcoded to 1 for Linux).
Now platform-detected.
Switched from ad-hoc to Apple Development signing with team ID.
Removed app sandbox from entitlements — proper signing makes it
unnecessary. All SBPL hacks eliminated.
PtySession.spawn() runs recvFd in a child isolate to avoid blocking
the backend isolate's event loop.
Terminal testmode test now passes: pane.spawn via backend isolate
successfully forks and execs the shell.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 28s
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
PtySession.spawn() now runs recvFd in a child isolate via
Isolate.spawn so the blocking FFI call doesn't stall the backend
isolate's event loop.
Terminal testmode test spawns a real backend isolate, opens a project,
and sends pane.spawn via IPC — the exact same path the full app uses.
Currently fails: ptyc successfully starts but its fork+execvp is
blocked by the macOS sandbox ("Operation not permitted"). The SBPL
allows /bin/zsh exec from the app process, but ptyc's child process
may not inherit the exec permission, or the PTYC_SOCK_FD is not
inherited by the ptyc child (Dart Process.start fd inheritance on
macOS).
IsolateClient.events getter exposed for test access.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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
PtySession.spawn() uses synchronous FFI calls (socketpair, recvFd via
SCM_RIGHTS) that block the merged UI/platform thread on macOS. The
test correctly identifies this — PTY must move to the backend isolate.
Three tests added (echo, shell, write-to-child) that will run on
Linux where threads are separate. macOS skips with a diagnostic.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sends a valid JSON request to ptyc via stdin, verifies it parses the
request (exit 2 = syscall failed, not exit 1 = bad request). Full PTY
setup needs socketpair/SCM_RIGHTS which only PtySession provides.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 30s
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
Dropdown width 380 → 480 to prevent RenderFlex overflow on recent
project rows. "Close Workspace" → "Close Project". Keyboard shortcuts
show ⌘ on macOS instead of Ctrl.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Backend isolate now boots in two phases: resolve toolchain on spawn
(binary availability only), initialize services on project.open. The
dispatcher stays empty until a project activates — IPC requests before
that return "No project active".
Scheduler ticker only runs while a project is open. Fires an immediate
first cycle on ProjectOpened so sidebar panels refresh without waiting
for the next interval. Stops on ProjectClosed.
Renamed workspace → project throughout backend messages
(project.validate, project.open, project.ready), callbacks
(onProjectOpen, onValidateProject), and methods
(openProject, validateProject, resolveProject).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The merged UI/platform thread on macOS (Flutter 3.41) freezes on any
synchronous work — file I/O, Process.run, even isolate spawning during
early frames. No timing workaround (Timer, addPostFrameCallback,
Future.delayed) was reliable.
Fix: spawn a backend isolate that owns the DaemonDispatcher, GitClient,
PqlClient, FilesService, EditorRegistry, and Toolchain resolution. The
main isolate stays free for rendering. Communication uses SendPort with
the existing IPC message protocol (IpcRequest/IpcResponse/IpcEvent) —
zero new serialization.
New files:
backend.dart — spawns isolate, manages SendPort/ReceivePort
backend_entry.dart — isolate entry point, boots all services
isolate_client.dart — replaces InProcessClient for production
Toolchain now exposes resolveToolchainPaths() as a top-level function
with self-contained PATH expansion (no module-level state that would
prevent isolate message passing).
ClideTestApp gains boot-sequence tests: compute(), Isolate.run(),
sequential Process.run, and the full resolve+exec chain.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
test / unit + widget + golden + a11y (push) Failing after 29s
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
The project switcher dropdown's "Open Local Project" action now uses
the native directory picker (same as the welcome screen). Shows "No
git repo found" dialog when the selected directory is not a git
repository.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
DebugProfile.entitlements gitignored (machine-specific sandbox paths).
native/dugite/ gitignored (downloaded at build time).
Linux runner: add pickDirectory handler using GtkFileChooserDialog
in the existing clide/window method channel.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
Standalone test harness activated via CLIDE_TESTMODE=true dart-define.
Runs a table of existence checks and exec tests against all external
binaries (git, pql, tmux, ptyc, zsh), including zsh-passthrough and
env variants. Results printed to stdout and shown in a minimal UI.
Auto-exits after 15 seconds.
make run-testmode launches it with a 60-second kill timer and pipes
output to /tmp/clide-testmode.log.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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>
OS-detecting Makefile (make run works on macOS/Linux/Windows), 1280x720
default window in MainMenu.xib, squared app icons, sandbox with scoped
SBPL exceptions for subprocess execution, _DARWIN_C_SOURCE for ptyc
compilation, expanded PATH merging Homebrew and ~/.local/bin for GUI
apps, native traffic dots skipped on macOS (titlebar owns them).
DebugProfile.entitlements is gitignored (machine-specific SBPL paths);
a template with __HOMEDIR__/__PROJECTS__/__SHELL__ placeholders is
committed.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Documentation:
- Rewrite README.md with current features and git operations
- Rewrite docs/ARCHITECTURE.md with layered architecture details
- Rewrite docs/tui-ide-spec.md with Alt-key shortcuts
- Add docs/code-organization.md for component architecture
- Add docs/user-manual.md for end users
- Update TODO.md to mark completed items
Code fixes:
- Fix undefined 'event' variable in diff_pane.py (was _event)
- Use ternary operator in editor.py save_file method
- Clean up imports in claude_events.py and syntax_service.py
- Auto-fix import sorting across multiple files
Config:
- Add snapshot report path to pyproject.toml pytest options
- Exclude clide/vendor from ruff linting
- Ignore TCH002/TCH003 type-checking import rules
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Release version 1.0.0 with comprehensive changelog documenting
all features added since initial development including skill
installer, TileList component, file watcher, and theme system.
Co-Authored-By: Claude <noreply@anthropic.com>
Update test fixtures and snapshots to reflect TileList component
and panel widget refactoring. Adjust integration tests for new
file browser behavior.
Co-Authored-By: Claude <noreply@anthropic.com>
Add reusable TileListView component for consistent card-style lists.
Refactor sidebar and context panels to use improved git integration,
enhanced branch status display, and better component organization.
Key changes:
- New TileListView/TileItem for reusable styled lists
- Enhanced git controller with graph traversal
- Improved branch status with remote tracking info
- Better file watcher integration
Co-Authored-By: Claude <noreply@anthropic.com>
Add SkillInstaller service to install bundled skill templates
(commit, branch, push, pull, stash) to user or project scope.
Includes template management and installation status checking.
Co-Authored-By: Claude <noreply@anthropic.com>
- Parse TODO.md markdown checkboxes and display in collapsible section
- Add ProjectTodoItem model for TODO.md items with section/subsection support
- Swap context panel tab order to: Jira, TODOs, Problems
- Add "Create TODO.md" button when file doesn't exist with template
- Click project TODO items to navigate to TODO.md at that line
- Add header to TODO.md explaining Clide integration format
- Add pre-commit config with ruff linting and formatting
- Update ruff ignore rules for Textual patterns
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Implement file system watching with watchdog for real-time file panel updates
- Add FileEventMessage for event-driven file change handling
- Integrate Claude events parsing for IDE awareness of Claude actions
- Add extension hooks for file changes (clide_on_file_changed, clide_on_file_saved)
- Enhance editor pane with syntax highlighting service
- Improve workspace panel with action bar and file operations
- Update Claude panel with PTY terminal integration
- Add TODO.md to track long-term project items
- Update keybindings to use Alt-based shortcuts
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Expand the README to better communicate Clide's value proposition,
including layout diagram, feature breakdown, tech stack, getting
started instructions, and keybindings reference.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move src/clide/ to clide/ (flatten directory structure)
- Add SettingsService for persistent user preferences
- Settings stored in ~/.clide/settings.json
- Persist theme, panel visibility, and compact mode state
- Fix terminal rendering glitch with throttled refresh (~60fps)
- Update pyproject.toml, Makefile, and tests for new structure
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Wireframes created in Penpot showing the main UI layouts:
- Main Layout: 3-panel view with sidebar, workspace+Claude, context panel
- Compact Mode: Claude-focused view taking full center area
- Git Changes: Git panel with staged/unstaged files and diff viewer
- Keybindings: Keyboard shortcuts reference modal
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>