feat(data): Data screen context menus for exhibit, node, ledger and staged kinds#1471

merged18
main
data/1151-context-menus
openedSep 15, 2026byMMatt Donovan
View on GitHubTwo-way sync enabledPR last imported 9d ago

Closes #1151

Summary

The Data screen's rows get their context menus through the shared registry (#701): exhibit (Open in viewer, Copy SHA-256, Copy relative path, Verify), node (Show only this, Expand below, Collapse below, Verify), ledger (Show target, Copy entry hash, Copy previous hash) and staged (Commit, Discard with confirmation, Copy SHA-256 labelled not anchored), exactly the X38 items and nothing else. Every item has an inline or keyboard route on the screen: Enter or a double-click opens a row, the Properties tab grows copy buttons, the strip and the pane header grow Verify, Shift+click on a twist expands or collapses a subtree, a ledger row click shows its target and its hash cells copy on click, and the Staging group's Upload, Commit and Discard buttons are now wired to the #1148 channels with Discard confirmed through one dialog whichever way it is reached. No item invokes shell:showItemInFolder; #1194 stays open. #1468, #1469 and #1470 are on main, so the verification block scores this PR's own diff.

Changes

  • src/renderer/components/contextmenu/entityMenu.ts: the four kinds, their entries and headers
  • src/renderer/components/data/useDataContextMenu.ts: targets built over the screen's own callbacks
  • src/renderer/components/data/DiscardStagedDialog.tsx, copy.ts: the confirm step and the clipboard helper
  • src/renderer/lib/api/staging.ts: upload, commit and discard mutations with their invalidations
  • src/renderer/components/data/DataTree.tsx, ArtifactTable.tsx, ManifestLedger.tsx, PropertiesTab.tsx, ArtifactTabs.tsx, ledgerModel.ts: menu wrappers and the inline routes
  • src/renderer/components/dashboard/cases/DataExplorer.tsx: wiring, live staging actions, Open in viewer through the Captures route
  • tests/components/DataExplorerContextMenu.test.tsx (new), tests/renderer/api/staging.test.ts (new), tests/components/entityMenu.test.tsx, screen test updates
  • docs/agents/architecture.md: component list

Evidence-affecting

Yes

