feat(problems): surface stale supporter-binary pins (T-495)

The Problems panel flags a configured tool path (app.tools) that no longer
points at a file — a real misconfig, echoing D-58's soft floor. A merely-
unfound optional tool isn't flagged (its use-time userError covers that).
Extracted to a pure supporterToolProblems(), flutter-tested (3 cases).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-29 09:15:05 +02:00
co-authored by Claude Opus 4.8
parent 62418b4010
commit 3be063d6da
4 changed files with 64 additions and 0 deletions
+15
View File
@@ -8852,3 +8852,18 @@ EXTENSION WIRE DONE + PUSHED (2026-06-28): item (1) complete — DrawingMessage
COMPLETE (2026-06-28): per-object overlay done captions (data-label/data-description) + lightbox (data-lightbox tap-to-zoom), positioned via the shared svgViewportFit so they track the painted SVG. Full T-318 scope built + tested: document envelope (draw_doc), template dispatch (draw_dispatch), DrawingCard widget, the draw CLI command (draw_commands), the extension wire (DrawingMessage + subscriber + renderer + boot registration), and the per-object overlay. ~40 tests across dart + flutter test. All acceptance met (raw SVG draws; a template dispatches; objects render captions; unknown template/primitive userError). Templates d2/icon/compare/image are separate children under T-317; T-494 (d2) is next, gated on T-495.', NULL, '2026-06-28 20:40:54', '2026-06-28 20:40:54.751', '2026-06-28 20:40:54.751', NULL, '3c1694be81a3d05e22c8c5a2221e99fd', 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 ('06FB2ERREMEEF26KKHGNZBWW64', 'status', 'in_progress', 'done', NULL, '2026-06-28 20:40:54', '2026-06-28 20:40:54.785', '2026-06-28 20:40:54.785', NULL, '389acc78ce89d7225e268e20f3822fee', 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 ('06FGYPJ6FTEPP4JK3D7D01ZSMM', 'status', 'backlog', 'in_progress', NULL, '2026-06-28 21:00:18', '2026-06-28 21:00:18.364', '2026-06-28 21:00:18.364', NULL, '00fa58dcedc18f6ce827b5a0ef6ad928', 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 ('06FGYPJ6FTEPP4JK3D7D01ZSMM', 'description', 'Implement D-104. clide resolves external supporter binaries (claude, d2, future supporter tools) via an explicit user-scope ''tools:'' map (name → absolute path), consulted FIRST.
Resolution order: (1) explicit settings path use it; honest error + fallback-with-warning if missing/non-exec. (2) bundled/pinned (pql D-58, git D-59). (3) login-shell PATH (T-439). (4) bare PATH.
First run: auto-detect each tool ONCE probe the login-shell PATH + well-known dirs (~/.local/bin, /usr/local/bin, /opt/homebrew, /home/linuxbrew/.linuxbrew/bin) and WRITE the discovered absolute paths into the map (pinned, not re-probed each launch). Provide a re-detect action.
Storage: user-scope SettingsStore keyed by machine (D-93) never committed. Surface in the Config tab (T-414) + flag unresolved tools in the Problems panel (echoes D-58''s soft floor). Generalizes D-58''s CLIDE_PQL_BIN override to all supporter tools. First consumer: the d2 template (T-494).', 'Implement D-104. clide resolves external supporter binaries (claude, d2, future supporter tools) via an explicit user-scope ''tools:'' map (name absolute path), consulted FIRST.
Resolution order: (1) explicit settings path use it; honest error + fallback-with-warning if missing/non-exec. (2) bundled/pinned (pql D-58, git D-59). (3) login-shell PATH (T-439). (4) bare PATH.
First run: auto-detect each tool ONCE probe the login-shell PATH + well-known dirs (~/.local/bin, /usr/local/bin, /opt/homebrew, /home/linuxbrew/.linuxbrew/bin) and WRITE the discovered absolute paths into the map (pinned, not re-probed each launch). Provide a re-detect action.
Storage: user-scope SettingsStore keyed by machine (D-93) never committed. Surface in the Config tab (T-414) + flag unresolved tools in the Problems panel (echoes D-58''s soft floor). Generalizes D-58''s CLIDE_PQL_BIN override to all supporter tools. First consumer: the d2 template (T-494).
RESOLUTION CORE DONE (2026-06-28): functional path resolution built + wired + tested (14 dart-test cases). SupporterBinaries resolver (lib/src/env/supporter_binaries.dart): explicit override -> login-shell/process PATH -> well-known dirs INCLUDING Homebrew-on-Linux (the D-104 gap). loadSupporterBinaries: first-run auto-detect + persist (pinned, not re-probed); isStalePin flags a moved tool. Boot wiring in main.dart exposes the process-wide activeSupporterBinaries. This UNBLOCKS T-494 the d2 template resolves d2 via activeSupporterBinaries.resolve(''d2''). REMAINING (UI follow-ons, not gating T-494): Config-tab override editor (view/edit/clear paths), a re-detect action, and Problems-panel surfacing of unresolved tools.', NULL, '2026-06-28 21:08:40', '2026-06-28 21:08:40.178', '2026-06-28 21:08:40.178', NULL, 'f155f8e589cd19c3cc52409495d24f50', 2) ON CONFLICT(hash) DO NOTHING;
+9
View File
@@ -10647,3 +10647,12 @@ Resolution order: (1) explicit settings path → use it; honest error + fallback
First run: auto-detect each tool ONCE probe the login-shell PATH + well-known dirs (~/.local/bin, /usr/local/bin, /opt/homebrew, /home/linuxbrew/.linuxbrew/bin) and WRITE the discovered absolute paths into the map (pinned, not re-probed each launch). Provide a re-detect action.
Storage: user-scope SettingsStore keyed by machine (D-93) never committed. Surface in the Config tab (T-414) + flag unresolved tools in the Problems panel (echoes D-58''s soft floor). Generalizes D-58''s CLIDE_PQL_BIN override to all supporter tools. First consumer: the d2 template (T-494).', 'in_progress', 'medium', NULL, NULL, 'D-104', '2026-06-28 17:50:02.366', '2026-06-28 21:00:18.364', NULL, 'de1818996b3226c6df2516d1aff9cfad', 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 ('06FGYPJ6FTEPP4JK3D7D01ZSMM', 'task', NULL, 'Supporter-binary path resolution: explicit user-scope overrides + first-run auto-detect', 'Implement D-104. clide resolves external supporter binaries (claude, d2, future supporter tools) via an explicit user-scope ''tools:'' map (name → absolute path), consulted FIRST.
Resolution order: (1) explicit settings path use it; honest error + fallback-with-warning if missing/non-exec. (2) bundled/pinned (pql D-58, git D-59). (3) login-shell PATH (T-439). (4) bare PATH.
First run: auto-detect each tool ONCE probe the login-shell PATH + well-known dirs (~/.local/bin, /usr/local/bin, /opt/homebrew, /home/linuxbrew/.linuxbrew/bin) and WRITE the discovered absolute paths into the map (pinned, not re-probed each launch). Provide a re-detect action.
Storage: user-scope SettingsStore keyed by machine (D-93) never committed. Surface in the Config tab (T-414) + flag unresolved tools in the Problems panel (echoes D-58''s soft floor). Generalizes D-58''s CLIDE_PQL_BIN override to all supporter tools. First consumer: the d2 template (T-494).
RESOLUTION CORE DONE (2026-06-28): functional path resolution built + wired + tested (14 dart-test cases). SupporterBinaries resolver (lib/src/env/supporter_binaries.dart): explicit override -> login-shell/process PATH -> well-known dirs INCLUDING Homebrew-on-Linux (the D-104 gap). loadSupporterBinaries: first-run auto-detect + persist (pinned, not re-probed); isStalePin flags a moved tool. Boot wiring in main.dart exposes the process-wide activeSupporterBinaries. This UNBLOCKS T-494 the d2 template resolves d2 via activeSupporterBinaries.resolve(''d2''). REMAINING (UI follow-ons, not gating T-494): Config-tab override editor (view/edit/clear paths), a re-detect action, and Problems-panel surfacing of unresolved tools.', 'in_progress', 'medium', NULL, NULL, 'D-104', '2026-06-28 17:50:02.366', '2026-06-28 21:08:40.177', NULL, '7e1f7077abd788309d38a51f8a3b1348', 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);