@tutti-os/workspace-file-reference 0.0.14 → 0.0.15
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/dist/{chunk-7C3RZYQE.js → chunk-HRC2MZ5H.js} +110 -3
- package/dist/chunk-HRC2MZ5H.js.map +1 -0
- package/dist/{chunk-CD3YNHYJ.js → chunk-KSK6PILG.js} +254 -37
- package/dist/chunk-KSK6PILG.js.map +1 -0
- package/dist/contracts/index.d.ts +46 -3
- package/dist/core/index.d.ts +57 -2
- package/dist/core/index.js +7 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js +7 -1
- package/dist/react/index.d.ts +62 -3
- package/dist/react/index.js +2 -2
- package/dist/{referenceSourceAggregator-yyyLVOPi.d.ts → referenceSourceAggregator-B8ATnJOZ.d.ts} +5 -0
- package/dist/ui/index.d.ts +32 -5
- package/dist/ui/index.js +807 -368
- package/dist/ui/index.js.map +1 -1
- package/package.json +6 -6
- package/dist/chunk-7C3RZYQE.js.map +0 -1
- package/dist/chunk-CD3YNHYJ.js.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tutti-os/workspace-file-reference",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.15",
|
|
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.
|
|
40
|
-
"@tutti-os/ui-system": "0.0.
|
|
41
|
-
"@tutti-os/workspace-file-manager": "0.0.
|
|
42
|
-
"@tutti-os/workspace-file-preview": "0.0.
|
|
39
|
+
"@tutti-os/ui-react-hooks": "0.0.15",
|
|
40
|
+
"@tutti-os/ui-system": "0.0.15",
|
|
41
|
+
"@tutti-os/workspace-file-manager": "0.0.15",
|
|
42
|
+
"@tutti-os/workspace-file-preview": "0.0.15",
|
|
43
43
|
"valtio": "^2.3.2"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
@@ -67,6 +67,6 @@
|
|
|
67
67
|
"scripts": {
|
|
68
68
|
"build": "tsup --config tsup.config.ts",
|
|
69
69
|
"test": "node --test --experimental-strip-types \"./src/**/*.test.ts\"",
|
|
70
|
-
"typecheck": "
|
|
70
|
+
"typecheck": "node ../../../tools/scripts/run-tsgo-typecheck.mjs"
|
|
71
71
|
}
|
|
72
72
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/referenceSourceUtils.ts","../src/core/referenceSourceAggregator.ts","../src/core/referenceListSource.ts","../src/core/index.ts"],"sourcesContent":["import type {\n NodeRef,\n ReferenceNode,\n SelectedReference\n} from \"../contracts/referenceSource.ts\";\nimport type { WorkspaceFileReference } from \"../contracts/index.ts\";\n\n/**\n * Reference Source Services 的共享 base 工具(形状处理,非取数)。\n * 设计见 docs/architecture/agent-reference-source-services.md §1 / §2。\n */\n\n/**\n * 「回到源根」哨兵 nodeId。源在 listSidebarGroups 里用它表示一个等价于源根的\n * 二级分组(如本地源的「个人」= 用户 home 根);picker 选中它走 navigateToRoot\n * 而非 ensureChildren,避免把哨兵当真实路径打后端。\n */\nexport const WORKSPACE_ROOT_GROUP_NODE_ID = \"__workspace_root__\";\n\n/** 节点的全局 key,用于 picker 树状态索引与去重。picker 不解析其内部结构。 */\nexport function nodeRefKey(ref: NodeRef): string {\n return `${ref.sourceId}\u0000${ref.nodeId}`;\n}\n\nexport function nodeKey(node: ReferenceNode): string {\n return nodeRefKey(node.ref);\n}\n\n/** 任意输入归一为 \"file\" | \"folder\"。 */\nexport function normalizeReferenceNodeKind(\n kind: string | null | undefined\n): \"file\" | \"folder\" {\n return kind === \"folder\" || kind === \"directory\" ? \"folder\" : \"file\";\n}\n\n/** folder 在前、同类按 displayName 本地化排序。 */\nexport function sortReferenceNodes(\n nodes: readonly ReferenceNode[]\n): ReferenceNode[] {\n return [...nodes].sort((left, right) => {\n if (left.kind !== right.kind) {\n return left.kind === \"folder\" ? -1 : 1;\n }\n return left.displayName.localeCompare(right.displayName, undefined, {\n sensitivity: \"base\"\n });\n });\n}\n\n/** 按 node key 去重,保留首次出现。支持 cursor append 的稳定去重。 */\nexport function dedupeReferenceNodes(\n nodes: readonly ReferenceNode[]\n): ReferenceNode[] {\n const seen = new Set<string>();\n const result: ReferenceNode[] = [];\n for (const node of nodes) {\n const key = nodeKey(node);\n if (seen.has(key)) {\n continue;\n }\n seen.add(key);\n result.push(node);\n }\n return result;\n}\n\n/** 续页累积:把新一页 append 到已有项后并去重(cursor 语义,不重排)。 */\nexport function appendReferencePage(\n current: readonly ReferenceNode[],\n next: readonly ReferenceNode[]\n): ReferenceNode[] {\n return dedupeReferenceNodes([...current, ...next]);\n}\n\n/** SelectedReference 与现有 WorkspaceFileReference 形状兼容,便于下游零改动复用。 */\nexport function selectedReferenceToWorkspaceFileReference(\n selected: SelectedReference\n): WorkspaceFileReference {\n return {\n path: selected.path,\n kind: selected.kind,\n ...(selected.displayName ? { displayName: selected.displayName } : {})\n };\n}\n","import type {\n ListChildrenResult,\n NodeRef,\n ReferenceNode,\n ReferencePreview,\n ReferenceScope,\n ReferenceSourceRegistry,\n ReferenceSourceService,\n SearchInput,\n SearchResult,\n SelectedReference\n} from \"../contracts/referenceSource.ts\";\n\n/**\n * 多源聚合器:根层级 = 每个可用源一个 folder 节点;其余按 node.ref.sourceId 委派。\n * 设计见 docs/architecture/agent-reference-source-services.md §3 / §4.4。\n */\n\n/**\n * 源根节点的 nodeId 哨兵。由聚合器创建源根节点时使用;\n * 任何真实源都不会产出 nodeId 等于此值的子节点(workspace 源 nodeId 是路径,\n * app 源 nodeId 以 \"app:\" 开头),因此路由无歧义。\n */\nexport const SOURCE_ROOT_NODE_ID = \"\u0000source-root\";\n\n/** 顶部 tab 的描述(source 身份 + 能力)。 */\nexport interface ReferenceSourceTab {\n sourceId: string;\n label: string;\n icon?: string;\n capabilities: ReferenceSourceService[\"capabilities\"];\n}\n\nexport interface ReferenceSourceAggregator {\n /** 顶部 tab 列表:每个可用源一个 tab(已过滤 isAvailable、按 order 排序)。 */\n listSources(scope: ReferenceScope): Promise<ReferenceSourceTab[]>;\n /** (备用,单树多根形态)根层级:每个可用源一个 folder 节点。 */\n listRoot(scope: ReferenceScope): Promise<ReferenceNode[]>;\n listChildren(\n scope: ReferenceScope,\n node: NodeRef,\n input?: {\n cursor?: string | null;\n filter?: string | null;\n signal?: AbortSignal;\n }\n ): Promise<ListChildrenResult>;\n search(\n scope: ReferenceScope,\n sourceId: string,\n input: SearchInput\n ): Promise<SearchResult>;\n open(scope: ReferenceScope, node: ReferenceNode): Promise<void>;\n readPreview(\n scope: ReferenceScope,\n node: ReferenceNode\n ): Promise<ReferencePreview | null>;\n resolveSelection(node: ReferenceNode): SelectedReference;\n /** 取已加载的源(用于读取 capabilities/metadata)。需先 listRoot 触发加载。 */\n getLoadedSource(sourceId: string): ReferenceSourceService | undefined;\n}\n\nexport function isSourceRootNode(ref: NodeRef): boolean {\n return ref.nodeId === SOURCE_ROOT_NODE_ID;\n}\n\nexport function createReferenceSourceAggregator(\n registry: ReferenceSourceRegistry\n): ReferenceSourceAggregator {\n // 同一 scope 内源稳定;缓存便于 resolveSelection 同步取源。\n const sourceMap = new Map<string, ReferenceSourceService>();\n\n async function loadSources(\n scope: ReferenceScope\n ): Promise<ReferenceSourceService[]> {\n const sources = await registry.getSources(scope);\n sourceMap.clear();\n for (const source of sources) {\n sourceMap.set(source.metadata.id, source);\n }\n return sources;\n }\n\n function requireSource(sourceId: string): ReferenceSourceService {\n const source = sourceMap.get(sourceId);\n if (!source) {\n throw new Error(`reference source not found: ${sourceId}`);\n }\n return source;\n }\n\n return {\n async listSources(scope) {\n const sources = await loadSources(scope);\n return sources.map((source) => ({\n sourceId: source.metadata.id,\n label: source.metadata.label,\n ...(source.metadata.icon ? { icon: source.metadata.icon } : {}),\n capabilities: source.capabilities\n }));\n },\n\n async listRoot(scope) {\n const sources = await loadSources(scope);\n return sources.map((source) => ({\n ref: { sourceId: source.metadata.id, nodeId: SOURCE_ROOT_NODE_ID },\n kind: \"folder\",\n displayName: source.metadata.label,\n hasChildren: true\n }));\n },\n\n async listChildren(scope, node, input) {\n const source = requireSource(node.sourceId);\n return source.listChildren(scope, {\n node: isSourceRootNode(node) ? null : node,\n cursor: input?.cursor ?? null,\n filter: input?.filter ?? null,\n signal: input?.signal\n });\n },\n\n async search(scope, sourceId, input) {\n const source = requireSource(sourceId);\n if (!source.search) {\n return { entries: [], nextCursor: null };\n }\n return source.search(scope, input);\n },\n\n async open(scope, node) {\n const source = requireSource(node.ref.sourceId);\n await source.open?.(scope, node);\n },\n\n async readPreview(scope, node) {\n const source = requireSource(node.ref.sourceId);\n return (await source.readPreview?.(scope, node)) ?? null;\n },\n\n resolveSelection(node) {\n return requireSource(node.ref.sourceId).resolveSelection(node);\n },\n\n getLoadedSource(sourceId) {\n return sourceMap.get(sourceId);\n }\n };\n}\n\n/** 静态 registry:持有一组源,按 isAvailable 过滤、按 order 排序。 */\nexport function createStaticReferenceSourceRegistry(\n sources: readonly ReferenceSourceService[]\n): ReferenceSourceRegistry {\n return {\n async getSources(scope) {\n const availability = await Promise.all(\n sources.map(async (source) => {\n try {\n return await source.isAvailable(scope);\n } catch {\n return false;\n }\n })\n );\n return sources\n .filter((_, index) => availability[index])\n .sort((left, right) => left.metadata.order - right.metadata.order);\n }\n };\n}\n","import type {\n ListChildrenResult,\n ReferenceNode,\n ReferencePreview,\n ReferenceScope,\n ReferenceSourceCapabilities,\n ReferenceSourceService,\n SearchInput,\n SearchResult,\n SelectedReference\n} from \"../contracts/referenceSource.ts\";\nimport type {\n WorkspaceFileReference,\n WorkspaceFileReferenceAdapter\n} from \"../contracts/index.ts\";\n\n/**\n * 统一的「引用列表协议」—— 与 app references 同一套 group/reference/parentGroupId/cursor 形状。\n * 各源(应用 / issue / 任务…)各自实现一个 ReferenceListBackend 把自家数据映射成此协议;\n * createReferenceListSource 把协议 item 映射成 ReferenceNode,各源前端逻辑完全复用。\n * 设计见 docs/architecture/agent-reference-source-services.md。\n */\n\nexport interface ReferenceListGroup {\n type: \"group\";\n /** 不透明分组 id;作为下钻的 parentGroupId 原样回传。 */\n id: string;\n displayName: string;\n referenceCount?: number | null;\n /** 可选分组图标(data URL / 远程 URL),如应用产物源的 app 图标。 */\n iconUrl?: string | null;\n}\n\nexport interface ReferenceListFile {\n /** daemon/host 可解析的文件路径。 */\n path: string;\n displayName?: string | null;\n sizeBytes?: number | null;\n mtimeMs?: number | null;\n mimeType?: string | null;\n}\n\nexport interface ReferenceListReference {\n type: \"reference\";\n reference: ReferenceListFile;\n}\n\nexport type ReferenceListItem = ReferenceListGroup | ReferenceListReference;\n\nexport interface ReferenceListRequest {\n /** null = 根层级。 */\n parentGroupId: string | null;\n cursor?: string | null;\n filter?: string | null;\n signal?: AbortSignal;\n}\n\nexport interface ReferenceListResult {\n items: ReferenceListItem[];\n nextCursor?: string | null;\n}\n\n/** 递归搜索请求(跨整源,非当前层 filter)。 */\nexport interface ReferenceListSearchRequest {\n query: string;\n cursor?: string | null;\n limit?: number;\n signal?: AbortSignal;\n}\n\n/** 各源自治的取数适配器:把自家数据映射成统一协议。 */\nexport interface ReferenceListBackend {\n list(\n scope: ReferenceScope,\n request: ReferenceListRequest\n ): Promise<ReferenceListResult>;\n /**\n * 可选:递归搜索。实现即代表该源支持全局搜索(对应 capabilities.searchable)。\n * 返回 flat reference items(协议层不返回 group)。\n */\n search?(\n scope: ReferenceScope,\n request: ReferenceListSearchRequest\n ): Promise<ReferenceListResult>;\n}\n\nexport interface CreateReferenceListSourceInput {\n sourceId: string;\n label: string;\n order?: number;\n capabilities: ReferenceSourceCapabilities;\n isAvailable: (scope: ReferenceScope) => boolean | Promise<boolean>;\n backend: ReferenceListBackend;\n /** open/preview 复用 host 链路(协议返回的 path 可被解析打开)。 */\n adapter: WorkspaceFileReferenceAdapter;\n}\n\nconst GROUP_PREFIX = \"g:\";\nconst FILE_PREFIX = \"f:\";\n\nexport function createReferenceListSource(\n input: CreateReferenceListSourceInput\n): ReferenceSourceService {\n const { sourceId, label, capabilities, isAvailable, backend, adapter } =\n input;\n\n function fileReferenceOf(node: ReferenceNode): WorkspaceFileReference {\n return { path: decodeSegment(FILE_PREFIX, node.ref.nodeId), kind: \"file\" };\n }\n\n const service: ReferenceSourceService = {\n metadata: { id: sourceId, label, order: input.order ?? 0 },\n capabilities,\n isAvailable,\n\n async listChildren(\n scope: ReferenceScope,\n { node, cursor, filter }\n ): Promise<ListChildrenResult> {\n // file 节点没有子节点。\n if (node && node.nodeId.startsWith(FILE_PREFIX)) {\n return { entries: [], nextCursor: null };\n }\n const parentGroupId = node\n ? decodeSegment(GROUP_PREFIX, node.nodeId)\n : null;\n const result = await backend.list(scope, {\n parentGroupId,\n cursor: cursor ?? null,\n filter: filter ?? null\n });\n return {\n entries: result.items.map((item) => itemToNode(sourceId, item)),\n nextCursor: result.nextCursor ?? null\n };\n },\n\n async open(_scope: ReferenceScope, node: ReferenceNode): Promise<void> {\n await adapter.openReference?.(fileReferenceOf(node));\n },\n\n async readPreview(\n scope: ReferenceScope,\n node: ReferenceNode\n ): Promise<ReferencePreview | null> {\n if (!adapter.readReferencePreview) {\n return null;\n }\n return adapter.readReferencePreview({\n workspaceId: scope.workspaceId,\n reference: fileReferenceOf(node)\n });\n },\n\n resolveSelection(node: ReferenceNode): SelectedReference {\n return {\n path: decodeSegment(FILE_PREFIX, node.ref.nodeId),\n kind: \"file\",\n ...(node.displayName ? { displayName: node.displayName } : {})\n };\n }\n };\n\n // 仅当 backend 实现了递归搜索时才暴露 search,与 capabilities.searchable 保持一致。\n const backendSearch = backend.search?.bind(backend);\n if (backendSearch) {\n service.search = async (\n scope: ReferenceScope,\n input: SearchInput\n ): Promise<SearchResult> => {\n const result = await backendSearch(scope, {\n query: input.query,\n cursor: input.cursor ?? null,\n ...(input.limit == null ? {} : { limit: input.limit }),\n ...(input.signal ? { signal: input.signal } : {})\n });\n return {\n entries: result.items.map((item) => itemToNode(sourceId, item)),\n nextCursor: result.nextCursor ?? null\n };\n };\n }\n\n return service;\n}\n\nfunction itemToNode(sourceId: string, item: ReferenceListItem): ReferenceNode {\n if (item.type === \"group\") {\n return {\n ref: { sourceId, nodeId: GROUP_PREFIX + base64UrlEncode(item.id) },\n kind: \"folder\",\n displayName: item.displayName,\n hasChildren: true,\n ...(item.referenceCount == null\n ? {}\n : { childCount: item.referenceCount }),\n ...(item.iconUrl ? { iconUrl: item.iconUrl } : {})\n };\n }\n const reference = item.reference;\n return {\n ref: { sourceId, nodeId: FILE_PREFIX + base64UrlEncode(reference.path) },\n kind: \"file\",\n displayName: reference.displayName?.trim() || basename(reference.path),\n ...(reference.sizeBytes == null ? {} : { sizeBytes: reference.sizeBytes }),\n ...(reference.mtimeMs == null ? {} : { mtimeMs: reference.mtimeMs }),\n ...(reference.mimeType ? { mimeType: reference.mimeType } : {})\n };\n}\n\nfunction decodeSegment(prefix: string, nodeId: string): string {\n if (!nodeId.startsWith(prefix)) {\n throw new Error(\n `reference-list nodeId missing ${prefix} prefix: ${nodeId}`\n );\n }\n return base64UrlDecode(nodeId.slice(prefix.length));\n}\n\nfunction basename(path: string): string {\n const trimmed = path.replace(/\\/+$/, \"\");\n const index = trimmed.lastIndexOf(\"/\");\n return index >= 0 ? trimmed.slice(index + 1) : trimmed;\n}\n\n/** UTF-8 安全的 base64url(浏览器/Node 通用)。 */\nexport function base64UrlEncode(value: string): string {\n const bytes = new TextEncoder().encode(value);\n let binary = \"\";\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary)\n .replace(/\\+/g, \"-\")\n .replace(/\\//g, \"_\")\n .replace(/=+$/, \"\");\n}\n\nexport function base64UrlDecode(value: string): string {\n const normalized = value.replace(/-/g, \"+\").replace(/_/g, \"/\");\n const binary = atob(normalized);\n const bytes = Uint8Array.from(binary, (char) => char.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n","import type { WorkspaceFileReference } from \"../contracts/index.ts\";\n\nexport * from \"./referenceSourceUtils.ts\";\nexport * from \"./referenceSourceAggregator.ts\";\nexport * from \"./referenceListSource.ts\";\n\nexport function uniqueWorkspaceFileReferences(\n refs: readonly WorkspaceFileReference[]\n): WorkspaceFileReference[] {\n const unique = new Map<string, WorkspaceFileReference>();\n for (const ref of refs) {\n const normalizedPath = ref.path.trim();\n if (!normalizedPath || unique.has(normalizedPath)) {\n continue;\n }\n unique.set(normalizedPath, {\n displayName: ref.displayName?.trim() || undefined,\n kind: ref.kind === \"folder\" ? \"folder\" : \"file\",\n path: normalizedPath,\n ...(ref.mtimeMs === undefined ? {} : { mtimeMs: ref.mtimeMs }),\n ...(ref.sizeBytes === undefined ? {} : { sizeBytes: ref.sizeBytes })\n });\n }\n return [...unique.values()];\n}\n"],"mappings":"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","names":["input"]}
|
|
@@ -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: \"image\"; objectUrl: string; reference: WorkspaceFileReference }\n | { status: \"loading\"; 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 let browseSequence = 0;\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 browseSequence += 1;\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 sequence = ++browseSequence;\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 (!retained || sequence !== browseSequence) {\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 (!retained || sequence !== browseSequence || !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 (!retained || sequence !== browseSequence) {\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 = ++browseSequence;\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 (!retained || sequence !== browseSequence || !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 (!retained || sequence !== browseSequence) {\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\") {\n URL.revokeObjectURL(nextState.objectUrl);\n }\n return;\n }\n if (nextState.status === \"image\") {\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 = ++browseSequence;\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 (!retained || sequence !== browseSequence) {\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 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\n if (loadedState.status === \"text\") {\n return {\n content: loadedState.content,\n reference,\n status: \"text\"\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 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 searchEntries: ReferenceNode[];\n searchNextCursor: string | null;\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\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 /** 确保某节点(null=当前源根)的子节点已加载(抽屉式导航进入用,不切换展开态)。 */\n ensureChildren(node: ReferenceNode | null): void;\n /** 确保指定源的根层级已加载(左栏可同时展开多源时,为非 active 源预载分组)。 */\n ensureSourceRoot(sourceId: string): void;\n toggleNode(node: ReferenceNode): void;\n loadMore(node: ReferenceNode | null): void;\n setSearchQuery(query: string): void;\n toggleSelection(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(): Promise<SelectedReference[]>;\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\nfunction emptyTabState(sourceId: string): ReferenceSourceTabState {\n return {\n sourceId,\n expandedKeys: {},\n childrenByKey: {},\n mode: \"browse\",\n searchQuery: \"\",\n searchEntries: [],\n searchNextCursor: null,\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 let tabsSequence = 0;\n let browseSequence = 0;\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 const sequence = ++browseSequence;\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 || sequence !== browseSequence) {\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 || sequence !== browseSequence) {\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 (sourceId: string, query: string) => {\n if (!retained) {\n return;\n }\n const sequence = ++searchSequence;\n searchAbortController?.abort();\n const abortController = new AbortController();\n searchAbortController = abortController;\n updateTab(sourceId, (tab) => ({\n ...tab,\n isSearchLoading: true,\n searchError: null\n }));\n try {\n const result = await aggregator.search(scope, sourceId, {\n query,\n signal: abortController.signal\n });\n if (!retained || sequence !== searchSequence) {\n return;\n }\n updateTab(sourceId, (tab) => ({\n ...tab,\n isSearchLoading: false,\n searchEntries: sortReferenceNodes(result.entries),\n searchNextCursor: result.nextCursor ?? null,\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 searchEntries: [],\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 = (sourceId: string, query: string) => {\n clearSearchTimer();\n if (!retained || !query) {\n return;\n }\n if (searchDebounceMs <= 0) {\n void runSearch(sourceId, query);\n return;\n }\n searchTimer = setTimeout(() => {\n searchTimer = null;\n void runSearch(sourceId, query);\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 void loadTabs();\n },\n close() {\n retained = false;\n cancelSearch();\n browseSequence += 1;\n tabsSequence += 1;\n },\n reset() {\n cancelSearch();\n browseSequence += 1;\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 cancelSearch();\n setSnapshot({ activeSourceId: sourceId });\n const tab = snapshot.bySource[sourceId];\n if (tab?.mode === \"search\" && tab.searchQuery.trim()) {\n scheduleSearch(sourceId, tab.searchQuery.trim());\n } else {\n ensureRootLoaded(sourceId);\n }\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 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 setSearchQuery(query) {\n const sourceId = snapshot.activeSourceId;\n if (!sourceId) {\n return;\n }\n const trimmed = query.trim();\n const nextMode: ReferenceSourcePickerMode = trimmed ? \"search\" : \"browse\";\n updateTab(sourceId, (tab) => ({\n ...tab,\n searchQuery: query,\n mode: nextMode,\n ...(nextMode === \"browse\"\n ? { isSearchLoading: false, searchEntries: [], searchError: null }\n : {})\n }));\n if (nextMode === \"search\") {\n scheduleSearch(sourceId, trimmed);\n } else {\n cancelSearch();\n ensureRootLoaded(sourceId);\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 clearSelection() {\n setSnapshot({ selection: [] });\n },\n async confirm() {\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 snapshot.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 };\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","tab"]}
|