Skip to content

feat(webui): turn empty findings and palette results into guidance - #421

Merged
George-RD merged 1 commit into
mainfrom
webui-guidance-deadends
Jul 17, 2026
Merged

feat(webui): turn empty findings and palette results into guidance#421
George-RD merged 1 commit into
mainfrom
webui-guidance-deadends

Conversation

@George-RD

Copy link
Copy Markdown
Collaborator

Part of #305 (priority 2 of three; #305 remains open for the topbar unit).

Implements dec.webui-design-direction's "dead ends become guidance":

  • Clean findings drawer shows the server-owned time of the successful scan currently being served, or an honest unavailable state, plus a copyable cairn scan CTA. Cached-scan fallback retains the prior timestamp; boot retries clear stale metadata.
  • /api/meta adds last_reconciled (epoch milliseconds), so the private webui wire moves uniformly from schema v3 to v4; every endpoint snapshot is rebased. The shared Query API/CLI/MCP wire is unchanged.
  • Command palette shows Enter hints only when results exist and report-specific guidance only when the report row is active; combobox/listbox/option + active-descendant semantics expose keyboard selection to assistive technology.
  • Pinned Biome 2.4.4 cleanup across ui assets aligns local and CI formatting.

Verification: full pre-archive gate; pinned Biome; token + size gates; strict Cairn scan; webui harness ux_defect_score=0, 11/11 scenarios. Sequential simplicity then adversarial review applied; final reviewer verdict SHIP.

