Enhance node source handling and improve canvas search focus - #137
Merged
cxxxxxn (cxxxxxn) merged 6 commits intoAug 26, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR improves Canvas and Preview Workspace UX around “missing node files”, canvas-wide search keyboard handling, and chat attachment sourcing, while updating architecture docs and adding targeted tests to lock in the new behaviors.
Changes:
- Refactors missing-file detection into a shared
missingFile.tsutility and surfaces missing-file status in the Canvas Layer Panel (row indicator + summary-driven missing-only filter). - Refines canvas search keyboard event ownership to avoid stealing Enter/Arrow from editors/controls outside the search surface.
- Adds “adjacent node as source” staging in split Preview Workspace chat, plus prompt rendering support/tests for source-only node-reference attachments.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| docs/architecture/web-architecture.md | Documents updated Canvas search keyboard ownership + layer-panel missing-node behaviors. |
| docs/architecture/preview-workspace.md | Documents adjacent-node-as-source behavior for chat beside nodes. |
| apps/web/src/i18n/resources/zh-CN/common.json | Adds new layer-panel and chat strings (missing nodes + adjacent source). |
| apps/web/src/i18n/resources/en/common.json | Adds new layer-panel and chat strings (missing nodes + adjacent source). |
| apps/web/src/hooks/useBuiltinThreadSettings.ts | Avoids stale settings reload during “first message sent” transition. |
| apps/web/src/hooks/useBuiltinThreadSettings.test.tsx | Adds coverage for first-message transition and established-thread mount behavior. |
| apps/web/src/components/Panels/PreviewWorkspace/PreviewWorkspace.tsx | Computes and passes adjacent-node target when split. |
| apps/web/src/components/Panels/PreviewWorkspace/PreviewWorkspace.test.tsx | Tests adjacent-node source candidate behavior in split workspace. |
| apps/web/src/components/Panels/PreviewWorkspace/PreviewRenderer.tsx | Derives adjacentNodeSourceId for chat based on adjacent node target. |
| apps/web/src/components/Panels/PreviewWorkspace/PreviewGroup.tsx | Threads adjacent-node target into active renderer only. |
| apps/web/src/components/Panels/ChatPanel/index.tsx | Plumbs adjacentNodeSourceId through ChatPanel into ChatInput. |
| apps/web/src/components/Panels/ChatPanel/ChatInput.tsx | Adds adjacent-node “source candidate” tile + deduping; extracts text preview tile UI. |
| apps/web/src/components/Panels/ChatPanel/ChatInput.test.tsx | Tests explicit confirmation and dedupe behavior for adjacent-node source staging. |
| apps/web/src/components/Panels/CanvasLayerPanel/TreeRowItem.tsx | Adds missing-file warning icon + tooltip per affected row. |
| apps/web/src/components/Panels/CanvasLayerPanel/MissingNodesSummary.tsx | New missing-nodes count + toggle/clear UI. |
| apps/web/src/components/Panels/CanvasLayerPanel/MissingNodesSummary.test.tsx | Tests summary toggle, clear, and disabled behavior. |
| apps/web/src/components/Panels/CanvasLayerPanel/missingNodeFilter.ts | New helper to intersect type chips with missing-only filtering. |
| apps/web/src/components/Panels/CanvasLayerPanel/missingNodeFilter.test.ts | Tests missing-only + chip intersection behavior. |
| apps/web/src/components/Panels/CanvasLayerPanel/index.tsx | Adds missing-node counting/state and integrates MissingNodesSummary + filtering. |
| apps/web/src/components/Panels/CanvasLayerPanel/CanvasSearchResults.tsx | Routes Enter/Arrow capture behavior through shouldCanvasSearchOwnKeyboard. |
| apps/web/src/components/Panels/CanvasLayerPanel/CanvasSearchResults.test.ts | Tests keyboard ownership routing logic. |
| apps/web/src/components/Panels/CanvasLayerPanel/canvasSearchKeyboard.ts | New helper deciding when search should own keyboard events. |
| apps/web/src/components/Panels/CanvasLayerPanel/CanvasLayerTree.tsx | Computes missing-file tooltip labels per row via getMissingFileKind. |
| apps/web/src/components/Nodes/MissingFileBanner.tsx | Re-exports missing-file utilities from new module. |
| apps/web/src/components/Nodes/missingFile.ts | New shared missing-file kind + predicate utilities. |
| apps/server/src/modules/agent/conversation/prompt/build-prompt.test.ts | Adds test for rendering source-only text attachment as node reference. |
| apps/server/src/modules/agent/conversation/prompt/attachments.ts | Renders source-only text attachments with origin ids as <attachment type="node" ... />. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+11
to
+17
| export function getMissingFileKind( | ||
| data: Record<string, unknown> | MissingFileData, | ||
| ): MissingFileKind | null { | ||
| if (data.contentMissing) return 'sidecar'; | ||
| if (data.artifactMissing) return 'artifact'; | ||
| return null; | ||
| } |
Comment on lines
+4
to
+27
| import { act } from 'react'; | ||
| import { createRoot, type Root } from 'react-dom/client'; | ||
| import { afterEach, describe, expect, it, vi } from 'vitest'; | ||
|
|
||
| import { MissingNodesSummary } from './MissingNodesSummary'; | ||
|
|
||
| ( | ||
| globalThis as { IS_REACT_ACT_ENVIRONMENT?: boolean } | ||
| ).IS_REACT_ACT_ENVIRONMENT = true; | ||
|
|
||
| describe('<MissingNodesSummary>', () => { | ||
| let root: Root | undefined; | ||
| let container: HTMLDivElement | undefined; | ||
|
|
||
| afterEach(() => { | ||
| act(() => root?.unmount()); | ||
| container?.remove(); | ||
| root = undefined; | ||
| container = undefined; | ||
| }); | ||
|
|
||
| const renderSummary = ( | ||
| props: Partial<React.ComponentProps<typeof MissingNodesSummary>> = {}, | ||
| ) => { |
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.
This pull request introduces several improvements to how missing files and nodes are detected, displayed, and handled in the Canvas Layer Panel, as well as refactoring and testing enhancements for keyboard navigation and missing node summaries. The main themes are: improved missing file detection and display, enhanced keyboard handling for canvas search, and new tests for critical UI components.
Missing file and node handling improvements:
missingFile.tsmodule, withgetMissingFileKindandhasMissingFileutilities, and updated all relevant imports and usages. [1] [2] [3]MissingNodesSummarycomponent to summarize and filter missing nodes, with associated tests for toggling, clearing, and disabling the filter. [1] [2]Keyboard handling and accessibility:
shouldCanvasSearchOwnKeyboardutility and integrated it into the Canvas Search Results component to ensure keyboard navigation is correctly routed between search, editors, and other controls. [1] [2] [3] [4]Attachment rendering and testing: