Skip to content

ENG-2272 Show candidate nodes as results in advanced node search - #1489

Open
trangdoan982 wants to merge 4 commits into
mainfrom
eng-2272-show-candidate-nodes-as-results-in-advanced-node-search
Open

trangdoan982 wants to merge 4 commits into
mainfrom
eng-2272-show-candidate-nodes-as-results-in-advanced-node-search

Conversation

@trangdoan982

@trangdoan982 trangdoan982 commented Sep 27, 2026 •

Copy link
Copy Markdown
Member

https://entire.io/gh/DiscourseGraphs/discourse-graph/trails/29

Reviewer brief

  • Result: With "Show candidate nodes" on, lines anywhere in the vault tagged with a node type's tag (e.g. #clm-candidate) appear in Advanced Node Search next to real nodes. They're filtered by node type, sorted with nodes, and open at the tagged line.
  • Review focus:
    • getCandidateNodes in apps/obsidian/src/services/QueryEngine.ts makes one pass over the metadata cache's tag index using a tag → node type map. It only reads files that had a match, and reads them in parallel.
    • Ranking: nodes and candidates share one fuzzy score. rankDiscourseNodesByTitle puts nodes first on equal scores or titles.
    • Row layout in apps/obsidian/src/components/NodeSearchModal.tsx: the badge sits in a fixed-width column so every title starts at the same x. A candidate uses its node type's badge outlined, a node uses it filled.
  • Risk or follow-up:
    • Size: 591 changed lines, of which 278 are tests in QueryEngine.test.ts. The implementation is 313 lines.
    • Datacore isn't used here, which goes against the "Datacore first" rule in apps/obsidian/AGENTS.md. Its tag index has no per-line position or text for paragraphs, quotes or headings, only for list items. The metadata cache has both for every line shape.
    • If two node types share a tag, only the last one gets candidates. Settings should block duplicate tags instead; that's tracked in ENG-2327.
    • The editor tag highlighter matches nodeType.tag exactly, while candidates match tags case-insensitively. I haven't checked whether CodeMirror lowercases tag names.

The diagram shows where candidates join the existing search pipeline.

flowchart LR
  T["NodeDisplayOptionsMenu.tsx<br/>Show candidate nodes toggle"] --> S["QueryEngine.getCandidateNodes<br/>tags → map lookup → cachedRead hit files<br/>title = titleFromTaggedLine(line)"]
  N["QueryEngine.getDiscourseNodeCandidates"] --> R
  S --> R["rankDiscourseNodesByTitle<br/>type filter → fuzzy score → nodes win ties"]
  R --> L["NodeSearchModal ResultList<br/>fixed badge column, filled vs outlined"]
  L --> O["openFileInNewTab(file, { line })"]
Loading

Verification

Live Obsidian, driven over CDP in a test vault with one claim node and three tagged lines:

Scenario Input Expected Actual Pass
Toggle shows candidates Query zephyr, toggle Show candidate nodes Off: no candidates. On: 3 tagged lines, each titled by its own line As expected; an untagged line in the same paragraph is excluded Yes
Rows are flush Toggle on, query zephyr, measure rows One title x and one badge x/width on every row; candidates outlined, nodes filled title x=495, badge x=443 w=44 on all 6 rows; 3 outlined, rest filled Yes
Type filter Toggle on, uncheck Evidence Evidence candidate hidden; claim candidates and node stay As expected Yes
Open at line Toggle on, query cool the coast, Enter Note opens in a new tab, cursor on the tagged line Cursor on line 2 Yes
Insert link Cursor in a note, candidate active, Cmd+Enter Insert action disabled, note unchanged; enabled again on a node row As expected Yes
Scenario Screenshot
Toggle shows candidates Toggle shows candidates
Rows are flush; candidates outlined Rows are flush; candidates outlined
Type filter applies to candidates Type filter applies to candidates
Enter opens the tagged line Enter opens the tagged line
Insert link disabled for candidates Insert link disabled for candidates

Tests: 17 tests in apps/obsidian/src/services/__tests__/QueryEngine.test.ts cover the candidate scan (line shapes, tag case, repeated and multiple tags, empty titles, unreadable files, which files get read) and mixed ranking (type filter, shared score scale, ties). Rerun with pnpm -C apps/obsidian test:unit. pnpm ci:validate passes.

Not verified: scan time on a large vault. I only measured it on the dev vault.

Loom video

https://www.loom.com/share/b4bae23957c642f4a79b07062f2eda49

Scope check

  • Ran $scope-check against the ENG ticket and final diff.
  • Scope beyond Done When:
    • Insert link is disabled for candidate results. A candidate is a line, not a node yet, so a link would point at the whole containing note. The requester agreed.
    • The title helpers moved from tagNodeHandler.ts to apps/obsidian/src/utils/taggedLine.ts, so QueryEngine doesn't import CodeMirror and modal code. titleFromTaggedLine now also strips a leading # or > . That also changes the initial title when creating a node from a tagged H1 or blockquote line. Levels ## and deeper were already stripped. The requester agreed.
    • The toggle label is "Show candidate nodes", following Done When instead of the Solution's "Show candidate content".

Standards check

  • Ran $dg-pr-adherence-check against the final diff and PR metadata.

Resolved the findings: openFileInNewTab/openFileInNewLeaf now take a named { line } option, activateOnKey moved to apps/obsidian/src/utils/keyboardHints.ts, return types are explicit, and the candidate badge's text colour comes from a class. The Loom is still outstanding.

Local delegated full review

  • Ran a comprehensive review of the entire final diff in a subagent with a fresh context. Use $dg-delegated-full-review when no other full-review workflow is available.

No findings.

🤖 Generated with Claude Code


Devin Review

@vercel

vercel Bot commented Sep 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
discourse-graph Ready Ready Preview Sep 28, 2026 3:10pm UTC

Request Review

@supabase

supabase Bot commented Sep 27, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project zytfjzqyijgagqxrzbmz because there are no changes detected in packages/database/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@linear-code

linear-code Bot commented Sep 27, 2026

Copy link
Copy Markdown

ENG-2272

@devin-ai-integration devin-ai-integration Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Devin Review found 1 potential issue.

1 flag not posted on this PR by your GitHub settings — view it in Devin Review. (Configure)

Devin Review

Comment thread apps/obsidian/src/services/QueryEngine.ts
trangdoan982 and others added 4 commits September 28, 2026 08:08
Add a "Show candidate nodes" toggle to a new Display options menu. When on,
lines tagged with a node type's tag are collected in one pass over the
metadata cache and ranked alongside nodes, with nodes winning ties.

Candidate rows use the node type's badge outlined instead of filled, in a
fixed-width column so every title lines up, and open at the tagged line.
Insert link is disabled for candidates since they are not nodes yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M385GX3NP1QPTJ9K30QK20TG
Pass the open line as a named option, move activateOnKey to
utils/keyboardHints, add explicit return types, and style the candidate
pill text with a class instead of an inline style.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M3J2QDY0GGKKK7WM2A69YA6X
Node type settings don't enforce unique tags, so the tag lookup now maps
each tag to all matching types instead of keeping only the last one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M3J3TS9ZG3TPS0TXYVGAGKY0
Duplicate node tags should be blocked in node type settings rather than
handled in candidate search; tracked in ENG-2327.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@trangdoan982
trangdoan982 force-pushed the eng-2272-show-candidate-nodes-as-results-in-advanced-node-search branch from db37e78 to ed66545 Compare September 28, 2026 15:08

This branch was successfully deployed

1 active deployment
Preview — ed66545e Deployed Sep 28, 2026 by vercel[bot]
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.

2 participants