Commit Graph
69 Commits
Author SHA1 Message Date
jpmschweitzer b0cc60735c chore(plan): split Tier-5 interactive panes (T-322/T-323) into epic T-506 2026-06-30 00:18:11 +02:00
jpmschweitzer cb8840aff3 feat(llm): Add Vibe CLI integration initiative (T-497, D-105)
- Add D-105: Support Vibe CLI as opt-in alternative to Claude Code CLI
- Add T-497 initiative with 6 children:
  - T-498: Adapt StreamJsonProcess + session management
  - T-500: Update config system for per-repo LLM selection
  - T-501: LLMDriver abstraction + per-repo config schema
  - T-502: Verify Vibe CLI permission + tool behavior
  - T-503: Hybrid LLM test suite + regression checks
  - T-504: pql improvements for hybrid agent workflow

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-28 22:18:53 +02:00
jpmschweitzerandClaude Opus 4.8 14bbd1fd2d feat(draw): clide draw command — drive a drawing card from the CLI (T-318)
Mirrors image.show: a Flutter-free `draw` handler reads + JSON-parses the
document (injected reader), lowers it to SVG via the template registry,
and publishes {svg, label, description} on the `draw` MessageBus channel
for the Claude extension to inject. Honest errors — notFound (missing
file), userError (bad JSON / unknown template / no --file), toolError (no
live UI). Covered by dart test (7 cases). The extension subscription that
injects the card remains to wire.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 22:18:53 +02:00
jpmschweitzerandClaude Opus 4.8 87634898c0 docs(design): finalize SVG subset + inline-normalize CSS for T-320
Pin the bounded SVG subset from a real d2 sample + our templates (markers
for arrowheads in; mask deferred to v1-ignore; foreignObject/filters/
gradients out, so mermaid isn't a launch target). Class styling resolves
via an inline-normalize preprocess (flatten <style> classes to inline
attrs) so the painter stays a pure attribute renderer. Tool-PATH for the
d2 binary now resolves via D-104.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 22:18:53 +02:00
jpmschweitzerandClaude Opus 4.8 ed22160bbb chore(plan): persist T-495 id mapping
The pre-commit changelog export left ticket_idmap unstaged; commit it so
the T-495 label↔record_id mapping survives a rebuild.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 22:18:53 +02:00
jpmschweitzerandClaude Opus 4.8 d036e6b9b0 chore(plan): persist drawing-card epic re-sequencing (D-103)
The pre-commit changelog export didn't re-stage the dependency edits from
this turn (blocker flip T-320↔T-318, template blockers, T-494). Stage
them explicitly so the re-sequencing persists.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 22:18:53 +02:00
jpmschweitzerandClaude Opus 4.8 b9fc720f97 feat(git): GitClient.init for the new-project flow (T-487)
clide treats a git repo as the workspace, so creating a new project starts with
`git init`. Add GitClient.init — `git init -b <main>` in workDir, deterministic
default branch, idempotent on an existing repo. The first primitive of the
new-project flow (T-486); the create-dir + scaffold service and the
`clide project new` verb build on it next.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 08:19:10 +02:00
jpmschweitzerandClaude Opus 4.8 222d4ae5e3 feat(claude): per-repo account badge in the Claude pane chrome (T-481)
The always-visible affordance for the multi-account epic: a compact badge in
the pane header showing which account this workspace is bound to (or "default"),
colour-tinted per account so two windows are distinguishable at a glance. Tapping
opens a picker of the registered accounts + Default; selecting binds/unbinds via
the shared bindWorkspaceAccount helper (respawn + lock-sync follow on the bus).
Hidden when no accounts are registered, so it adds no chrome for users not using
the feature.

accountAccent derives the tint by hashing the name into a fixed set of theme
tokens — never an arbitrary colour, so the palette stays theme-owned.

The welcome-view accounts section (the other half of T-481) is split to T-486:
the welcome builtin is intentionally decoupled from feature builtins, so it needs
a welcome-section contribution point rather than importing claude directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-28 00:43:40 +02:00
jpmschweitzerandClaude Opus 4.8 a72906d25d chore(plan): reconcile T-477/T-478 label collision from the merge
The merged T-476 breakdown reused T-477/T-478 (already held by the
window-size fix + Summer Night theme). Relabel the two per-repo-account
children to T-483/T-484 (identities/record_ids unchanged), preserving the
labels already referenced in CHANGELOG and pushed commits.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-27 07:45:10 +02:00
jpmschweitzerandClaude Opus 4.8 026156261c Merge origin/main: T-476 per-repo-account breakdown
Union-resolved the .pql/changelog logs (append-only, idempotent INSERT … ON
CONFLICT DO UPDATE — latest-updated wins on replay), keeping both sides:
this session's T-158 changes and origin's T-476 6-child breakdown. pql.db
rebuilt clean (2785 statements).

NOTE — label collision to reconcile (record_ids intact, labels only):
the breakdown reused T-477 and T-478, already held by the window-size bug
and the Summer Night theme. Reconcile with `pql ticket relabel`.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 11:36:03 +02:00
Jeroen SchweitzerandClaude Opus 4.7 3f627c5b17 chore(plan): break T-476 down into 6 children under an epic
Convert T-476 from story to epic and file the implementation slices:
T-477 storage/registry/migration, T-478 spawn-time CLAUDE_CONFIG_DIR
injection, T-479 multi-dir /ide lock writer, T-480 clide CLI verbs
(D-6 parity), T-481 pane badge + welcome accounts UI, T-482 settings
rows. Blocker graph wired (T-356 -> T-477 -> fan-out -> T-480 -> UI).
Epic body refined with the proven mechanism, surveyed alternatives,
concrete code touchpoints, and acceptance.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-26 09:50:57 +02:00
jpmschweitzerandClaude Opus 4.8 367792490d chore(plan): refine T-158 (team-sidebar usage budget) implementation plan
Grounded against the current tree: T-415 already ships the account budget
(parseUsageText/ClaudeUsage + Activity tab). Key finding — usage is
per-ACCOUNT (one shared ~/.claude login across all sessions), so a literal
per-member split would repeat identical numbers and isn't meaningful even
under T-476 (per-repo, not per-session, login). Refinement recommends a
single shared-account section in the team tab (resolves Q-34), lists the
exact files to touch, alternatives, and acceptance. No code yet.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-26 08:59:50 +02:00
jpmschweitzerandClaude Opus 4.8 198c8b18b5 feat(i18n): i18n key fields on command + settings contributions (T-462)
Lets manifest labels (command-palette/menu titles, settings labels) localize,
not just displayed widget strings. Adds optional titleKey/i18nNamespace to
CommandContribution and labelKey/helpKey/titleKey + a category i18nNamespace to
the settings schema. The command palette and menu bar now resolve titles via a
shared localizedCommandTitle helper — and the palette's fuzzy search matches
the localized title too (PaletteController.titleResolver). No behaviour change
until the per-extension keys + catalog entries land (placeholder == English).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-19 09:44:35 +02:00
jpmschweitzerandClaude Opus 4.8 6b5317342b chore(plan): file T-472/T-473/T-474 (ClideSettings migration follow-ups)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 21:00:28 +02:00
jpmschweitzerandClaude Opus 4.8 a7ea38acde refactor(settings): ClideSettings — one live-preferences facade (D-101)
Introduce ClideSettings, a single widget-facing facade for the app's live
user preferences, namespaced by concern: ClideSettings.fonts.monoOf(context)
/ .fonts.uiOf(context), ClideSettings.theme.of(context),
ClideSettings.i18n.of(context). "Plumb once, use many."

Fonts are carried by a new root-provided ClideSettingsScope (resolved from the
font settings in root_shell, rebuilt on change); theme and i18n delegate to
their existing live providers (ClideTheme / the I18n service) so there's one
source of truth and their many consumers migrate incrementally rather than in
a big-bang. Reads outside a scope fall back to the bundled font defaults, so a
widget renders without a provider (isolated tests).

Migrate ~93 monospace-font call sites across 33 files from the clideMonoFamily
const to ClideSettings.fonts.monoOf(context) — pure refactor, identical family
when no override is set. 11 context-less helper sites (markdown static spans,
a few top-level/static builders) keep the const for now and are tracked in
T-472. Records D-101; updates the ui-design skill's font-family rule.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:57:16 +02:00
jpmschweitzerandClaude Opus 4.8 8ad5c9ba6e chore(plan): file T-471 (monospace font picker follow-up)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:16:38 +02:00
jpmschweitzerandClaude Opus 4.8 b1057b41c8 chore(plan): file T-470 (Claude apply-to-current prompt follow-up)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 20:00:46 +02:00
jpmschweitzerandClaude Opus 4.8 4bbb0ee4b3 feat(settings): schema-driven settings engine (T-448)
The core of the settings panel (epic T-444). Subsystems describe a category
as data — a SettingsCategory of carded SettingsSections of SettingsFields
(toggle / select / text / number / opens-external-file), each bound to a
SettingsStore key with help text, a default, and reset-to-default.

Registration is declarative: a new SettingsCategoryContribution carries the
category; the extension manager routes it into a new kernel SettingsRegistry
(exposed on KernelServices), which the panel reads via ClideKernel. Adding a
category is now pure data + a contribution — no widget code.

SettingsCategoryView renders a category into carded sections per ui-design
surface.md: panelHeader card fill, dividerColor border, inputs receding to
panelBackground; select reuses the anchored-overlay menu, text/number commit
on Enter or blur (numeric clamps to bounds). The modal panel now shows the
selected/first registered category, falling back to the empty state.

Tests: registry (sort / dedup / notify), contribution routing on activation,
renderer (render + toggle/select write-through + reset), modal-with-category.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 12:07:51 +02:00
jpmschweitzerandClaude Opus 4.8 50d10c792a chore(plan): file T-461 (red error border on API-error cards)
Flag API-error conversation cards with a red statusError border (the card
already has an error status + bordered variant; just needs wiring). UI
tracker T-276.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 09:42:54 +02:00
jpmschweitzerandClaude Opus 4.8 f5fab2f4c2 chore(plan): file T-460 (Appearance font pickers + bundle Inter)
UI + monospace font pickers in the Appearance settings tab; bundle Inter
(SIL OFL) as the default UI font. Child of the settings-UI epic T-444,
renders alongside the theme picker (T-452).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 09:40:32 +02:00
jpmschweitzerandClaude Opus 4.8 f6a3c527f4 chore(plan): file T-458 EOL/EOF fidelity, T-459 split-collapse bug
Both filed under the T-276 UI epic.

T-458: the editor records neither the original EOL style nor the
trailing-newline state when it reads a file (registry.dart), and only
normalizes on save when .editorconfig asks. Any layer that rewrites
newlines therefore produces cross-platform commit churn with no
.gitattributes backstop. Ticket captures the record-on-read /
preserve-on-save / gitattributes plan.

T-459: closing the last editor panel in the main column's top split
does not collapse it. Suspect the asymmetric top/bottom split logic in
slot_host.dart and closeEditor() not moving the active tab off
editor.active. Root cause not yet confirmed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 16:20:05 +02:00
jpmschweitzerandClaude Opus 4.8 804bba1680 docs(design): settings-UI wireframes + settings-ui implementation epic (T-302, T-444)
Close T-302 with the Frame0 wireframes for the schema-driven settings UI, and
open the implementation epic T-444 under the Tier-6 epic T-8.

Wireframes (docs/design/wireframes/settings/, JSON source + PNG):
- settings-screen — modal shell + Editor category (all field-type patterns,
  scope tags, carded sections)
- settings-search — cross-category search-active state
- settings-claude — mirrors the sidebar Claude Config panel (settings controls
  + carded config lists)
- settings-appearance — theme-picker swatch grid (live bundled-theme previews)

Design answers: full-screen MODAL overlay; rail + cross-category search IA;
per-field scope-tag model (folder/globe/circle-dashed); carded sections; the
schema-driven renderer makes per-category tabs data, not new design.

Also documents the sectioned-card preference in the ui-design skill
(references/surface.md → "Settings & grouped lists — sectioned cards").

Epic T-444 children: infra (modal shell T-445, rail T-447, field renderer
T-448, scope-tag control T-449, search T-450) + per-category (Editor=T-290
reparented, Keymap T-451, Appearance/theme-picker T-452, Activity T-453,
Terminal T-455, Extensions T-456, Claude T-457).

Also files: T-441/T-442 (UI bugs), T-446 (slash-typeahead intermittent),
T-454 (Claude remote-control not plumbed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 15:41:55 +02:00
jpmschweitzerandClaude Opus 4.8 b5146cc9ad chore(plan): relabel local T-440 -> T-443 (duplicate across clones)
The push race created two T-440s: the remote tree-sitter.dll task and our
local Playwright-e2e follow-up. Kept the already-shared remote one as T-440;
renumbered our local one to T-443 via pql ticket relabel (record_id stable).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 12:18:39 +02:00
jpmschweitzer 7fa9c168b9 Merge remote-tracking branch 'origin/main'
# Conflicts:
#	.pql/changelog/ticket_idmap/2026-06.sql
#	.pql/changelog/tickets/2026-06.sql
2026-06-16 12:17:15 +02:00
jpmschweitzerandClaude Opus 4.8 e54d5263e0 feat(vim): ex command-line overlay (:w :q :wq :x :e :N, ZZ) (T-407)
Under the Vim preset, `:` opens a transient one-line ex overlay running a
fixed v1 table; ZZ runs :wq directly. Completes the last built child of the
T-403 cross-pane vim layer (T-405 part 2 gt/gT still open).

- ExLineController + parseExCommand grammar + editor-targeted executors
  (lib/kernel/src/ex_line.dart); the overlay (lib/widgets/src/ex_line_overlay
  .dart) reuses the quick-open chrome, mounts in the root_shell Stack, and
  publishes the exline.open scope flag. Unknown commands flash + stay open;
  with no active buffer every command no-ops (2026-06-13 decision).
- :q closes the active tab via editor.close on its id — the registry promotes
  the next buffer and the split self-collapses on the last (2026-06-12
  decision); :w/:wq/:x/ZZ save (+close) the active buffer.
- :e <path> seeds quick-open (new QuickOpenController.open(seed:)); :N adds the
  editor.goto-line IPC/CLI verb (reuses _offsetForLine). Goto needs caret sync:
  EditorController now handles editor.selection-changed and the editor view
  moves the caret on a selection-only change.
- `:` and ZZ are typed intents; the editor matcher and PaneKeyNav now bubble
  unhandled typed intents to the app-root Actions, so they fire from any focus.
  vim.yaml binds `:`, ZZ (shift+z shift+z), and Esc-dismiss.

Tests: parser/controller/executors, editor.goto-line daemon tests,
selection-changed (controller + view), full overlay widget test. make test
green; analyze + format clean.

Also files T-441 (drop bold from the ticket-id card label) and T-442
(sub-agent renders as 3 cards instead of one bundle) under the T-276 UI epic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-16 11:44:48 +02:00
dehlakandClaude dfcfeed8b1 file T-440: build + vendor tree-sitter.dll for Windows
Split the Windows-DLL slice out of T-25 (cross-OS libtree-sitter
build). The FFI loader already resolves tree-sitter.dll on Windows,
but no Windows binary is vendored — only the Linux .so — so
tree-sitter highlighting silently falls back to plain text on
Windows. T-440 is the narrow task to build and vendor that DLL now;
CI reproducibility and the macOS .dylib stay on the T-25 umbrella.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-15 19:03:33 +02:00
jpmschweitzerandClaude Opus 4.8 ffcf17a136 chore(plan): close T-438 (web fence done); file T-440 (Playwright e2e follow-up)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 17:57:49 +02:00
jpmschweitzerandClaude Opus 4.8 ca08c2a17d feat(web): fence dart:ffi behind web stubs so the WASM build compiles (T-438, D-100)
`flutter build web --wasm` had been broken since the tree-sitter/PTY dart:ffi
pivot. Per D-100 (resolving Q-50: keep the web "happy accident" alive), every
native binding now sits behind a `dart.library.ffi` conditional import with a
graceful web stub. Desktop builds are unchanged — no fidelity loss; the web
target degrades (no terminal, native git, or syntax highlighting).

Discriminator is `dart.library.ffi`, not `dart.library.io` — dart2wasm provides
dart:io, so FFI is the only blocker.

Fences:
- PTY: pty_session → pty_backend_io / pty_backend_web (stub throws).
- tree-sitter: pure types → syntax_result.dart; tree_sitter_service is now a
  facade over _ffi/_stub; tree_sitter_boot_io/stub fences TreeSitterLib.init().
- watchdog: watchdog_windows_stub (all -1 sampler).
- claude ABI probe: native_abi_io/stub (was `dart:ffi show Abi`).
- testmode fd-check: fd_check_io/stub.

Also dart2js-safe: the 64-bit FNV literals in session_naming.dart + paths.dart
(the dual JS fallback rejected them) — split into 32-bit halves, dropped a
no-op 64-bit mask. Desktop/wasm hash values unchanged.

CI: added a `web-wasm` job (flutter build web --wasm) so the fence can't rot.
Two FFI-constructing tree-sitter tests import _ffi.dart directly (the analyzer
resolves the conditional facade to the stub branch).

Verified: `flutter build web --wasm` → built; `flutter analyze` clean;
`make test` green. Full Playwright e2e harness wiring is the tracked follow-on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 17:31:24 +02:00
jpmschweitzerandClaude Opus 4.8 4bba2ef2f0 D-100 (fence dart:ffi) + amend D-32 (GitHub Actions); close T-384
- D-32 amended: Gitea-primary/not-activated → GitHub Actions, active
  (Linux test + Windows ConPTY/soak + release; web-WASM e2e withheld).
  The staged Gitea pipeline was never activated and is gone.
- Q-50 resolved → D-100: FENCE the web/WASM target. Every dart:ffi
  importer goes behind a conditional-import facade with a web stub so
  `flutter build web --wasm` compiles; desktop fidelity untouched. Keeps
  the web "happy accident" alive as a hopeful future target per user.
- T-438 filed for the fence implementation (12 ffi importers + CI wasm
  compile gate + re-enable e2e/ui targets).
- T-384 closed (done): Gitea premise OBE, scripts repointed (2026-06-12),
  D-32 reconciled; the dead e2e targets delegated to T-438.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 16:29:11 +02:00
jpmschweitzerandClaude Opus 4.8 8f962226a0 file T-437: /clear kills the Claude session (exit 1) on CLI 2.1.177
Regression of T-268's /clear mechanism. /clear deletes the transcript and
respawns with the same deterministic --session-id, but claude 2.1.177 now
tracks session ids in ~/.claude/sessions/<pid>.json (+history.jsonl) beyond
the per-project transcript clide purges, so the id reads as in-use and
claude exits 1 at startup validation. Codebase only probed <=2.1.175.

Hypothesis is strong but unconfirmed: the pane shows an opaque "code 1" and
swallows claude's stderr — capturing it is fix step 1. Filed high with
ranked fixes (mint fresh id on clear; or clean the registry; surface stderr).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 13:23:09 +02:00
jpmschweitzerandClaude Opus 4.8 b7d6d6f6f2 chore(plan): mark T-434 (PTY FFI breadcrumbs) done
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-15 09:57:12 +02:00
jpmschweitzerandClaude Opus 4.8 154c2c8e43 file T-424 (ConPTY Job-Object reaping) + T-425 logging epic
Follow-ups from the Windows test-freeze analysis:
- T-424 (bug, high): place each WindowsPty child in a kill-on-close Windows
  Job Object so the child AND its conhost.exe are reaped on session/test-
  process exit (rank-1 freeze culprit). Sibling ConPTY-teardown fixes noted
  in the description.
- T-425 (epic, high): crash-survivable logging & observability, so the next
  freeze leaves on-disk evidence. Children: T-426 FileLogSink, T-427 FFI
  breadcrumbs, T-428 watchdog isolate, T-429 dev/prod verbosity toggle,
  T-430 testmode/CI wiring.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 20:16:55 +02:00
jpmschweitzerandClaude Opus 4.8 bb0d78f8de Q-51 + T-422 epic: unify workspace lifecycle on one fenced primitive
The status-bar branch bleed (T-421) is a symptom of a deeper gap: there
is no single "open workspace X" primitive — only project.open() (in-place,
same process, shared daemonBus) and newWindow() (blank detached process,
no repo arg, no env scrub). T-367 and T-269 are the same root.

- Q-51 (architecture): unify on WorkspaceService.open(root, target);
  open question of whether in-place switching survives at all vs a
  strict workspace⇒window⇒process⇒socket⇒bus⇒session-id 1:1 mapping.
- T-422 epic owns the unification; T-421 reparented under it; T-423
  builds the primitive and routes all entry points through it.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 17:47:33 +02:00
jpmschweitzerandClaude Opus 4.8 07b5133e99 file T-421: status-bar git branch bleeds across parallel windows
Bug: the status-bar branch sometimes shows another open window's
branch. Filed high-priority with investigation notes — contradicts the
T-269 cross-window isolation invariant. Two candidate root causes
captured (shared in-memory DaemonBus vs inherited CLIDE_SOCK).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-14 17:31:26 +02:00
jpmschweitzerandClaude Opus 4.8 5a21ea949a workspace tab cycle commands + ctrl+pagedown/up (T-405 part 1)
Add workspace.tab.next / workspace.tab.previous commands that cycle the
Slots.workspace tab strip with wraparound (no-op under two tabs), bound
ctrl+pagedown / ctrl+pageup across every preset via defaultBindings. Single-
chord, so no global matcher needed. Activating a tab also focuses the
workspace slot.

Part 2 (vim gt/gT) is deferred — it needs the global multi-chord matcher
T-404 introduces. T-405 stays open for that follow-up.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-13 18:06:36 +02:00
jpmschweitzerandClaude Opus 4.8 68acb89e83 refine T-403 vim cross-pane tickets + file workflow-card polish (T-419)
Ran a two-agent parallel workflow to refine the four T-403 children against
the actual code, appending a sharpened scope / acceptance-criteria / files /
dependencies / open-questions block to each:
- T-404 (ctrl+w window family), T-405 (tab cycle + gt/gT),
  T-406 (normal-mode list/scroll nav), T-407 (ex `:` overlay).

Both agents independently surfaced the shared structural blocker — no global
multi-chord SequenceMatcher exists today (the global key path is single-chord;
only the editor has a matcher) — and a recommended sequencing, now recorded as
a coordination note on the parent T-403 (build the matcher once; T-406 first).

Also files T-419 under the UI tracker (T-276): keep the workflow run card's
agent rows + usage visible while collapsed.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-12 22:07:13 +02:00
jpmschweitzerandClaude Fable 5 1674d3021a tint the Claude sidebar tab icon with the Claude accent (T-418)
TabContribution gains an optional iconColor honoured by the icon rail:
full-strength when active/hovered, dimmed (70%) when idle, so the tint
reads as identity without outshouting the active-state border. The
Claude Activity tab sets claudeAccent (#D97757) — nominative use per the
licenses.yaml trademark note (it marks Claude's own panel).

Filed and closed as a try-it-out (user request); trivially revertible if
the accent doesn't land visually.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 13:30:22 +02:00
jpmschweitzerandClaude 7c4ac182f6 file status-bar styling cohesion bug (T-417)
Ticket-only commit so the pql changelog write-through persists. T-417
captures the font/size/token/vertical-alignment drift across the five
bottom status bar items, filed under the UI tracker epic T-276.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-12 13:25:04 +02:00
jpmschweitzerandClaude Fable 5 02c6dd4cf0 route slash commands: TUI-only builtins become local notices (T-411)
clide forwards composer input to a headless (stream-json) CLI, where the
TUI's interactive commands don't exist. A known-but-TUI-only command
errored raw ("/x isn't available in this environment", rendered as fake
claude prose); an un-advertised one (e.g. /effort on 2.1.175) was worse —
bracket-pasted to the model as literal text, burning a real turn.

Probed claude 2.1.175 for ground truth: the initialize handshake's
slash_commands advertises skills + the headless builtins only; forwarded
local-command output comes back as an assistant message with model
"<synthetic>"; set_effort is not a control subtype; /usage works headless.

- slash_commands.dart: SlashRoute routing table (owned > advertised >
  TUI-only catalog > forward) + kTuiOnlyCommands with clide-native hints
  + tuiOnlyNotice(). One source of truth replacing ad-hoc checks.
- claude_pane._send routes 'unavailable' to a local notice card; nothing
  reaches the session.
- transcript_reader: AssistantTextMessage.synthetic ("<synthetic>" model)
  so CLI-local output is distinguishable; "<synthetic>" no longer
  clobbers the tracked model in SessionStatus (latent /usage bug).
- conversation_view: synthetic output renders as a muted framed "clide"
  card (T-306 styling), never coral Claude prose.
- kFallbackSlashCommands trimmed to the genuinely-headless builtin set —
  it doubles as the router's advertised fallback, and the old list's
  TUI-only entries would have routed to a raw CLI error.

Board (rides this commit): T-414 gains the user's sidebar styling-pass
note; T-416 filed — surface Claude Code Workflow runs in convo/status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 12:25:19 +02:00
jpmschweitzerandClaude Fable 5 91c5501cf3 file the Claude power-control-panel epic (T-410 + five stories)
Design: capture every TUI-only harness slash command properly instead of
leaking the CLI's raw "isn't available in this environment" error, and
grow the Claude sidebar into an interactive control panel.

Grounded in the version-keyed initialize probes (~/.config/clide/claude):
the advertised slash_commands list is the authoritative "forwards safely"
set; TUI-only builtins are absent from it. Three layers: a declarative
routing table (forward/owned/unavailable) replacing kClideOwnedCommands,
a reactive catch-all that renders unknown TUI-command errors as hint
cards, and D-6 parity controls in the sidebar Config/Activity tabs
(model/effort/permission pickers, session controls, usage block).

T-411 routing+capture, T-412 /effort spike, T-413 open-in-clide family,
T-414 Config-tab controls, T-415 Activity controls + usage (revisits
T-158).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 10:59:42 +02:00
jpmschweitzerandClaude Fable 5 f378be4084 persist the ticket dep-graph export
The pre-commit hook staged the ticket/history tables but left the
deps + idmap exports (the T-398..T-402 and T-403..T-407 blocker
links) unstaged on the previous commit; sweep them in.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 05:23:47 +02:00
jpmschweitzerandClaude Opus 4.8 898a0316e5 claude: Bash live-tail detection + read-only file follower (T-325, core)
The detection/follow core for the live-tail sub-card, with the UI wiring
to follow. Claude Code runs every Bash tool itself and clide only sees the
final tool_result block — we can't mirror the running process, so instead
we detect a file-backed source the command follows and open our own
read-only follower on the same file.

- bash_tail_source.dart: detectBashTailSource() parses a Bash command for a
  single, safe, file-backed source (tail/cat/less with one file arg, inside
  the workspace via resolveUnderRoot). Returns null for a pipe-into-tail, a
  redirect, two files, or a path outside the repo — the caller then shows a
  "nothing to follow" note. bashHasTailIntent() gates WHEN the segment
  appears: v1 triggers on `tail`/follow-flags only, so ordinary cat/ls/git
  cards stay clean (cat/less remain detectable for later).
- file_tail_follower.dart: a polling, read-only `tail -f`-style follower
  (no subprocess, no touching Claude's command) that emits the trailing
  window then appended deltas, and re-reads from the top on truncation.

Tested: 19 parser cases (incl. the `git push | tail -25` and outside-
workspace null cases), the intent predicate, and the follower (initial
window / appended delta / missing file / rotation / start / stop).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 17:12:53 +02:00
jpmschweitzerandClaude Opus 4.8 1238802f54 deps: CVE audit + refresh safe pins, document held ones (T-353)
Reviewed every direct and transitive dependency against the GitHub
Advisory Database / OSV (Pub ecosystem). No advisory affects any
dependency at its current pin or upgrade target — the "N packages have
newer versions" noise is freshness, not security. (Consistent with
`dart pub get` printing no advisory warnings.)

Bumped the safe pins + their licenses.yaml entries in the same commit:
- ffi 2.1.3 -> 2.2.0
- jovial_svg 1.1.26 -> 1.1.30 (pulls jovial_misc 0.10.0 + xml 7.0.1)
- mocktail 1.0.4 -> 1.0.5

Held, with the reason recorded inline in pubspec.yaml:
- markdown 7.2.2: 7.3.1 requires Dart ^3.9.0 — defer to an SDK-floor bump
- alchemist 0.12.1: 0.13.0 disabled text anti-aliasing -> golden churn
- test 1.31.0: flutter_test SDK-locks the resolvable ceiling

make test green (incl. SVG/xml goldens — the xml 6->7 major didn't churn
rendering).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-11 08:58:54 +02:00
jpmschweitzerandClaude Opus 4.8 a0501b4a0a pql: refetch ticket + decision sidebars when the workspace opens (T-352)
On a desktop launch the daemon's PqlClient boots with workDir set to the
launch CWD (e.g. HOME), not the repo — swapIpcServer only rewires it once
the project opens. The tickets and decisions panes fire their first pql
fetch before that swap, so pql runs in the wrong directory against a
stale/global pql.db and the pane errors (observed:
"ticket_deps.blocker_record_id missing — pql.db is from an earlier
schema"). A manual refresh worked because by then the workspace was open.

This is a wrong-workDir timing issue, not db-busy, so the T-350 retry
doesn't catch it. Both panes now re-fetch on ProjectOpened, which fires
after the IPC server swaps to the project workRoot.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 20:38:44 +02:00
jpmschweitzerandClaude Opus 4.8 16dc628fee linux: require wayland-client so frameless chrome can't be dropped (T-349)
The frameless custom chrome (D-057) is gated on HAS_WAYLAND_CLIENT, which
was only defined when CMake's non-required wayland-client check happened
to find it. A build host/container without the Wayland client dev headers
(plausible on Bazzite/immutable distros that build in a distrobox) silently
compiled the decoration-suppression out, so the rebuilt app shipped the
compositor's native title bar (double title bar on KDE Plasma Wayland).

Make wayland-client a hard requirement: fail the configure with an
actionable message (Fedora wayland-devel / Debian libwayland-dev) rather
than drop a core feature. Fix the stale "xdg-decoration" comment — the
code uses the KDE server-decoration protocol.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 19:46:25 +02:00
jpmschweitzerandClaude Opus 4.8 b7e0835b74 pre-push: skip the test suite unless lib/ or pubspec changed (T-348)
The hook ran the full ~2min push-check on every push, even one touching
only docs, changelog, pql data, tests, or assets. Diff the pushed range
(from the hook's stdin) and run the full gate only when lib/ (app/runtime
source) or pubspec.* (deps/version) changed; otherwise run just the
instant decisions + changelog gates.

Other changes ride along with a lib change in practice, the full suite
stays available via `make push-check`, and the release CI runs it forced
on a tagged version. A state we can't classify (unfetched remote sha, new
branch) falls back to the full gate.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 19:22:12 +02:00
jpmschweitzerandClaude Opus 4.8 b0f2580150 persist T-345..T-347 ticket id mappings
The ticket_idmap export was uncommitted working-tree churn that a rebase
DB-rebuild dropped, so pql could not resolve T-347 by id. Re-export the
mappings from the rebuilt DB.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 19:22:12 +02:00
jpmschweitzer 034a9d289e ticket update 2026-06-10 18:17:13 +02:00
jpmschweitzerandClaude Opus 4.8 bc7ee3b88c tickets: file T-342 — per-subagent activity cards
Investigated whether spawned subagents get their own collapsing card.
They don't: groupConversation/_isFoldable (activity_cluster.dart) treats
Task/Agent tool-uses like any non-diff tool, so consecutive spawns merge
into one "Activity / N steps" cluster. T-263/T-264/T-338 only shaped what
renders INSIDE one agent card. Filed T-342 (under T-276) for the
complement: break distinct Agent spawns out into their own labelled cards.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 17:27:35 +02:00
jpmschweitzerandClaude Opus 4.8 026e331146 clickable file references in the Claude conversation (T-300)
Workspace file paths mentioned by Claude now linkify and open in the
editor: bare (lib/app.dart), with a line (lib/app.dart:42), backticked,
or as markdown links. Only paths that exist in the repo linkify — the
resolver gates on existence so prose (version numbers, "e.g.") stays
literal. Clicking maps to the editor.open verb, jumping to the line when
a :line suffix is present (D-6 parity).

ClideMarkdown gains resolveFileRef + onOpenFile hooks; conversation_view
resolves against the open project root + existsSync and dispatches over
IPC. Detection covers running prose, whole-content code spans, and link
hrefs.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-10 15:55:53 +02:00