3 Commits
Author SHA1 Message Date
jpmschweitzerandClaude 7b30748bf5 rewire daemon services on project open
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
The daemon dispatcher (pql, git, files, editor) was built once at
boot against cwd and never updated. Opening a project from the
welcome screen or directory picker had no effect on the daemon
services — pql couldn't find its index, git operated on the wrong
repo.

Now onProjectOpen rebuilds the full dispatcher against the new
workspace root and swaps it into the InProcessClient. The IPC
client's dispatcher field is no longer final.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 22:29:03 +02:00
jpmschweitzerandClaude a5221792ba fix sidebar order and ptyc status bar warning
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
Revert priority sort in tabsFor() — registration order in
main.dart is the intended sidebar order, not priority. The
priority fields on extensions were dead code.

Remove ptyc from toolchain missing list since NativePty
replaced it.

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 22:22:23 +02:00
jpmschweitzerandClaude 79342277b8 fix desktop integration and rename Linux runner
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
StartupWMClass now matches the GTK application ID
(net.schweitz.clide) so the running window groups with the
launcher icon. Desktop file installs as
net.schweitz.clide.desktop per freedesktop convention.

Renamed my_application.{cc,h} to clide_app.{cc,h} with
matching GObject type (ClideApp / CLIDE_APP).

