chore(plan): close T-511 (per-workspace PATH preset shipped)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 18:49:33 +02:00
co-authored by Claude Fable 5
parent 7b395c5a0a
commit 670915fbc9
3 changed files with 9 additions and 0 deletions
@@ -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;
+1
View File
@@ -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);
+7
View File
@@ -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.<fnv1a64Hex(canonicalWorkspaceKey(presetRoot))> in ~/.config/clide/settings.yaml — never committed; presetRootFor() resolves a linked-worktree workspace (gitdir: pointer file, e.g. .worktrees/<name>) 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);