From 670915fbc9915180ee84e7bd57d5963c91e55e67 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Mon, 13 Jul 2026 18:49:33 +0200 Subject: [PATCH] chore(plan): close T-511 (per-workspace PATH preset shipped) Co-Authored-By: Claude Fable 5 --- .pql/changelog/ticket_history/2026-07.sql | 1 + .pql/changelog/ticket_idmap/2026-07.sql | 1 + .pql/changelog/tickets/2026-07.sql | 7 +++++++ 3 files changed, 9 insertions(+) diff --git a/.pql/changelog/ticket_history/2026-07.sql b/.pql/changelog/ticket_history/2026-07.sql index 274bdb3e..b250a7fa 100644 --- a/.pql/changelog/ticket_history/2026-07.sql +++ b/.pql/changelog/ticket_history/2026-07.sql @@ -107,3 +107,4 @@ Injection (prepend, dedup, next-spawn semantics): PTY panes via PaneRegistry.pat CLI (D-6): one cmd id env.path → clide env path list|set|add|remove|clear|capture; Flutter-free handler lib/src/daemon/env_path_commands.dart over an injected PathPresetStore port (adapter in main.dart); mutations publish on envPathChannel; capture diffs loginShellPathOrNull() (new shell_env getter) vs process PATH. UI: Settings → Tools → Workspace PATH section, custom control (ordered list, add/remove/reorder, missing-dir warning, worktree note, capture suggestions) in builtin.tools-settings; en+nl catalogs. .worktrees/ added to IgnoreSet.builtin() and the project-init gitignore scaffold. Tests: path_preset_test (pure fns + real worktree layout), env_path_commands_test (all verbs), agent_bootstrap prependDirs cases, PaneRegistry pathForSpawn PTY test, widget tests for the control incl. worktree key sharing + capture. make test (4048) + make test-a11y green.', NULL, '2026-07-13 15:39:31', '2026-07-13 15:39:31.309', '2026-07-13 15:39:31.309', NULL, '44007d87d28b52050716cd913009d341', 2) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'status', 'in_progress', 'done', NULL, '2026-07-13 16:48:56', '2026-07-13 16:48:56.833', '2026-07-13 16:48:56.833', NULL, 'd6c02324e60b8d412840b1ffd600a13f', 2) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/ticket_idmap/2026-07.sql b/.pql/changelog/ticket_idmap/2026-07.sql index c815b867..87ac7aa1 100644 --- a/.pql/changelog/ticket_idmap/2026-07.sql +++ b/.pql/changelog/ticket_idmap/2026-07.sql @@ -2,3 +2,4 @@ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_ INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ4D1M6ESSSQ1ZERTH4V9YN4', 'T-508', '2026-07-02 09:41:14.425', '2026-07-02 09:41:14.425', NULL, '5389a964251dc22408c41ceac6954f4d', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FJ91RYFXBJH99HJ18QTHY2B0', 'T-509', '2026-07-02 20:31:02.783', '2026-07-02 20:31:02.783', NULL, 'ea835aca1960e1bee3d0710be19b8bba', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FK3CDZQD2JM95ZQY5MH53PWC', 'T-510', '2026-07-05 09:52:40.384', '2026-07-05 09:52:40.384', NULL, '6acffc225f49858f782c8c5e801e1c24', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); +INSERT INTO ticket_idmap (record_id, ticket_id, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'T-511', '2026-07-13 15:17:10.276', '2026-07-13 15:17:10.276', NULL, 'ffc35cbc7ffe3577e9f103ce6b411857', 2) ON CONFLICT(record_id) DO UPDATE SET ticket_id=excluded.ticket_id, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > ticket_idmap.updated_at OR (excluded.updated_at = ticket_idmap.updated_at AND excluded.hash > ticket_idmap.hash); diff --git a/.pql/changelog/tickets/2026-07.sql b/.pql/changelog/tickets/2026-07.sql index 17833518..a6ae975b 100644 --- a/.pql/changelog/tickets/2026-07.sql +++ b/.pql/changelog/tickets/2026-07.sql @@ -90,3 +90,10 @@ Injection (prepend, dedup, next-spawn semantics): PTY panes via PaneRegistry.pat CLI (D-6): one cmd id env.path → clide env path list|set|add|remove|clear|capture; Flutter-free handler lib/src/daemon/env_path_commands.dart over an injected PathPresetStore port (adapter in main.dart); mutations publish on envPathChannel; capture diffs loginShellPathOrNull() (new shell_env getter) vs process PATH. UI: Settings → Tools → Workspace PATH section, custom control (ordered list, add/remove/reorder, missing-dir warning, worktree note, capture suggestions) in builtin.tools-settings; en+nl catalogs. .worktrees/ added to IgnoreSet.builtin() and the project-init gitignore scaffold. Tests: path_preset_test (pure fns + real worktree layout), env_path_commands_test (all verbs), agent_bootstrap prependDirs cases, PaneRegistry pathForSpawn PTY test, widget tests for the control incl. worktree key sharing + capture. make test (4048) + make test-a11y green.', 'in_progress', 'high', NULL, NULL, 'D-106', '2026-07-13 15:17:10.275', '2026-07-13 15:39:31.309', NULL, 'c5a978f32c7497e478c471069ed20b7c', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash); +INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FNR3DP0D48AZZ3NRA8JF3Q10', 'task', NULL, 'Per-workspace PATH preset: settings + CLI (env.path) + spawn injection, worktree-aware (FR-1)', 'Implements D-106 (FR-1 + worktree addendum). Storage: user-scope key app.env.pathPrepend. in ~/.config/clide/settings.yaml — never committed; presetRootFor() resolves a linked-worktree workspace (gitdir: pointer file, e.g. .worktrees/) to the main repo root so all worktrees share the repo''s preset. + +Injection (prepend, dedup, next-spawn semantics): PTY panes via PaneRegistry.pathForSpawn hook (main.dart wires the preset-aware closure); hosted Claude via agentEnvDelta(prependDirs:) — now exports PATH whenever a preset exists even if clide is already on PATH (previous gap) — threaded orchestrator.pathPresetFor ← claude extension ← ctx.settings. Toolchain/supporter-binary resolution deliberately preset-blind (T-98/D-92 fence). + +CLI (D-6): one cmd id env.path → clide env path list|set|add|remove|clear|capture; Flutter-free handler lib/src/daemon/env_path_commands.dart over an injected PathPresetStore port (adapter in main.dart); mutations publish on envPathChannel; capture diffs loginShellPathOrNull() (new shell_env getter) vs process PATH. UI: Settings → Tools → Workspace PATH section, custom control (ordered list, add/remove/reorder, missing-dir warning, worktree note, capture suggestions) in builtin.tools-settings; en+nl catalogs. + +.worktrees/ added to IgnoreSet.builtin() and the project-init gitignore scaffold. Tests: path_preset_test (pure fns + real worktree layout), env_path_commands_test (all verbs), agent_bootstrap prependDirs cases, PaneRegistry pathForSpawn PTY test, widget tests for the control incl. worktree key sharing + capture. make test (4048) + make test-a11y green.', 'done', 'high', NULL, NULL, 'D-106', '2026-07-13 15:17:10.275', '2026-07-13 16:48:56.833', NULL, '09c6b262b3c0ecfd2f621d27f2cc5eb2', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);