Co-Authored-By: Claude <noreply@anthropic.com>
2026-05-03 22:12:05 +02:00
13 changed files with 187 additions and 182 deletions
+100 -100
View File
@@ -1,5 +1,5 @@
{
"exported_at": "2026-05-03T20:06:31Z",
"exported_at": "2026-05-03T20:29:03Z",
"decisions": [
{
"id": "D-1",
@@ -9,7 +9,7 @@
"status": "active",
"date": "2026-04-20",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-3",
@@ -19,7 +19,7 @@
"status": "active",
"date": "2026-04-20",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-4",
@@ -29,7 +29,7 @@
"status": "active",
"date": "2026-04-20",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-5",
@@ -39,7 +39,7 @@
"status": "active",
"date": "2026-04-20",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-6",
@@ -49,7 +49,7 @@
"status": "active",
"date": "2026-04-20",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-7",
@@ -59,7 +59,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-8",
@@ -69,7 +69,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-9",
@@ -79,7 +79,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-10",
@@ -89,7 +89,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-11",
@@ -99,7 +99,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-12",
@@ -109,7 +109,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-13",
@@ -119,7 +119,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-14",
@@ -129,7 +129,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-15",
@@ -139,7 +139,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-16",
@@ -149,7 +149,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-17",
@@ -159,7 +159,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-18",
@@ -169,7 +169,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-19",
@@ -179,7 +179,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-20",
@@ -189,7 +189,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/accessibility.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-21",
@@ -199,7 +199,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/accessibility.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-22",
@@ -209,7 +209,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/accessibility.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-23",
@@ -219,7 +219,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-24",
@@ -229,7 +229,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-25",
@@ -239,7 +239,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-26",
@@ -249,7 +249,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-27",
@@ -259,7 +259,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-28",
@@ -269,7 +269,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-29",
@@ -279,7 +279,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-30",
@@ -289,7 +289,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-31",
@@ -299,7 +299,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/tooling.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-32",
@@ -309,7 +309,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/tooling.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-33",
@@ -319,7 +319,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/tooling.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-34",
@@ -329,7 +329,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-35",
@@ -339,7 +339,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-36",
@@ -349,7 +349,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-37",
@@ -359,7 +359,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-38",
@@ -369,7 +369,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-39",
@@ -379,7 +379,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-40",
@@ -389,7 +389,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-41",
@@ -399,7 +399,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-42",
@@ -409,7 +409,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/tooling.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-43",
@@ -419,7 +419,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-44",
@@ -429,7 +429,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-45",
@@ -439,7 +439,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-46",
@@ -449,7 +449,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-47",
@@ -459,7 +459,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-48",
@@ -469,7 +469,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-49",
@@ -479,7 +479,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-50",
@@ -489,7 +489,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-51",
@@ -499,7 +499,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-52",
@@ -509,7 +509,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-53",
@@ -519,7 +519,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-54",
@@ -529,7 +529,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-55",
@@ -539,7 +539,7 @@
"status": "active",
"date": "2026-04-23",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-56",
@@ -549,7 +549,7 @@
"status": "active",
"date": "2026-04-23",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-57",
@@ -559,7 +559,7 @@
"status": "active",
"date": "2026-04-23",
"file_path": "decisions/architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-58",
@@ -569,7 +569,7 @@
"status": "active",
"date": "2026-04-23",
"file_path": "decisions/tooling.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "D-59",
@@ -579,7 +579,7 @@
"status": "active",
"date": "2026-04-25",
"file_path": "decisions/tooling.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-1",
@@ -588,7 +588,7 @@
"title": "Authorisation granularity on the IPC socket",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-2",
@@ -597,7 +597,7 @@
"title": "Back-pressure on event streams",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-3",
@@ -606,7 +606,7 @@
"title": "Event persistence + audit/undo",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-4",
@@ -615,7 +615,7 @@
"title": "`.canvas` schema compatibility with Obsidian",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-5",
@@ -624,7 +624,7 @@
"title": "IPC wire-format stability + `schema_version:`",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-6",
@@ -633,7 +633,7 @@
"title": "Window chrome — native frame vs frameless custom",
"status": "resolved",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-7",
@@ -642,7 +642,7 @@
"title": "macOS app bundle signing / notarisation",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-8",
@@ -651,7 +651,7 @@
"title": "Extension API shape — widgets, subcommands, both?",
"status": "open",
"file_path": "decisions/questions-extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-9",
@@ -660,7 +660,7 @@
"title": "Lua runtime vendoring",
"status": "open",
"file_path": "decisions/questions-extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-10",
@@ -669,7 +669,7 @@
"title": "Extension manifest `schema_version:`",
"status": "open",
"file_path": "decisions/questions-extensions.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-11",
@@ -678,7 +678,7 @@
"title": "Coverage gates — hard thresholds vs soft reporting",
"status": "open",
"file_path": "decisions/questions-testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-12",
@@ -687,7 +687,7 @@
"title": "Screen-reader automation (axe-core via Playwright)",
"status": "open",
"file_path": "decisions/questions-testing.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-13",
@@ -696,7 +696,7 @@
"title": "Web production-mode a11y",
"status": "open",
"file_path": "decisions/questions-accessibility.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-14",
@@ -705,7 +705,7 @@
"title": "i18n plurals / gender / date-format tooling",
"status": "open",
"file_path": "decisions/questions-accessibility.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-15",
@@ -714,7 +714,7 @@
"title": "Editor tab — full LSP vs tree-sitter-only highlight",
"status": "open",
"file_path": "decisions/questions-process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-16",
@@ -723,7 +723,7 @@
"title": "`tree-sitter-dart` grammar maintenance",
"status": "open",
"file_path": "decisions/questions-process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-17",
@@ -732,7 +732,7 @@
"title": "Icon set growth",
"status": "open",
"file_path": "decisions/questions-process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-18",
@@ -741,7 +741,7 @@
"title": "Theme hot-reload in release builds",
"status": "open",
"file_path": "decisions/questions-process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-19",
@@ -750,7 +750,7 @@
"title": "(withdrawn)",
"status": "resolved",
"file_path": "decisions/questions-process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-20",
@@ -759,7 +759,7 @@
"title": "Kernel DB service — namespaced SQL access?",
"status": "open",
"file_path": "decisions/questions-process.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-21",
@@ -768,7 +768,7 @@
"title": "Pql absorbs planning vs keeps separate",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-22",
@@ -777,7 +777,7 @@
"title": "Ticket persistence strategy",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-23",
@@ -786,7 +786,7 @@
"title": "SSH-remote development — run clide against a remote workspace",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-25",
@@ -795,7 +795,7 @@
"title": "Body text face — mono everywhere vs Josefin Sans UI + mono code",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-26",
@@ -804,7 +804,7 @@
"title": "Small screen layout (\u003c 1000px)",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-27",
@@ -813,7 +813,7 @@
"title": "Two-editor split",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-28",
@@ -822,7 +822,7 @@
"title": "Terminal strip scope — shell only or logs/errors/tests",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-29",
@@ -831,7 +831,7 @@
"title": "Branch picker location",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-30",
@@ -840,7 +840,7 @@
"title": "Focus behavior when editor is dirty and viewer is peeked",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "Q-31",
@@ -849,7 +849,7 @@
"title": "XWayland fallback for frameless — proper Wayland protocol needed",
"status": "open",
"file_path": "decisions/questions-architecture.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-2",
@@ -859,7 +859,7 @@
"status": "active",
"date": "2026-04-20",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-3",
@@ -869,7 +869,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-4",
@@ -879,7 +879,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-5",
@@ -889,7 +889,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-6",
@@ -899,7 +899,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-7",
@@ -909,7 +909,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-8",
@@ -919,7 +919,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-9",
@@ -929,7 +929,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-10",
@@ -939,7 +939,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-11",
@@ -949,7 +949,7 @@
"status": "active",
"date": "2026-04-21",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
},
{
"id": "R-12",
@@ -959,7 +959,7 @@
"status": "active",
"date": "2026-04-22",
"file_path": "decisions/rejected.md",
"synced_at": "2026-05-03 19:50:09"
"synced_at": "2026-05-03 20:28:13"
}
],
"decision_refs": [
+3 -2
View File
@@ -167,11 +167,11 @@ ifeq ($(FLUTTER_OS),linux)
done
@mkdir -p $(HOME)/.local/share/applications
@sed 's|Exec=clide|Exec=$(INSTALL_PREFIX)/clide/clide|' linux/clide.desktop \
> $(HOME)/.local/share/applications/clide.desktop
> $(HOME)/.local/share/applications/net.schweitz.clide.desktop
@gtk-update-icon-cache -f -t $(HOME)/.local/share/icons/hicolor 2>/dev/null || true
@update-desktop-database $(HOME)/.local/share/applications 2>/dev/null || true
@echo "installed: $(INSTALL_DIR)/clide -> $(INSTALL_PREFIX)/clide/clide"
@echo "desktop: ~/.local/share/applications/clide.desktop"
@echo "desktop: ~/.local/share/applications/net.schweitz.clide.desktop"
@echo "version: $(VERSION)"
else ifeq ($(FLUTTER_OS),macos)
@mkdir -p $(HOME)/Applications
@@ -189,6 +189,7 @@ uninstall: ## Remove installed clide.
ifeq ($(FLUTTER_OS),linux)
rm -f $(INSTALL_DIR)/clide
rm -rf $(INSTALL_PREFIX)/clide
rm -f $(HOME)/.local/share/applications/net.schweitz.clide.desktop
rm -f $(HOME)/.local/share/applications/clide.desktop
@for size in $(ICON_SIZES); do \
rm -f $(HOME)/.local/share/icons/hicolor/$${size}x$${size}/apps/clide.png; \
+8 -4
View File
@@ -8,10 +8,14 @@ class InProcessClient extends DaemonClient {
InProcessClient({
required Logger log,
required DaemonBus events,
required this.dispatcher,
}) : super(socketPath: '', log: log, events: events);
required DaemonDispatcher dispatcher,
}) : _dispatcher = dispatcher,
super(socketPath: '', log: log, events: events);
final DaemonDispatcher dispatcher;
DaemonDispatcher _dispatcher;
DaemonDispatcher get dispatcher => _dispatcher;
set dispatcher(DaemonDispatcher d) => _dispatcher = d;
int _nextReqId = 0;
@override
@@ -27,6 +31,6 @@ class InProcessClient extends DaemonClient {
Future<IpcResponse> request(String cmd, {Map<String, Object?> args = const {}}) {
final id = '${_nextReqId++}';
final req = IpcRequest(id: id, cmd: cmd, args: args);
return dispatcher.dispatch(req);
return _dispatcher.dispatch(req);
}
}
+2 -5
View File
@@ -68,14 +68,11 @@ class PanelRegistry extends ChangeNotifier {
List<TabContribution> tabsFor(SlotId id) {
final tabs = contributionsFor(id).whereType<TabContribution>().toList();
final order = _order[id];
if (order == null || order.isEmpty) {
tabs.sort((a, b) => a.priority.compareTo(b.priority));
return tabs;
}
if (order == null || order.isEmpty) return tabs;
tabs.sort((a, b) {
final ai = order.indexOf(a.id);
final bi = order.indexOf(b.id);
if (ai < 0 && bi < 0) return a.priority.compareTo(b.priority);
if (ai < 0 && bi < 0) return 0;
if (ai < 0) return 1;
if (bi < 0) return -1;
return ai.compareTo(bi);
-1
View File
@@ -54,7 +54,6 @@ class Toolchain extends ChangeNotifier {
if (_git == null) 'git',
if (_pql == null) 'pql',
if (_tmux == null) 'tmux',
if (_ptyc == null) 'ptyc',
];
/// Returns a Future that completes when resolution finishes.
+30 -14
View File
@@ -71,6 +71,25 @@ Future<void> main() async {
toolchain.applyResolved(resolveToolchainPaths(root));
}
InProcessClient? ipcClient;
DaemonBus? daemonBus;
DaemonDispatcher _buildDispatcher(DaemonBus events, Toolchain tc, Directory workRoot) {
final dispatcher = DaemonDispatcher();
final eventSink = _BusEventSink(events);
final paneRegistry = PaneRegistry(events: eventSink);
registerPaneCommands(dispatcher, paneRegistry);
final filesService = FilesService(root: workRoot, events: eventSink);
registerFilesCommands(dispatcher, filesService);
final editorRegistry = EditorRegistry(events: eventSink, workspaceRoot: workRoot);
registerEditorCommands(dispatcher, editorRegistry);
final gitClient = GitClient(toolchain: tc, workDir: workRoot);
registerGitCommands(dispatcher, gitClient, eventSink);
final pql = PqlClient(workDir: workRoot, toolchain: tc);
registerPqlCommands(dispatcher, pql);
return dispatcher;
}
final services = await KernelServices.boot(
appDir: appDir,
bundledThemes: themes,
@@ -81,20 +100,17 @@ Future<void> main() async {
daemonClientFactory: kIsWeb
? null
: (log, events) {
final dispatcher = DaemonDispatcher();
final eventSink = _BusEventSink(events);
final filesService = FilesService.atCwd(events: eventSink);
final workRoot = filesService.root;
final paneRegistry = PaneRegistry(events: eventSink);
registerPaneCommands(dispatcher, paneRegistry);
registerFilesCommands(dispatcher, filesService);
final editorRegistry = EditorRegistry(events: eventSink, workspaceRoot: workRoot);
registerEditorCommands(dispatcher, editorRegistry);
final gitClient = GitClient(toolchain: toolchain, workDir: workRoot);
registerGitCommands(dispatcher, gitClient, eventSink);
final pql = PqlClient(workDir: workRoot, toolchain: toolchain);
registerPqlCommands(dispatcher, pql);
return InProcessClient(log: log, events: events, dispatcher: dispatcher);
daemonBus = events;
final workRoot = FilesService.atCwd(events: _BusEventSink(events)).root;
final dispatcher = _buildDispatcher(events, toolchain, workRoot);
ipcClient = InProcessClient(log: log, events: events, dispatcher: dispatcher);
return ipcClient!;
},
onProjectOpen: kIsWeb
? null
: (path) async {
if (ipcClient == null || daemonBus == null) return;
ipcClient!.dispatcher = _buildDispatcher(daemonBus!, toolchain, Directory(path));
},
);
+1 -1
View File
@@ -7,5 +7,5 @@ Icon=clide
Terminal=false
Categories=Development;IDE;TextEditor;
Keywords=code;editor;ide;claude;terminal;
StartupWMClass=clide
StartupWMClass=net.schweitz.clide
MimeType=inode/directory;
+1 -1
View File
@@ -4,7 +4,7 @@ project(runner LANGUAGES C CXX)
# Any new source files that you add to the application should be added here.
add_executable(${BINARY_NAME}
"main.cc"
"my_application.cc"
"clide_app.cc"
"protocols/server-decoration-protocol.c"
"${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
)
@@ -1,4 +1,4 @@
#include "my_application.h"
#include "clide_app.h"
#include <flutter_linux/flutter_linux.h>
#ifdef GDK_WINDOWING_X11
@@ -13,12 +13,12 @@
#include "flutter/generated_plugin_registrant.h"
struct _MyApplication {
struct _ClideApp {
GtkApplication parent_instance;
char** dart_entrypoint_arguments;
};
G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
G_DEFINE_TYPE(ClideApp, clide_app, GTK_TYPE_APPLICATION)
// D-057: KDE server-decoration protocol — request no decorations.
#ifdef HAS_WAYLAND_CLIENT
@@ -81,7 +81,6 @@ static void request_no_server_decorations(GtkWindow* window) {
struct org_kde_kwin_server_decoration* deco =
org_kde_kwin_server_decoration_manager_create(kde_deco_manager, surface);
if (deco != nullptr) {
// Mode 0 = None (no decorations at all)
org_kde_kwin_server_decoration_request_mode(deco, 0);
wl_display_roundtrip(wl_dpy);
}
@@ -100,12 +99,12 @@ static void on_window_realize(GtkWidget* widget, gpointer data) {
#endif
}
static void first_frame_cb(MyApplication* self, FlView* view) {
static void first_frame_cb(ClideApp* self, FlView* view) {
gtk_widget_show(gtk_widget_get_toplevel(GTK_WIDGET(view)));
}
static void my_application_activate(GApplication* application) {
MyApplication* self = MY_APPLICATION(application);
static void clide_app_activate(GApplication* application) {
ClideApp* self = CLIDE_APP(application);
GtkWindow* window =
GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
@@ -249,10 +248,10 @@ static void my_application_activate(GApplication* application) {
gtk_widget_grab_focus(GTK_WIDGET(view));
}
static gboolean my_application_local_command_line(GApplication* application,
gchar*** arguments,
int* exit_status) {
MyApplication* self = MY_APPLICATION(application);
static gboolean clide_app_local_command_line(GApplication* application,
gchar*** arguments,
int* exit_status) {
ClideApp* self = CLIDE_APP(application);
self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
g_autoptr(GError) error = nullptr;
@@ -267,34 +266,34 @@ static gboolean my_application_local_command_line(GApplication* application,
return TRUE;
}
static void my_application_startup(GApplication* application) {
G_APPLICATION_CLASS(my_application_parent_class)->startup(application);
static void clide_app_startup(GApplication* application) {
G_APPLICATION_CLASS(clide_app_parent_class)->startup(application);
}
static void my_application_shutdown(GApplication* application) {
G_APPLICATION_CLASS(my_application_parent_class)->shutdown(application);
static void clide_app_shutdown(GApplication* application) {
G_APPLICATION_CLASS(clide_app_parent_class)->shutdown(application);
}
static void my_application_dispose(GObject* object) {
MyApplication* self = MY_APPLICATION(object);
static void clide_app_dispose(GObject* object) {
ClideApp* self = CLIDE_APP(object);
g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
G_OBJECT_CLASS(clide_app_parent_class)->dispose(object);
}
static void my_application_class_init(MyApplicationClass* klass) {
G_APPLICATION_CLASS(klass)->activate = my_application_activate;
static void clide_app_class_init(ClideAppClass* klass) {
G_APPLICATION_CLASS(klass)->activate = clide_app_activate;
G_APPLICATION_CLASS(klass)->local_command_line =
my_application_local_command_line;
G_APPLICATION_CLASS(klass)->startup = my_application_startup;
G_APPLICATION_CLASS(klass)->shutdown = my_application_shutdown;
G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
clide_app_local_command_line;
G_APPLICATION_CLASS(klass)->startup = clide_app_startup;
G_APPLICATION_CLASS(klass)->shutdown = clide_app_shutdown;
G_OBJECT_CLASS(klass)->dispose = clide_app_dispose;
}
static void my_application_init(MyApplication* self) {}
static void clide_app_init(ClideApp* self) {}
MyApplication* my_application_new() {
ClideApp* clide_app_new() {
g_set_prgname(APPLICATION_ID);
return MY_APPLICATION(g_object_new(my_application_get_type(),
"application-id", APPLICATION_ID, "flags",
G_APPLICATION_NON_UNIQUE, nullptr));
return CLIDE_APP(g_object_new(clide_app_get_type(),
"application-id", APPLICATION_ID, "flags",
G_APPLICATION_NON_UNIQUE, nullptr));
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef CLIDE_APP_H_
#define CLIDE_APP_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(ClideApp, clide_app, CLIDE, APP, GtkApplication)
ClideApp* clide_app_new();
#endif // CLIDE_APP_H_
+2 -2
View File
@@ -1,6 +1,6 @@
#include "my_application.h"
#include "clide_app.h"
int main(int argc, char** argv) {
g_autoptr(MyApplication) app = my_application_new();
g_autoptr(ClideApp) app = clide_app_new();
return g_application_run(G_APPLICATION(app), argc, argv);
}
-21
View File
@@ -1,21 +0,0 @@
#ifndef FLUTTER_MY_APPLICATION_H_
#define FLUTTER_MY_APPLICATION_H_
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(MyApplication,
my_application,
MY,
APPLICATION,
GtkApplication)
/**
* my_application_new:
*
* Creates a new Flutter-based application.
*
* Returns: a new #MyApplication.
*/
MyApplication* my_application_new();
#endif // FLUTTER_MY_APPLICATION_H_
+2 -2
View File
@@ -31,11 +31,11 @@ void main() {
expect(r.contributionsFor(Slots.sidebar), isEmpty);
});
test('contribute appends to the slot and orders by priority', () {
test('contribute appends to the slot in registration order', () {
r.contribute(_tab(id: 'a', slot: Slots.sidebar, priority: 10));
r.contribute(_tab(id: 'b', slot: Slots.sidebar, priority: -5));
r.contribute(_tab(id: 'c', slot: Slots.sidebar, priority: 0));
expect(r.tabsFor(Slots.sidebar).map((t) => t.id), ['b', 'c', 'a']);
expect(r.tabsFor(Slots.sidebar).map((t) => t.id), ['a', 'b', 'c']);
});
test('first tab contribution becomes the active tab', () {