feat: node view redesign — single-scroll, no tabs

Ports the full node view redesign from ra-h. Replaces the 4-tab layout
(Desc/Notes/Edges/Source) with a single-scroll document view.

- New FocusPanel: frontmatter rows, collapse toggle, NodeSearchModal,
  TipTap SourceEditor, section headers with extending rules
- NodeSearchModal: new full-screen portal modal for creating connections
- SourceEditor: TipTap WYSIWYG editor (new file)
- SourceReader: removed header chrome, added onContentClick prop
- Source formatters: inherit font, 15px/1.7, no max-width centering
- DimensionTags: subtle dashed + button replaces green pill
- autoEmbedQueue: recover nodes stuck in 'chunking' state on startup
- edges: fix extra parameter in getNodeConnectionsSQLite

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
“BeeRad”
2026-03-20 17:03:06 +11:00
co-authored by Claude Sonnet 4.6
parent 0d2c499b70
commit 6677b1b64b
13 changed files with 2568 additions and 2923 deletions
-1
View File
@@ -522,7 +522,6 @@ export class EdgeService {
nodeId,
nodeId,
nodeId,
nodeId,
nodeId
]);
+9 -2
View File
@@ -18,10 +18,17 @@ export class AutoEmbedQueue {
private readonly cooldownMs = DEFAULT_COOLDOWN_MS;
async recoverStuckNodes(): Promise<void> {
const stuckNodes = await nodeService.getNodes({ chunkStatus: 'not_chunked', limit: 1000 });
for (const node of stuckNodes) {
const notChunked = await nodeService.getNodes({ chunkStatus: 'not_chunked', limit: 1000 });
for (const node of notChunked) {
this.enqueue(node.id, { reason: 'startup_recovery' });
}
// Recover nodes stuck in 'chunking' state — these were interrupted mid-process
// and will never complete without intervention since executeTask skips them otherwise
const stuckChunking = await nodeService.getNodes({ chunkStatus: 'chunking', limit: 1000 });
for (const node of stuckChunking) {
this.enqueue(node.id, { force: true, reason: 'stuck_chunking_recovery' });
}
}
enqueue(nodeId: number, task: Omit<AutoEmbedTask, 'nodeId'> = {}): boolean {