feat(template): multi-tab artifact viewing (issue #116)#127
Merged
Conversation
Closes #116. Adds an array-backed "open tabs" store (`tabsStore`) and a centralised `useOpen(event, id)` hook so every artifact-opening surface (graph node, rail row, in-panel link, NodeRef chip, breadcrumb) honours the same modifier policy: Shift+click adds a new tab without dropping the active, plain click replaces the active tab. A `TabBar` widget renders above `ArtifactPanel` with per-tab close buttons; closing the active tab falls back to the first remaining; closing the last hides the panel. The store is intentionally unpersisted — `beforeunload` clears it so reload starts clean. Graph view highlights every artifact in the tab strip via two layers: the active tab gets the existing orange selection-ring + edge highlights (unchanged behaviour); inactive opened tabs and any 1-hop neighbour stay fully opaque (no BFS dimming) and edges incident to any opened node lose the dim treatment. Achieved by extending `nodeClass` to accept a `visibleIds` set and `edgeClass` to accept `openedIds`; each of the seven graph views computes `visibleIds = adjacentToSet(openedIds, edges)` once per render via `$derived`. Wiring touches every entry point so `MouseEvent`/`KeyboardEvent` reaches `useOpen` unchanged: `g.node` click + Enter/Space in all seven views, `InsightsRail` row buttons, `ArtifactPanel.onNavigate` for in-body NodeRef chips, `NodeRef.onSelect` itself. Verified with `npm run check` (0 errors) and a browser smoke walk via chrome MCP — all PRD-032 acceptance criteria (AC-1..AC-5) pass with no console errors. EvidencePack EVID-037 records the run with structured fields (verdict supports / CL3 / evidence_type test) → R_eff = 1.0. Refs: PRD-032, EVID-037 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bump `.opened` box stroke-width from default 1px to 2.2px and label font-weight to 600 across Force/Tree/Radial/Lanes views; apply equivalent emphasis on Matrix row/col labels, Sankey bar stroke, and Sunburst arc in the remaining views (where `.opened` was newly added). Active tab keeps the orange selection-ring as the only orange cue; opened-but-not- active now reads as "deliberately surfaced" against unopened background without competing with active highlight. Refs: PRD-032 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Reworks the highlight gradient to pure opacity, per user feedback: keep the orange selection-ring (and orange `edge-active` stroke) as the only orange cue, reserved for the active tab + its incident edges; everything else differentiates by opacity alone. - `nodeClass(id, focusId, distances, openedIds, visibleIds)` now buckets in priority: opened (= openedIds) → `node-active` (opacity 1); 1-hop adjacent (= visibleIds) → `node-near`; otherwise the existing hover-distance fallback. - Drops the `.opened` stroke-width / font-weight overrides added in the previous commit so the only visual cue between "opened" and "background" is opacity. - Tightens focus-soft opacity gradient so opened-vs-adjacent is distinguishable: `node-near` 0.7 (was 0.92), `node-mid` 0.5 (0.75), `node-far` 0.38 (0.64), `node-outside` 0.28 (0.56), `edge-dim` 0.32 (0.62) — and the base `.edge-dim` opacity drops to 0.18 from 0.44 so dimmed edges fade further. - `.edge-active` no longer bumps stroke-width to 2 — only the colour changes to var(--accent), so opened-incident and active-incident edges read at the same visual weight, with orange the only diff. Refs: PRD-032 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…atrix In Sankey/Sunburst the active selection bumps `.bar`/`.arc` fill-opacity from the base 0.78 to 1 plus an accent stroke and glow, while opened (non-active) tabs got nothing → opened bars looked dimmer than active even though both were "opened". Match active's fill-opacity on `.opened` so the only visual diff is the orange stroke/glow that marks the active. Matrix gets a parallel cue: the row/col label underline now also paints on `.opened` (in `var(--fg)`), reserving accent-coloured underlining for `.selected`. Refs: PRD-032 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sankey's `.link` base stroke-opacity is 0.36 (intentional ambient mute); `.edge-active` overrides to 0.92. Opened-incident edges previously had no class → fell back to 0.36, so edges flowing into opened-but-not-active nodes (ADR-001/2/3 in the user's screenshot) read at less than half the visibility of edges incident to the active node. `edgeClass` now returns a dedicated `edge-on` class for opened-incident edges (instead of empty string). SankeyView styles `.link.edge-on` at the same 0.92 stroke-opacity as `edge-active` — matching brightness, no accent colour. Force/Tree/Radial/Lanes already render edges at default full opacity so no CSS change there; the new class is a no-op there unless a future view wants to differentiate. Refs: PRD-032 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Force/Tree/Radial/Lanes selection-ring + `.node.selected .box` filters were using `drop-shadow(0 0 8px currentColor)`. In light theme `currentColor` resolves to the inherited foreground (near-black) instead of the accent, producing a dark gray halo around the active node next to the orange ring. Pin the drop-shadow colour to `var(--accent)` so the glow is always primary across themes. Refs: PRD-032 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
tabsStore(entities/artifact-tabs) +useOpen(event, id)hook centralise the Shift+click-vs-plain-click policy across every artifact-opening surface.TabBarwidget (widgets/artifact-tabs) renders the open tabs aboveArtifactPanelwith per-tab close, fall-back-to-first when closing the active tab, andbeforeunloadclear (no persistence).nodeClass(now takesvisibleIds) andedgeClass(now takesopenedIds); applied uniformly to all seven graph views (Force, Tree, Radial, Lanes, Matrix, Sankey, Sunburst).Closes #116.
Why
Reviewers and maintainers walking a chain of linked artifacts (PRD → RFC → ADR → evidence) lose scroll position and re-fetch on every plain click. Tabs make the comparison stateless and the linked context visible in the graph at all times.
Test plan
npm run check— 0 errors, 0 warnings (svelte-kit sync + svelte-check, 1064 files).npm run build—dist/anddist-nightly/produced (~1.41M each, both stable + nightly images).Forgeplan
PRD-032 active, EVID-037 active (
verdict supports / congruence_level 3 / evidence_type test) →R_eff = 1.0for PRD-032.🤖 Generated with Claude Code