App.tsx was 702 lines and the highest-churn file (102 commits/month). Extract three hooks to reduce it to 537 lines and distribute future changes across focused modules: - useConflictFlow: conflict resolution orchestration - useAppSave: save/flush/rename orchestration - useVaultBridge: agent/MCP file operation handlers All files score 10.0 on CodeScene. 2226 tests pass. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
57 lines
2.1 KiB
TypeScript
57 lines
2.1 KiB
TypeScript
import { useCallback } from 'react'
|
|
import type { VaultEntry } from '../types'
|
|
|
|
interface VaultBridgeDeps {
|
|
entriesByPath: Map<string, VaultEntry>
|
|
resolvedPath: string
|
|
reloadVault: () => Promise<unknown>
|
|
onSelectNote: (entry: VaultEntry) => void
|
|
activeTabPath: string | null
|
|
}
|
|
|
|
function findEntry(entriesByPath: Map<string, VaultEntry>, resolvedPath: string, path: string): VaultEntry | undefined {
|
|
return entriesByPath.get(path) ?? entriesByPath.get(`${resolvedPath}/${path}`)
|
|
}
|
|
|
|
function findInFresh(entries: unknown, resolvedPath: string, path: string): VaultEntry | undefined {
|
|
return (entries as VaultEntry[]).find(e => e.path === path || e.path === `${resolvedPath}/${path}`)
|
|
}
|
|
|
|
export function useVaultBridge({
|
|
entriesByPath, resolvedPath, reloadVault, onSelectNote, activeTabPath,
|
|
}: VaultBridgeDeps) {
|
|
const reloadAndOpen = useCallback((path: string) => {
|
|
reloadVault().then(fresh => {
|
|
const entry = findInFresh(fresh, resolvedPath, path)
|
|
if (entry) onSelectNote(entry)
|
|
})
|
|
}, [reloadVault, onSelectNote, resolvedPath])
|
|
|
|
const openNoteByPath = useCallback((path: string) => {
|
|
const entry = findEntry(entriesByPath, resolvedPath, path)
|
|
if (entry) onSelectNote(entry)
|
|
else reloadAndOpen(path)
|
|
}, [entriesByPath, resolvedPath, onSelectNote, reloadAndOpen])
|
|
|
|
const handlePulseOpenNote = useCallback((relativePath: string) => {
|
|
const entry = findEntry(entriesByPath, resolvedPath, `${resolvedPath}/${relativePath}`)
|
|
?? entriesByPath.get(relativePath)
|
|
if (entry) onSelectNote(entry)
|
|
}, [entriesByPath, resolvedPath, onSelectNote])
|
|
|
|
const handleAgentFileModified = useCallback((relativePath: string) => {
|
|
const fullPath = `${resolvedPath}/${relativePath}`
|
|
if (activeTabPath === relativePath || activeTabPath === fullPath) reloadVault()
|
|
}, [reloadVault, activeTabPath, resolvedPath])
|
|
|
|
const handleAgentVaultChanged = useCallback(() => { reloadVault() }, [reloadVault])
|
|
|
|
return {
|
|
openNoteByPath,
|
|
handlePulseOpenNote,
|
|
handleAgentFileCreated: reloadAndOpen,
|
|
handleAgentFileModified,
|
|
handleAgentVaultChanged,
|
|
}
|
|
}
|