Priority 2 of dec.webui-design-direction (#305):

- The clean findings drawer shows the server-owned time of the
  successful scan currently being served, plus a copyable cairn scan
  CTA. Cached-scan fallback retains the prior time; retries clear stale
  browser metadata. The HTTP UI wire moves to schema version 4.
- Command palette results expose Enter affordances that match the active
  action, with combobox/listbox semantics and active-descendant state.
- Pinned Biome 2.4.4 formatting is applied across ui assets so local
  verification matches CI.

todo.webui-guidance-deadends is done; #305 remains open for priority 3.
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added reconciliation timing to empty findings states, showing when the latest scan was completed or indicating when timing is unavailable.
    • Added command palette guidance for opening highlighted results and reporting issues.
    • Improved command palette accessibility with keyboard navigation state and semantic result labeling.
  • Improvements

    • Updated UI metadata to include the latest reconciliation timestamp.
    • Refined command palette hint styling and empty-state presentation.

Walkthrough

The WebUI now reports the cached scan reconciliation time, displays it in the findings empty state, and updates the metadata schema to version 4. The command palette adds ARIA result semantics and contextual Enter hints. Generated symbol metadata and several non-functional UI formatting changes were also updated.

Changes

WebUI guidance

Layer / File(s) Summary
Reconciliation metadata flow
src/ui/server.*, src/ui/mod.rs, src/ui_assets/app.js, src/ui_assets/findings-panel.js, docs/design-system/copy.toml, tests/*, meta/todos/*
The server records and returns last_reconciled, the client passes metadata into the findings drawer, and tests and copy are updated for schema version 4 and reconciliation messaging.
Command palette hints and accessibility
src/ui_assets/command-palette.js, src/ui_assets/style.css, docs/design-system/copy.toml
Palette results now expose combobox/listbox ARIA state and display contextual Enter hints with matching styling and copy.

Generated metadata and cleanup

Layer / File(s) Summary
Regenerated symbol metadata
map.json
UI module file listings and recorded symbol source ranges were regenerated.
Non-functional UI cleanup
src/ui/server.rs, src/ui_assets/canvas-chrome.js, src/ui_assets/graph-canvas.js, src/ui_assets/utils.js
Existing comments, formatting, conditional rendering, color calculation, spacing, and report URL expression formatting were adjusted without behavior changes.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Poem

I’m a bunny with timestamps bright,
Guiding empty findings into light.
Enter hops where results gleam,
Report rows join the helpdesk dream.
Fresh scans, clear hints—what a neat WebUI scene!


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Docstring Coverage ❌ Error Docstring coverage is 38.46% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main WebUI change: turning empty findings and palette results into guidance.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the WebUI guidance, schema, accessibility, and formatting updates.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch webui-guidance-deadends

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
map.json (1)

4044-4121: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Remove duplicated symbols from the generated metadata.

The symbols for cairn.root are duplicated 7 times in total in this array (this block is a duplicate of the one starting at line 3746). This duplication also occurs in other modules with multiple entries in their paths array, such as cairn.lsp (duplicated 2 times) and cairn.mcp (duplicated 2 times).

This indicates a bug in the metadata generator, likely appending the module's symbols once for each path in the module's paths array instead of deduplicating them. Please fix the underlying generator and regenerate map.json to ensure data integrity.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@map.json` around lines 4044 - 4121, Fix the metadata generator so each
module’s symbols are emitted once regardless of how many entries appear in its
paths array, deduplicating symbols before appending them to the generated
output. Verify this for modules such as cairn.root, cairn.lsp, and cairn.mcp,
then regenerate map.json with no duplicate symbol blocks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/ui_assets/command-palette.js`:
- Around line 151-158: Update the command-palette hint template around shown and
activeIdx so it renders exactly one Enter hint: use the report-specific copy
when the active item’s __action is "report-issue", otherwise use the default
Enter copy. Remove the separate second hint row while preserving the existing
visibility condition.

In `@src/ui_assets/style.css`:
- Line 2464: Replace the hardcoded padding value near the style rule containing
`padding: 1px 6px` with the appropriate spacing variables from `tokens.css`,
using the closest matching tokens for both vertical and horizontal spacing while
preserving the current layout intent.

---

Outside diff comments:
In `@map.json`:
- Around line 4044-4121: Fix the metadata generator so each module’s symbols are
emitted once regardless of how many entries appear in its paths array,
deduplicating symbols before appending them to the generated output. Verify this
for modules such as cairn.root, cairn.lsp, and cairn.mcp, then regenerate
map.json with no duplicate symbol blocks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 2203c0df-4bce-4022-8703-f527d4a9fd37

📥 Commits

Reviewing files that changed from the base of the PR and between d1e7caa and 2033005.

⛔ Files ignored due to path filters (14)
  • tests/snapshots/wire_format_snapshots__api_blueprint.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_dependents_app_api.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_depends_app_api.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_graph.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_lint.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_meta.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_node_app_api.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_node_app_api_contract.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_node_app_api_decisions.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_node_app_api_rationale.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_node_app_api_research.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_node_app_api_sources.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_node_app_api_todos.snap is excluded by !**/*.snap
  • tests/snapshots/wire_format_snapshots__api_status.snap is excluded by !**/*.snap
📒 Files selected for processing (15)
  • docs/design-system/copy.toml
  • map.json
  • meta/todos/todo.webui-guidance-deadends.md
  • src/ui/mod.rs
  • src/ui/server.rs
  • src/ui/server/meta.rs
  • src/ui_assets/app.js
  • src/ui_assets/canvas-chrome.js
  • src/ui_assets/command-palette.js
  • src/ui_assets/findings-panel.js
  • src/ui_assets/graph-canvas.js
  • src/ui_assets/style.css
  • src/ui_assets/utils.js
  • tests/graph_explorer.rs
  • tests/wire_format_snapshots.rs

Comment on lines +151 to +158
${
q !== "" && shown.length > 0
? html`<div class="cmd-palette-hint">
<span class="hint-row"><kbd>Enter</kbd> ${copy("webui.palette-hints.enter")}</span>
${shown[activeIdx]?.__action === "report-issue" ? html`<span class="hint-row"><kbd>Enter</kbd> ${copy("webui.palette-hints.report")}</span>` : null}
</div>`
: null
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Make the Enter keyboard hints mutually exclusive.

Currently, when the active item is the report-issue action, both the default Enter hint and the report-specific Enter hint are rendered simultaneously and stack vertically. Since pressing Enter performs exactly one action for the focused item, displaying two different instructions for the same key is confusing.

Conditionally render a single hint string based on the active item instead of rendering a second row.

💡 Proposed fix
-        ${
-          q !== "" && shown.length > 0
-            ? html`<div class="cmd-palette-hint">
-                <span class="hint-row"><kbd>Enter</kbd> ${copy("webui.palette-hints.enter")}</span>
-                ${shown[activeIdx]?.__action === "report-issue" ? html`<span class="hint-row"><kbd>Enter</kbd> ${copy("webui.palette-hints.report")}</span>` : null}
-              </div>`
-            : null
-        }
+        ${
+          q !== "" && shown.length > 0
+            ? html`<div class="cmd-palette-hint">
+                <span class="hint-row">
+                  <kbd>Enter</kbd> 
+                  ${shown[activeIdx]?.__action === "report-issue" ? copy("webui.palette-hints.report") : copy("webui.palette-hints.enter")}
+                </span>
+              </div>`
+            : null
+        }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
${
q !== "" && shown.length > 0
? html`<div class="cmd-palette-hint">
<span class="hint-row"><kbd>Enter</kbd> ${copy("webui.palette-hints.enter")}</span>
${shown[activeIdx]?.__action === "report-issue" ? html`<span class="hint-row"><kbd>Enter</kbd> ${copy("webui.palette-hints.report")}</span>` : null}
</div>`
: null
}
${
q !== "" && shown.length > 0
? html`<div class="cmd-palette-hint">
<span class="hint-row">
<kbd>Enter</kbd>
${shown[activeIdx]?.__action === "report-issue" ? copy("webui.palette-hints.report") : copy("webui.palette-hints.enter")}
</span>
</div>`
: null
}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ui_assets/command-palette.js` around lines 151 - 158, Update the
command-palette hint template around shown and activeIdx so it renders exactly
one Enter hint: use the report-specific copy when the active item’s __action is
"report-issue", otherwise use the default Enter copy. Remove the separate second
hint row while preserving the existing visibility condition.

Comment thread src/ui_assets/style.css
background: var(--stone-3);
border: 1px solid var(--seam-thin);
border-radius: var(--r-edge);
padding: 1px 6px;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Use design system tokens for spacing.

As per coding guidelines, UI work must derive visual values from tokens.css rather than hardcoding them. This principle applies to spacing as well. Consider replacing the hardcoded pixel padding (1px 6px) with the appropriate spacing tokens (e.g., var(--s-0) or var(--s-1)) to ensure consistency with the design system.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/ui_assets/style.css` at line 2464, Replace the hardcoded padding value
near the style rule containing `padding: 1px 6px` with the appropriate spacing
variables from `tokens.css`, using the closest matching tokens for both vertical
and horizontal spacing while preserving the current layout intent.

Source: Coding guidelines

@George-RD
George-RD merged commit 6487d29 into main Jul 17, 2026
17 checks passed
@github-actions github-actions Bot mentioned this pull request Aug 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant