Repository navigation
Viewer M1: verification loop, claim-first Inspector, freshness in place, legacy cleanup - #15
Merged
Merged
Conversation
…hness in place, root hint)
- Source jumps open the cited file beside the diagram with focus kept in
the diagram, select the whole cited range and highlight it with a theme
decoration that moves with the next jump and is cleared when the panel
closes. Alt+Enter (or Alt+click on an Open link) moves focus to the
editor. Notebook citations select and reveal the cell, and highlight its
lines when the cell editor is ready within 500 ms. A jump into a file
whose bytes match the last validation skips the full revalidation.
- A click on a card, connection, finding or Outline row only selects it;
Enter, a double-click and the Inspector's Open links open the source.
Shortcut sheet, legend and docs updated.
- The stale frame now carries [{path, reason}]. Cards, connections,
findings and quotes citing a stale file are marked (icon and words, no
colour for unchanged files), stale Open links are disabled with the
reason, and the status bar counts the files. After the mount the host
banner is drawn as a notice under the header; "checking" goes to the
status bar.
- When most tracked files are missing from the root but exist with the
published hashes under the artifact's folder or a parent below the root,
the banner says so instead of "no longer match" and offers Add folder to
workspace / Open folder. Panels revalidate on workspace folder changes.
No path is ever substituted.
No contract change, no new setting, geometry golden unchanged. Checked by
local tests only (webview 130, extension 281); not checked in live VS Code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- The Inspector shows a step's full authored detail as a paragraph under
the title, the phase label (never the id) and the kind. The mono line that
repeated the title is gone; the basis appears once (no Attributes table
for authored steps; a connection's title is its authored label without
the " · basis" suffix), with one sentence for inferred or unresolved.
- Findings show their suggestion as "What to change" in the Inspector and
the expanded Findings row. The analyzer-era workflow.css rule that hid
.mlv-insp__fix is removed; no label is drawn when there is no suggestion.
A step's findings now come before its quotes.
- Document-wide limitations are listed once, in the header Details; the
Inspector shows "N document-wide limitations apply. Show", which opens
Details at the list and moves focus there.
- A caption under the evidence heading says a matching quote shows the lines
are unchanged since publishing, not that they support the claim.
- A card's accessible name (and the selection announcement) ends with the
first sentence of the claim, at most 160 characters, and names the phase
by label.
- Authored notebook cells print as recorded, counted from 0
("cell 34, line 2"), matching the evidence, the helper's --cell, the
extension and the model's own labels; author labels are untouched.
- The phase chip tooltip says what a click does; a connection's hover card
is titled with its authored label.
The projection's card inputs (sublabel, attrs={basis}, the edge label
suffix) are unchanged; MLNode.detail/phaseLabel and MLEdge.authoredLabel
are new fields that layout does not read. Geometry golden byte-identical.
New webview/test/inspector-content.test.mjs loads the shipped stylesheet
into jsdom and checks visibility by computed style; three existing tests
updated for the deliberate wording and cell-number changes. Checked by
local tests only (webview 143, extension 281); not checked in live VS Code.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Removes the analyzer-era viewer modules that no authored document reaches:
the diff overlay (diff/overlay, adopt, changed, ui/diffbar), the pipeline
chooser (ui/pipelinechooser, scope/pipelines and the `pipeline:` scope
kind), the answer card (ui/answers), the rollup reader (rollup/rolled),
resolved config (config/resolved), rule fixes, suppression and rule docs
(ui/fixes, ui/suppress, ui/ruledocs and the trust disclosures in
ui/evidence), the chrome banners (ui/chromebanners), the standalone half of
bridges.ts with export/download and the standalone theme switch, and
"group by" (ui/railgroup, dropped as the owner accepted). The call sites
that only served them go too, with the matching types and the ViewState
keys railGroupBy, answersOpen, diffOnly and pipelineChosen (an old saved
state that still carries them is ignored).
The live part of rollup/rolled.ts, the weight of a merged cable, moves to
render/weight.ts; routeWeight is now ids.length || 1, which is what it
returned for every authored edge (no authored edge carries a weight).
Checks (local only): both geometry-golden digests unchanged; a jsdom tour of
39 authored documents (shakedown artifacts, the sample, the skill example
and the dev artifacts), 6454 steps, records the same DOM, ViewState and
posted frames (SVG export included) before and after, leaving out only the
removed elements, each of which was hidden or display:none under the
shipped stylesheet. TypeScript 26061 -> 20173 lines; dist/mlview.js
364619 -> 303850 bytes. Webview tests 143 -> 142 ("file groups report the
weakest authored basis" exercised group by file); two tests updated for the
removed chooser, banners and grouping. Extension tests 281 pass.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every node the viewer draws comes from normalizeWorkflow, so the branches for analyzer graphs, and the fields only those graphs carried, could not be reached. Removed: - Frames: the viewer no longer posts selectNode, scopeChanged, askAssistant or action (the host has no handler for any of them), and no longer dispatches setFilter, setScope, requestExport or cursorHint (the host never sends them). revealNode, revealIssue and restoreState stay. - State: the loading skeleton, App.error, the "only changed" chip and filter, showSuppressed and rule-code filters (saved states that still carry those keys are read and the keys ignored). - Types: ghost, dynamic, confidence, fqn, ports, stage evidence and the authored flag on nodes; suppression, change, why and confidence on findings; file, line, count, codes and scope on notes; frameworks, filesFailed and stats.truncated; the canReanalyze, canExport and canAskAssistant capabilities. - Code: the notebook flat-line cell mapping and out-of-order caveat, the concern scope presets, ghost pruning in the projection, the relatedLocs connector guess, the coverage chip vocabulary (chromenotes.ts) and the analyzer-only Inspector sections (Ask, Ports, Why this stage, Attributes); unused exports. Three visible changes: a merged cable's tooltip no longer mentions the retired rollup, its accessible name no longer repeats the merge count as a weight, and a saved state carrying showSuppressed no longer shows "Clear filters" on load. Checked: geometry golden byte-identical; a jsdom tour of 39 authored documents (6454 steps, DOM, ViewState, posted frames and SVG export) is identical to the previous commit once the retired frames and the three changes above are set aside, with no errors. Webview 142/142, extension 281/281. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The stylesheets still carried the retired analyzer viewer: the answer card, the diff overlay and fix disclosure, the rail's group headers, suppression, baseline and change chips, confidence chips, evidence weights and rule cards, the banners, the standalone theme switch, the loading skeleton, the pipeline chooser, ghost, low-confidence and dynamic cards, the rolled-up card, the clean-state caveat and attribute tables, and the block that hid analyzer controls in an authored document. - Deleted chromeanswers.css, diff.css, railevidence.css and railgroups.css. Their two live rules move to the end of the layer before them, so the cascade order is unchanged: the legend's scroll shadow (chromepanels.css) and the wrapping finding meta line (rail.css). - rollup.css becomes weight.css and keeps only the weighted cable. - Dead rules removed from chrome, chromepanels, chromestates, export (print list), node, rail, scope and workflow. Each removed selector was checked twice: no TypeScript source creates its class or attribute, and a jsdom tour of 39 authored documents never matched it. Computed styles of every element at 195 points of that tour are identical before and after, apart from the retired --mlv-diff-* and --mlv-fix tokens nothing reads. mlview.css goes from 82,027 to 61,726 bytes. CHANGELOG, docs/STATUS.md and webview/README.md describe steps 3 and 4. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
webview/tools/screenshots/capture.mjs opens documents in the built viewer in headless Chrome and saves one PNG per state plus index.json (what was clicked, what the page posted, what it showed, console errors). - Chrome is driven over --remote-debugging-pipe (fds 3 and 4, JSON messages separated by NUL), so it runs on Node 20 without WebSocket. Chrome is found through CHROME or the usual macOS, Linux and Windows install paths; otherwise it exits with a message saying how to set it. - The page plays the VS Code side: a small table of Dark Modern, Light Modern and Dark High Contrast colours (VS Code 1.139 theme files, MIT), an excerpt of VS Code's default webview stylesheet, a stub acquireVsCodeApi, and the panel's own inline bootstrap read from vscode-extension/src/authoredPanel.ts. After `ready` it gets the frames the extension posts: init, workflow, and for the stale states the step 1 `stale` frame and the stale banner. - States: initial, select-node, hover-node, hover-connection, focus-mode, filter, search, finding (with its suggestion), stale, stale-selected and narrow-selected (900x800). - Inputs: samples/configured_training.mlview.json (read only) and a synthetic 120-step document built from tools/benchmark-model.mjs, or --artifact/--workspace for local artifacts (cited files are hashed against the published hashes). --viewer loads another checkout's dist and bootstrap for before/after pictures. Not part of npm test, CI or the e2e gates; no artifacts or screenshots are committed. test/screenshot-pipe.test.mjs checks the pipe framing, the client and the Chrome lookup without Chrome. Docs: webview/README.md, scripts/README.md, CHANGELOG.md, docs/STATUS.md, THIRD_PARTY_NOTICES.md (and its extension copy). The pictures are a rendering check with a simulated host, not live VS Code validation or usability evidence. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…int wording Fixes from independent model reviews of the M1 branch. Each code fix has a regression test that fails without it. Local tests only (jsdom, the mock vscode module, a child Node process); not tried in live VS Code. Geometry golden byte-identical; no contract change, no new setting. - M1-R1, M1-R3, UX-1: the first click of a double-click arms an opener (webview/src/ui/doubleclick.ts); a root capture listener takes the second click of the same sequence (MouseEvent.detail >= 2), wherever it lands, and opens what the first click selected, swallowing the rest of the gesture. A double-click on a finding or Outline step now opens (the first click rebuilt the rows, so the dblclick went to a detached node); a shifted row, a rail that opens over the canvas, its scrim, the canvas background or an Inspector control under the second click no longer break it. The row panels' dblclick delegation is gone. Tests send Chrome's click, click, dblclick order. - M1-R2: each source jump has a sequence number; an overtaken notebook jump no longer clears or moves a later jump's highlight. - A11Y-1: the range highlight also draws editor.rangeHighlightBorder, which High Contrast themes define instead of a background. - COPY-1: in the root-hint case the host sends reason 'elsewhere'; marks, status bar, Inspector, chips and jump toasts say "in another folder" and point to the notice. The host's own jump refusal agrees. - COPY-2: the Inspector stale note no longer says the claim was not re-checked. - COPY-3: the root-hint text leads with the files and names each folder once. - A11Y-2: stale marks use --mlv-stale-ink (warning mixed 30% toward text): 4.2:1 or more in Light Modern and 2026 Light (was 2.2-3.0:1); test/stale-contrast.test.mjs checks six default themes. - M1-R4: the spoken claim no longer stops at "i.e."/"e.g."/"etc.". - DOC-1: the shortcut sheet and docs say which targets a double-click opens. - PRUNE-1: findChrome joins macOS/Linux candidates with path.posix; a test runs it with node:path mapped to path.win32. - PRUNE-2: the docs say the screenshot capture is opt-in but its pipe test runs in npm test, CI and both e2e drivers. Rebuilt webview/dist and vscode-extension/media. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…extension host In a single-folder window the root hint's "Add folder to workspace" makes VS Code enter an untitled multi-root workspace: it stops the extension host, switches the workspace and starts a new host. The open panel kept its tab but nothing answered it. VS Code 1.139 calls a panel serializer only for the lazily restored tabs it deserializes when a window loads, never for a live panel after a host restart, so the serializer was never reached. Before adding the folder in a single-folder window, the host now saves a note in globalState (the new workspace starts with an empty workspace state): the window's vscode.env.sessionId, the folder, and each open diagram's artifact and tab title. At activation the new host closes one dead diagram tab per noted panel (window.tabGroups, TabInputWebview viewType "mainThreadWebview-mlview.authoredDiagram", front tabs first) and opens the diagram again in the same group, where it validates against the added folder. The note is used once and ignored when older than a minute, from another window, or for a folder not in the workspace. A host that sees the folder change itself withdraws its own note. Multi-root windows keep re-validating in place. Restore now keeps one panel per artifact. Tests: test/folder-add-restart.test.js (11 cases); the mock gains tabGroups, TabInputWebview, workspaceFile, env.sessionId and a memento. Checked live in an isolated VS Code 1.139 Extension Development Host. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t restart Commit 48d5957 saved a reopen note only when the root hint's own button added a folder, so every other extension host restart in a window still left a dead diagram tab: VS Code's "Add Folder to Workspace...", "Save Workspace As...", "Developer: Restart Extension Host", an extension install or update that restarts extensions. The root hint's notification also outlived the restart with dead buttons. Each host now keeps a registry of its open panels in globalState ("mlview.openPanels": per vscode.env.sessionId, each panel's artifact, tab title and column), written on open, retitle, group change and close but not at shutdown. At activation, when this session has entries, the new host replaces each dead tab with a panel for its artifact in the same group. A dead tab and a restored tab not yet shown look the same to the tabs API, and a restored tab is revived by the serializer as soon as it comes to the front, so only front tabs are judged, 500 ms after activation or a tab change; a front diagram tab that no panel shows by then is dead. VS Code revives a restored panel with column 0 and reports its group about 20 ms later, so a visible panel with the tab's title counts until then. A dead tab behind others is replaced when it is brought to the front. An artifact already open gets no second panel. Other sessions' entries are pruned after 14 days (at most 20 kept). The hint's Add folder only flushes the registry. The root hint no longer shows a notification; the panel notice carries both actions. Tests: test/host-restart.test.js (17 cases) replaces folder-add-restart.test.js, whose decoy test passed for the wrong reason. The mock gains Disposable, tab events, TabGroup.activeTab, panel-linked tabs and view states. A mutation check of the new logic caught 19 of 19 mutations. Extension tests: 299. Checked live in isolated VS Code 1.139 Extension Development Hosts; an extension install or update was not tried. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…fter a restart An independent live check passed the generalized recovery and found three guards no test pinned: the settle delay restarting at each tab change, title matching even when an entry has the tab's group, and a column-0 panel covering only a tab with its own title. Three tests now pin them (each fails with its guard removed). The docs now say a diagram put back after an extension restart starts with a fresh view, while Reload Window keeps the selection and zoom. Co-Authored-By: Claude Opus 5.5 <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.
Milestone M1 of the UI/UX direction the owner approved on 2026-10-01: tighter checking of claims against source, an Inspector that shows the claim, and removal of dead analyzer code. Diagram shapes do not change; the geometry golden is byte-identical. There are no pilot records here, so any merge method is fine.
What changes for a reader
detail) and the phase name (not its id). The title is no longer repeated.Cleanup
Dead analyzer UI is removed: the diff overlay, pipeline chooser, answers card, fix/suppress/rule panels, group-by-file and legacy branches and types.
revealNode/revealIssueandrestoreStateare kept.webview/srcdist/mlview.jsDeveloper tool
webview/tools/screenshots/is an opt-in headless-Chrome screenshot harness. It uses Chrome's--remote-debugging-pipe(so it works on Node 20) and a simulated host. Its default inputs are the repo sample and a synthetic document. It is not a CI gate, but its message-parsing test runs innpm test.Checks
sh scripts/e2e.sh --skip-npm-install: E2E OK: 15 exercised gates (pytest 915 passed; webview 155/155; extension 302/302). Node v26.4.0, Python 3.13.15.These checks show behaviour, not usability or semantic accuracy. An extension install or update was not tried live. Pilot-01 reviews keep using the frozen candidate VSIX.
Known limits (documented):
🤖 Generated with Claude Code