@tutti-os/workspace-file-reference 0.0.31 → 0.0.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tutti-os/workspace-file-reference",
3
- "version": "0.0.31",
3
+ "version": "0.0.33",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -36,10 +36,10 @@
36
36
  "directory": "packages/workspace/file-reference"
37
37
  },
38
38
  "dependencies": {
39
- "@tutti-os/ui-react-hooks": "0.0.31",
40
- "@tutti-os/ui-system": "0.0.31",
41
- "@tutti-os/workspace-file-manager": "0.0.31",
42
- "@tutti-os/workspace-file-preview": "0.0.31",
39
+ "@tutti-os/ui-react-hooks": "0.0.33",
40
+ "@tutti-os/ui-system": "0.0.33",
41
+ "@tutti-os/workspace-file-manager": "0.0.33",
42
+ "@tutti-os/workspace-file-preview": "0.0.33",
43
43
  "valtio": "^2.3.2"
44
44
  },
45
45
  "devDependencies": {
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/react/internal/reference/WorkspaceFileReferencePickerState.ts","../src/react/internal/reference/useWorkspaceFileReferencePickerView.ts","../src/react/internal/reference/WorkspaceFileReferencePickerController.ts","../src/react/internal/reference/referenceSourcePickerController.ts"],"sourcesContent":["import type {\n WorkspaceFileReference,\n WorkspaceFileReferencePrefetchReason,\n WorkspaceFileReferencePrefetchState,\n WorkspaceFileReferenceTreeSnapshot\n} from \"../../../contracts/index.ts\";\n\nexport const workspaceFileReferenceDefaultExpandedDepth = 4;\n\nexport interface WorkspaceFileReferenceDirectoryState {\n displayPath: string;\n entries: WorkspaceFileReference[];\n loaded: boolean;\n loading: boolean;\n prefetchReason?: WorkspaceFileReferencePrefetchReason | null;\n prefetchState?: WorkspaceFileReferencePrefetchState | null;\n}\n\nexport function normalizeDirectoryPath(path: string): string {\n if (!path || path === \"/\") {\n return \"/\";\n }\n return path.replace(/\\/+$/, \"\") || \"/\";\n}\n\nexport function collectVisibleTreeEntries(\n entries: readonly WorkspaceFileReference[],\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>,\n expandedFolderPaths: Record<string, boolean>\n): WorkspaceFileReference[] {\n const collected: WorkspaceFileReference[] = [];\n\n for (const entry of entries) {\n collected.push(entry);\n if (entry.kind !== \"folder\") {\n continue;\n }\n const folderKey = normalizeDirectoryPath(entry.path);\n if (!expandedFolderPaths[folderKey]) {\n continue;\n }\n const childEntries = directoryStateByPath[folderKey]?.entries ?? [];\n if (childEntries.length === 0) {\n continue;\n }\n collected.push(\n ...collectVisibleTreeEntries(\n childEntries,\n directoryStateByPath,\n expandedFolderPaths\n )\n );\n }\n\n return collected;\n}\n\nexport function mergeExpandedFolderPaths(\n current: Record<string, boolean>,\n prefetched: Record<string, boolean>\n): Record<string, boolean> {\n return {\n ...prefetched,\n ...current\n };\n}\n\nexport function mergePrefetchedDirectoryState(\n current: Record<string, WorkspaceFileReferenceDirectoryState>,\n prefetched: Record<string, WorkspaceFileReferenceDirectoryState>\n): Record<string, WorkspaceFileReferenceDirectoryState> {\n return {\n ...current,\n ...prefetched\n };\n}\n\nexport function createWorkspaceFileReferenceDirectoryStateFromSnapshot(\n snapshot: WorkspaceFileReferenceTreeSnapshot\n): Record<string, WorkspaceFileReferenceDirectoryState> {\n const stateByPath: Record<string, WorkspaceFileReferenceDirectoryState> = {};\n addReferenceDirectoryStateFromSnapshot(stateByPath, snapshot.directory);\n return stateByPath;\n}\n\nfunction addReferenceDirectoryStateFromSnapshot(\n stateByPath: Record<string, WorkspaceFileReferenceDirectoryState>,\n directory: WorkspaceFileReferenceTreeSnapshot[\"directory\"]\n) {\n const normalizedPath = normalizeDirectoryPath(directory.directoryPath);\n stateByPath[normalizedPath] = {\n displayPath: directory.directoryPath,\n entries: directory.entries.map((entry) => ({\n displayName: entry.displayName,\n kind: entry.kind,\n path: entry.path\n })),\n loaded: true,\n loading: false,\n prefetchReason: directory.prefetchReason,\n prefetchState: directory.prefetchState\n };\n\n for (const entry of directory.entries) {\n if (entry.kind !== \"folder\") {\n continue;\n }\n const folderKey = normalizeDirectoryPath(entry.path);\n if (entry.prefetchedDirectory) {\n addReferenceDirectoryStateFromSnapshot(\n stateByPath,\n entry.prefetchedDirectory\n );\n continue;\n }\n if (entry.prefetchState) {\n stateByPath[folderKey] = {\n displayPath: entry.path,\n entries: [],\n loaded: false,\n loading: false,\n prefetchReason: entry.prefetchReason,\n prefetchState: entry.prefetchState\n };\n }\n }\n}\n\nexport async function prefetchReferenceTree(input: {\n listDirectory: (path: string) => Promise<{\n displayPath: string;\n entries: WorkspaceFileReference[];\n normalizedPath: string;\n } | null>;\n maxDepth: number;\n path: string;\n depth?: number;\n}): Promise<{\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n expandedFolderPaths: Record<string, boolean>;\n}> {\n const { depth = 1, listDirectory, maxDepth, path } = input;\n const listing = await listDirectory(path);\n if (!listing) {\n return {\n directoryStateByPath: {},\n expandedFolderPaths: {}\n };\n }\n\n const directoryStateByPath: Record<\n string,\n WorkspaceFileReferenceDirectoryState\n > = {\n [listing.normalizedPath]: {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n }\n };\n const expandedFolderPaths: Record<string, boolean> = {\n [listing.normalizedPath]: true\n };\n\n if (depth >= maxDepth) {\n return {\n directoryStateByPath,\n expandedFolderPaths\n };\n }\n\n for (const entry of listing.entries) {\n if (entry.kind !== \"folder\") {\n continue;\n }\n try {\n const childTree = await prefetchReferenceTree({\n depth: depth + 1,\n listDirectory,\n maxDepth,\n path: entry.path\n });\n Object.assign(directoryStateByPath, childTree.directoryStateByPath);\n Object.assign(expandedFolderPaths, childTree.expandedFolderPaths);\n } catch {\n // Skip unreadable branches so one protected folder does not blank the whole tree.\n }\n }\n\n return {\n directoryStateByPath,\n expandedFolderPaths\n };\n}\n","import {\n useCallback,\n useEffect,\n useEffectEvent,\n useMemo,\n useState\n} from \"react\";\nimport { useSnapshot } from \"valtio\";\nimport type {\n WorkspaceFileReferenceAdapter,\n WorkspaceFileReference\n} from \"../../../contracts/index.ts\";\nimport { uniqueWorkspaceFileReferences } from \"../../../core/index.ts\";\nimport {\n collectVisibleTreeEntries,\n normalizeDirectoryPath\n} from \"./WorkspaceFileReferencePickerState.ts\";\nimport {\n createWorkspaceFileReferencePickerController,\n type WorkspaceFileReferencePreviewState\n} from \"./WorkspaceFileReferencePickerController.ts\";\n\nexport type { WorkspaceFileReferencePreviewState };\n\nexport interface UseWorkspaceFileReferencePickerViewInput {\n fileAdapter?: WorkspaceFileReferenceAdapter;\n initialPath?: string | null;\n onClose: () => void;\n onConfirm: (refs: WorkspaceFileReference[]) => void;\n open: boolean;\n workspaceId: string;\n}\n\nexport function useWorkspaceFileReferencePickerView({\n fileAdapter,\n initialPath,\n onClose,\n onConfirm,\n open,\n workspaceId\n}: UseWorkspaceFileReferencePickerViewInput) {\n const readPickerSnapshot = useSnapshot as <T extends object>(store: T) => T;\n const trimmedInitialPath = initialPath?.trim() ?? \"\";\n const initialDirectoryPath = trimmedInitialPath\n ? normalizeDirectoryPath(trimmedInitialPath)\n : null;\n const [focusedPath, setFocusedPath] = useState<string | null>(null);\n const [selectedRefs, setSelectedRefs] = useState<WorkspaceFileReference[]>(\n []\n );\n\n const pickerController = useMemo(\n () =>\n createWorkspaceFileReferencePickerController({\n fileAdapter,\n workspaceId\n }),\n [fileAdapter, workspaceId]\n );\n const pickerSnapshot = readPickerSnapshot(pickerController.store);\n const {\n browseRootPath,\n directoryStateByPath,\n expandedFolderPaths,\n isBrowseLoading,\n isSearchLoading,\n mode,\n previewState,\n searchEntries,\n searchQuery\n } = pickerSnapshot;\n const isLoading = mode === \"search\" ? isSearchLoading : isBrowseLoading;\n\n const finalizeRequestedReferences = useEffectEvent(\n (refs: WorkspaceFileReference[]) => {\n onConfirm(uniqueWorkspaceFileReferences(refs));\n onClose();\n }\n );\n\n const setSearchQuery = useCallback(\n (query: string) => {\n pickerController.setSearchQuery(query);\n },\n [pickerController]\n );\n\n useEffect(() => {\n if (!open) {\n return;\n }\n\n pickerController.reset();\n pickerController.open();\n setFocusedPath(null);\n setSelectedRefs([]);\n return () => {\n pickerController.close();\n };\n }, [initialDirectoryPath, open, pickerController]);\n\n useEffect(() => {\n if (!open || mode !== \"browse\") {\n return;\n }\n pickerController.loadBrowseRoot();\n }, [mode, open, pickerController]);\n\n useEffect(() => {\n if (!open || !fileAdapter || mode !== \"browse\") {\n return;\n }\n if (\n fileAdapter.listDirectory ||\n fileAdapter.loadReferenceTree ||\n !fileAdapter.requestReferences\n ) {\n return;\n }\n let canceled = false;\n void fileAdapter.requestReferences({ workspaceId }).then((refs) => {\n if (!canceled) {\n finalizeRequestedReferences(refs);\n }\n });\n return () => {\n canceled = true;\n };\n }, [fileAdapter, finalizeRequestedReferences, mode, open, workspaceId]);\n\n useEffect(() => {\n if (\n !open ||\n mode !== \"browse\" ||\n pickerSnapshot.initialPathRevealed ||\n !initialDirectoryPath ||\n !browseRootPath\n ) {\n return;\n }\n\n let canceled = false;\n const reveal = async () => {\n const focusedInitialPath =\n await pickerController.revealInitialPath(initialDirectoryPath);\n if (!canceled && focusedInitialPath) {\n setFocusedPath(focusedInitialPath);\n }\n };\n\n void reveal();\n return () => {\n canceled = true;\n };\n }, [\n browseRootPath,\n initialDirectoryPath,\n mode,\n open,\n pickerController,\n pickerSnapshot.initialPathRevealed\n ]);\n\n const browseRootEntries = useMemo(\n () =>\n browseRootPath\n ? (directoryStateByPath[normalizeDirectoryPath(browseRootPath)]\n ?.entries ?? [])\n : [],\n [browseRootPath, directoryStateByPath]\n );\n\n const visibleEntries = useMemo(\n () =>\n mode === \"search\"\n ? searchEntries\n : collectVisibleTreeEntries(\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths\n ),\n [\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths,\n mode,\n searchEntries\n ]\n );\n\n useEffect(() => {\n if (!open) {\n return;\n }\n setFocusedPath((current) => {\n if (current && visibleEntries.some((entry) => entry.path === current)) {\n return current;\n }\n return visibleEntries[0]?.path ?? null;\n });\n }, [open, visibleEntries]);\n\n const focusedEntry =\n visibleEntries.find((entry) => entry.path === focusedPath) ??\n selectedRefs.find((entry) => entry.path === focusedPath) ??\n null;\n\n useEffect(() => {\n pickerController.setPreviewReference(open ? focusedEntry : null);\n }, [focusedEntry, open, pickerController]);\n\n const toggleRef = (ref: WorkspaceFileReference) => {\n setSelectedRefs((current) => {\n const existing = current.some((item) => item.path === ref.path);\n return existing\n ? current.filter((item) => item.path !== ref.path)\n : uniqueWorkspaceFileReferences([...current, ref]);\n });\n };\n\n const toggleFolder = (entry: WorkspaceFileReference) => {\n pickerController.toggleFolder(entry);\n };\n\n return {\n browseRootEntries,\n directoryStateByPath,\n expandedFolderPaths,\n focusedEntry,\n focusedPath,\n isLoading,\n mode,\n previewState,\n searchQuery,\n selectedRefs,\n visibleEntries,\n setFocusedPath,\n setSearchQuery,\n toggleFolder,\n toggleRef\n };\n}\n","import { proxy } from \"valtio/vanilla\";\nimport {\n createWorkspaceFilePreviewLoadedState,\n resolveWorkspaceFilePreviewReadiness\n} from \"@tutti-os/workspace-file-preview\";\nimport type {\n WorkspaceFilePreviewActivationTarget,\n WorkspaceFilePreviewReadonlyReason\n} from \"@tutti-os/workspace-file-preview\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceAdapter,\n WorkspaceFileReferencePreview\n} from \"../../../contracts/index.ts\";\nimport { uniqueWorkspaceFileReferences } from \"../../../core/index.ts\";\nimport {\n createWorkspaceFileReferenceDirectoryStateFromSnapshot,\n normalizeDirectoryPath,\n type WorkspaceFileReferenceDirectoryState\n} from \"./WorkspaceFileReferencePickerState.ts\";\n\nexport type WorkspaceFileReferencePickerMode = \"browse\" | \"search\";\n\nexport type WorkspaceFileReferencePreviewState =\n | { status: \"directory\"; reference: WorkspaceFileReference }\n | { status: \"empty\" }\n | { status: \"error\"; reference: WorkspaceFileReference }\n | { status: \"html\"; content: string; reference: WorkspaceFileReference }\n | { status: \"image\"; objectUrl: string; reference: WorkspaceFileReference }\n | { status: \"loading\"; reference: WorkspaceFileReference }\n | { status: \"video\"; objectUrl: string; reference: WorkspaceFileReference }\n | {\n maxSizeBytes?: number;\n reason: WorkspaceFilePreviewReadonlyReason;\n reference: WorkspaceFileReference;\n status: \"readonly\";\n }\n | { status: \"text\"; content: string; reference: WorkspaceFileReference }\n | { status: \"unsupported\"; reference: WorkspaceFileReference }\n | { status: \"unavailable\"; reference: WorkspaceFileReference };\n\nexport interface WorkspaceFileReferencePickerControllerSnapshot {\n browseError: Error | null;\n browseRootPath: string | null;\n directoryStateByPath: Record<string, WorkspaceFileReferenceDirectoryState>;\n expandedFolderPaths: Record<string, boolean>;\n initialPathRevealed: boolean;\n isBrowseLoading: boolean;\n isSearchLoading: boolean;\n mode: WorkspaceFileReferencePickerMode;\n previewState: WorkspaceFileReferencePreviewState;\n searchEntries: WorkspaceFileReference[];\n searchError: Error | null;\n searchQuery: string;\n}\n\nexport interface CreateWorkspaceFileReferencePickerControllerInput {\n fileAdapter?: WorkspaceFileReferenceAdapter;\n searchDebounceMs?: number;\n workspaceId: string;\n}\n\nexport interface WorkspaceFileReferencePickerController {\n close(): void;\n getSnapshot(): WorkspaceFileReferencePickerControllerSnapshot;\n loadBrowseRoot(): void;\n open(): void;\n reset(): void;\n revealInitialPath(initialDirectoryPath: string): Promise<string | null>;\n setPreviewReference(reference: WorkspaceFileReference | null): void;\n setSearchQuery(query: string): void;\n readonly store: WorkspaceFileReferencePickerControllerSnapshot;\n toggleFolder(entry: WorkspaceFileReference): void;\n}\n\nconst defaultDirectoryPath = \"/\";\nconst defaultSearchDebounceMs = 180;\n\nexport function createWorkspaceFileReferencePickerController(\n input: CreateWorkspaceFileReferencePickerControllerInput\n): WorkspaceFileReferencePickerController {\n const searchDebounceMs = input.searchDebounceMs ?? defaultSearchDebounceMs;\n // 浏览取数按 key 隔离失效:全局单调 ticket(nextBrowseSeq,永不回退/复用)派发,\n // latestBrowseSeqByKey 记录每个目录(及 reveal 批量)的最新 ticket。取数 resolve 时凭\n // 自身 ticket 是否仍为该 key 的最新值判定是否落库 —— 不同目录的并发取数互不作废\n // (否则全局单计数会让后发取数把先发的另一目录取数结果静默丢弃、令其 loading 永不\n // 清除)。cancelCurrentBrowse 清空该表使全部在途浏览取数失效。\n let nextBrowseSeq = 0;\n const latestBrowseSeqByKey = new Map<string, number>();\n const stampBrowse = (seqKey: string): number => {\n const sequence = ++nextBrowseSeq;\n latestBrowseSeqByKey.set(seqKey, sequence);\n return sequence;\n };\n const isBrowseStale = (seqKey: string, sequence: number): boolean =>\n !retained || latestBrowseSeqByKey.get(seqKey) !== sequence;\n /** reveal 批量加载用的固定 seq key(不与单目录 key 冲突)。 */\n const REVEAL_SEQ_KEY = \"\u0000reveal\";\n let previewObjectUrl: string | null = null;\n let previewSequence = 0;\n let retained = false;\n let searchAbortController: AbortController | null = null;\n let searchSequence = 0;\n let searchTimer: ReturnType<typeof setTimeout> | null = null;\n let snapshot: WorkspaceFileReferencePickerControllerSnapshot = {\n browseError: null,\n browseRootPath: null,\n directoryStateByPath: {},\n expandedFolderPaths: {},\n initialPathRevealed: false,\n isBrowseLoading: false,\n isSearchLoading: false,\n mode: \"browse\",\n previewState: { status: \"empty\" },\n searchEntries: [],\n searchError: null,\n searchQuery: \"\"\n };\n const store = proxy(snapshot);\n\n const setSnapshot = (\n update:\n | Partial<WorkspaceFileReferencePickerControllerSnapshot>\n | ((\n current: WorkspaceFileReferencePickerControllerSnapshot\n ) => WorkspaceFileReferencePickerControllerSnapshot)\n ) => {\n const next =\n typeof update === \"function\"\n ? update(snapshot)\n : { ...snapshot, ...update };\n if (next === snapshot) {\n return;\n }\n snapshot = next;\n Object.assign(store, next);\n };\n\n const loadDirectoryListing = async (path?: string | null) => {\n if (!input.fileAdapter?.listDirectory) {\n return null;\n }\n const listing = await input.fileAdapter.listDirectory({\n path: path ?? undefined,\n workspaceId: input.workspaceId\n });\n const displayPath =\n listing.directoryPath || listing.rootPath || path || defaultDirectoryPath;\n const normalizedPath = normalizeDirectoryPath(displayPath);\n\n return {\n displayPath,\n entries: uniqueWorkspaceFileReferences(listing.entries),\n normalizedPath\n };\n };\n\n const resolveMode = (query: string) =>\n query.trim().length > 0 && input.fileAdapter?.searchReferences\n ? \"search\"\n : \"browse\";\n\n const clearSearchTimer = () => {\n if (searchTimer === null) {\n return;\n }\n clearTimeout(searchTimer);\n searchTimer = null;\n };\n\n const cancelCurrentSearch = () => {\n clearSearchTimer();\n searchSequence += 1;\n searchAbortController?.abort();\n searchAbortController = null;\n };\n\n const cancelCurrentBrowse = () => {\n // 清空 ticket 表:在途取数 resolve 时其 key 已无最新 ticket(get→undefined),被丢弃。\n latestBrowseSeqByKey.clear();\n };\n\n const cancelCurrentPreview = () => {\n previewSequence += 1;\n if (!previewObjectUrl) {\n return;\n }\n URL.revokeObjectURL(previewObjectUrl);\n previewObjectUrl = null;\n };\n\n const clearSearchResults = () => {\n cancelCurrentSearch();\n setSnapshot({\n isSearchLoading: false,\n searchEntries: [],\n searchError: null\n });\n };\n\n const runSearch = async (query: string) => {\n if (!retained || !input.fileAdapter?.searchReferences) {\n return;\n }\n\n const sequence = ++searchSequence;\n searchAbortController?.abort();\n const abortController = new AbortController();\n searchAbortController = abortController;\n setSnapshot({\n isSearchLoading: true,\n searchError: null\n });\n\n try {\n const refs = await input.fileAdapter.searchReferences({\n query,\n signal: abortController.signal,\n workspaceId: input.workspaceId\n });\n if (!retained || sequence !== searchSequence) {\n return;\n }\n setSnapshot({\n isSearchLoading: false,\n searchEntries: uniqueWorkspaceFileReferences(refs),\n searchError: null\n });\n } catch (error) {\n if (isAbortError(error) || sequence !== searchSequence || !retained) {\n return;\n }\n setSnapshot({\n isSearchLoading: false,\n searchEntries: [],\n searchError: normalizeControllerError(\n error,\n \"Workspace file reference search failed\"\n )\n });\n } finally {\n if (sequence === searchSequence) {\n searchAbortController = null;\n }\n }\n };\n\n const scheduleSearch = () => {\n clearSearchTimer();\n const query = snapshot.searchQuery.trim();\n if (!retained || !input.fileAdapter?.searchReferences || !query) {\n clearSearchResults();\n return;\n }\n\n if (searchDebounceMs <= 0) {\n void runSearch(query);\n return;\n }\n\n searchTimer = setTimeout(() => {\n searchTimer = null;\n void runSearch(query);\n }, searchDebounceMs);\n };\n\n const loadBrowseRoot = async () => {\n if (\n !retained ||\n snapshot.mode !== \"browse\" ||\n !(\n input.fileAdapter?.listDirectory || input.fileAdapter?.loadReferenceTree\n )\n ) {\n return;\n }\n const activeBrowseRootPath = snapshot.browseRootPath;\n const normalizedRoot = activeBrowseRootPath\n ? normalizeDirectoryPath(activeBrowseRootPath)\n : null;\n if (\n normalizedRoot &&\n snapshot.directoryStateByPath[normalizedRoot]?.loaded\n ) {\n return;\n }\n\n const seqKey = normalizedRoot ?? \"\";\n const sequence = stampBrowse(seqKey);\n setSnapshot({\n browseError: null,\n isBrowseLoading: true\n });\n\n try {\n if (input.fileAdapter.loadReferenceTree) {\n const treeSnapshot = await input.fileAdapter.loadReferenceTree({\n path: activeBrowseRootPath ?? undefined,\n prefetchBudgetMs: 500,\n prefetchDepth: 4,\n workspaceId: input.workspaceId\n });\n if (isBrowseStale(seqKey, sequence)) {\n return;\n }\n setSnapshot({\n browseRootPath: normalizeDirectoryPath(\n treeSnapshot.directory.directoryPath\n ),\n directoryStateByPath:\n createWorkspaceFileReferenceDirectoryStateFromSnapshot(\n treeSnapshot\n ),\n isBrowseLoading: false\n });\n return;\n }\n\n const listing = await loadDirectoryListing(activeBrowseRootPath);\n if (isBrowseStale(seqKey, sequence) || !listing) {\n return;\n }\n setSnapshot((current) => ({\n ...current,\n browseRootPath: listing.normalizedPath,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [listing.normalizedPath]: {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n }\n },\n isBrowseLoading: false\n }));\n } catch (error) {\n if (isBrowseStale(seqKey, sequence)) {\n return;\n }\n setSnapshot({\n browseError: normalizeControllerError(\n error,\n \"Workspace file reference browse failed\"\n ),\n isBrowseLoading: false\n });\n }\n };\n\n const loadFolderChildren = async (folder: WorkspaceFileReference) => {\n const folderKey = normalizeDirectoryPath(folder.path);\n if (\n !retained ||\n snapshot.directoryStateByPath[folderKey]?.loaded ||\n snapshot.directoryStateByPath[folderKey]?.loading\n ) {\n return;\n }\n\n const sequence = stampBrowse(folderKey);\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [folderKey]: {\n displayPath: folder.path,\n entries: current.directoryStateByPath[folderKey]?.entries ?? [],\n loaded: current.directoryStateByPath[folderKey]?.loaded ?? false,\n loading: true\n }\n }\n }));\n\n try {\n const listing = await loadDirectoryListing(folderKey);\n if (isBrowseStale(folderKey, sequence) || !listing) {\n return;\n }\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [folderKey]: {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n }\n }\n }));\n } catch {\n if (isBrowseStale(folderKey, sequence)) {\n return;\n }\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n [folderKey]: {\n displayPath:\n current.directoryStateByPath[folderKey]?.displayPath ??\n folder.path,\n entries: current.directoryStateByPath[folderKey]?.entries ?? [],\n loaded: current.directoryStateByPath[folderKey]?.loaded ?? false,\n loading: false\n }\n }\n }));\n }\n };\n\n const loadReferencePreview = async (\n reference: WorkspaceFileReference,\n target: WorkspaceFilePreviewActivationTarget,\n sequence: number\n ) => {\n try {\n const preview = await input.fileAdapter?.readReferencePreview?.({\n reference,\n workspaceId: input.workspaceId\n });\n if (!retained || sequence !== previewSequence) {\n return;\n }\n if (!preview) {\n setSnapshot({\n previewState: { reference, status: \"unsupported\" }\n });\n return;\n }\n\n const nextState = createReferencePreviewState(reference, target, preview);\n if (!retained || sequence !== previewSequence) {\n if (nextState.status === \"image\" || nextState.status === \"video\") {\n URL.revokeObjectURL(nextState.objectUrl);\n }\n return;\n }\n if (nextState.status === \"image\" || nextState.status === \"video\") {\n previewObjectUrl = nextState.objectUrl;\n }\n setSnapshot({\n previewState: nextState\n });\n } catch {\n if (!retained || sequence !== previewSequence) {\n return;\n }\n setSnapshot({\n previewState: { reference, status: \"error\" }\n });\n }\n };\n\n const setPreviewReference = (reference: WorkspaceFileReference | null) => {\n cancelCurrentPreview();\n if (!retained || !reference) {\n setSnapshot({\n previewState: { status: \"empty\" }\n });\n return;\n }\n\n const readiness = resolveWorkspaceFilePreviewReadiness(reference);\n if (readiness.status === \"directory\") {\n setSnapshot({\n previewState: { reference, status: \"directory\" }\n });\n return;\n }\n if (readiness.status === \"unsupported\") {\n setSnapshot({\n previewState: { reference, status: \"unsupported\" }\n });\n return;\n }\n if (readiness.status === \"readonly\") {\n setSnapshot({\n previewState: {\n maxSizeBytes: readiness.maxSizeBytes,\n reason: readiness.reason,\n reference,\n status: \"readonly\"\n }\n });\n return;\n }\n\n if (!input.fileAdapter?.readReferencePreview) {\n setSnapshot({\n previewState: { reference, status: \"unavailable\" }\n });\n return;\n }\n\n const sequence = ++previewSequence;\n setSnapshot({\n previewState: { reference, status: \"loading\" }\n });\n void loadReferencePreview(reference, readiness.target, sequence);\n };\n\n return {\n close() {\n retained = false;\n cancelCurrentBrowse();\n cancelCurrentPreview();\n cancelCurrentSearch();\n setSnapshot({\n isBrowseLoading: false,\n isSearchLoading: false,\n previewState: { status: \"empty\" }\n });\n },\n getSnapshot() {\n return snapshot;\n },\n loadBrowseRoot() {\n void loadBrowseRoot();\n },\n open() {\n if (retained) {\n return;\n }\n retained = true;\n if (snapshot.mode === \"search\") {\n scheduleSearch();\n return;\n }\n void loadBrowseRoot();\n },\n async revealInitialPath(initialDirectoryPath) {\n if (\n !retained ||\n snapshot.mode !== \"browse\" ||\n snapshot.initialPathRevealed ||\n !snapshot.browseRootPath\n ) {\n return null;\n }\n\n const rootPath = normalizeDirectoryPath(snapshot.browseRootPath);\n if (!isPathInsideOrEqual(initialDirectoryPath, rootPath)) {\n setSnapshot({\n initialPathRevealed: true\n });\n return null;\n }\n\n const sequence = stampBrowse(REVEAL_SEQ_KEY);\n const loadedDirectories: Record<\n string,\n WorkspaceFileReferenceDirectoryState\n > = {};\n const expandedDirectories: Record<string, boolean> = {};\n const directoryState = (path: string) =>\n loadedDirectories[path] ?? snapshot.directoryStateByPath[path];\n\n const directoryPaths = directoryChainBetween(\n rootPath,\n initialDirectoryPath\n );\n for (const directoryPath of directoryPaths) {\n expandedDirectories[directoryPath] = true;\n }\n\n const listings = await Promise.all(\n directoryPaths\n .filter((directoryPath) => !directoryState(directoryPath)?.loaded)\n .map(async (directoryPath) => {\n try {\n return await loadDirectoryListing(directoryPath);\n } catch {\n return null;\n }\n })\n );\n\n for (const listing of listings) {\n if (!listing) {\n continue;\n }\n loadedDirectories[listing.normalizedPath] = {\n displayPath: listing.displayPath,\n entries: listing.entries,\n loaded: true,\n loading: false\n };\n }\n\n if (isBrowseStale(REVEAL_SEQ_KEY, sequence)) {\n return null;\n }\n setSnapshot((current) => ({\n ...current,\n directoryStateByPath: {\n ...current.directoryStateByPath,\n ...loadedDirectories\n },\n expandedFolderPaths: {\n ...current.expandedFolderPaths,\n ...expandedDirectories\n },\n initialPathRevealed: true\n }));\n return initialDirectoryPath;\n },\n reset() {\n cancelCurrentBrowse();\n cancelCurrentPreview();\n cancelCurrentSearch();\n setSnapshot({\n browseError: null,\n browseRootPath: null,\n directoryStateByPath: {},\n expandedFolderPaths: {},\n initialPathRevealed: false,\n isBrowseLoading: false,\n isSearchLoading: false,\n mode: \"browse\",\n previewState: { status: \"empty\" },\n searchEntries: [],\n searchError: null,\n searchQuery: \"\"\n });\n },\n setPreviewReference(reference) {\n setPreviewReference(reference);\n },\n setSearchQuery(query) {\n if (query === snapshot.searchQuery) {\n return;\n }\n const nextMode = resolveMode(query);\n setSnapshot({\n mode: nextMode,\n searchQuery: query,\n ...(nextMode === \"browse\" ? { isSearchLoading: false } : {})\n });\n if (nextMode === \"search\") {\n cancelCurrentBrowse();\n scheduleSearch();\n return;\n }\n clearSearchResults();\n void loadBrowseRoot();\n },\n get store() {\n return store;\n },\n toggleFolder(entry) {\n const folderKey = normalizeDirectoryPath(entry.path);\n const childState = snapshot.directoryStateByPath[folderKey];\n const nextExpanded = !(snapshot.expandedFolderPaths[folderKey] ?? false);\n\n setSnapshot((current) => ({\n ...current,\n expandedFolderPaths: {\n ...current.expandedFolderPaths,\n [folderKey]: nextExpanded\n }\n }));\n if (nextExpanded && !childState?.loaded && !childState?.loading) {\n void loadFolderChildren(entry);\n }\n }\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === \"AbortError\";\n}\n\nfunction normalizeControllerError(\n error: unknown,\n fallbackMessage: string\n): Error {\n return error instanceof Error ? error : new Error(fallbackMessage);\n}\n\nfunction createReferencePreviewState(\n reference: WorkspaceFileReference,\n target: WorkspaceFilePreviewActivationTarget,\n preview: WorkspaceFileReferencePreview\n): WorkspaceFileReferencePreviewState {\n const loadedState = createWorkspaceFilePreviewLoadedState({\n bytes: preview.bytes,\n contentType: preview.contentType,\n entry: reference,\n renderHtml: true,\n target: {\n ...target,\n fileKind: preview.kind\n }\n });\n\n if (loadedState.status === \"image\") {\n return {\n objectUrl: URL.createObjectURL(\n new Blob([loadedState.bytes], {\n type: loadedState.contentType\n })\n ),\n reference,\n status: \"image\"\n };\n }\n if (loadedState.status === \"video\") {\n return {\n objectUrl: URL.createObjectURL(\n new Blob([loadedState.bytes], {\n type: loadedState.contentType\n })\n ),\n reference,\n status: \"video\"\n };\n }\n\n if (loadedState.status === \"text\") {\n return {\n content: loadedState.content,\n reference,\n status: \"text\"\n };\n }\n if (loadedState.status === \"html\") {\n return {\n content: loadedState.content,\n reference,\n status: \"html\"\n };\n }\n\n return {\n maxSizeBytes: loadedState.maxSizeBytes,\n reason: loadedState.reason,\n reference,\n status: \"readonly\"\n };\n}\n\nfunction isPathInsideOrEqual(path: string, root: string): boolean {\n const normalizedPath = normalizeDirectoryPath(path);\n const normalizedRoot = normalizeDirectoryPath(root);\n if (normalizedRoot === \"/\") {\n return normalizedPath.startsWith(\"/\");\n }\n return (\n normalizedPath === normalizedRoot ||\n normalizedPath.startsWith(`${normalizedRoot}/`)\n );\n}\n\nfunction directoryChainBetween(root: string, target: string): string[] {\n const normalizedRoot = normalizeDirectoryPath(root);\n let current = normalizeDirectoryPath(target);\n const chain: string[] = [];\n\n while (current && current !== normalizedRoot) {\n chain.unshift(current);\n const parent = dirnameDirectoryPath(current);\n if (parent === current) {\n break;\n }\n current = parent;\n }\n\n return chain;\n}\n\nfunction dirnameDirectoryPath(path: string): string {\n const normalized = normalizeDirectoryPath(path);\n if (normalized === \"/\") {\n return \"/\";\n }\n const index = normalized.lastIndexOf(\"/\");\n if (index <= 0) {\n return \"/\";\n }\n return normalized.slice(0, index);\n}\n","import { proxy } from \"valtio/vanilla\";\nimport type {\n NodeRef,\n ReferenceHandle,\n ReferenceLocateTarget,\n ReferenceNode,\n ReferenceScope,\n SelectedReference\n} from \"../../../contracts/referenceSource.ts\";\nimport type {\n ReferenceSourceAggregator,\n ReferenceSourceTab\n} from \"../../../core/referenceSourceAggregator.ts\";\nimport { SOURCE_ROOT_NODE_ID } from \"../../../core/referenceSourceAggregator.ts\";\nimport {\n appendReferencePage,\n nodeRefKey,\n sortReferenceNodes\n} from \"../../../core/referenceSourceUtils.ts\";\n\n/**\n * node-keyed 多源 picker 的逻辑层 controller(顶部分源 tab)。\n * 独立于现有 WorkspaceFileReferencePickerController —— issue-manager 不受影响。\n * 设计见 docs/architecture/agent-reference-source-services.md §2 / §3。\n *\n * 本层只管:tabs、per-source inline 展开树(node-keyed)、cursor 加载更多、\n * per-tab 搜索、跨 tab 选中集、confirm。预览/打开留待 UI 接入步骤。\n */\n\nexport type ReferenceSourcePickerMode = \"browse\" | \"search\";\n\nexport interface ReferenceSourceNodeChildrenState {\n /** 已累积的子节点(含多页 append)。 */\n entries: ReferenceNode[];\n nextCursor: string | null;\n loaded: boolean;\n loading: boolean;\n error: Error | null;\n}\n\nexport interface ReferenceSourceTabState {\n sourceId: string;\n expandedKeys: Record<string, boolean>;\n /** key = nodeRefKey;源根用 ROOT_CHILDREN_KEY。 */\n childrenByKey: Record<string, ReferenceSourceNodeChildrenState>;\n mode: ReferenceSourcePickerMode;\n searchQuery: string;\n /** 已选文件类型筛选分类 id(全局统一口径);与 searchQuery 一起构成「查询」。 */\n searchFilters: string[];\n /** 当前搜索限定的二级分组节点 nodeId(左栏选中分组);null = 跨整源搜索。 */\n searchScopeNodeId: string | null;\n searchEntries: ReferenceNode[];\n searchNextCursor: string | null;\n /**\n * 当前查询使用的结果上限(增长式分页:拉到底部时 +SEARCH_PAGE_SIZE 重查)。\n * 0 = 尚未发起查询;每次新查询(改关键词/筛选/分组/换源)重置为 SEARCH_PAGE_SIZE。\n */\n searchLimit: number;\n /** 是否可能还有更多结果(本页返回数 ≥ 请求上限,且未达全局上限)。 */\n searchHasMore: boolean;\n /** 正在加载下一页(增长 limit 重查在途);用于底部 spinner,不清空已有结果。 */\n isSearchLoadingMore: boolean;\n isSearchLoading: boolean;\n searchError: Error | null;\n}\n\nexport interface ReferenceSourcePickerSnapshot {\n isLoadingTabs: boolean;\n tabsError: Error | null;\n tabs: ReferenceSourceTab[];\n activeSourceId: string | null;\n bySource: Record<string, ReferenceSourceTabState>;\n /** 跨 tab 累积的选中文件节点,按选中顺序。 */\n selection: ReferenceNode[];\n}\n\n/** confirmGrouped 的产物:一个 navigable 源文件夹 = 一个 bundle(保留分组)。 */\nexport interface ReferenceConfirmBundle {\n /** 被选中的文件夹节点(提供 displayName / iconUrl / ref 作为 bundle 身份)。 */\n root: ReferenceNode;\n /**\n * 该 bundle 归一成的可被 agent 解析的领域句柄(见 ReferenceHandle)。\n * 由所属源 describeReferenceHandle 解码;发给 agent 的 `mention://workspace-reference/...`\n * 由它构造,替代把文件路径全部展开。源不支持解码时为 null。\n */\n handle: ReferenceHandle | null;\n}\n\nexport interface ReferenceConfirmGroupedResult {\n /** 单独选中的文件 + 非 navigable 源的文件夹(保持单条引用)。 */\n files: SelectedReference[];\n /** 每个 navigable 源文件夹一项,文件已折叠在内。 */\n bundles: ReferenceConfirmBundle[];\n}\n\nexport interface ReferenceSourcePickerController {\n readonly store: ReferenceSourcePickerSnapshot;\n getSnapshot(): ReferenceSourcePickerSnapshot;\n open(): void;\n close(): void;\n reset(): void;\n setActiveSource(sourceId: string): void;\n /**\n * 把「定位目标」解析为从源根到目标的真实 ReferenceNode 路径(root → leaf)。\n * 纯数据解析:逐层 listChildren 找到真实节点(带 displayName 等),不改动任何 UI/导航态。\n * 源不支持定位 / 未找到时返回部分路径(可能为空)。供「打开即定位」一次性应用。\n */\n locatePath(target: ReferenceLocateTarget): Promise<ReferenceNode[]>;\n /** 确保某节点(null=当前源根)的子节点已加载(抽屉式导航进入用,不切换展开态)。 */\n ensureChildren(node: ReferenceNode | null): void;\n /** 确保指定源的根层级已加载(左栏可同时展开多源时,为非 active 源预载分组)。 */\n ensureSourceRoot(sourceId: string): void;\n /** 幂等展开某 folder 并确保其子节点已加载(定位目标默认展开用)。 */\n expandNode(node: ReferenceNode): void;\n toggleNode(node: ReferenceNode): void;\n loadMore(node: ReferenceNode | null): void;\n /**\n * 拉取指定源根层级的下一页(左栏二级分组分页用)。\n * 与 loadMore(null) 的区别:后者只作用于 active 源;本方法显式指定源,\n * 使左栏任一源(无论是否 active)都能继续拉取其分组。\n */\n loadMoreSourceRoot(sourceId: string): void;\n /**\n * 设置搜索关键词。scopeNodeId 指定把搜索限定在 active 源内某个二级分组(左栏选中分组)\n * 的节点 nodeId;缺省/null = 跨整源搜索。query 与 filters 任一非空即进入查询(平铺)态。\n */\n setSearchQuery(query: string, scopeNodeId?: string | null): void;\n /**\n * 设置已选文件类型筛选分类(全局统一口径)。与 setSearchQuery 同构:\n * 与现有关键词一起构成查询并(去抖)重搜;query 与 filters 同时为空才回浏览态。\n */\n setSearchFilters(filters: string[], scopeNodeId?: string | null): void;\n /** 搜索进行中切换左栏分组时更新限定范围并以现有关键词/筛选重搜。 */\n setSearchScope(scopeNodeId: string | null): void;\n /**\n * 加载更多查询结果(增长式分页):以同一关键词/筛选、更大的 limit 立即重查,\n * 结果整体替换(保留旧结果直到新结果就绪)。无更多 / 在途 / 非查询态时 no-op。\n */\n loadMoreSearch(): void;\n toggleSelection(node: ReferenceNode): void;\n toggleSingleSelectionAndExpand(node: ReferenceNode): void;\n clearSelection(): void;\n /**\n * 选中归一。文件 → 单条;文件夹按所属源区分:\n * - 本地(非 navigable)源:保持单条 folder 引用(filesystem 路径与目录一一对应);\n * - app/issue(navigable)源:其文件夹下文件在 filesystem 里不一定落在该目录路径下,\n * 故递归 listChildren 枚举,展开成多条文件引用。\n * 含异步枚举,故返回 Promise;结果按 path 去重、保序。\n */\n confirm(selection?: readonly ReferenceNode[]): Promise<SelectedReference[]>;\n /**\n * 与 confirm 同源,但保留分组:navigable 源的每个选中文件夹折叠成一个 bundle\n * (文件已递归展开在内),其余作为单条文件。供「文件夹 = 一个节点」的插入形态用。\n */\n confirmGrouped(\n selection?: readonly ReferenceNode[]\n ): Promise<ReferenceConfirmGroupedResult>;\n}\n\nexport interface CreateReferenceSourcePickerControllerInput {\n aggregator: ReferenceSourceAggregator;\n scope: ReferenceScope;\n searchDebounceMs?: number;\n}\n\n/** 源根 children 的 key(node===null 时)。 */\nexport const ROOT_CHILDREN_KEY = nodeRefKey({\n sourceId: \"\",\n nodeId: SOURCE_ROOT_NODE_ID\n});\n\nconst defaultSearchDebounceMs = 180;\n\n/** 查询(搜索/筛选)结果的初始/每页步长。拉到底部 +一页 重查(增长式分页)。 */\nexport const SEARCH_PAGE_SIZE = 30;\n/**\n * 查询结果的全局上限。增长式分页对每个源都用「同一关键词/筛选 + 更大 limit 重查」实现,\n * 由各源 daemon 自行夹取(本地 200、应用硬校验 ≤200、议题 ≤200),故统一封顶 200。\n */\nexport const SEARCH_MAX_LIMIT = 200;\n\nfunction emptyTabState(sourceId: string): ReferenceSourceTabState {\n return {\n sourceId,\n expandedKeys: {},\n childrenByKey: {},\n mode: \"browse\",\n searchQuery: \"\",\n searchFilters: [],\n searchScopeNodeId: null,\n searchEntries: [],\n searchNextCursor: null,\n searchLimit: 0,\n searchHasMore: false,\n isSearchLoadingMore: false,\n isSearchLoading: false,\n searchError: null\n };\n}\n\nfunction emptyChildrenState(): ReferenceSourceNodeChildrenState {\n return {\n entries: [],\n nextCursor: null,\n loaded: false,\n loading: false,\n error: null\n };\n}\n\nexport function createReferenceSourcePickerController(\n input: CreateReferenceSourcePickerControllerInput\n): ReferenceSourcePickerController {\n const { aggregator, scope } = input;\n const searchDebounceMs = input.searchDebounceMs ?? defaultSearchDebounceMs;\n\n let retained = false;\n // tabs 加载完成的 promise(供 revealTarget 等到 setActiveSource 可生效)。\n let tabsReady: Promise<void> = Promise.resolve();\n let tabsSequence = 0;\n // 浏览取数的「按 key 隔离」失效计数:全局单调 ticket(nextBrowseSeq,永不回退/复用)\n // 派发,latestBrowseSeqByKey 记录每个 (source, children-key) 的最新 ticket。\n // 取数 resolve 时凭自身 ticket 是否仍为该 key 的最新值判定是否落库 —— 这样不同\n // key 的并发取数互不作废(否则全局单计数会让后发的取数把先发的另一 key 取数结果\n // 静默丢弃、令其 loading 永不清除)。close/reset 清空该表使全部在途取数失效。\n let nextBrowseSeq = 0;\n const latestBrowseSeqByKey = new Map<string, number>();\n let searchSequence = 0;\n let searchAbortController: AbortController | null = null;\n let searchTimer: ReturnType<typeof setTimeout> | null = null;\n\n let snapshot: ReferenceSourcePickerSnapshot = {\n isLoadingTabs: false,\n tabsError: null,\n tabs: [],\n activeSourceId: null,\n bySource: {},\n selection: []\n };\n const store = proxy(snapshot);\n\n const setSnapshot = (\n update:\n | Partial<ReferenceSourcePickerSnapshot>\n | ((\n current: ReferenceSourcePickerSnapshot\n ) => ReferenceSourcePickerSnapshot)\n ) => {\n const next =\n typeof update === \"function\"\n ? update(snapshot)\n : { ...snapshot, ...update };\n if (next === snapshot) {\n return;\n }\n snapshot = next;\n Object.assign(store, next);\n };\n\n /** 不可变地更新某 tab 的状态。 */\n const updateTab = (\n sourceId: string,\n updater: (tab: ReferenceSourceTabState) => ReferenceSourceTabState\n ) => {\n setSnapshot((current) => {\n const existing = current.bySource[sourceId] ?? emptyTabState(sourceId);\n const nextTab = updater(existing);\n if (nextTab === existing) {\n return current;\n }\n return {\n ...current,\n bySource: { ...current.bySource, [sourceId]: nextTab }\n };\n });\n };\n\n const childrenKeyForNode = (node: ReferenceNode | null): string =>\n node ? nodeRefKey(node.ref) : ROOT_CHILDREN_KEY;\n\n const setChildrenState = (\n sourceId: string,\n key: string,\n patch: Partial<ReferenceSourceNodeChildrenState>\n ) => {\n updateTab(sourceId, (tab) => {\n const current = tab.childrenByKey[key] ?? emptyChildrenState();\n return {\n ...tab,\n childrenByKey: {\n ...tab.childrenByKey,\n [key]: { ...current, ...patch }\n }\n };\n });\n };\n\n const loadChildren = async (\n sourceId: string,\n node: ReferenceNode | null,\n options: { append: boolean }\n ) => {\n if (!retained) {\n return;\n }\n const key = childrenKeyForNode(node);\n const tab = snapshot.bySource[sourceId];\n const existing = tab?.childrenByKey[key];\n const cursor = options.append ? (existing?.nextCursor ?? null) : null;\n if (existing?.loading) {\n return;\n }\n if (options.append && !cursor) {\n return;\n }\n\n // ROOT_CHILDREN_KEY 等常量 key 在各源间复用,故 ticket 表按 (source, key) 命名空间。\n const seqKey = `${sourceId}\u0000${key}`;\n const sequence = ++nextBrowseSeq;\n latestBrowseSeqByKey.set(seqKey, sequence);\n setChildrenState(sourceId, key, { loading: true, error: null });\n\n try {\n const result = await aggregator.listChildren(\n scope,\n node ? node.ref : { sourceId, nodeId: SOURCE_ROOT_NODE_ID },\n { cursor }\n );\n if (!retained || latestBrowseSeqByKey.get(seqKey) !== sequence) {\n return;\n }\n // append 走 cursor 语义:保序 append + 去重,不重排已得项(不变式 #4)。\n // 首次加载则整体排序(folder 在前、按名)。\n const prior =\n snapshot.bySource[sourceId]?.childrenByKey[key]?.entries ?? [];\n // 源声明已排序(如「最近访问」按访问时间倒序)时保留其顺序,不再重排。\n const entries = options.append\n ? appendReferencePage(prior, result.entries)\n : result.ordered\n ? [...result.entries]\n : sortReferenceNodes(result.entries);\n setChildrenState(sourceId, key, {\n entries,\n nextCursor: result.nextCursor ?? null,\n loaded: true,\n loading: false,\n error: null\n });\n } catch (error) {\n if (!retained || latestBrowseSeqByKey.get(seqKey) !== sequence) {\n return;\n }\n setChildrenState(sourceId, key, {\n loading: false,\n error: normalizeError(error, \"load children failed\")\n });\n }\n };\n\n const ensureRootLoaded = (sourceId: string) => {\n const root = snapshot.bySource[sourceId]?.childrenByKey[ROOT_CHILDREN_KEY];\n if (root?.loaded || root?.loading) {\n return;\n }\n void loadChildren(sourceId, null, { append: false });\n };\n\n const loadTabs = async () => {\n if (!retained) {\n return;\n }\n const sequence = ++tabsSequence;\n setSnapshot({ isLoadingTabs: true, tabsError: null });\n try {\n const tabs = await aggregator.listSources(scope);\n if (!retained || sequence !== tabsSequence) {\n return;\n }\n const activeSourceId =\n snapshot.activeSourceId &&\n tabs.some((tab) => tab.sourceId === snapshot.activeSourceId)\n ? snapshot.activeSourceId\n : (tabs[0]?.sourceId ?? null);\n setSnapshot((current) => ({\n ...current,\n isLoadingTabs: false,\n tabs,\n activeSourceId,\n bySource: Object.fromEntries(\n tabs.map((tab) => [\n tab.sourceId,\n current.bySource[tab.sourceId] ?? emptyTabState(tab.sourceId)\n ])\n )\n }));\n if (activeSourceId) {\n ensureRootLoaded(activeSourceId);\n }\n } catch (error) {\n if (!retained || sequence !== tabsSequence) {\n return;\n }\n setSnapshot({\n isLoadingTabs: false,\n tabsError: normalizeError(error, \"load reference sources failed\")\n });\n }\n };\n\n const clearSearchTimer = () => {\n if (searchTimer !== null) {\n clearTimeout(searchTimer);\n searchTimer = null;\n }\n };\n\n const cancelSearch = () => {\n clearSearchTimer();\n searchSequence += 1;\n searchAbortController?.abort();\n searchAbortController = null;\n };\n\n const runSearch = async (\n sourceId: string,\n query: string,\n filters: string[],\n scopeNodeId: string | null,\n limit: number,\n loadingMore: boolean\n ) => {\n if (!retained) {\n return;\n }\n const sequence = ++searchSequence;\n searchAbortController?.abort();\n const abortController = new AbortController();\n searchAbortController = abortController;\n // 加载更多:只置底部 spinner、保留旧结果;新查询:置主 loading。\n updateTab(sourceId, (tab) => ({\n ...tab,\n ...(loadingMore\n ? { isSearchLoadingMore: true }\n : { isSearchLoading: true }),\n searchError: null\n }));\n try {\n const result = await aggregator.search(scope, sourceId, {\n query,\n limit,\n signal: abortController.signal,\n ...(filters.length > 0 ? { filters } : {}),\n ...(scopeNodeId == null ? {} : { withinNodeId: scopeNodeId })\n });\n if (!retained || sequence !== searchSequence) {\n return;\n }\n updateTab(sourceId, (tab) => ({\n ...tab,\n isSearchLoading: false,\n isSearchLoadingMore: false,\n searchEntries: sortReferenceNodes(result.entries),\n searchNextCursor: result.nextCursor ?? null,\n searchLimit: limit,\n // 本页返回数达到请求上限、且未触全局上限 → 认为可能还有更多(增长式分页启发式)。\n searchHasMore:\n result.entries.length >= limit && limit < SEARCH_MAX_LIMIT,\n searchError: null\n }));\n } catch (error) {\n if (isAbortError(error) || !retained || sequence !== searchSequence) {\n return;\n }\n updateTab(sourceId, (tab) => ({\n ...tab,\n isSearchLoading: false,\n isSearchLoadingMore: false,\n // 加载更多失败时保留已有结果,仅新查询失败才清空。\n ...(loadingMore ? {} : { searchEntries: [], searchHasMore: false }),\n searchError: normalizeError(error, \"reference search failed\")\n }));\n } finally {\n if (sequence === searchSequence) {\n searchAbortController = null;\n }\n }\n };\n\n /**\n * 递归枚举文件夹下的所有文件节点(app/issue 源专用:文件夹引用需展开成逐个文件)。\n * 走 listChildren + cursor 分页,深入子文件夹;按 nodeRefKey 去重兼防环。不设数量上限。\n */\n const collectFolderFiles = async (\n folder: ReferenceNode\n ): Promise<ReferenceNode[]> => {\n const files: ReferenceNode[] = [];\n const seen = new Set<string>();\n const walk = async (node: ReferenceNode): Promise<void> => {\n let cursor: string | null = null;\n do {\n const result = await aggregator.listChildren(scope, node.ref, {\n cursor\n });\n for (const entry of result.entries) {\n const key = nodeRefKey(entry.ref);\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n if (entry.kind === \"folder\") {\n await walk(entry);\n } else {\n files.push(entry);\n }\n }\n cursor = result.nextCursor ?? null;\n } while (cursor);\n };\n await walk(folder);\n return files;\n };\n\n const scheduleSearch = (\n sourceId: string,\n query: string,\n filters: string[],\n scopeNodeId: string | null\n ) => {\n clearSearchTimer();\n // query 与 filters 同时为空才跳过 —— 仅选了筛选(query 空)也要发起查询。\n if (!retained || (!query && filters.length === 0)) {\n return;\n }\n // 新查询恒从首页(SEARCH_PAGE_SIZE)起。\n if (searchDebounceMs <= 0) {\n void runSearch(\n sourceId,\n query,\n filters,\n scopeNodeId,\n SEARCH_PAGE_SIZE,\n false\n );\n return;\n }\n searchTimer = setTimeout(() => {\n searchTimer = null;\n void runSearch(\n sourceId,\n query,\n filters,\n scopeNodeId,\n SEARCH_PAGE_SIZE,\n false\n );\n }, searchDebounceMs);\n };\n\n return {\n get store() {\n return store;\n },\n getSnapshot() {\n return snapshot;\n },\n open() {\n if (retained) {\n return;\n }\n retained = true;\n tabsReady = loadTabs();\n },\n close() {\n retained = false;\n cancelSearch();\n // 清空 ticket 表:在途取数 resolve 时其 key 已无最新 ticket(get→undefined),被丢弃。\n latestBrowseSeqByKey.clear();\n tabsSequence += 1;\n },\n reset() {\n cancelSearch();\n latestBrowseSeqByKey.clear();\n tabsSequence += 1;\n setSnapshot({\n isLoadingTabs: false,\n tabsError: null,\n tabs: [],\n activeSourceId: null,\n bySource: {},\n selection: []\n });\n },\n setActiveSource(sourceId) {\n if (!snapshot.tabs.some((tab) => tab.sourceId === sourceId)) {\n return;\n }\n // 跨源切换时把「当前查询」(切换前 active 源的关键词+筛选)带到目标源:\n // 有查询则在目标源已选分组范围内用同一查询重搜(切到对应 tab 即重搜),\n // 无查询则回浏览态加载源根。query 随 tab 走,搜索框/筛选在切源后仍可见。\n const prevTab = snapshot.activeSourceId\n ? snapshot.bySource[snapshot.activeSourceId]\n : undefined;\n const carriedQuery = prevTab?.searchQuery ?? \"\";\n const carriedFilters = prevTab?.searchFilters ?? [];\n const trimmed = carriedQuery.trim();\n cancelSearch();\n setSnapshot({ activeSourceId: sourceId });\n if (trimmed === \"\" && carriedFilters.length === 0) {\n // 全局查询为空:目标源回浏览态(清掉其可能残留的旧查询/结果),加载源根。\n updateTab(sourceId, (tab) =>\n tab.mode === \"browse\" &&\n tab.searchQuery === \"\" &&\n tab.searchFilters.length === 0\n ? tab\n : {\n ...tab,\n mode: \"browse\",\n searchQuery: \"\",\n searchFilters: [],\n searchEntries: [],\n searchHasMore: false,\n isSearchLoading: false,\n isSearchLoadingMore: false,\n searchError: null\n }\n );\n ensureRootLoaded(sourceId);\n return;\n }\n // 范围用目标源自身已选分组(尚未进过分组则 null=跨整源);随后左栏自动/手动\n // 进入分组会经 setSearchScope 再以新范围重搜(去抖窗口内合并,不重复请求)。\n const nextScopeNodeId =\n snapshot.bySource[sourceId]?.searchScopeNodeId ?? null;\n updateTab(sourceId, (tab) => ({\n ...tab,\n searchQuery: carriedQuery,\n searchFilters: carriedFilters,\n searchScopeNodeId: nextScopeNodeId,\n mode: \"search\",\n // 沿用旧结果直到新结果就绪,避免切源瞬间闪空。\n isSearchLoading: true,\n searchError: null\n }));\n scheduleSearch(sourceId, trimmed, carriedFilters, nextScopeNodeId);\n },\n async locatePath(target) {\n // 等 tabs 就绪(view 在本 promise resolve 后再 setActiveSource,届时 tabs 已加载)。\n await tabsReady;\n if (!retained) {\n return [];\n }\n const refs = await aggregator.locateTarget(\n scope,\n target.sourceId,\n target.params\n );\n if (!refs || refs.length === 0) {\n return [];\n }\n // 逐层 listChildren,把不透明 NodeRef 解析成带 displayName 的真实节点。\n const path: ReferenceNode[] = [];\n let parent: NodeRef = {\n sourceId: target.sourceId,\n nodeId: SOURCE_ROOT_NODE_ID\n };\n for (const ref of refs) {\n const targetKey = nodeRefKey(ref);\n let cursor: string | null = null;\n let node: ReferenceNode | undefined;\n do {\n const { entries, nextCursor } = await aggregator.listChildren(\n scope,\n parent,\n { cursor }\n );\n node = entries.find((entry) => nodeRefKey(entry.ref) === targetKey);\n cursor = nextCursor ?? null;\n } while (!node && cursor);\n if (!node) {\n break;\n }\n path.push(node);\n parent = ref;\n }\n return path;\n },\n ensureChildren(node) {\n const sourceId = node ? node.ref.sourceId : snapshot.activeSourceId;\n if (!sourceId) {\n return;\n }\n const key = childrenKeyForNode(node);\n const childState = snapshot.bySource[sourceId]?.childrenByKey[key];\n if (!childState?.loaded && !childState?.loading) {\n void loadChildren(sourceId, node, { append: false });\n }\n },\n ensureSourceRoot(sourceId) {\n if (\n !sourceId ||\n !snapshot.tabs.some((tab) => tab.sourceId === sourceId)\n ) {\n return;\n }\n ensureRootLoaded(sourceId);\n },\n expandNode(node) {\n if (node.kind !== \"folder\") {\n return;\n }\n const sourceId = node.ref.sourceId;\n const key = nodeRefKey(node.ref);\n updateTab(sourceId, (tab) =>\n tab.expandedKeys[key] === true\n ? tab\n : {\n ...tab,\n expandedKeys: { ...tab.expandedKeys, [key]: true }\n }\n );\n const childState = snapshot.bySource[sourceId]?.childrenByKey[key];\n if (!childState?.loaded && !childState?.loading) {\n void loadChildren(sourceId, node, { append: false });\n }\n },\n toggleNode(node) {\n if (node.kind !== \"folder\") {\n return;\n }\n const sourceId = node.ref.sourceId;\n const key = nodeRefKey(node.ref);\n const wasExpanded =\n snapshot.bySource[sourceId]?.expandedKeys[key] ?? false;\n const nextExpanded = !wasExpanded;\n updateTab(sourceId, (tab) => ({\n ...tab,\n expandedKeys: { ...tab.expandedKeys, [key]: nextExpanded }\n }));\n const childState = snapshot.bySource[sourceId]?.childrenByKey[key];\n if (nextExpanded && !childState?.loaded && !childState?.loading) {\n void loadChildren(sourceId, node, { append: false });\n }\n },\n loadMore(node) {\n const sourceId = node ? node.ref.sourceId : snapshot.activeSourceId;\n if (!sourceId) {\n return;\n }\n void loadChildren(sourceId, node, { append: true });\n },\n loadMoreSourceRoot(sourceId) {\n if (!sourceId) {\n return;\n }\n void loadChildren(sourceId, null, { append: true });\n },\n setSearchQuery(query, scopeNodeId = null) {\n const sourceId = snapshot.activeSourceId;\n if (!sourceId) {\n return;\n }\n const filters = snapshot.bySource[sourceId]?.searchFilters ?? [];\n const trimmed = query.trim();\n // 查询态 = 关键词或筛选任一非空。\n const nextMode: ReferenceSourcePickerMode =\n trimmed || filters.length > 0 ? \"search\" : \"browse\";\n updateTab(sourceId, (tab) => ({\n ...tab,\n searchQuery: query,\n searchScopeNodeId: scopeNodeId,\n mode: nextMode,\n // 进入搜索:立刻置 loading(搜索是 debounce 的,否则键入到取数之间会先渲染空态,\n // 造成「空态 → spinner → 结果」闪烁)。保留上次 searchEntries,细化关键词时沿用旧结果而非闪空。\n ...(nextMode === \"browse\"\n ? { isSearchLoading: false, searchEntries: [], searchError: null }\n : { isSearchLoading: true, searchError: null })\n }));\n if (nextMode === \"search\") {\n scheduleSearch(sourceId, trimmed, filters, scopeNodeId);\n } else {\n cancelSearch();\n ensureRootLoaded(sourceId);\n }\n },\n setSearchFilters(filters, scopeNodeId = null) {\n const sourceId = snapshot.activeSourceId;\n if (!sourceId) {\n return;\n }\n const tab = snapshot.bySource[sourceId];\n const trimmed = tab?.searchQuery.trim() ?? \"\";\n const scopeId = scopeNodeId ?? tab?.searchScopeNodeId ?? null;\n const nextMode: ReferenceSourcePickerMode =\n trimmed || filters.length > 0 ? \"search\" : \"browse\";\n updateTab(sourceId, (current) => ({\n ...current,\n searchFilters: filters,\n searchScopeNodeId: scopeId,\n mode: nextMode,\n ...(nextMode === \"browse\"\n ? { isSearchLoading: false, searchEntries: [], searchError: null }\n : { isSearchLoading: true, searchError: null })\n }));\n if (nextMode === \"search\") {\n scheduleSearch(sourceId, trimmed, filters, scopeId);\n } else {\n cancelSearch();\n ensureRootLoaded(sourceId);\n }\n },\n setSearchScope(scopeNodeId) {\n // 搜索中切换左栏分组(如从某 app 切到另一 app):更新限定范围并以现有关键词/筛选重搜。\n const sourceId = snapshot.activeSourceId;\n if (!sourceId) {\n return;\n }\n const tab = snapshot.bySource[sourceId];\n if (!tab || tab.searchScopeNodeId === scopeNodeId) {\n return;\n }\n updateTab(sourceId, (current) => ({\n ...current,\n searchScopeNodeId: scopeNodeId\n }));\n const trimmed = tab.searchQuery.trim();\n const filters = tab.searchFilters;\n if (tab.mode === \"search\" && (trimmed || filters.length > 0)) {\n scheduleSearch(sourceId, trimmed, filters, scopeNodeId);\n }\n },\n loadMoreSearch() {\n const sourceId = snapshot.activeSourceId;\n if (!sourceId) {\n return;\n }\n const tab = snapshot.bySource[sourceId];\n if (\n !tab ||\n tab.mode !== \"search\" ||\n !tab.searchHasMore ||\n tab.isSearchLoadingMore\n ) {\n return;\n }\n const trimmed = tab.searchQuery.trim();\n if (!trimmed && tab.searchFilters.length === 0) {\n return;\n }\n const nextLimit = Math.min(\n (tab.searchLimit || SEARCH_PAGE_SIZE) + SEARCH_PAGE_SIZE,\n SEARCH_MAX_LIMIT\n );\n if (nextLimit <= tab.searchLimit) {\n return;\n }\n // 加载更多立即触发(不去抖),清掉在途去抖的新查询定时器以免相互覆盖。\n clearSearchTimer();\n void runSearch(\n sourceId,\n trimmed,\n tab.searchFilters,\n tab.searchScopeNodeId,\n nextLimit,\n true\n );\n },\n toggleSelection(node) {\n // 文件与文件夹都可作为引用选中(文件夹的展开在 confirm 时按源处理)。\n const key = nodeRefKey(node.ref);\n setSnapshot((current) => {\n const exists = current.selection.some(\n (item) => nodeRefKey(item.ref) === key\n );\n return {\n ...current,\n selection: exists\n ? current.selection.filter((item) => nodeRefKey(item.ref) !== key)\n : [...current.selection, node]\n };\n });\n },\n toggleSingleSelectionAndExpand(node) {\n const key = nodeRefKey(node.ref);\n setSnapshot((current) => {\n if (current.selection.length > 1) {\n return current;\n }\n const exists = current.selection.some(\n (item) => nodeRefKey(item.ref) === key\n );\n return {\n ...current,\n selection: exists ? [] : [node]\n };\n });\n if (node.kind === \"folder\") {\n const sourceId = node.ref.sourceId;\n const childKey = nodeRefKey(node.ref);\n updateTab(sourceId, (tab) =>\n tab.expandedKeys[childKey] === true\n ? tab\n : {\n ...tab,\n expandedKeys: { ...tab.expandedKeys, [childKey]: true }\n }\n );\n const childState = snapshot.bySource[sourceId]?.childrenByKey[childKey];\n if (!childState?.loaded && !childState?.loading) {\n void loadChildren(sourceId, node, { append: false });\n }\n }\n },\n clearSelection() {\n setSnapshot({ selection: [] });\n },\n async confirm(selection = snapshot.selection) {\n const resolved: SelectedReference[] = [];\n const seenPaths = new Set<string>();\n const push = (ref: SelectedReference) => {\n if (seenPaths.has(ref.path)) {\n return;\n }\n seenPaths.add(ref.path);\n resolved.push(ref);\n };\n for (const node of selection) {\n if (node.kind !== \"folder\") {\n push(aggregator.resolveSelection(node));\n continue;\n }\n const navigable =\n aggregator.getLoadedSource(node.ref.sourceId)?.capabilities\n .navigable ?? false;\n if (!navigable) {\n // 本地源:文件夹保持单条引用(目录路径在 filesystem 里有效)。\n push(aggregator.resolveSelection(node));\n continue;\n }\n // app/issue 源:文件夹下文件不一定落在该目录路径,递归枚举展开成逐个文件引用。\n const files = await collectFolderFiles(node);\n for (const fileNode of files) {\n push(aggregator.resolveSelection(fileNode));\n }\n }\n return resolved;\n },\n async confirmGrouped(selection = snapshot.selection) {\n const files: SelectedReference[] = [];\n const bundles: ReferenceConfirmBundle[] = [];\n const seenPaths = new Set<string>();\n const pushFile = (ref: SelectedReference) => {\n if (seenPaths.has(ref.path)) {\n return;\n }\n seenPaths.add(ref.path);\n files.push(ref);\n };\n for (const node of selection) {\n const source = aggregator.getLoadedSource(node.ref.sourceId);\n const navigable =\n node.kind === \"folder\" && (source?.capabilities.navigable ?? false);\n if (!navigable) {\n // 文件、或非 navigable 源的文件夹:保持单条引用。\n pushFile(aggregator.resolveSelection(node));\n continue;\n }\n // navigable 源文件夹:折叠成一个 bundle。句柄由源解码,供 agent 经\n // `mention://workspace-reference/...` + CLI 按需解析。**不再递归展开文件**——\n // agent 序列化走句柄、chip 数量取 childCount,故确认即时(大产物不再卡顿)。\n const handle = source?.describeReferenceHandle?.(node) ?? null;\n bundles.push({ root: node, handle });\n }\n return { files, bundles };\n }\n };\n}\n\nfunction isAbortError(error: unknown): boolean {\n return error instanceof Error && error.name === \"AbortError\";\n}\n\nfunction normalizeError(error: unknown, fallback: string): Error {\n return error instanceof Error ? error : new Error(fallback);\n}\n"],"mappings":"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","names":["proxy","defaultSearchDebounceMs","proxy","isAbortError"]}