Evidence impact

  • Evidentiary result or interpretation that could change: Commit writes to the chain and is now reachable from the screen; Discard deletes pooled bytes that nothing records, which is why it confirms. Copy SHA-256 writes the stored digest unchanged, and the pooled row's copy is labelled not anchored so a pasted hash cannot read as evidence. An item is enabled only when its inline route is: Copy relative path needs a recorded path, Copy entry hash needs a readable entry, Copy previous hash needs a readable non-genesis entry (an unreadable line shows no hash and only a readable first entry reads genesis), Show target needs an id the inventory still holds, and a node's Verify covers the rows the node shows this session, so Verify on Integrity Exceptions verifies exactly the exceptions listed and the pane header on a Selector node verifies exactly its hits.
  • What verification proves and does not prove after this change: unchanged; Verify from a row, a node or the strip is the same exhibits:verify per Exhibit in sequence, and a verify that throws re-buckets the row as unverified for the session (#1470).
  • Backward verification preserved (existing evidence packages still verify): yes; no main-process code changes beyond what #1469 carries.
  • Known-answer test added or extended, or why none applies: entityMenu.test.tsx pins the four kinds' items, order and gating (no path, genesis, no target, no viewer) and the absence of any reveal-in-folder route; DataExplorerContextMenu.test.tsx pins each item against the bridge call or state change it accelerates, the unchanged hash and path on the clipboard, that Enter on an inline button in the table or on a ledger hash cell is that button's activation and not a row open or Show target, that an unreadable ledger line shows no hash and copies none, that the pane header's Verify on a Selector node covers exactly the matched rows, that Discard reaches the channel only through the confirm, and that node Verify on Integrity Exceptions covers the session's exceptions and goes off once they clear.

Verification

pnpm preflight at 8891fe797a1950447c93cf02f1ee8166180a6bf5 on Node v20.20.2; diff scored against origin/main (merge base 6a1637935). Result: pass.

  • pnpm lint - pass (exit 0)
  • pnpm lint:boundaries - pass (exit 0)
  • pnpm lint:agents-md - pass (exit 0) - CLAUDE.md and AGENTS.md match
  • pnpm typecheck - pass (exit 0)
  • pnpm build - pass (exit 0)
  • pnpm build:extension - skipped - no extension/ changes
  • pnpm test:coverage - pass (exit 0) - 4222 passed, 10 skipped (4232), thresholds met
  • pnpm coverage:diff - pass (exit 0) - 94.55% of 165 changed lines covered (floor 90%)

Pull request description generated by Claude Code

Checks

12 successful ยท 2 skipped
All checks passed
8891fe7

Added 8 commits

  • docs(plans): working notes for the four open Data screen tickets02228f8
  • test(data): cover node titles, toggles, search clear, staging actions0486f8d
  • fix(diagnostics): admit the exhibits and manifest query domains483ed3e
  • Merge branch 'data/1148-staging-pool' into data/1151-context-menus63b12bb
  • feat(data): staging pool with manual upload, commit and discard6b86f7e
  • feat(data): context menus for exhibit, node, ledger and staged rows7b47ec4
  • feat(data): rebuild the Data screen shell over the exhibit inventoryd721167
  • feat(data): per-row tabs, Results nodes and verify-all on Data screend97c436
Synced from GitHub

Warning

Review limit reached

Next included review available in 24 minutes.

Check out review usage here.

View limit details

Limit details: Youโ€™ve used the included review currently available.

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. You're only billed for reviews past your plan's rate limits ($0.25/file).

Learn how review limits work.

Review configuration:

โš™๏ธ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Free

Run ID: e3edc3a0-6965-48c8-ad72-9130f2a82715

๐Ÿ“ฅ Commits

Reviewing files that changed from the base of the PR and between 6a1637935e09b3856ec08a57f3a2c0ac08342a23 and 8891fe797a1950447c93cf02f1ee8166180a6bf5.

๐Ÿ“’ Files selected for processing (18)
  • docs/agents/architecture.md
  • src/renderer/components/contextmenu/entityMenu.ts
  • src/renderer/components/dashboard/cases/DataExplorer.tsx
  • src/renderer/components/data/ArtifactTable.tsx
  • src/renderer/components/data/ArtifactTabs.tsx
  • src/renderer/components/data/DataTree.tsx
  • src/renderer/components/data/DiscardStagedDialog.tsx
  • src/renderer/components/data/ManifestLedger.tsx
  • src/renderer/components/data/PropertiesTab.tsx
  • src/renderer/components/data/copy.ts
  • src/renderer/components/data/ledgerModel.ts
  • src/renderer/components/data/useDataContextMenu.ts
  • src/renderer/lib/api/staging.ts
  • tests/components/DataExplorer.test.tsx
  • tests/components/DataExplorerContextMenu.test.tsx
  • tests/components/DataExplorerResults.test.tsx
  • tests/components/entityMenu.test.tsx
  • tests/renderer/api/staging.test.ts

Note

๐ŸŽ Summarized by CodeRabbit Free

Your organization is on the Free plan. CodeRabbit will generate a high-level summary and a walkthrough for each pull request. For a comprehensive line-by-line review, please upgrade your subscription to CodeRabbit Essentials by visiting https://app.coderabbit.ai/settings/billing.

Comment @coderabbitai help to get the list of available commands.

Added 7 commits

  • fix(data): anchored-only Views counts, no derived-file inferencef5ac387
  • Merge branch 'data/1149-shell' into data/1150-tabs-results0a23944
  • fix(data): keep the pool row when discard cannot unlink; clamp overrides4a4ac3e
  • Merge branch 'data/1148-staging-pool' into data/1151-context-menus17394cd
  • Merge branch 'data/1150-tabs-results' into data/1151-context-menus4b672dc
  • fix(data): gate menu items on their routes; Enter stays on buttons4678916
  • Merge branch 'main' into data/1151-context-menus9749c1a

Reviewer pre-pass (9749c1a2): request changes

#severityfile:linefinding
1gateCI at 9749c1a2Every required check (CI, Security, Pre-pass gate) failed in 2-4s with zero steps run โ€” GitHub's annotation is "job was not started because recent account payments have failed or your spending limit needs to be increased" โ€” so no check has actually run at head.
2blockingsrc/renderer/components/data/ManifestLedger.tsx:124-125Enter on a focused hash-cell button also fires the row's Show target (no target === currentTarget guard, unlike ArtifactTable.tsx:60), so a keyboard copy navigates away from the ledger โ€” reproduced.
3blockingsrc/renderer/components/data/ManifestLedger.tsx:78HashCell prints "genesis" for any empty value, so an unreadable line's empty entry hash (ledgerModel.ts:64) now reads "genesis" in the entry-hash column where main rendered nothing, and the menu's Copy entry hash on that row copies '' with a success toast โ€” reproduced.
4blockingsrc/renderer/components/dashboard/cases/DataExplorer.tsx:389The pane-header Verify calls rowsForNode without { verifications, keywordMatches } (the table at :174 passes them), so on a keyword: node it is hidden while the menu's Verify is enabled โ€” that item has no inline route there, against AC 2 and the body's "a node's Verify covers the rows the node shows this session".
5non-blockingsrc/renderer/lib/api/staging.ts:7The comment says commit also invalidates "the captures list the buckets read"; the code at :26-29 invalidates only the inventory and the manifest snapshot.

Full report: /tmp/bb-review-1471-out/report.md

Added 3 commits

  • fix(data): ledger Enter guard, empty hash cells and Copy entry hash gateeb99357
  • fix(data): pane-header Verify reads the session context the table reads0be7620
  • fix(data): no node Verify on the Manifest Ledger node8891fe7

Reviewer pre-pass (0be76202): request changes

#severityfile:linefinding
1gateCI at 0be76202Every required check failed in 1-3 s with zero steps run (billing refusal, same as round 1), so nothing has executed on this tree; local loop is green and reproduces the body's figures exactly.
2blockingsrc/renderer/components/contextmenu/entityMenu.ts:619-624The corrected comment names Integrity Exceptions as the only node whose menu Verify is not the header's, but on the Manifest Ledger node rowsForNode falls through to every anchored Exhibit (dataTableModel.ts:219-221), the menu's Verify is enabled over all of them, and there is no header Verify (DataExplorer.tsx:393-394) โ€” reproduced; the body's "every item has an inline route" is false there.
3non-blockingPR body, Summary"the branch carries the staging pool and the verification block scores the whole stack against main" is stale: #1469/#1470 are on main and the block at head scores this PR's 165 lines.
4non-blockingsrc/renderer/components/data/ManifestLedger.tsx:129The row onClick Show target route is uncovered; "a ledger row click shows its target" is pinned only through Enter.

Round-1 F2-F5 confirmed fixed and pinned; each new test fails with its source reverted to 9749c1a2.

Full report: /tmp/bb-review-1471-out/round2/report.md

Fix for the round-two blocker pushed as 8891fe79: the Manifest Ledger node now offers no Verify in the menu, matching the pane header, and the nodeMenuEntries comment names both exceptions. Pinned by a new case in tests/components/DataExplorerContextMenu.test.tsx that fails at 0be76202 and passes at head (checked in this session by reverting the hook file). pnpm preflight at 8891fe79: pass, 4222 tests, diff coverage 94.55%; the body carries that block, and its Summary no longer claims the block scores the stack. CI has not run at any head since 04:42 UTC because GitHub Actions is refusing jobs on billing grounds; the merge waits on that.