file T-252 (lightbox) and close T-248 review

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-06 10:31:29 +02:00
co-authored by Claude Opus 4.8
parent b446bd024d
commit b05f6617d3
2 changed files with 32 additions and 0 deletions
@@ -398,3 +398,4 @@ New scope for this ticket:
Net: this is now a verify-and-reconcile task, not a build-from-scratch one. Related: T-249, T-208.', NULL, '2026-06-06 08:12:53', '2026-06-06 08:12:53', '2026-06-06 08:12:53', NULL, '44685b2fe0265e9e8b110d4306de92be', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-248', 'status', 'done', 'review', NULL, '2026-06-06 08:14:01', '2026-06-06 08:14:01', '2026-06-06 08:14:01', NULL, '1cfdde30e08e7e18f8b9eb39df3abcbc', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-249', 'status', 'ready', 'done', NULL, '2026-06-06 08:21:40', '2026-06-06 08:21:40', '2026-06-06 08:21:40', NULL, '996d52afaf650a7d5021184a673d09a3', 1) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-248', 'status', 'review', 'done', NULL, '2026-06-06 08:31:25', '2026-06-06 08:31:25', '2026-06-06 08:31:25', NULL, '231d1bb74f6f154f7e888760f1c4e3a6', 1) ON CONFLICT(hash) DO NOTHING;
+31
View File
@@ -888,3 +888,34 @@ Scope:
Dependency: pairs with T-248 without the /clide skill + discovery verb, Claude won''t know this card/verb exists even once shipped. Build the plumbing here; T-248 makes it discoverable.
Refs: D-6 (parity), D-78 (interaction zone, display-only conversation widgets). Related: T-248.', 'done', 'medium', NULL, NULL, 'D-6', '2026-06-06 07:21:17', '2026-06-06 08:21:40', NULL, '7280f99bd28193b894588954367eb367', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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 (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-252', 'story', NULL, 'Full-screen lightbox overlay (zoom + pan) for image cards', 'Click an inline image card (T-249) to open it in a full-screen overlay with zoom + pan — the standard lightbox UX from other apps (dimmed backdrop, image fit-to-screen, scroll/pinch to zoom, drag to pan when zoomed past fit, Esc or backdrop-click to dismiss).
Build the overlay as a SHARED PRIMITIVE WIDGET, not image-specific. A reusable zoomable-viewer / lightbox primitive under lib/widgets/ (e.g. ClideLightbox + ClideZoomPanViewer) that takes any child/content; the image card is its first consumer, and the canvas, graph, and diff/image previews can adopt it later. Own-the-rendering-stack + prefer-zero-deps still apply: Flutter''s SDK InteractiveViewer is the SDK-first starting point (allowed), but keep the gesture/zoom logic in the primitive so we control the UX, not an opinionated package.
Scope:
- Shared primitive (lib/widgets/): a full-screen overlay with a dimmed backdrop hosted via the existing DialogRouter (single-at-a-time modal, D-78 interaction surface). Content scales to fit on open; zoom via scroll wheel / pinch / +- ; pan by drag when zoomed in; double-click toggles fit<->100%/2x; Esc and backdrop-click dismiss. Min/max zoom clamp. Keyboard + AT reachable (ClideTappable / Semantics), theme tokens / ui-design for any chrome (close affordance, zoom hint).
- Image card wiring (T-249): the inline card stays display-only per D-78 the click is a navigation gesture that opens the lightbox, not an inline control. Render the same resolved file at full resolution in the overlay; missing-file degrades to the existing placeholder.
- Parity (D-6): a CLI counterpart to open an image straight into the lightbox (e.g. clide image show <path> --fullscreen, or clide image open <path>), registered so it surfaces in clide capabilities (T-248).
Refs: D-78 (interaction zone / display-only conversation widgets), D-6 (CLI/UI parity), DialogRouter (lib/kernel/src/dialog.dart). Builds on T-249 (image card + clide image show). Related: T-248.', 'backlog', 'medium', NULL, NULL, 'D-78', '2026-06-06 08:28:43', '2026-06-06 08:28:43', NULL, '2a4f0e70eb9f313249480c14aa56f2c4', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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 (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-248', 'story', NULL, '/clide skill — advertise the clide tool surface to Claude', 'Create a `/clide` skill (none exists today — only legacy templates under legacy/clide/templates/skills/) that advertises the clide CLI surface to Claude so new affordances become discoverable.
Problem: my knowledge of the clide surface comes from a hand-curated session blurb. There is no runtime discovery `clide help` is a stub, `clide <subsystem>` with no verb just prints `usage:`, and the dispatcher''s registered command table (e.g. pane_commands.dart) is never exposed. D-6 guarantees a verb EXISTS for every UI action, but parity != discoverability: a correctly-registered verb is still unreachable if nothing tells me it''s there.
Scope:
- Self-description first (prereq for a non-rotting skill): add a discovery verb that reflects the live dispatcher registry e.g. `clide capabilities` (machine-readable JSON: subsystems -> verbs -> arg schema) and/or flesh out `clide help` to enumerate subsystems/verbs. Sourced from the registry so it never drifts.
- `/clide` SKILL.md: trigger description always visible to Claude; body points at the discovery verb rather than hard-coding a verb list, plus conventions (slots: sidebar/workspace/context, pane kinds, focus/spawn/close/write/resize). Thin and always-correct.
This is what makes T-249 (image viewer) and future panels reachable by Claude the moment they register no skill edit per panel.
Refs: D-6 (CLI/event-surface parity). Related: T-249.
RE-SCOPE (2026-06-06, from T-208 completeness review): partly overtaken by reality do NOT build from scratch.
- The `clide capabilities` verb already EXISTS in code: registered in lib/src/daemon/dispatcher.dart:12 (built-in) and as an umbrella command in lib/src/cli/argv_to_request.dart:28. Its handler (_capabilities, dispatcher.dart:86) enumerates the live registry with arg schemas so the non-rotting design is already implemented server-side.
- A `/clide` skill is ALSO already present this session (other ongoing work), and it instructs agents to "Start with `clide capabilities` to enumerate the live tool surface."
- BUT: against the live instance, `clide capabilities` returns a usage stub at exit 0 (`usage: clide capabilities <verb> [args...]`) instead of the command table i.e. the discoverability entry point the skill advertises is currently DEAD. Likely a stale running build or a C-client umbrella mismatch (native/clide-cli/clide.c forwards argv but the live server treats `capabilities` as a subsystem needing a verb).
New scope for this ticket:
1. Verify/fix the live `clide capabilities` path end-to-end (rebuild/restart vs real wiring gap in the C client / server umbrella handling). Acceptance: `clide capabilities` returns the JSON command table against a running instance.
2. Reconcile with the already-shipped `/clide` skill rather than authoring anew confirm it points at the working verb and covers the conventions.
Net: this is now a verify-and-reconcile task, not a build-from-scratch one. Related: T-249, T-208.', 'done', 'medium', NULL, NULL, 'D-6', '2026-06-06 07:21:17', '2026-06-06 08:31:25', NULL, 'd2d8d30c578bce8229924619542d5aa7', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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);