@knkcs/mediahub-ui 0.1.0
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/index.d.ts +1686 -0
- package/dist/index.js +4357 -0
- package/dist/index.js.map +1 -0
- package/dist/testing.d.ts +487 -0
- package/dist/testing.js +413 -0
- package/dist/testing.js.map +1 -0
- package/package.json +71 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/lib/rpc-errors.ts","../src/connect-clients.ts","../src/provider.tsx","../src/statushub.ts","../src/lib/sas-upload.ts","../src/hooks/use-add-version.ts","../src/hooks/use-assets.ts","../src/hooks/use-authz.ts","../src/hooks/use-folders.ts","../src/hooks/use-grants.ts","../src/hooks/use-collections.ts","../src/hooks/use-tags.ts","../src/hooks/use-asset-types.ts","../src/hooks/use-users.ts","../src/hooks/use-dashboard.ts","../src/hooks/use-ai-connections.ts","../src/hooks/use-ai-processes.ts","../src/hooks/use-ai-process-runs.ts","../src/stores/selection-store.ts","../src/stores/preferences-store.ts","../src/stores/upload-store.ts","../src/components/asset-status-badge.tsx","../src/components/asset-grid.tsx","../src/components/asset-preview.tsx","../src/components/asset-status-control.tsx","../src/components/bulk-action-bar.tsx","../src/components/collection-chip-field.tsx","../src/components/collection-panel.tsx","../src/components/folder-breadcrumbs.tsx","../src/components/leak-guard-refusal-dialog.tsx","../src/lib/move-guard.ts","../src/components/manage-access-dialog.tsx","../src/components/move-dialog.tsx","../src/components/restricted.tsx","../src/components/restricted-folder-dialog.tsx","../src/components/folder-tree.tsx","../src/components/inline-edit-field.tsx","../src/components/tag-chip-field.tsx","../src/components/tag-panel.tsx","../src/components/upload/upload-dialog.tsx","../src/components/upload/upload-drop-zone.tsx","../src/components/upload/upload-toast-stack.tsx","../src/asset-library-resolve.ts","../src/asset-library.tsx","../src/lib/asset-metadata-form.ts","../src/asset-detail.tsx","../src/components/picker/picker-asset-card.tsx","../src/components/picker/picker-footer.tsx","../src/components/picker/use-picker-selection.ts","../src/asset-picker.tsx","../src/collection-picker.tsx","../src/index.ts"],"sourcesContent":["import { toaster } from \"@knkcs/anker/primitives\";\n\n/**\n * Transport-level error mapping (guardian#50): permission denials and\n * leak-guard conflicts become human-readable descriptions; every other error\n * keeps the server's message, which for validation failures is deliberate\n * guidance.\n *\n * The mapping is structural on purpose — mediahub-ui takes no dependency on\n * `@connectrpc/connect` or generated proto types. A ConnectError is\n * recognized by its numeric `code`; a leak-guard conflict by an error detail\n * of type `mediahub.v1.LeakGuardViolation`, whose `debug` field carries the\n * server's protoJSON (Connect JSON protocol) naming the refusing rule and\n * the asset→collection exposures involved.\n */\n\n/** Connect/gRPC wire codes (subset we map). */\nconst CODE_PERMISSION_DENIED = 7;\nconst CODE_FAILED_PRECONDITION = 9;\nconst CODE_UNAVAILABLE = 14;\n\nconst LEAK_GUARD_DETAIL_TYPE = \"mediahub.v1.LeakGuardViolation\";\n\n/** One offending asset→collection pair behind a leak-guard refusal. */\nexport interface LeakGuardExposure {\n\tassetId: string;\n\tassetName: string;\n\tcollectionId: string;\n\tcollectionName: string;\n}\n\nexport interface RpcErrorDescription {\n\tkind: \"permission-denied\" | \"leak-guard\" | \"other\";\n\ttitle: string;\n\tdescription: string;\n\t/** Present for leak-guard conflicts: the items the refusal involves. */\n\texposures?: LeakGuardExposure[];\n\t/** Present for leak-guard conflicts: the refusing rule's explanation\n\t * without the joined item list — for surfaces that render `exposures`\n\t * themselves (e.g. the refusal dialog). */\n\truleText?: string;\n}\n\nconst PERMISSION_DENIED_TITLE = \"You don't have access\";\nconst PERMISSION_DENIED_BODY =\n\t\"You don't have permission to do this. The item's Owner or a workspace admin can grant you access.\";\n\nconst LEAK_GUARD_TITLE = \"Blocked to prevent a leak\";\nconst LEAK_GUARD_GENERIC =\n\t\"This change would expose Restricted material, so it was refused.\";\n\n/** Explanations per refusing rule, keyed by the wire enum's protoJSON name. */\nconst LEAK_GUARD_RULES: Record<string, string> = {\n\tLEAK_GUARD_RULE_RESTRICTED_ASSET_INTO_OPEN_COLLECTION:\n\t\t\"These assets live in a Restricted folder. An open collection is visible to the whole workspace, so adding them would leak Restricted material.\",\n\tLEAK_GUARD_RULE_ASSET_INTO_RESTRICTED_CHAIN_WHILE_EXPOSED:\n\t\t\"An open collection still exposes this asset, so moving it into a Restricted folder would leak Restricted material. Remove it from the collection first.\",\n\tLEAK_GUARD_RULE_FOLDER_INTO_RESTRICTED_CHAIN_WHILE_EXPOSED:\n\t\t\"An open collection still exposes assets inside this folder, so moving it under a Restricted folder would leak Restricted material. Remove those assets from their collections first.\",\n};\n\nfunction connectCode(err: unknown): number | undefined {\n\tif (typeof err !== \"object\" || err === null) return undefined;\n\tconst code = (err as { code?: unknown }).code;\n\treturn typeof code === \"number\" ? code : undefined;\n}\n\n/** Whether an RPC failure is a Connect permission denial. Callers that probe\n * for authority (a denial means \"not an authority\", not \"broken\") branch on\n * this instead of re-implementing the structural code check. */\nexport function isPermissionDenied(err: unknown): boolean {\n\treturn connectCode(err) === CODE_PERMISSION_DENIED;\n}\n\n/**\n * Whether an RPC failure is \"try again in a moment\" rather than a verdict.\n *\n * The server refuses a status change, and a behavior-filtered listing, with\n * Unavailable while statushub cannot be reached (statushub integration\n * standard §6, knkCS/mediahub#120) — the one code that means the same request,\n * unchanged, will work once the service answers again. mediahub being\n * unreachable itself arrives as the same code and means the same thing to the\n * reader, so the two are deliberately not told apart.\n */\nexport function isRetryableUnavailable(err: unknown): boolean {\n\treturn connectCode(err) === CODE_UNAVAILABLE;\n}\n\nfunction isLeakGuardDetailType(type: unknown): boolean {\n\treturn (\n\t\ttypeof type === \"string\" &&\n\t\t(type === LEAK_GUARD_DETAIL_TYPE ||\n\t\t\ttype.endsWith(`/${LEAK_GUARD_DETAIL_TYPE}`))\n\t);\n}\n\ninterface LeakGuardViolation {\n\trule?: string;\n\texposures: LeakGuardExposure[];\n}\n\nfunction asExposure(raw: unknown): LeakGuardExposure {\n\tconst r = (raw ?? {}) as Record<string, unknown>;\n\tconst str = (v: unknown) => (typeof v === \"string\" ? v : \"\");\n\treturn {\n\t\tassetId: str(r.assetId),\n\t\tassetName: str(r.assetName),\n\t\tcollectionId: str(r.collectionId),\n\t\tcollectionName: str(r.collectionName),\n\t};\n}\n\n/** Reads the violation from a detail's protoJSON `debug` (or from a decoded\n * message carrying `$typeName`). `rule` stays a protoJSON enum name. */\nfunction violationFrom(raw: unknown): LeakGuardViolation {\n\tif (typeof raw !== \"object\" || raw === null) return { exposures: [] };\n\tconst v = raw as Record<string, unknown>;\n\tconst exposures = Array.isArray(v.exposures)\n\t\t? v.exposures.map(asExposure)\n\t\t: [];\n\treturn { rule: typeof v.rule === \"string\" ? v.rule : undefined, exposures };\n}\n\nfunction findLeakGuardViolation(err: unknown): LeakGuardViolation | undefined {\n\tconst details = (err as { details?: unknown }).details;\n\tif (!Array.isArray(details)) return undefined;\n\tfor (const d of details) {\n\t\tif (typeof d !== \"object\" || d === null) continue;\n\t\tconst entry = d as Record<string, unknown>;\n\t\t// Wire shape from the Connect JSON protocol: { type, value, debug? }.\n\t\tif (isLeakGuardDetailType(entry.type)) {\n\t\t\treturn violationFrom(entry.debug);\n\t\t}\n\t\t// Already-decoded message (e.g. via findDetails with a registry).\n\t\tif (isLeakGuardDetailType(entry.$typeName)) {\n\t\t\treturn violationFrom(entry);\n\t\t}\n\t}\n\treturn undefined;\n}\n\n/**\n * Describes an RPC failure for the user. Permission denials and leak-guard\n * conflicts get mapped copy (never the raw server string); anything else\n * keeps the server's message under the caller's title, matching the previous\n * toast behavior.\n */\nexport function describeRpcError(\n\terr: unknown,\n\tfallbackTitle: string,\n): RpcErrorDescription {\n\tconst code = connectCode(err);\n\n\tif (code === CODE_PERMISSION_DENIED) {\n\t\treturn {\n\t\t\tkind: \"permission-denied\",\n\t\t\ttitle: PERMISSION_DENIED_TITLE,\n\t\t\tdescription: PERMISSION_DENIED_BODY,\n\t\t};\n\t}\n\n\tif (code === CODE_FAILED_PRECONDITION) {\n\t\tconst violation = findLeakGuardViolation(err);\n\t\tif (violation) {\n\t\t\tconst rule =\n\t\t\t\t(violation.rule && LEAK_GUARD_RULES[violation.rule]) ??\n\t\t\t\tLEAK_GUARD_GENERIC;\n\t\t\t// Single-line join: toast descriptions render as HTML text, where\n\t\t\t// newlines collapse to spaces.\n\t\t\tconst items = violation.exposures\n\t\t\t\t.map((e) => `${e.assetName} — in collection “${e.collectionName}”`)\n\t\t\t\t.join(\" • \");\n\t\t\treturn {\n\t\t\t\tkind: \"leak-guard\",\n\t\t\t\ttitle: LEAK_GUARD_TITLE,\n\t\t\t\tdescription: items ? `${rule} Involved: ${items}` : rule,\n\t\t\t\texposures: violation.exposures,\n\t\t\t\truleText: rule,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn {\n\t\tkind: \"other\",\n\t\ttitle: fallbackTitle,\n\t\tdescription:\n\t\t\terr instanceof Error ? err.message : \"An unexpected error occurred\",\n\t};\n}\n\n/**\n * The app-wide error toast: maps the failure with describeRpcError and shows\n * it. `fallbackTitle` is used only for errors outside the two mapped\n * families, preserving each call site's existing title.\n */\nexport function showRpcErrorToast(err: unknown, fallbackTitle: string): void {\n\tconst d = describeRpcError(err, fallbackTitle);\n\ttoaster.error({ title: d.title, description: d.description });\n}\n","// Structural shapes of the generated Connect service clients we depend on —\n// defined here rather than imported from web/src/gen so this package keeps\n// ZERO @connectrpc/proto peerDeps (odon pattern). Hosts pass their generated\n// clients (createClient(Service, transport)) which satisfy these structurally.\nimport type {\n\tAIConnectionClient,\n\tAIProcessClient,\n\tAssetClient,\n\tAssetTypeClient,\n\tAuthzClient,\n\tCollectionClient,\n\tDashboardClient,\n\tDirectoryClient,\n\tFolderClient,\n\tGrantClient,\n\tMediahubClients,\n\tTagClient,\n} from \"./clients\";\nimport { isPermissionDenied } from \"./lib/rpc-errors\";\nimport type {\n\tAIConnectionInfo,\n\tAIProcessInfo,\n\tAIProcessRunInfo,\n\tAssetInfo,\n\tAssetTypeInfo,\n\tAssetVersionInfo,\n\tCollectionInfo,\n\tCollectionType,\n\tFolderInfo,\n\tGrantEntry,\n\tGrantLevel,\n\tGrantResourceType,\n\tTagInfo,\n\tUserInfo,\n\tWorkspaceStats,\n} from \"./types\";\n\ntype Ts = { seconds: bigint; nanos: number } | undefined;\nconst mapTs = (t: Ts): Date | undefined =>\n\tt\n\t\t? new Date(Number(t.seconds) * 1000 + Math.floor(t.nanos / 1e6))\n\t\t: undefined;\n\nconst COLLTYPE_TO_NUM: Record<CollectionType, number> = {\n\tunspecified: 0,\n\tstatic: 1,\n\tsmart: 2,\n};\nconst NUM_TO_COLLTYPE: CollectionType[] = [\"unspecified\", \"static\", \"smart\"];\n\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapVersion = (v: any): AssetVersionInfo => ({\n\tid: v.id,\n\tversionNumber: v.versionNumber,\n\toriginalFilename: v.originalFilename,\n\tstorageKey: v.storageKey,\n\tfileSize: Number(v.fileSize),\n\tmimeType: v.mimeType,\n\tcreatedBy: v.createdBy,\n\tcomment: v.comment,\n\tcreatedAt: mapTs(v.createdAt),\n});\n/** Wire → domain: metadata travels as a JSON document (see asset.proto).\n * Malformed input degrades to {} — reads must never throw. */\nfunction parseAssetMetadata(raw: string | undefined): Record<string, unknown> {\n\tif (!raw) return {};\n\ttry {\n\t\tconst parsed = JSON.parse(raw) as unknown;\n\t\treturn typeof parsed === \"object\" &&\n\t\t\tparsed !== null &&\n\t\t\t!Array.isArray(parsed)\n\t\t\t? (parsed as Record<string, unknown>)\n\t\t\t: {};\n\t} catch {\n\t\treturn {};\n\t}\n}\n\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapAsset = (a: any): AssetInfo => ({\n\tid: a.id,\n\tworkspaceId: a.workspaceId,\n\tname: a.name,\n\tdescription: a.description,\n\tstatusSlug: a.statusSlug ?? \"\",\n\tcurrentVersion: a.currentVersion,\n\tmetadata: parseAssetMetadata(a.metadata),\n\tassetTypeId: a.assetTypeId,\n\tfolderId: a.folderId,\n\tcreatedBy: a.createdBy,\n\tupdatedBy: a.updatedBy,\n\tcreatedAt: mapTs(a.createdAt),\n\tupdatedAt: mapTs(a.updatedAt),\n\tversions: (a.versions ?? []).map(mapVersion),\n\ttagIds: a.tagIds ?? [],\n\tcollectionIds: a.collectionIds ?? [],\n\tanalyzeWithAi: a.analyzeWithAi ?? false,\n});\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapFolder = (f: any): FolderInfo => ({\n\tid: f.id,\n\tworkspaceId: f.workspaceId,\n\tname: f.name,\n\tslug: f.slug,\n\tparentId: f.parentId,\n\trestricted: f.restricted ?? false,\n});\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapCollection = (c: any): CollectionInfo => ({\n\tid: c.id,\n\tworkspaceId: c.workspaceId,\n\tname: c.name,\n\tslug: c.slug,\n\tdescription: c.description,\n\ttype: NUM_TO_COLLTYPE[c.type] ?? \"unspecified\",\n\trules: c.rules,\n\trestricted: c.restricted ?? false,\n});\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapTag = (t: any): TagInfo => ({\n\tid: t.id,\n\tworkspaceId: t.workspaceId,\n\tname: t.name,\n\tslug: t.slug,\n});\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapAssetType = (t: any): AssetTypeInfo => ({\n\tid: t.id,\n\tworkspaceId: t.workspaceId,\n\tname: t.name,\n\tslug: t.slug,\n\tdescription: t.description,\n\tallowedMimeTypes: t.allowedMimeTypes ?? [],\n\tmetadataSchema: t.metadataSchema,\n\tactive: t.active,\n});\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapAIConnection = (c: any): AIConnectionInfo => ({\n\tid: c.id,\n\tworkspaceId: c.workspaceId,\n\tname: c.name,\n\tprovider: c.provider,\n\tendpoint: c.endpoint ?? \"\",\n\tdeployment: c.deployment ?? \"\",\n\tapiVersion: c.apiVersion ?? \"\",\n\tbaseUrl: c.baseUrl ?? \"\",\n\tmodel: c.model ?? \"\",\n\tdescription: c.description ?? \"\",\n\tactive: c.active,\n\thasApiKey: c.hasApiKey,\n});\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapAIProcess = (p: any): AIProcessInfo => ({\n\tid: p.id,\n\tworkspaceId: p.workspaceId,\n\tassetTypeId: p.assetTypeId,\n\tconnectionId: p.connectionId,\n\tname: p.name,\n\tprompt: p.prompt,\n\toutputs: (p.outputs ?? []).map(\n\t\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\t\t(o: any) => ({\n\t\t\tkey: o.key,\n\t\t\ttarget: o.target,\n\t\t\tmetadataAccessor: o.metadataAccessor ?? \"\",\n\t\t}),\n\t),\n\tposition: p.position ?? 0,\n\tactive: p.active,\n});\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\nconst mapAIProcessRun = (r: any): AIProcessRunInfo => ({\n\tid: r.id,\n\taiProcessId: r.aiProcessId,\n\tprocessName: r.processName ?? \"\",\n\tstatus: r.status ?? \"\",\n\terror: r.error ?? \"\",\n\tstartedAt: mapTs(r.startedAt),\n\tfinishedAt: mapTs(r.finishedAt),\n});\n\n// ─── Asset ────────────────────────────────────────────────────────────────────\n\n// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\ntype ProtoResponse = { [key: string]: any };\n\nexport interface ConnectAssetServiceClient {\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tlistAssets(req: any): Promise<{\n\t\tassets: ProtoResponse[];\n\t\tpagination?: {\n\t\t\ttotal: number;\n\t\t\tpage: number;\n\t\t\tpageSize: number;\n\t\t\ttotalPages: number;\n\t\t};\n\t}>;\n\tgetAsset(req: { id: string }): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tcreateAsset(req: any): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tupdateAsset(req: any): Promise<ProtoResponse>;\n\tdeleteAsset(req: { id: string }): Promise<unknown>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tgetUploadURL(req: any): Promise<{ uploadUrl: string; versionId: string }>;\n\tfinalizeUpload(req: { versionId: string }): Promise<ProtoResponse>;\n\tgetDownloadURL(req: { assetId: string; versionId: string }): Promise<{\n\t\tdownloadUrl: string;\n\t}>;\n\tmoveAsset(req: { id: string; folderId: string }): Promise<ProtoResponse>;\n\ttransitionAssetStatus(req: {\n\t\tid: string;\n\t\tfromStatusSlug: string;\n\t\ttoStatusSlug: string;\n\t}): Promise<ProtoResponse>;\n\tenhanceAssetMetadata(req: { assetId: string }): Promise<ProtoResponse>;\n\tlistAIProcessRuns(req: { assetId: string }): Promise<{\n\t\truns: ProtoResponse[];\n\t}>;\n}\n\nexport function createConnectAssetClient(\n\tc: ConnectAssetServiceClient,\n): AssetClient {\n\treturn {\n\t\tasync list(workspaceId, f) {\n\t\t\tconst res = await c.listAssets({\n\t\t\t\tworkspaceId,\n\t\t\t\tfolderId: f.folderId ?? \"\",\n\t\t\t\tassetTypeId: f.assetTypeId ?? \"\",\n\t\t\t\tstatusSlug: f.statusSlug ?? \"\",\n\t\t\t\tsearch: f.search ?? \"\",\n\t\t\t\tbehavior: f.behavior && f.behavior !== \"unspecified\" ? f.behavior : \"\",\n\t\t\t\ttagIds: f.tagIds ?? [],\n\t\t\t\tcollectionIds: f.collectionIds ?? [],\n\t\t\t});\n\t\t\tconst p = res.pagination;\n\t\t\treturn {\n\t\t\t\titems: res.assets.map(mapAsset),\n\t\t\t\ttotal: p?.total ?? res.assets.length,\n\t\t\t\tpage: p?.page ?? 1,\n\t\t\t\tpageSize: p?.pageSize ?? res.assets.length,\n\t\t\t\ttotalPages: p?.totalPages ?? 1,\n\t\t\t};\n\t\t},\n\t\tasync get(id) {\n\t\t\treturn mapAsset((await c.getAsset({ id })).asset);\n\t\t},\n\t\tasync create(workspaceId, params) {\n\t\t\treturn mapAsset(\n\t\t\t\t(\n\t\t\t\t\tawait c.createAsset({\n\t\t\t\t\t\tworkspaceId,\n\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\tdescription: params.description ?? \"\",\n\t\t\t\t\t\tassetTypeId: params.assetTypeId,\n\t\t\t\t\t\tfolderId: params.folderId ?? \"\",\n\t\t\t\t\t\tmetadata: JSON.stringify(params.metadata ?? {}),\n\t\t\t\t\t\tanalyzeWithAi: params.analyzeWithAi,\n\t\t\t\t\t})\n\t\t\t\t).asset,\n\t\t\t);\n\t\t},\n\t\tasync update(id, patch) {\n\t\t\treturn mapAsset(\n\t\t\t\t(\n\t\t\t\t\tawait c.updateAsset({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tname: patch.name ?? \"\",\n\t\t\t\t\t\tdescription: patch.description ?? \"\",\n\t\t\t\t\t\tmetadata: JSON.stringify(patch.metadata ?? {}),\n\t\t\t\t\t})\n\t\t\t\t).asset,\n\t\t\t);\n\t\t},\n\t\tasync delete(id) {\n\t\t\tawait c.deleteAsset({ id });\n\t\t},\n\t\tasync getUploadUrl(p) {\n\t\t\tconst r = await c.getUploadURL({\n\t\t\t\tassetId: p.assetId,\n\t\t\t\tfilename: p.filename,\n\t\t\t\tcontentType: p.contentType,\n\t\t\t\tfileSize: BigInt(p.fileSize),\n\t\t\t\tcomment: p.comment ?? \"\",\n\t\t\t});\n\t\t\treturn { uploadUrl: r.uploadUrl, versionId: r.versionId };\n\t\t},\n\t\tasync finalizeUpload(versionId) {\n\t\t\treturn mapAsset((await c.finalizeUpload({ versionId })).asset);\n\t\t},\n\t\tasync getDownloadUrl(assetId, versionId) {\n\t\t\treturn (await c.getDownloadURL({ assetId, versionId })).downloadUrl;\n\t\t},\n\t\tasync move(id, folderId) {\n\t\t\treturn mapAsset((await c.moveAsset({ id, folderId })).asset);\n\t\t},\n\t\tasync transitionStatus(id, fromStatusSlug, toStatusSlug) {\n\t\t\treturn mapAsset(\n\t\t\t\t(await c.transitionAssetStatus({ id, fromStatusSlug, toStatusSlug }))\n\t\t\t\t\t.asset,\n\t\t\t);\n\t\t},\n\t\tasync enhanceMetadata(id) {\n\t\t\treturn mapAsset((await c.enhanceAssetMetadata({ assetId: id })).asset);\n\t\t},\n\t\tasync listProcessRuns(assetId) {\n\t\t\tconst res = await c.listAIProcessRuns({ assetId });\n\t\t\treturn res.runs.map(mapAIProcessRun);\n\t\t},\n\t};\n}\n\n// ─── Folder ───────────────────────────────────────────────────────────────────\n\nexport interface ConnectFolderServiceClient {\n\tlistFolders(req: { workspaceId: string; parentId: string }): Promise<{\n\t\tfolders: ProtoResponse[];\n\t}>;\n\tgetFolder(req: { id: string }): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tcreateFolder(req: any): Promise<ProtoResponse>;\n\tupdateFolder(req: { id: string; name: string }): Promise<ProtoResponse>;\n\tdeleteFolder(req: { id: string }): Promise<unknown>;\n\tmoveFolder(req: { id: string; parentId: string }): Promise<ProtoResponse>;\n\t/** Restricted toggles — land with guardian#53; optional so the package\n\t * keeps accepting pre-#53 generated clients. */\n\trestrictFolder?(req: { id: string }): Promise<ProtoResponse>;\n\tunrestrictFolder?(req: { id: string }): Promise<ProtoResponse>;\n}\n\nexport function createConnectFolderClient(\n\tc: ConnectFolderServiceClient,\n): FolderClient {\n\treturn {\n\t\tasync list(workspaceId, parentId) {\n\t\t\tconst res = await c.listFolders({ workspaceId, parentId });\n\t\t\treturn res.folders.map(mapFolder);\n\t\t},\n\t\tasync get(id) {\n\t\t\treturn mapFolder((await c.getFolder({ id })).folder);\n\t\t},\n\t\tasync create(params) {\n\t\t\treturn mapFolder(\n\t\t\t\t(\n\t\t\t\t\tawait c.createFolder({\n\t\t\t\t\t\tworkspaceId: params.workspaceId,\n\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\tslug: params.slug,\n\t\t\t\t\t\tparentId: params.parentId,\n\t\t\t\t\t\trestricted: params.restricted ?? false,\n\t\t\t\t\t})\n\t\t\t\t).folder,\n\t\t\t);\n\t\t},\n\t\tasync update(id, name) {\n\t\t\treturn mapFolder((await c.updateFolder({ id, name })).folder);\n\t\t},\n\t\tasync delete(id) {\n\t\t\tawait c.deleteFolder({ id });\n\t\t},\n\t\tasync move(id, parentId) {\n\t\t\treturn mapFolder((await c.moveFolder({ id, parentId })).folder);\n\t\t},\n\t\tasync setRestricted(id, restricted) {\n\t\t\tconst call = restricted ? c.restrictFolder : c.unrestrictFolder;\n\t\t\tif (typeof call !== \"function\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"This server can't toggle Restricted yet (RestrictFolder/UnrestrictFolder, guardian#53).\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn mapFolder((await call({ id })).folder);\n\t\t},\n\t};\n}\n\n// ─── Collection ───────────────────────────────────────────────────────────────\n\nexport interface ConnectCollectionServiceClient {\n\tlistCollections(req: { workspaceId: string }): Promise<{\n\t\tcollections: ProtoResponse[];\n\t}>;\n\tgetCollection(req: { id: string }): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tcreateCollection(req: any): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tupdateCollection(req: any): Promise<ProtoResponse>;\n\tdeleteCollection(req: { id: string }): Promise<unknown>;\n\taddAssets(req: {\n\t\tcollectionId: string;\n\t\tassetIds: string[];\n\t}): Promise<unknown>;\n\tremoveAssets(req: {\n\t\tcollectionId: string;\n\t\tassetIds: string[];\n\t}): Promise<unknown>;\n\t/** Restricted toggles — land with guardian#53; optional so the package\n\t * keeps accepting pre-#53 generated clients. */\n\trestrictCollection?(req: { id: string }): Promise<ProtoResponse>;\n\tunrestrictCollection?(req: { id: string }): Promise<ProtoResponse>;\n}\n\nexport function createConnectCollectionClient(\n\tc: ConnectCollectionServiceClient,\n): CollectionClient {\n\treturn {\n\t\tasync list(workspaceId) {\n\t\t\tconst res = await c.listCollections({ workspaceId });\n\t\t\treturn res.collections.map(mapCollection);\n\t\t},\n\t\tasync get(id) {\n\t\t\treturn mapCollection((await c.getCollection({ id })).collection);\n\t\t},\n\t\tasync create(params) {\n\t\t\treturn mapCollection(\n\t\t\t\t(\n\t\t\t\t\tawait c.createCollection({\n\t\t\t\t\t\tworkspaceId: params.workspaceId,\n\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\tslug: params.slug,\n\t\t\t\t\t\tdescription: params.description,\n\t\t\t\t\t\ttype: COLLTYPE_TO_NUM[params.type],\n\t\t\t\t\t\trules: params.rules,\n\t\t\t\t\t\trestricted: params.restricted ?? false,\n\t\t\t\t\t})\n\t\t\t\t).collection,\n\t\t\t);\n\t\t},\n\t\tasync update(id, patch) {\n\t\t\treturn mapCollection(\n\t\t\t\t(\n\t\t\t\t\tawait c.updateCollection({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tname: patch.name ?? \"\",\n\t\t\t\t\t\tdescription: patch.description ?? \"\",\n\t\t\t\t\t\trules: patch.rules ?? \"\",\n\t\t\t\t\t})\n\t\t\t\t).collection,\n\t\t\t);\n\t\t},\n\t\tasync delete(id) {\n\t\t\tawait c.deleteCollection({ id });\n\t\t},\n\t\tasync addAssets(collectionId, assetIds) {\n\t\t\tawait c.addAssets({ collectionId, assetIds });\n\t\t},\n\t\tasync removeAssets(collectionId, assetIds) {\n\t\t\tawait c.removeAssets({ collectionId, assetIds });\n\t\t},\n\t\tasync setRestricted(id, restricted) {\n\t\t\tconst call = restricted ? c.restrictCollection : c.unrestrictCollection;\n\t\t\tif (typeof call !== \"function\") {\n\t\t\t\tthrow new Error(\n\t\t\t\t\t\"This server can't toggle Restricted yet (RestrictCollection/UnrestrictCollection, guardian#53).\",\n\t\t\t\t);\n\t\t\t}\n\t\t\treturn mapCollection((await call({ id })).collection);\n\t\t},\n\t};\n}\n\n// ─── Tag ──────────────────────────────────────────────────────────────────────\n\nexport interface ConnectTagServiceClient {\n\tlistTags(req: { workspaceId: string }): Promise<{ tags: ProtoResponse[] }>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tcreateTag(req: any): Promise<ProtoResponse>;\n\tupdateTag(req: { id: string; name: string }): Promise<ProtoResponse>;\n\tdeleteTag(req: { id: string }): Promise<unknown>;\n\ttagAssets(req: { tagId: string; assetIds: string[] }): Promise<unknown>;\n\tuntagAssets(req: { tagId: string; assetIds: string[] }): Promise<unknown>;\n}\n\nexport function createConnectTagClient(c: ConnectTagServiceClient): TagClient {\n\treturn {\n\t\tasync list(workspaceId) {\n\t\t\tconst res = await c.listTags({ workspaceId });\n\t\t\treturn res.tags.map(mapTag);\n\t\t},\n\t\tasync create(params) {\n\t\t\treturn mapTag(\n\t\t\t\t(\n\t\t\t\t\tawait c.createTag({\n\t\t\t\t\t\tworkspaceId: params.workspaceId,\n\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\tslug: params.slug,\n\t\t\t\t\t})\n\t\t\t\t).tag,\n\t\t\t);\n\t\t},\n\t\tasync update(id, name) {\n\t\t\treturn mapTag((await c.updateTag({ id, name })).tag);\n\t\t},\n\t\tasync delete(id) {\n\t\t\tawait c.deleteTag({ id });\n\t\t},\n\t\tasync tagAssets(tagId, assetIds) {\n\t\t\tawait c.tagAssets({ tagId, assetIds });\n\t\t},\n\t\tasync untagAssets(tagId, assetIds) {\n\t\t\tawait c.untagAssets({ tagId, assetIds });\n\t\t},\n\t};\n}\n\n// ─── Asset Type ───────────────────────────────────────────────────────────────\n\nexport interface ConnectAssetTypeServiceClient {\n\tlistAssetTypes(req: { workspaceId: string }): Promise<{\n\t\tassetTypes: ProtoResponse[];\n\t}>;\n\tgetAssetType(req: { id: string }): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tcreateAssetType(req: any): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tupdateAssetType(req: any): Promise<ProtoResponse>;\n\tdeleteAssetType(req: { id: string }): Promise<unknown>;\n}\n\nexport function createConnectAssetTypeClient(\n\tc: ConnectAssetTypeServiceClient,\n): AssetTypeClient {\n\treturn {\n\t\tasync list(workspaceId) {\n\t\t\tconst res = await c.listAssetTypes({ workspaceId });\n\t\t\treturn res.assetTypes.map(mapAssetType);\n\t\t},\n\t\tasync get(id) {\n\t\t\treturn mapAssetType((await c.getAssetType({ id })).assetType);\n\t\t},\n\t\tasync create(params) {\n\t\t\treturn mapAssetType(\n\t\t\t\t(\n\t\t\t\t\tawait c.createAssetType({\n\t\t\t\t\t\tworkspaceId: params.workspaceId,\n\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\tslug: params.slug,\n\t\t\t\t\t\tdescription: params.description,\n\t\t\t\t\t\tallowedMimeTypes: params.allowedMimeTypes,\n\t\t\t\t\t\tmetadataSchema: params.metadataSchema,\n\t\t\t\t\t})\n\t\t\t\t).assetType,\n\t\t\t);\n\t\t},\n\t\tasync update(id, patch) {\n\t\t\treturn mapAssetType(\n\t\t\t\t(\n\t\t\t\t\tawait c.updateAssetType({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tname: patch.name ?? \"\",\n\t\t\t\t\t\tdescription: patch.description ?? \"\",\n\t\t\t\t\t\tallowedMimeTypes: patch.allowedMimeTypes ?? [],\n\t\t\t\t\t\tmetadataSchema: patch.metadataSchema ?? \"\",\n\t\t\t\t\t\tactive: patch.active ?? true,\n\t\t\t\t\t})\n\t\t\t\t).assetType,\n\t\t\t);\n\t\t},\n\t\tasync delete(id) {\n\t\t\tawait c.deleteAssetType({ id });\n\t\t},\n\t};\n}\n\n// ─── User / Directory ─────────────────────────────────────────────────────────\n\nexport interface ConnectUserServiceClient {\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tresolveUsers(req: { userIds: string[] }): Promise<{ users: any[] }>;\n\tlistWorkspaceMembers(req: {\n\t\tworkspaceId: string;\n\t\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\t}): Promise<{ members: any[] }>;\n}\n\nexport function createConnectDirectoryClient(\n\tc: ConnectUserServiceClient,\n): DirectoryClient {\n\treturn {\n\t\tasync resolveUsers(ids) {\n\t\t\tconst res = await c.resolveUsers({ userIds: ids });\n\t\t\t// The wire type is any-erased at the client boundary (interface\n\t\t\t// above); type the two fields we actually consume.\n\t\t\treturn (res.users ?? []).map(\n\t\t\t\t(u: { id: string; displayName: string }): UserInfo => ({\n\t\t\t\t\tid: u.id,\n\t\t\t\t\tdisplayName: u.displayName,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\tasync listWorkspaceMembers(workspaceId) {\n\t\t\tconst res = await c.listWorkspaceMembers({ workspaceId });\n\t\t\treturn (res.members ?? []).map(\n\t\t\t\t(m: { userId: string; displayName: string }): UserInfo => ({\n\t\t\t\t\tid: m.userId,\n\t\t\t\t\tdisplayName: m.displayName,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t};\n}\n\n// ─── Grants ───────────────────────────────────────────────────────────────────\n\nconst GRANT_RESOURCE_TO_NUM: Record<GrantResourceType, number> = {\n\tasset: 1,\n\tfolder: 2,\n\tcollection: 3,\n};\n/** Wire → domain levels; anything unknown maps to undefined and is dropped\n * rather than invented (same distrust as the service's tuple reads). */\nconst NUM_TO_GRANT_LEVEL: Record<number, GrantLevel | undefined> = {\n\t1: \"viewer\",\n\t2: \"editor\",\n};\nconst GRANT_LEVEL_TO_NUM: Record<GrantLevel, number> = {\n\tviewer: 1,\n\teditor: 2,\n};\n\nexport interface ConnectGrantServiceClient {\n\tgrantAccess(req: {\n\t\tresourceType: number;\n\t\tresourceId: string;\n\t\tuserId: string;\n\t\tlevel: number;\n\t}): Promise<unknown>;\n\trevokeAccess(req: {\n\t\tresourceType: number;\n\t\tresourceId: string;\n\t\tuserId: string;\n\t}): Promise<unknown>;\n\tlistGrants(req: { resourceType: number; resourceId: string }): Promise<{\n\t\townerUserId: string;\n\t\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\t\tgrants: any[];\n\t}>;\n}\n\nexport function createConnectGrantClient(\n\tc: ConnectGrantServiceClient,\n): GrantClient {\n\treturn {\n\t\tasync list(resourceType, resourceId) {\n\t\t\tconst res = await c.listGrants({\n\t\t\t\tresourceType: GRANT_RESOURCE_TO_NUM[resourceType],\n\t\t\t\tresourceId,\n\t\t\t});\n\t\t\tconst grants: GrantEntry[] = [];\n\t\t\tfor (const g of res.grants ?? []) {\n\t\t\t\tconst level = NUM_TO_GRANT_LEVEL[g.level as number];\n\t\t\t\tif (level) grants.push({ userId: g.userId as string, level });\n\t\t\t}\n\t\t\treturn { ownerUserId: res.ownerUserId ?? \"\", grants };\n\t\t},\n\t\tasync grant(resourceType, resourceId, userId, level) {\n\t\t\tawait c.grantAccess({\n\t\t\t\tresourceType: GRANT_RESOURCE_TO_NUM[resourceType],\n\t\t\t\tresourceId,\n\t\t\t\tuserId,\n\t\t\t\tlevel: GRANT_LEVEL_TO_NUM[level],\n\t\t\t});\n\t\t},\n\t\tasync revoke(resourceType, resourceId, userId) {\n\t\t\tawait c.revokeAccess({\n\t\t\t\tresourceType: GRANT_RESOURCE_TO_NUM[resourceType],\n\t\t\t\tresourceId,\n\t\t\t\tuserId,\n\t\t\t});\n\t\t},\n\t};\n}\n\n/**\n * Authority probe (guardian#55): GrantService gates every call — ListGrants\n * included — on exactly the toggle/grant authority (Owner of the resource or\n * admin of its workspace, mediahub ADR-0001), so a roster read doubles as the\n * check. A denial means \"not an authority\"; other failures reject unchanged.\n */\nexport function createConnectAuthzClient(\n\tc: ConnectGrantServiceClient,\n): AuthzClient {\n\treturn {\n\t\tasync canManage(resourceType, resourceId) {\n\t\t\ttry {\n\t\t\t\tawait c.listGrants({\n\t\t\t\t\tresourceType: GRANT_RESOURCE_TO_NUM[resourceType],\n\t\t\t\t\tresourceId,\n\t\t\t\t});\n\t\t\t\treturn true;\n\t\t\t} catch (err) {\n\t\t\t\tif (isPermissionDenied(err)) return false;\n\t\t\t\tthrow err;\n\t\t\t}\n\t\t},\n\t};\n}\n\n// ─── Dashboard ────────────────────────────────────────────────────────────────\n\nexport interface ConnectDashboardServiceClient {\n\tgetWorkspaceStats(req: { workspaceId: string }): Promise<{\n\t\ttotalAssets: bigint;\n\t\ttotalStorageBytes: bigint;\n\t\tstatusCounts: Array<{\n\t\t\tstatusSlug: string;\n\t\t\tname: string;\n\t\t\tcolor: string;\n\t\t\tbehavior: string;\n\t\t\tcount: bigint;\n\t\t}>;\n\t\trecentUploads: Array<{\n\t\t\tid: string;\n\t\t\tname: string;\n\t\t\tassetTypeName: string;\n\t\t\tstatusName: string;\n\t\t\tstatusColor: string;\n\t\t\tcreatedAt?: { seconds: bigint; nanos: number } | undefined;\n\t\t}>;\n\t}>;\n\tgetDashboardLayout(req: { workspaceId: string }): Promise<{\n\t\tlayoutJson: string;\n\t}>;\n\tsaveDashboardLayout(req: {\n\t\tworkspaceId: string;\n\t\tlayoutJson: string;\n\t}): Promise<unknown>;\n}\n\nexport function createConnectDashboardClient(\n\tc: ConnectDashboardServiceClient,\n): DashboardClient {\n\treturn {\n\t\tasync getWorkspaceStats(workspaceId): Promise<WorkspaceStats> {\n\t\t\tconst res = await c.getWorkspaceStats({ workspaceId });\n\t\t\treturn {\n\t\t\t\ttotalAssets: Number(res.totalAssets),\n\t\t\t\ttotalStorageBytes: Number(res.totalStorageBytes),\n\t\t\t\tstatusCounts: res.statusCounts.map((s) => ({\n\t\t\t\t\tstatusSlug: s.statusSlug,\n\t\t\t\t\tname: s.name,\n\t\t\t\t\tcolor: s.color,\n\t\t\t\t\tbehavior: s.behavior,\n\t\t\t\t\tcount: Number(s.count),\n\t\t\t\t})),\n\t\t\t\trecentUploads: res.recentUploads.map((r) => ({\n\t\t\t\t\tid: r.id,\n\t\t\t\t\tname: r.name,\n\t\t\t\t\tassetTypeName: r.assetTypeName,\n\t\t\t\t\tstatusName: r.statusName,\n\t\t\t\t\tstatusColor: r.statusColor,\n\t\t\t\t\tcreatedAt: mapTs(r.createdAt),\n\t\t\t\t})),\n\t\t\t};\n\t\t},\n\t\tasync getDashboardLayout(workspaceId) {\n\t\t\tconst res = await c.getDashboardLayout({ workspaceId });\n\t\t\treturn res.layoutJson;\n\t\t},\n\t\tasync saveDashboardLayout(workspaceId, layoutJson) {\n\t\t\tawait c.saveDashboardLayout({ workspaceId, layoutJson });\n\t\t},\n\t};\n}\n\n// ─── AI Connection ────────────────────────────────────────────────────────────\n\nexport interface ConnectAIConnectionServiceClient {\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tlistAIConnections(req: any): Promise<{ connections: ProtoResponse[] }>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tgetAIConnection(req: any): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tcreateAIConnection(req: any): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tupdateAIConnection(req: any): Promise<ProtoResponse>;\n\tdeleteAIConnection(req: { id: string }): Promise<unknown>;\n}\n\nexport function createConnectAIConnectionClient(\n\tc: ConnectAIConnectionServiceClient,\n): AIConnectionClient {\n\treturn {\n\t\tasync list(workspaceId) {\n\t\t\treturn (\n\t\t\t\tawait c.listAIConnections({\n\t\t\t\t\tworkspaceId,\n\t\t\t\t\tpagination: { page: 1, pageSize: 1000 },\n\t\t\t\t})\n\t\t\t).connections.map(mapAIConnection);\n\t\t},\n\t\tasync get(id) {\n\t\t\treturn mapAIConnection((await c.getAIConnection({ id })).connection);\n\t\t},\n\t\tasync create(params) {\n\t\t\treturn mapAIConnection(\n\t\t\t\t(await c.createAIConnection({ ...params })).connection,\n\t\t\t);\n\t\t},\n\t\tasync update(id, patch) {\n\t\t\treturn mapAIConnection(\n\t\t\t\t(\n\t\t\t\t\tawait c.updateAIConnection({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tname: patch.name ?? \"\",\n\t\t\t\t\t\tendpoint: patch.endpoint ?? \"\",\n\t\t\t\t\t\tdeployment: patch.deployment ?? \"\",\n\t\t\t\t\t\tapiVersion: patch.apiVersion ?? \"\",\n\t\t\t\t\t\tbaseUrl: patch.baseUrl ?? \"\",\n\t\t\t\t\t\tmodel: patch.model ?? \"\",\n\t\t\t\t\t\tapiKey: patch.apiKey ?? \"\",\n\t\t\t\t\t\tdescription: patch.description ?? \"\",\n\t\t\t\t\t\tactive: patch.active ?? true,\n\t\t\t\t\t})\n\t\t\t\t).connection,\n\t\t\t);\n\t\t},\n\t\tasync delete(id) {\n\t\t\tawait c.deleteAIConnection({ id });\n\t\t},\n\t};\n}\n\n// ─── AI Process ───────────────────────────────────────────────────────────────\n\nexport interface ConnectAIProcessServiceClient {\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tlistAIProcesses(req: any): Promise<{ processes: ProtoResponse[] }>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tgetAIProcess(req: any): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tcreateAIProcess(req: any): Promise<ProtoResponse>;\n\t// biome-ignore lint/suspicious/noExplicitAny: structural Connect shape\n\tupdateAIProcess(req: any): Promise<ProtoResponse>;\n\tdeleteAIProcess(req: { id: string }): Promise<unknown>;\n}\n\nexport function createConnectAIProcessClient(\n\tc: ConnectAIProcessServiceClient,\n): AIProcessClient {\n\treturn {\n\t\tasync list(assetTypeId) {\n\t\t\treturn (await c.listAIProcesses({ assetTypeId })).processes.map(\n\t\t\t\tmapAIProcess,\n\t\t\t);\n\t\t},\n\t\tasync get(id) {\n\t\t\treturn mapAIProcess((await c.getAIProcess({ id })).process);\n\t\t},\n\t\tasync create(params) {\n\t\t\treturn mapAIProcess(\n\t\t\t\t(\n\t\t\t\t\tawait c.createAIProcess({\n\t\t\t\t\t\tworkspaceId: params.workspaceId,\n\t\t\t\t\t\tassetTypeId: params.assetTypeId,\n\t\t\t\t\t\tconnectionId: params.connectionId,\n\t\t\t\t\t\tname: params.name,\n\t\t\t\t\t\tprompt: params.prompt,\n\t\t\t\t\t\toutputs: params.outputs,\n\t\t\t\t\t\tposition: params.position,\n\t\t\t\t\t})\n\t\t\t\t).process,\n\t\t\t);\n\t\t},\n\t\tasync update(id, patch) {\n\t\t\treturn mapAIProcess(\n\t\t\t\t(\n\t\t\t\t\tawait c.updateAIProcess({\n\t\t\t\t\t\tid,\n\t\t\t\t\t\tconnectionId: patch.connectionId ?? \"\",\n\t\t\t\t\t\tname: patch.name ?? \"\",\n\t\t\t\t\t\tprompt: patch.prompt ?? \"\",\n\t\t\t\t\t\toutputs: patch.outputs ?? [],\n\t\t\t\t\t\tposition: patch.position ?? 0,\n\t\t\t\t\t\tactive: patch.active ?? true,\n\t\t\t\t\t})\n\t\t\t\t).process,\n\t\t\t);\n\t\t},\n\t\tasync delete(id) {\n\t\t\tawait c.deleteAIProcess({ id });\n\t\t},\n\t};\n}\n\n// ─── Bundle ───────────────────────────────────────────────────────────────────\n\nexport function createConnectMediahubClients(gen: {\n\tasset: ConnectAssetServiceClient;\n\tfolder: ConnectFolderServiceClient;\n\tcollection: ConnectCollectionServiceClient;\n\ttag: ConnectTagServiceClient;\n\tassetType: ConnectAssetTypeServiceClient;\n\tuser: ConnectUserServiceClient;\n\tgrant: ConnectGrantServiceClient;\n\tdashboard: ConnectDashboardServiceClient;\n\taiConnection: ConnectAIConnectionServiceClient;\n\taiProcess: ConnectAIProcessServiceClient;\n}): MediahubClients {\n\treturn {\n\t\tassets: createConnectAssetClient(gen.asset),\n\t\tfolders: createConnectFolderClient(gen.folder),\n\t\tcollections: createConnectCollectionClient(gen.collection),\n\t\ttags: createConnectTagClient(gen.tag),\n\t\tassetTypes: createConnectAssetTypeClient(gen.assetType),\n\t\tdirectory: createConnectDirectoryClient(gen.user),\n\t\tgrants: createConnectGrantClient(gen.grant),\n\t\tdashboard: createConnectDashboardClient(gen.dashboard),\n\t\taiConnection: createConnectAIConnectionClient(gen.aiConnection),\n\t\taiProcess: createConnectAIProcessClient(gen.aiProcess),\n\t\tauthz: createConnectAuthzClient(gen.grant),\n\t};\n}\n","import { createContext, useContext, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { MediahubClients } from \"./clients\";\n\n/** Host-app routes for the places this package can only point at, never\n * navigate to itself (it has no router dependency). Rendered as plain\n * anchors; hosts include any basename in the returned href. */\nexport interface MediahubLinks {\n\t/** Route to an asset's detail view. */\n\tassetHref?: (assetId: string) => string;\n\t/** Route to a collection's view. */\n\tcollectionHref?: (collectionId: string) => string;\n}\n\ninterface MediahubContextValue {\n\tclients: MediahubClients;\n\tworkspaceId: string;\n\tlinks: MediahubLinks;\n}\n\nconst MediahubContext = createContext<MediahubContextValue | null>(null);\n\nconst EMPTY_LINKS: MediahubLinks = {};\n\nexport interface MediahubProviderProps {\n\tclients: MediahubClients;\n\t/** Ambient workspace scope — every hook reads it. */\n\tworkspaceId: string;\n\t/** Host routes for cross-surface references (e.g. the leak-guard refusal\n\t * dialog's pair links). Omitted routes render as plain text. */\n\tlinks?: MediahubLinks;\n\tchildren: ReactNode;\n}\n\nexport function MediahubProvider({\n\tclients,\n\tworkspaceId,\n\tlinks,\n\tchildren,\n}: MediahubProviderProps) {\n\tconst value = useMemo(\n\t\t() => ({\n\t\t\tclients,\n\t\t\tworkspaceId,\n\t\t\tlinks: links ?? EMPTY_LINKS,\n\t\t}),\n\t\t[clients, workspaceId, links],\n\t);\n\treturn (\n\t\t<MediahubContext.Provider value={value}>\n\t\t\t{children}\n\t\t</MediahubContext.Provider>\n\t);\n}\nMediahubProvider.displayName = \"MediahubProvider\";\n\nfunction useMediahubContext(): MediahubContextValue {\n\tconst ctx = useContext(MediahubContext);\n\tif (!ctx) {\n\t\tthrow new Error(\n\t\t\t\"useMediahubClients/useWorkspaceId must be used within <MediahubProvider>\",\n\t\t);\n\t}\n\treturn ctx;\n}\n\nexport function useMediahubClients(): MediahubClients {\n\treturn useMediahubContext().clients;\n}\n\nexport function useWorkspaceId(): string {\n\treturn useMediahubContext().workspaceId;\n}\n\n/** Host-supplied routes. Empty object when the host didn't pass `links` to\n * `<MediahubProvider>` — consumers degrade to plain text. */\nexport function useMediahubLinks(): MediahubLinks {\n\treturn useMediahubContext().links;\n}\n","import { useStatuses } from \"@knkcs/statushub-ui\";\nimport type { StatusInfo } from \"@knkcs/statushub-ui\";\n\n/**\n * The catalogue an asset's status belongs to: mediahub's `asset` entity type,\n * as registered with statushub at startup (integration standard §1).\n *\n * Every statushub-ui component and hook this package uses is pinned to it, so\n * a host never names it and can never point a mediahub surface at another\n * service's statuses. Exported because a host's settings screen embeds\n * `StatusSettings` pinned to the same catalogue (§10) — `<StatusSettings\n * {...ASSET_STATUS_CATALOGUE} />` — and one constant is how the two cannot\n * come to disagree.\n */\nexport const ASSET_STATUS_CATALOGUE = {\n\tserviceSlug: \"mediahub\",\n\tentityTypeSlug: \"asset\",\n} as const;\n\n/** The asset catalogue's statuses in the viewer's workspace. */\nexport function useAssetStatuses() {\n\treturn useStatuses(ASSET_STATUS_CATALOGUE);\n}\n\n/**\n * The status a slug names.\n *\n * `isLoading` is reported separately on purpose: \"not answered yet\" and\n * \"answered, and this slug is not in the catalogue\" look the same in the data\n * and mean opposite things. Collapsing them makes every list paint its raw\n * slugs for one frame before the names arrive.\n *\n * Once the catalogue has answered, a missing status is an **unknown status** —\n * the slug was deleted, or statushub had never answered at birth (§5) — and\n * callers render the raw slug rather than nothing: the asset still has a\n * status, mediahub just cannot name it.\n */\nexport function useAssetStatus(slug: string): {\n\tstatus: StatusInfo | undefined;\n\tisLoading: boolean;\n} {\n\tconst { data, isLoading } = useAssetStatuses();\n\treturn {\n\t\tstatus: slug ? data?.find((s) => s.slug === slug) : undefined,\n\t\tisLoading,\n\t};\n}\n","/** Direct-to-Azure SAS upload via XHR PUT (x-ms-blob-type: BlockBlob). */\nexport async function uploadFileToSAS(\n\turl: string,\n\tfile: File,\n\tcontentType: string,\n\tonProgress: (progress: number) => void,\n): Promise<void> {\n\treturn new Promise((resolve, reject) => {\n\t\tconst xhr = new XMLHttpRequest();\n\t\txhr.open(\"PUT\", url);\n\t\txhr.setRequestHeader(\"x-ms-blob-type\", \"BlockBlob\");\n\t\txhr.setRequestHeader(\"Content-Type\", contentType);\n\t\txhr.upload.onprogress = (e) => {\n\t\t\tif (e.lengthComputable) {\n\t\t\t\tonProgress(Math.round((e.loaded / e.total) * 100));\n\t\t\t}\n\t\t};\n\t\txhr.onload = () => {\n\t\t\tif (xhr.status >= 200 && xhr.status < 300) {\n\t\t\t\tresolve();\n\t\t\t} else {\n\t\t\t\treject(new Error(`Upload failed: ${xhr.status} ${xhr.statusText}`));\n\t\t\t}\n\t\t};\n\t\txhr.onerror = () => reject(new Error(\"Network error during upload\"));\n\t\txhr.send(file);\n\t});\n}\n","import { useMutation, useQueryClient } from \"@tanstack/react-query\";\nimport { useState } from \"react\";\nimport { uploadFileToSAS } from \"../lib/sas-upload\";\nimport { useMediahubClients } from \"../provider\";\n\nexport interface AddVersionVars {\n\tassetId: string;\n\tfile: File;\n\tcomment?: string;\n}\n\nexport function useAddVersion() {\n\tconst { assets } = useMediahubClients();\n\tconst qc = useQueryClient();\n\tconst [progress, setProgress] = useState(0);\n\n\tconst mutation = useMutation({\n\t\tmutationFn: async ({ assetId, file, comment }: AddVersionVars) => {\n\t\t\tsetProgress(0);\n\t\t\tconst contentType = file.type || \"application/octet-stream\";\n\t\t\tconst { uploadUrl, versionId } = await assets.getUploadUrl({\n\t\t\t\tassetId,\n\t\t\t\tfilename: file.name,\n\t\t\t\tcontentType,\n\t\t\t\tfileSize: file.size,\n\t\t\t\tcomment: comment ?? \"\",\n\t\t\t});\n\t\t\tif (!uploadUrl || !versionId) {\n\t\t\t\tthrow new Error(\"getUploadUrl returned an incomplete response\");\n\t\t\t}\n\t\t\tawait uploadFileToSAS(uploadUrl, file, contentType, setProgress);\n\t\t\treturn assets.finalizeUpload(versionId);\n\t\t},\n\t\tonSuccess: (_data, vars) => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] });\n\t\t\tqc.invalidateQueries({\n\t\t\t\tqueryKey: [\"mediahub\", \"assets\", \"detail\", vars.assetId],\n\t\t\t});\n\t\t},\n\t});\n\n\treturn { ...mutation, progress };\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\nimport type { AssetFilters, CreateAssetParams } from \"../types\";\n\nexport function useAssets(filters: AssetFilters = {}) {\n\tconst { assets } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"assets\", workspaceId, filters],\n\t\tqueryFn: () => assets.list(workspaceId, filters),\n\t});\n}\n\nexport function useAsset(id: string) {\n\tconst { assets } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"assets\", \"detail\", id],\n\t\tqueryFn: () => assets.get(id),\n\t\tenabled: !!id,\n\t});\n}\n\nexport function useCreateAsset() {\n\tconst { assets } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (params: CreateAssetParams) =>\n\t\t\tassets.create(workspaceId, params),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n\nexport function useUpdateAsset() {\n\tconst { assets } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tid: string;\n\t\t\tpatch: {\n\t\t\t\tname?: string;\n\t\t\t\tdescription?: string;\n\t\t\t\tmetadata?: Record<string, unknown>;\n\t\t\t};\n\t\t}) => assets.update(vars.id, vars.patch),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n\nexport function useDeleteAsset() {\n\tconst { assets } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => assets.delete(id),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n\nexport function useMoveAsset() {\n\tconst { assets } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { id: string; folderId: string }) =>\n\t\t\tassets.move(vars.id, vars.folderId),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n\nexport function useTransitionAssetStatus() {\n\tconst { assets } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tid: string;\n\t\t\t/** The slug the caller last saw — the change is made against it. */\n\t\t\tfromStatusSlug: string;\n\t\t\ttoStatusSlug: string;\n\t\t}) =>\n\t\t\tassets.transitionStatus(vars.id, vars.fromStatusSlug, vars.toStatusSlug),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n\nexport function useEnhanceAssetMetadata() {\n\tconst { assets } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => assets.enhanceMetadata(id),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n\nexport function usePreviewURL(assetId: string, versionId: string) {\n\tconst { assets } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"assets\", \"preview-url\", assetId, versionId],\n\t\tqueryFn: () => assets.getDownloadUrl(assetId, versionId),\n\t\tenabled: !!assetId && !!versionId,\n\t\tstaleTime: 15 * 60 * 1000,\n\t});\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useMediahubClients } from \"../provider\";\nimport type { GrantResourceType } from \"../types\";\n\n/**\n * Whether the current user may manage a resource — toggle its Restricted\n * flag, grant or revoke access (Owner of the resource or admin of its\n * workspace, mediahub ADR-0001). Consumers read `data === true`; a pending or\n * failed probe hides authority-only actions (fail closed).\n */\nexport function useCanManage(\n\tresourceType: GrantResourceType,\n\tresourceId: string,\n) {\n\tconst { authz } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"can-manage\", resourceType, resourceId],\n\t\tqueryFn: () => authz.canManage(resourceType, resourceId),\n\t\tenabled: !!resourceId,\n\t\t// Authority rarely changes mid-session; don't re-probe on every menu open.\n\t\tstaleTime: 5 * 60_000,\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\n\nexport function useFolders(parentId = \"\", opts?: { enabled?: boolean }) {\n\tconst { folders } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"folders\", workspaceId, parentId],\n\t\tqueryFn: () => folders.list(workspaceId, parentId),\n\t\tenabled: opts?.enabled ?? true,\n\t});\n}\n\nexport function useFolder(id: string) {\n\tconst { folders } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"folder\", id],\n\t\tqueryFn: () => folders.get(id),\n\t\tenabled: !!id,\n\t});\n}\n\nexport function useCreateFolder() {\n\tconst { folders } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tname: string;\n\t\t\tslug: string;\n\t\t\tparentId: string;\n\t\t\trestricted?: boolean;\n\t\t}) => folders.create({ workspaceId, ...vars }),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folders\"] }),\n\t});\n}\n\nexport function useUpdateFolder() {\n\tconst { folders } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { id: string; name: string }) =>\n\t\t\tfolders.update(vars.id, vars.name),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folders\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folder\"] });\n\t\t},\n\t});\n}\n\nexport function useDeleteFolder() {\n\tconst { folders } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => folders.delete(id),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folders\"] }),\n\t});\n}\n\nexport function useMoveFolder() {\n\tconst { folders } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { id: string; parentId: string }) =>\n\t\t\tfolders.move(vars.id, vars.parentId),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folders\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folder\"] });\n\t\t},\n\t});\n}\n\nexport function useSetFolderRestricted() {\n\tconst { folders } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { id: string; restricted: boolean }) =>\n\t\t\tfolders.setRestricted(vars.id, vars.restricted),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folders\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"folder\"] });\n\t\t\t// The toggle moves the subtree in/out of the open-content counts and\n\t\t\t// unscoped listings (#49) — asset pages must refetch.\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] });\n\t\t},\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { describeRpcError } from \"../lib/rpc-errors\";\nimport { useMediahubClients } from \"../provider\";\nimport type { GrantLevel, GrantResourceType } from \"../types\";\n\n/**\n * The roster read doubles as the sharing panel's authority gate: the server\n * answers PermissionDenied for everyone but the resource's Owner and\n * workspace admins, and that denial is a final answer — never retried.\n */\nexport function useGrants(\n\tresourceType: GrantResourceType,\n\tresourceId: string,\n\topts?: { enabled?: boolean },\n) {\n\tconst { grants } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"grants\", resourceType, resourceId],\n\t\tqueryFn: () => grants.list(resourceType, resourceId),\n\t\tenabled: opts?.enabled ?? true,\n\t\tretry: (failureCount, error) =>\n\t\t\tdescribeRpcError(error, \"\").kind !== \"permission-denied\" &&\n\t\t\tfailureCount < 3,\n\t});\n}\n\nexport function useGrantAccess() {\n\tconst { grants } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tresourceType: GrantResourceType;\n\t\t\tresourceId: string;\n\t\t\tuserId: string;\n\t\t\tlevel: GrantLevel;\n\t\t}) =>\n\t\t\tgrants.grant(vars.resourceType, vars.resourceId, vars.userId, vars.level),\n\t\t// Settled, not success: the server's upsert is delete-then-write, so a\n\t\t// mid-failure can leave the grantee revoked — the roster must re-assert\n\t\t// server truth after a failure too.\n\t\tonSettled: (_data, _err, vars) =>\n\t\t\tqc.invalidateQueries({\n\t\t\t\tqueryKey: [\"mediahub\", \"grants\", vars.resourceType, vars.resourceId],\n\t\t\t}),\n\t});\n}\n\nexport function useRevokeAccess() {\n\tconst { grants } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tresourceType: GrantResourceType;\n\t\t\tresourceId: string;\n\t\t\tuserId: string;\n\t\t}) => grants.revoke(vars.resourceType, vars.resourceId, vars.userId),\n\t\tonSettled: (_data, _err, vars) =>\n\t\t\tqc.invalidateQueries({\n\t\t\t\tqueryKey: [\"mediahub\", \"grants\", vars.resourceType, vars.resourceId],\n\t\t\t}),\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\nimport type { CollectionType } from \"../types\";\n\nexport function useCollections() {\n\tconst { collections } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"collections\", workspaceId],\n\t\tqueryFn: () => collections.list(workspaceId),\n\t});\n}\n\nexport function useCollection(id: string) {\n\tconst { collections } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"collection\", id],\n\t\tqueryFn: () => collections.get(id),\n\t\tenabled: !!id,\n\t});\n}\n\nexport function useCreateCollection() {\n\tconst { collections } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tname: string;\n\t\t\tslug: string;\n\t\t\tdescription: string;\n\t\t\ttype: CollectionType;\n\t\t\trules: string;\n\t\t\trestricted?: boolean;\n\t\t}) => collections.create({ workspaceId, ...vars }),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collections\"] }),\n\t});\n}\n\nexport function useUpdateCollection() {\n\tconst { collections } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tid: string;\n\t\t\tpatch: { name?: string; description?: string; rules?: string };\n\t\t}) => collections.update(vars.id, vars.patch),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collections\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collection\"] });\n\t\t},\n\t});\n}\n\nexport function useDeleteCollection() {\n\tconst { collections } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => collections.delete(id),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collections\"] }),\n\t});\n}\n\nexport function useAddAssetsToCollection() {\n\tconst { collections } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { collectionId: string; assetIds: string[] }) =>\n\t\t\tcollections.addAssets(vars.collectionId, vars.assetIds),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collection\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] });\n\t\t},\n\t});\n}\n\nexport function useSetCollectionRestricted() {\n\tconst { collections } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { id: string; restricted: boolean }) =>\n\t\t\tcollections.setRestricted(vars.id, vars.restricted),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collections\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collection\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] });\n\t\t},\n\t});\n}\n\nexport function useRemoveAssetsFromCollection() {\n\tconst { collections } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { collectionId: string; assetIds: string[] }) =>\n\t\t\tcollections.removeAssets(vars.collectionId, vars.assetIds),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collection\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] });\n\t\t},\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\n\nexport function useTags() {\n\tconst { tags } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"tags\", workspaceId],\n\t\tqueryFn: () => tags.list(workspaceId),\n\t});\n}\n\nexport function useCreateTag() {\n\tconst { tags } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { name: string; slug: string }) =>\n\t\t\ttags.create({ workspaceId, ...vars }),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"tags\"] }),\n\t});\n}\n\nexport function useUpdateTag() {\n\tconst { tags } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { id: string; name: string }) =>\n\t\t\ttags.update(vars.id, vars.name),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"tags\"] }),\n\t});\n}\n\nexport function useDeleteTag() {\n\tconst { tags } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => tags.delete(id),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"tags\"] }),\n\t});\n}\n\nexport function useTagAssets() {\n\tconst { tags } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { tagId: string; assetIds: string[] }) =>\n\t\t\ttags.tagAssets(vars.tagId, vars.assetIds),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n\nexport function useUntagAssets() {\n\tconst { tags } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: { tagId: string; assetIds: string[] }) =>\n\t\t\ttags.untagAssets(vars.tagId, vars.assetIds),\n\t\tonSuccess: () => qc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] }),\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\n\nexport function useAssetTypes() {\n\tconst { assetTypes } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"assetTypes\", workspaceId],\n\t\tqueryFn: () => assetTypes.list(workspaceId),\n\t});\n}\n\nexport function useAssetType(id: string) {\n\tconst { assetTypes } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"assetType\", id],\n\t\tqueryFn: () => assetTypes.get(id),\n\t\tenabled: !!id,\n\t});\n}\n\nexport function useCreateAssetType() {\n\tconst { assetTypes } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tname: string;\n\t\t\tslug: string;\n\t\t\tdescription: string;\n\t\t\tallowedMimeTypes: string[];\n\t\t\tmetadataSchema: string;\n\t\t}) => assetTypes.create({ workspaceId, ...vars }),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assetTypes\"] }),\n\t});\n}\n\nexport function useUpdateAssetType() {\n\tconst { assetTypes } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tid: string;\n\t\t\tpatch: {\n\t\t\t\tname?: string;\n\t\t\t\tdescription?: string;\n\t\t\t\tallowedMimeTypes?: string[];\n\t\t\t\tmetadataSchema?: string;\n\t\t\t\tactive?: boolean;\n\t\t\t};\n\t\t}) => assetTypes.update(vars.id, vars.patch),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assetTypes\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assetType\"] });\n\t\t},\n\t});\n}\n\nexport function useDeleteAssetType() {\n\tconst { assetTypes } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => assetTypes.delete(id),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assetTypes\"] }),\n\t});\n}\n","import { useQuery } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\n\nexport function useUsers(ids: string[]) {\n\tconst { directory } = useMediahubClients();\n\tconst sorted = [...ids].filter(Boolean).sort();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"users\", sorted],\n\t\tqueryFn: () => directory.resolveUsers(sorted),\n\t\tenabled: sorted.length > 0,\n\t\tstaleTime: 1000 * 60 * 10,\n\t\tselect: (data): Record<string, string> =>\n\t\t\tObject.fromEntries(data.map((u) => [u.id, u.displayName])),\n\t});\n}\n\n/** The active workspace's member listing — backs the grant picker\n * (guardian#52). Server-sorted by display name; unpaginated by design. */\nexport function useWorkspaceMembers(opts?: { enabled?: boolean }) {\n\tconst { directory } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"members\", workspaceId],\n\t\tqueryFn: () => directory.listWorkspaceMembers(workspaceId),\n\t\tenabled: opts?.enabled ?? true,\n\t\tstaleTime: 1000 * 60 * 5,\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\n\nexport function useWorkspaceStats() {\n\tconst { dashboard } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"workspace-stats\", workspaceId],\n\t\tqueryFn: () => dashboard.getWorkspaceStats(workspaceId),\n\t\tstaleTime: 30_000,\n\t});\n}\n\nexport function useGetDashboardLayout() {\n\tconst { dashboard } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"dashboard-layout\", workspaceId],\n\t\tqueryFn: () => dashboard.getDashboardLayout(workspaceId),\n\t});\n}\n\nexport function useSaveDashboardLayout() {\n\tconst { dashboard } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (layoutJson: string) =>\n\t\t\tdashboard.saveDashboardLayout(workspaceId, layoutJson),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({\n\t\t\t\tqueryKey: [\"mediahub\", \"dashboard-layout\", workspaceId],\n\t\t\t}),\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\n\nexport function useAIConnections() {\n\tconst { aiConnection } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"ai-connections\", workspaceId],\n\t\tqueryFn: () => aiConnection.list(workspaceId),\n\t});\n}\n\nexport function useAIConnection(id: string) {\n\tconst { aiConnection } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"ai-connection\", id],\n\t\tqueryFn: () => aiConnection.get(id),\n\t\tenabled: !!id,\n\t});\n}\n\nexport function useCreateAIConnection() {\n\tconst { aiConnection } = useMediahubClients();\n\tconst workspaceId = useWorkspaceId();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tname: string;\n\t\t\tprovider: string;\n\t\t\tendpoint: string;\n\t\t\tdeployment: string;\n\t\t\tapiVersion: string;\n\t\t\tbaseUrl: string;\n\t\t\tmodel: string;\n\t\t\tapiKey: string;\n\t\t\tdescription: string;\n\t\t}) => aiConnection.create({ workspaceId, ...vars }),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-connections\"] }),\n\t});\n}\n\nexport function useUpdateAIConnection() {\n\tconst { aiConnection } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tid: string;\n\t\t\tpatch: {\n\t\t\t\tname?: string;\n\t\t\t\tendpoint?: string;\n\t\t\t\tdeployment?: string;\n\t\t\t\tapiVersion?: string;\n\t\t\t\tbaseUrl?: string;\n\t\t\t\tmodel?: string;\n\t\t\t\tapiKey?: string;\n\t\t\t\tdescription?: string;\n\t\t\t\tactive?: boolean;\n\t\t\t};\n\t\t}) => aiConnection.update(vars.id, vars.patch),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-connections\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-connection\"] });\n\t\t},\n\t});\n}\n\nexport function useDeleteAIConnection() {\n\tconst { aiConnection } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => aiConnection.delete(id),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-connections\"] }),\n\t});\n}\n","import { useMutation, useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useMediahubClients } from \"../provider\";\n\nexport function useAIProcesses(assetTypeId: string) {\n\tconst { aiProcess } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"ai-processes\", assetTypeId],\n\t\tqueryFn: () => aiProcess.list(assetTypeId),\n\t\tenabled: !!assetTypeId,\n\t});\n}\n\nexport function useAIProcess(id: string) {\n\tconst { aiProcess } = useMediahubClients();\n\treturn useQuery({\n\t\tqueryKey: [\"mediahub\", \"ai-process\", id],\n\t\tqueryFn: () => aiProcess.get(id),\n\t\tenabled: !!id,\n\t});\n}\n\nexport function useCreateAIProcess() {\n\tconst { aiProcess } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tassetTypeId: string;\n\t\t\tconnectionId: string;\n\t\t\tname: string;\n\t\t\tprompt: string;\n\t\t\toutputs: { key: string; target: string; metadataAccessor: string }[];\n\t\t\tposition: number;\n\t\t\tworkspaceId: string;\n\t\t}) => aiProcess.create(vars),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-processes\"] }),\n\t});\n}\n\nexport function useUpdateAIProcess() {\n\tconst { aiProcess } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (vars: {\n\t\t\tid: string;\n\t\t\tpatch: {\n\t\t\t\tconnectionId?: string;\n\t\t\t\tname?: string;\n\t\t\t\tprompt?: string;\n\t\t\t\toutputs?: { key: string; target: string; metadataAccessor: string }[];\n\t\t\t\tposition?: number;\n\t\t\t\tactive?: boolean;\n\t\t\t};\n\t\t}) => aiProcess.update(vars.id, vars.patch),\n\t\tonSuccess: () => {\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-processes\"] });\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-process\"] });\n\t\t},\n\t});\n}\n\nexport function useDeleteAIProcess() {\n\tconst { aiProcess } = useMediahubClients();\n\tconst qc = useQueryClient();\n\treturn useMutation({\n\t\tmutationFn: (id: string) => aiProcess.delete(id),\n\t\tonSuccess: () =>\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"ai-processes\"] }),\n\t});\n}\n","import { useQuery, useQueryClient } from \"@tanstack/react-query\";\nimport { useEffect, useRef } from \"react\";\nimport { useMediahubClients } from \"../provider\";\nimport type { AIProcessRunInfo } from \"../types\";\n\nexport const isActive = (runs: AIProcessRunInfo[] | undefined): boolean =>\n\t(runs ?? []).some((r) => r.status === \"queued\" || r.status === \"running\");\n\nexport function useAIProcessRuns(assetId: string) {\n\tconst { assets } = useMediahubClients();\n\tconst qc = useQueryClient();\n\tconst wasActive = useRef(false);\n\n\tconst query = useQuery({\n\t\tqueryKey: [\"mediahub\", \"ai-process-runs\", assetId],\n\t\tqueryFn: () => assets.listProcessRuns(assetId),\n\t\tenabled: !!assetId,\n\t\trefetchInterval: (q) =>\n\t\t\tisActive(q.state.data as AIProcessRunInfo[] | undefined) ? 2000 : false,\n\t});\n\n\t// Reset wasActive when assetId changes so switching to a new asset doesn't\n\t// fire a spurious completion-invalidate on the previous asset's state.\n\t// (assetId is read inside the effect body — a dep the body never mentions\n\t// is what biome flagged in #74; deleting the dep would kill the reset.)\n\tconst seenAssetId = useRef(assetId);\n\tuseEffect(() => {\n\t\tif (seenAssetId.current !== assetId) {\n\t\t\tseenAssetId.current = assetId;\n\t\t\twasActive.current = false;\n\t\t}\n\t}, [assetId]);\n\n\t// When runs transition from active → all-terminal, refresh the asset so the\n\t// AI-applied description/tags/metadata appear.\n\tuseEffect(() => {\n\t\tconst active = isActive(query.data);\n\t\tif (wasActive.current && !active) {\n\t\t\tqc.invalidateQueries({\n\t\t\t\tqueryKey: [\"mediahub\", \"assets\", \"detail\", assetId],\n\t\t\t});\n\t\t}\n\t\twasActive.current = active;\n\t}, [query.data, assetId, qc]);\n\n\treturn query;\n}\n","import { create } from \"zustand\";\n\ninterface SelectionState {\n\tselectedIds: string[];\n\tlastClickedId: string | null;\n}\n\ninterface SelectionActions {\n\ttoggle: (id: string) => void;\n\tselectAll: (ids: string[]) => void;\n\tsetSelection: (ids: string[]) => void;\n\tselectRange: (targetId: string, orderedIds: string[]) => void;\n\tclearSelection: () => void;\n}\n\n// Note: To check if an item is selected in React components, use:\n// useSelectionStore((s) => s.selectedIds.includes(id))\n// Do NOT add an isSelected method to the store — it won't trigger re-renders\n// when used as a Zustand selector.\n\ntype SelectionStore = SelectionState & SelectionActions;\n\nexport const useSelectionStore = create<SelectionStore>((set, get) => ({\n\tselectedIds: [],\n\tlastClickedId: null,\n\n\ttoggle: (id) => {\n\t\tset((state) => {\n\t\t\tconst exists = state.selectedIds.includes(id);\n\t\t\treturn {\n\t\t\t\tselectedIds: exists\n\t\t\t\t\t? state.selectedIds.filter((i) => i !== id)\n\t\t\t\t\t: [...state.selectedIds, id],\n\t\t\t\tlastClickedId: id,\n\t\t\t};\n\t\t});\n\t},\n\n\tselectAll: (ids) => set({ selectedIds: [...ids], lastClickedId: null }),\n\n\tsetSelection: (ids) => set({ selectedIds: ids, lastClickedId: null }),\n\n\tselectRange: (targetId, orderedIds) => {\n\t\tconst { lastClickedId, selectedIds } = get();\n\t\tif (!lastClickedId) {\n\t\t\tset({ selectedIds: [targetId], lastClickedId: targetId });\n\t\t\treturn;\n\t\t}\n\t\tconst startIdx = orderedIds.indexOf(lastClickedId);\n\t\tconst endIdx = orderedIds.indexOf(targetId);\n\t\tif (startIdx === -1 || endIdx === -1) return;\n\t\tconst low = Math.min(startIdx, endIdx);\n\t\tconst high = Math.max(startIdx, endIdx);\n\t\tconst rangeIds = orderedIds.slice(low, high + 1);\n\t\tconst merged = new Set([...selectedIds, ...rangeIds]);\n\t\tset({ selectedIds: [...merged], lastClickedId: targetId });\n\t},\n\n\tclearSelection: () => set({ selectedIds: [], lastClickedId: null }),\n}));\n","import { create } from \"zustand\";\nimport { persist } from \"zustand/middleware\";\n\ninterface PreferencesState {\n\tsidebarCollapsed: boolean;\n\tviewMode: \"list\" | \"grid\";\n}\n\ninterface PreferencesActions {\n\ttoggleSidebar: () => void;\n\tsetViewMode: (mode: \"list\" | \"grid\") => void;\n}\n\ntype PreferencesStore = PreferencesState & PreferencesActions;\n\nexport const usePreferencesStore = create<PreferencesStore>()(\n\tpersist(\n\t\t(set) => ({\n\t\t\tsidebarCollapsed: false,\n\t\t\tviewMode: \"list\",\n\n\t\t\ttoggleSidebar: () =>\n\t\t\t\tset((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),\n\n\t\t\tsetViewMode: (mode) => set({ viewMode: mode }),\n\t\t}),\n\t\t{\n\t\t\tname: \"mediahub-preferences\",\n\t\t},\n\t),\n);\n","import type { QueryClient } from \"@tanstack/react-query\";\nimport { create } from \"zustand\";\nimport type { AssetClient } from \"../clients\";\nimport { describeRpcError } from \"../lib/rpc-errors\";\nimport { uploadFileToSAS } from \"../lib/sas-upload\";\n\nexport interface UploadFile {\n\tclientId: string;\n\tfile: File;\n\tassetTypeId: string;\n\tstatus:\n\t\t| \"pending\"\n\t\t| \"creating\"\n\t\t| \"uploading\"\n\t\t| \"finalizing\"\n\t\t| \"done\"\n\t\t| \"error\";\n\tprogress: number;\n\terror?: string;\n\tassetId?: string;\n\tversionId?: string;\n}\n\ninterface UploadState {\n\tfiles: UploadFile[];\n\tvisible: boolean;\n\texpanded: boolean;\n\tanalyzeWithAi: boolean;\n\tqueryClient: QueryClient | null;\n\tassetClient: AssetClient | null;\n}\n\ninterface UploadActions {\n\taddFiles: (files: File[]) => void;\n\tsetAssetType: (clientId: string, assetTypeId: string) => void;\n\tsetBatchAssetType: (assetTypeId: string) => void;\n\tsetAnalyzeWithAi: (v: boolean) => void;\n\tstartUpload: (workspaceId: string, folderId?: string) => void;\n\tsetQueryClient: (qc: QueryClient) => void;\n\tsetAssetClient: (client: AssetClient) => void;\n\tclearPending: () => void;\n\tdismiss: () => void;\n\ttoggleExpanded: () => void;\n}\n\ntype UploadStore = UploadState & UploadActions;\n\nfunction updateFile(\n\tfiles: UploadFile[],\n\tclientId: string,\n\tpatch: Partial<UploadFile>,\n): UploadFile[] {\n\treturn files.map((f) => (f.clientId === clientId ? { ...f, ...patch } : f));\n}\n\nexport const useUploadStore = create<UploadStore>((set, get) => ({\n\tfiles: [],\n\tvisible: false,\n\texpanded: true,\n\tanalyzeWithAi: true,\n\tqueryClient: null,\n\tassetClient: null,\n\n\taddFiles: (newFiles) => {\n\t\tconst entries: UploadFile[] = newFiles.map((file) => ({\n\t\t\t// Client-only tracking ID; KSUID convention applies to server-persisted IDs\n\t\t\tclientId: crypto.randomUUID(),\n\t\t\tfile,\n\t\t\tassetTypeId: \"\",\n\t\t\tstatus: \"pending\" as const,\n\t\t\tprogress: 0,\n\t\t}));\n\t\tset((state) => ({ files: [...state.files, ...entries] }));\n\t},\n\n\tsetAssetType: (clientId, assetTypeId) => {\n\t\tset((state) => ({\n\t\t\tfiles: updateFile(state.files, clientId, { assetTypeId }),\n\t\t}));\n\t},\n\n\tsetBatchAssetType: (assetTypeId) => {\n\t\tset((state) => ({\n\t\t\tfiles: state.files.map((f) =>\n\t\t\t\tf.status === \"pending\" ? { ...f, assetTypeId } : f,\n\t\t\t),\n\t\t}));\n\t},\n\n\tsetAnalyzeWithAi: (v) => set({ analyzeWithAi: v }),\n\n\tstartUpload: async (workspaceId, folderId) => {\n\t\tconst client = get().assetClient;\n\t\tif (!client) throw new Error(\"upload-store: assetClient not set\");\n\n\t\tset({ visible: true, expanded: true });\n\n\t\tconst pending = get().files.filter((f) => f.status === \"pending\");\n\n\t\tfor (const entry of pending) {\n\t\t\tconst { clientId, file, assetTypeId } = entry;\n\n\t\t\ttry {\n\t\t\t\t// Step 1: Create asset\n\t\t\t\tset((state) => ({\n\t\t\t\t\tfiles: updateFile(state.files, clientId, { status: \"creating\" }),\n\t\t\t\t}));\n\n\t\t\t\tconst asset = await client.create(workspaceId, {\n\t\t\t\t\tname: file.name,\n\t\t\t\t\tassetTypeId,\n\t\t\t\t\tfolderId: folderId ?? \"\",\n\t\t\t\t\tmetadata: {},\n\t\t\t\t\tanalyzeWithAi: get().analyzeWithAi,\n\t\t\t\t});\n\t\t\t\tconst assetId = asset.id;\n\t\t\t\tif (!assetId) throw new Error(\"create returned no asset ID\");\n\n\t\t\t\tset((state) => ({\n\t\t\t\t\tfiles: updateFile(state.files, clientId, { assetId }),\n\t\t\t\t}));\n\n\t\t\t\t// Step 2: Get upload URL\n\t\t\t\tconst { uploadUrl, versionId } = await client.getUploadUrl({\n\t\t\t\t\tassetId,\n\t\t\t\t\tfilename: file.name,\n\t\t\t\t\tcontentType: file.type || \"application/octet-stream\",\n\t\t\t\t\tfileSize: file.size,\n\t\t\t\t\tcomment: \"\",\n\t\t\t\t});\n\t\t\t\tif (!uploadUrl || !versionId) {\n\t\t\t\t\tthrow new Error(\"getUploadUrl returned incomplete response\");\n\t\t\t\t}\n\n\t\t\t\tset((state) => ({\n\t\t\t\t\tfiles: updateFile(state.files, clientId, {\n\t\t\t\t\t\tversionId,\n\t\t\t\t\t\tstatus: \"uploading\",\n\t\t\t\t\t}),\n\t\t\t\t}));\n\n\t\t\t\t// Step 3: PUT to SAS URL via XHR\n\t\t\t\tawait uploadFileToSAS(\n\t\t\t\t\tuploadUrl,\n\t\t\t\t\tfile,\n\t\t\t\t\tfile.type || \"application/octet-stream\",\n\t\t\t\t\t(progress) => {\n\t\t\t\t\t\tset((state) => ({\n\t\t\t\t\t\t\tfiles: updateFile(state.files, clientId, { progress }),\n\t\t\t\t\t\t}));\n\t\t\t\t\t},\n\t\t\t\t);\n\n\t\t\t\t// Step 4: Finalize upload\n\t\t\t\tset((state) => ({\n\t\t\t\t\tfiles: updateFile(state.files, clientId, { status: \"finalizing\" }),\n\t\t\t\t}));\n\t\t\t\tawait client.finalizeUpload(versionId);\n\n\t\t\t\t// Step 5: Mark done + invalidate cache\n\t\t\t\tset((state) => ({\n\t\t\t\t\tfiles: updateFile(state.files, clientId, {\n\t\t\t\t\t\tstatus: \"done\",\n\t\t\t\t\t\tprogress: 100,\n\t\t\t\t\t}),\n\t\t\t\t}));\n\n\t\t\t\tconst qc = get().queryClient;\n\t\t\t\tif (qc) {\n\t\t\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"assets\"] });\n\t\t\t\t}\n\t\t\t} catch (err) {\n\t\t\t\t// Denials and leak-guard conflicts render mapped copy in the\n\t\t\t\t// upload stack; anything else keeps the raw message as before.\n\t\t\t\tconst described = describeRpcError(err, \"Upload failed\");\n\t\t\t\tconst message =\n\t\t\t\t\tdescribed.kind === \"other\"\n\t\t\t\t\t\t? err instanceof Error\n\t\t\t\t\t\t\t? err.message\n\t\t\t\t\t\t\t: String(err)\n\t\t\t\t\t\t: described.description;\n\t\t\t\tset((state) => ({\n\t\t\t\t\tfiles: updateFile(state.files, clientId, {\n\t\t\t\t\t\tstatus: \"error\",\n\t\t\t\t\t\terror: message,\n\t\t\t\t\t}),\n\t\t\t\t}));\n\t\t\t}\n\t\t}\n\t},\n\n\tsetQueryClient: (qc) => set({ queryClient: qc }),\n\n\tsetAssetClient: (client) => set({ assetClient: client }),\n\n\tclearPending: () =>\n\t\tset((state) => ({\n\t\t\tfiles: state.files.filter((f) => f.status !== \"pending\"),\n\t\t})),\n\n\tdismiss: () =>\n\t\tset({ visible: false, files: [], expanded: true, analyzeWithAi: true }),\n\n\ttoggleExpanded: () => set((state) => ({ expanded: !state.expanded })),\n}));\n","import { Text } from \"@knkcs/anker/primitives\";\nimport { StatusBadge } from \"@knkcs/statushub-ui\";\nimport { useAssetStatus } from \"../statushub\";\n\nexport interface AssetStatusBadgeProps {\n\t/** The asset's stored status slug. Empty renders nothing. */\n\tslug: string;\n}\n\n/**\n * An asset's status, named and coloured from statushub's catalogue.\n *\n * This is the one place mediahub turns a stored slug into something readable\n * (statushub's integration standard §10: the consumer renders statuses itself,\n * with statushub-ui's components — no host slot). A slug the catalogue does\n * not carry — an **unknown status**, deleted or never answered for (§5) —\n * prints as itself, because the asset has a status either way and saying\n * nothing would read as having none.\n */\nexport function AssetStatusBadge({ slug }: AssetStatusBadgeProps) {\n\tconst { status, isLoading } = useAssetStatus(slug);\n\tif (!slug) return null;\n\t// Nothing rather than the slug while the catalogue is in flight: the slug\n\t// is what an unknown status looks like, and showing it here would flash a\n\t// raw `in-review` across every row of every list on each mount.\n\tif (isLoading) return null;\n\tif (!status) {\n\t\treturn (\n\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\">\n\t\t\t\t{slug}\n\t\t\t</Text>\n\t\t);\n\t}\n\treturn <StatusBadge status={status} />;\n}\nAssetStatusBadge.displayName = \"AssetStatusBadge\";\n","import { SelectableCard } from \"@knkcs/anker/components\";\nimport { Grid, Skeleton, Text } from \"@knkcs/anker/primitives\";\nimport { FileText, Film, Image, Music } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { usePreviewURL } from \"../hooks/use-preview-url\";\nimport { useSelectionStore } from \"../stores/selection-store\";\nimport type { AssetInfo } from \"../types\";\nimport { AssetStatusBadge } from \"./asset-status-badge\";\n\nfunction getMimeCategory(asset: AssetInfo): string {\n\tconst version = asset.versions[asset.versions.length - 1];\n\tif (!version) return \"unknown\";\n\tconst mime = version.mimeType;\n\tif (mime.startsWith(\"image/\")) return \"image\";\n\tif (mime.startsWith(\"video/\")) return \"video\";\n\tif (mime.startsWith(\"audio/\")) return \"audio\";\n\tif (mime === \"application/pdf\") return \"pdf\";\n\treturn \"unknown\";\n}\n\nfunction TypeIcon({ category }: { category: string }) {\n\tswitch (category) {\n\t\tcase \"image\":\n\t\t\treturn <Image size={32} opacity={0.3} />;\n\t\tcase \"video\":\n\t\t\treturn <Film size={32} opacity={0.3} />;\n\t\tcase \"audio\":\n\t\t\treturn <Music size={32} opacity={0.3} />;\n\t\tdefault:\n\t\t\treturn <FileText size={32} opacity={0.3} />;\n\t}\n}\nTypeIcon.displayName = \"TypeIcon\";\n\ninterface AssetCardProps {\n\tasset: AssetInfo;\n\tonOpen: (asset: AssetInfo) => void;\n}\n\nconst AssetCard: React.FC<AssetCardProps> = ({ asset, onOpen }) => {\n\tconst isSelected = useSelectionStore((s) => s.selectedIds.includes(asset.id));\n\tconst anySelected = useSelectionStore((s) => s.selectedIds.length > 0);\n\tconst toggle = useSelectionStore((s) => s.toggle);\n\tconst category = getMimeCategory(asset);\n\tconst latestVersion = asset.versions[asset.versions.length - 1];\n\tconst previewQuery = usePreviewURL(\n\t\tcategory === \"image\" && latestVersion ? asset.id : \"\",\n\t\tlatestVersion?.id ?? \"\",\n\t);\n\tconst previewUrl = previewQuery.data;\n\tconst [imgError, setImgError] = useState(false);\n\n\treturn (\n\t\t<SelectableCard\n\t\t\tselected={isSelected}\n\t\t\tselectionVisible={anySelected}\n\t\t\tonSelect={() => toggle(asset.id)}\n\t\t\tonClick={() => onOpen(asset)}\n\t\t>\n\t\t\t<SelectableCard.Thumbnail height=\"160px\">\n\t\t\t\t{category === \"image\" && previewUrl && !imgError ? (\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={previewUrl}\n\t\t\t\t\t\talt={asset.name || \"Asset preview\"}\n\t\t\t\t\t\tonError={() => setImgError(true)}\n\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\twidth: \"100%\",\n\t\t\t\t\t\t\theight: \"100%\",\n\t\t\t\t\t\t\tobjectFit: \"cover\",\n\t\t\t\t\t\t}}\n\t\t\t\t\t/>\n\t\t\t\t) : category === \"image\" && previewQuery.isLoading ? (\n\t\t\t\t\t<Skeleton w=\"full\" h=\"full\" />\n\t\t\t\t) : (\n\t\t\t\t\t<TypeIcon category={category} />\n\t\t\t\t)}\n\t\t\t</SelectableCard.Thumbnail>\n\t\t\t<SelectableCard.Body>\n\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\" truncate>\n\t\t\t\t\t{asset.name}\n\t\t\t\t</Text>\n\t\t\t</SelectableCard.Body>\n\t\t\t<SelectableCard.Footer>\n\t\t\t\t<AssetStatusBadge slug={asset.statusSlug} />\n\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\">\n\t\t\t\t\t{category.charAt(0).toUpperCase() + category.slice(1)}\n\t\t\t\t</Text>\n\t\t\t</SelectableCard.Footer>\n\t\t</SelectableCard>\n\t);\n};\nAssetCard.displayName = \"AssetCard\";\n\nexport interface AssetGridProps {\n\tassets: AssetInfo[];\n\tonOpen: (asset: AssetInfo) => void;\n}\n\nexport const AssetGrid: React.FC<AssetGridProps> = ({ assets, onOpen }) => {\n\treturn (\n\t\t<Grid templateColumns=\"repeat(auto-fill, minmax(200px, 1fr))\" gap={4}>\n\t\t\t{assets.map((asset) => (\n\t\t\t\t<AssetCard key={asset.id} asset={asset} onOpen={onOpen} />\n\t\t\t))}\n\t\t</Grid>\n\t);\n};\nAssetGrid.displayName = \"AssetGrid\";\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Box, Flex, Skeleton, Text } from \"@knkcs/anker/primitives\";\nimport { Download, FileText, Film, Image, Music } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { usePreviewURL } from \"../hooks/use-preview-url\";\n\ninterface AssetPreviewProps {\n\tassetId: string;\n\tversionId: string;\n\tmimeType: string;\n\tfileName: string;\n}\n\nfunction TypeIcon({ mimeType }: { mimeType: string }) {\n\tif (mimeType.startsWith(\"image/\")) return <Image size={48} opacity={0.3} />;\n\tif (mimeType.startsWith(\"video/\")) return <Film size={48} opacity={0.3} />;\n\tif (mimeType.startsWith(\"audio/\")) return <Music size={48} opacity={0.3} />;\n\treturn <FileText size={48} opacity={0.3} />;\n}\nTypeIcon.displayName = \"TypeIcon\";\n\nexport const AssetPreview: React.FC<AssetPreviewProps> = ({\n\tassetId,\n\tversionId,\n\tmimeType,\n\tfileName,\n}) => {\n\tconst previewQuery = usePreviewURL(assetId, versionId);\n\tconst url = previewQuery.data;\n\tconst [error, setError] = useState(false);\n\n\tif (previewQuery.isLoading) {\n\t\treturn <Skeleton w=\"full\" h=\"full\" minH=\"200px\" />;\n\t}\n\n\tif (!url || error) {\n\t\treturn (\n\t\t\t<Flex\n\t\t\t\tdirection=\"column\"\n\t\t\t\talign=\"center\"\n\t\t\t\tjustify=\"center\"\n\t\t\t\tgap={3}\n\t\t\t\tp={6}\n\t\t\t\th=\"full\"\n\t\t\t\tminH=\"200px\"\n\t\t\t>\n\t\t\t\t<TypeIcon mimeType={mimeType} />\n\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\">\n\t\t\t\t\tPreview not available\n\t\t\t\t</Text>\n\t\t\t\t{url && (\n\t\t\t\t\t<Button asChild size=\"sm\" variant=\"outline\">\n\t\t\t\t\t\t<a href={url} download={fileName}>\n\t\t\t\t\t\t\t<Download size={14} />\n\t\t\t\t\t\t\tDownload\n\t\t\t\t\t\t</a>\n\t\t\t\t\t</Button>\n\t\t\t\t)}\n\t\t\t</Flex>\n\t\t);\n\t}\n\n\t// Image\n\tif (mimeType.startsWith(\"image/\")) {\n\t\treturn (\n\t\t\t<Box\n\t\t\t\th=\"full\"\n\t\t\t\tminH=\"200px\"\n\t\t\t\tdisplay=\"flex\"\n\t\t\t\talignItems=\"center\"\n\t\t\t\tjustifyContent=\"center\"\n\t\t\t\tp={2}\n\t\t\t>\n\t\t\t\t<img\n\t\t\t\t\tsrc={url}\n\t\t\t\t\talt={fileName}\n\t\t\t\t\tonError={() => setError(true)}\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tmaxWidth: \"100%\",\n\t\t\t\t\t\tmaxHeight: \"100%\",\n\t\t\t\t\t\tobjectFit: \"contain\",\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t</Box>\n\t\t);\n\t}\n\n\t// Video\n\tif (mimeType.startsWith(\"video/\")) {\n\t\treturn (\n\t\t\t<Box h=\"full\" minH=\"200px\" p={2}>\n\t\t\t\t<video\n\t\t\t\t\tsrc={url}\n\t\t\t\t\tcontrols\n\t\t\t\t\tonError={() => setError(true)}\n\t\t\t\t\tstyle={{ width: \"100%\", maxHeight: \"100%\" }}\n\t\t\t\t>\n\t\t\t\t\t<track kind=\"captions\" />\n\t\t\t\t</video>\n\t\t\t</Box>\n\t\t);\n\t}\n\n\t// Audio\n\tif (mimeType.startsWith(\"audio/\")) {\n\t\treturn (\n\t\t\t<Flex\n\t\t\t\tdirection=\"column\"\n\t\t\t\talign=\"center\"\n\t\t\t\tjustify=\"center\"\n\t\t\t\tgap={4}\n\t\t\t\tp={6}\n\t\t\t\th=\"full\"\n\t\t\t\tminH=\"200px\"\n\t\t\t>\n\t\t\t\t<Music size={48} opacity={0.3} />\n\t\t\t\t<audio\n\t\t\t\t\tsrc={url}\n\t\t\t\t\tcontrols\n\t\t\t\t\tonError={() => setError(true)}\n\t\t\t\t\tstyle={{ width: \"100%\" }}\n\t\t\t\t>\n\t\t\t\t\t<track kind=\"captions\" />\n\t\t\t\t</audio>\n\t\t\t</Flex>\n\t\t);\n\t}\n\n\t// PDF\n\tif (mimeType === \"application/pdf\") {\n\t\treturn (\n\t\t\t<Box h=\"full\" minH=\"400px\">\n\t\t\t\t<iframe\n\t\t\t\t\tsrc={url}\n\t\t\t\t\ttitle={fileName}\n\t\t\t\t\twidth=\"100%\"\n\t\t\t\t\theight=\"100%\"\n\t\t\t\t\tstyle={{ border: \"none\" }}\n\t\t\t\t/>\n\t\t\t</Box>\n\t\t);\n\t}\n\n\t// Fallback\n\treturn (\n\t\t<Flex\n\t\t\tdirection=\"column\"\n\t\t\talign=\"center\"\n\t\t\tjustify=\"center\"\n\t\t\tgap={3}\n\t\t\tp={6}\n\t\t\th=\"full\"\n\t\t\tminH=\"200px\"\n\t\t>\n\t\t\t<TypeIcon mimeType={mimeType} />\n\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\">\n\t\t\t\tPreview not available\n\t\t\t</Text>\n\t\t\t<Button asChild size=\"sm\" variant=\"outline\">\n\t\t\t\t<a href={url} download={fileName}>\n\t\t\t\t\t<Download size={14} />\n\t\t\t\t\tDownload\n\t\t\t\t</a>\n\t\t\t</Button>\n\t\t</Flex>\n\t);\n};\nAssetPreview.displayName = \"AssetPreview\";\n","import { StatusTransitionControl } from \"@knkcs/statushub-ui\";\nimport { useTransitionAssetStatus } from \"../hooks/use-assets\";\nimport { showRpcErrorToast } from \"../lib/rpc-errors\";\nimport { ASSET_STATUS_CATALOGUE } from \"../statushub\";\n\nexport interface AssetStatusControlProps {\n\tassetId: string;\n\t/** The asset's stored status slug — what the viewer is looking at. */\n\tstatusSlug: string;\n}\n\n/**\n * An asset's status, and the moves statushub allows away from it.\n *\n * statushub-ui offers the moves; mediahub's own `TransitionAssetStatus` makes\n * them (integration standard §3) — the browser never writes to statushub. The\n * slug being shown travels with the change, so a screen drawn before somebody\n * else moved this asset on is refused as a conflict instead of overwriting\n * them.\n *\n * Guarded moves are shown (`canRevert`) and statushub decides them: its answer\n * is per-caller, and mediahub keeps no who-may-revert rule of its own. The\n * control swallows what `onTransition` throws — error handling is the\n * consumer's — so the refusal is toasted here.\n */\nexport function AssetStatusControl({\n\tassetId,\n\tstatusSlug,\n}: AssetStatusControlProps) {\n\tconst transition = useTransitionAssetStatus();\n\treturn (\n\t\t<StatusTransitionControl\n\t\t\t{...ASSET_STATUS_CATALOGUE}\n\t\t\tcurrentStatusSlug={statusSlug}\n\t\t\tquickAdvance={false}\n\t\t\tcanRevert\n\t\t\tonTransition={async (to) => {\n\t\t\t\ttry {\n\t\t\t\t\tawait transition.mutateAsync({\n\t\t\t\t\t\tid: assetId,\n\t\t\t\t\t\tfromStatusSlug: statusSlug,\n\t\t\t\t\t\ttoStatusSlug: to.slug,\n\t\t\t\t\t});\n\t\t\t\t} catch (err) {\n\t\t\t\t\tshowRpcErrorToast(err, \"Status change failed\");\n\t\t\t\t}\n\t\t\t}}\n\t\t/>\n\t);\n}\nAssetStatusControl.displayName = \"AssetStatusControl\";\n","import { BulkActionBar as AnkerBulkActionBar } from \"@knkcs/anker/components\";\nimport { useConfirmModal } from \"@knkcs/anker/feedback\";\nimport { Box, Flex, Text, toaster } from \"@knkcs/anker/primitives\";\nimport { FolderOpen, Tag, Trash2 } from \"lucide-react\";\nimport { useDeleteAsset } from \"../hooks/use-assets\";\nimport {\n\tuseAddAssetsToCollection,\n\tuseCollections,\n} from \"../hooks/use-collections\";\nimport { useTagAssets, useTags } from \"../hooks/use-tags\";\nimport { describeRpcError, showRpcErrorToast } from \"../lib/rpc-errors\";\nimport { useSelectionStore } from \"../stores/selection-store\";\n\n// biome-ignore lint/suspicious/noEmptyInterface: intentional empty props\ninterface BulkActionBarProps {}\n\nexport const BulkActionBar: React.FC<BulkActionBarProps> = () => {\n\tconst selectedIds = useSelectionStore((s) => s.selectedIds);\n\tconst clearSelection = useSelectionStore((s) => s.clearSelection);\n\tconst count = selectedIds.length;\n\n\tconst deleteAsset = useDeleteAsset();\n\tconst { confirm } = useConfirmModal();\n\tconst tagAssets = useTagAssets();\n\tconst addToCollection = useAddAssetsToCollection();\n\tconst tagsQuery = useTags();\n\tconst collectionsQuery = useCollections();\n\tconst tags = tagsQuery.data ?? [];\n\tconst collections = collectionsQuery.data ?? [];\n\n\tasync function handleBulkDelete() {\n\t\tconst confirmed = await confirm({\n\t\t\ttitle: \"Delete Assets\",\n\t\t\tmessage: `Delete ${count} asset${count > 1 ? \"s\" : \"\"}? This cannot be undone.`,\n\t\t\tconfirmLabel: \"Delete\",\n\t\t});\n\t\tif (!confirmed) return;\n\t\tconst ids = useSelectionStore.getState().selectedIds;\n\t\tconst n = ids.length;\n\t\tif (n === 0) return;\n\t\tlet failed = 0;\n\t\tlet firstErr: unknown;\n\t\tfor (const id of ids) {\n\t\t\ttry {\n\t\t\t\tawait deleteAsset.mutateAsync(id);\n\t\t\t} catch (err) {\n\t\t\t\tfailed++;\n\t\t\t\tfirstErr ??= err;\n\t\t\t}\n\t\t}\n\t\tif (failed === 0) {\n\t\t\ttoaster.success({ title: `${n} asset${n > 1 ? \"s\" : \"\"} deleted` });\n\t\t\tuseSelectionStore.getState().clearSelection();\n\t\t} else {\n\t\t\t// Mapped families explain themselves; other errors keep the bare\n\t\t\t// count so raw server strings never enter the toast.\n\t\t\tconst described = describeRpcError(\n\t\t\t\tfirstErr,\n\t\t\t\t`${n - failed} deleted, ${failed} failed`,\n\t\t\t);\n\t\t\ttoaster.error(\n\t\t\t\tdescribed.kind === \"other\"\n\t\t\t\t\t? { title: `${n - failed} deleted, ${failed} failed` }\n\t\t\t\t\t: { title: described.title, description: described.description },\n\t\t\t);\n\t\t}\n\t}\n\n\tasync function handleBulkTag(tagId: string) {\n\t\ttry {\n\t\t\tawait tagAssets.mutateAsync({ tagId, assetIds: [...selectedIds] });\n\t\t\ttoaster.success({ title: \"Tags updated\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\tasync function handleBulkAddToCollection(collectionId: string) {\n\t\ttry {\n\t\t\tawait addToCollection.mutateAsync({\n\t\t\t\tcollectionId,\n\t\t\t\tassetIds: [...selectedIds],\n\t\t\t});\n\t\t\ttoaster.success({ title: \"Added to collection\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\treturn (\n\t\t<AnkerBulkActionBar\n\t\t\tselectedCount={count}\n\t\t\tonClear={clearSelection}\n\t\t\tcountLabel={(n) => `${n} selected`}\n\t\t>\n\t\t\t<AnkerBulkActionBar.PopoverAction\n\t\t\t\tlabel=\"Add Tags\"\n\t\t\t\ticon={<Tag size={14} />}\n\t\t\t>\n\t\t\t\t<Flex direction=\"column\" gap={1} p={2}>\n\t\t\t\t\t{tags.map((tag) => (\n\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\tkey={tag.id}\n\t\t\t\t\t\t\tasChild\n\t\t\t\t\t\t\tpx={2}\n\t\t\t\t\t\t\tpy={1}\n\t\t\t\t\t\t\trounded=\"md\"\n\t\t\t\t\t\t\tfontSize=\"sm\"\n\t\t\t\t\t\t\ttextAlign=\"left\"\n\t\t\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\t\t\t_hover={{ bg: \"bg.muted\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<button type=\"button\" onClick={() => handleBulkTag(tag.id)}>\n\t\t\t\t\t\t\t\t{tag.name}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</Box>\n\t\t\t\t\t))}\n\t\t\t\t\t{tags.length === 0 && (\n\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\" p={2}>\n\t\t\t\t\t\t\tNo tags available\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)}\n\t\t\t\t</Flex>\n\t\t\t</AnkerBulkActionBar.PopoverAction>\n\n\t\t\t<AnkerBulkActionBar.PopoverAction\n\t\t\t\tlabel=\"Add to Collection\"\n\t\t\t\ticon={<FolderOpen size={14} />}\n\t\t\t>\n\t\t\t\t<Flex direction=\"column\" gap={1} p={2}>\n\t\t\t\t\t{collections.map((col) => (\n\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\tkey={col.id}\n\t\t\t\t\t\t\tasChild\n\t\t\t\t\t\t\tpx={2}\n\t\t\t\t\t\t\tpy={1}\n\t\t\t\t\t\t\trounded=\"md\"\n\t\t\t\t\t\t\tfontSize=\"sm\"\n\t\t\t\t\t\t\ttextAlign=\"left\"\n\t\t\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\t\t\t_hover={{ bg: \"bg.muted\" }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\tonClick={() => handleBulkAddToCollection(col.id)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{col.name}\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</Box>\n\t\t\t\t\t))}\n\t\t\t\t\t{collections.length === 0 && (\n\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\" p={2}>\n\t\t\t\t\t\t\tNo collections available\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t)}\n\t\t\t\t</Flex>\n\t\t\t</AnkerBulkActionBar.PopoverAction>\n\n\t\t\t<AnkerBulkActionBar.Action\n\t\t\t\tlabel=\"Delete\"\n\t\t\t\ticon={<Trash2 size={14} />}\n\t\t\t\tcolorPalette=\"red\"\n\t\t\t\tonClick={handleBulkDelete}\n\t\t\t/>\n\t\t</AnkerBulkActionBar>\n\t);\n};\nBulkActionBar.displayName = \"BulkActionBar\";\n","import { ChipPicker } from \"@knkcs/anker/components\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport {\n\tuseAddAssetsToCollection,\n\tuseCollections,\n\tuseRemoveAssetsFromCollection,\n} from \"../hooks/use-collections\";\nimport { showRpcErrorToast } from \"../lib/rpc-errors\";\nimport type { CollectionInfo } from \"../types\";\n\ninterface CollectionChipFieldProps {\n\tassetId: string;\n\tassignedCollectionIds: string[];\n}\n\nexport const CollectionChipField: React.FC<CollectionChipFieldProps> = ({\n\tassetId,\n\tassignedCollectionIds,\n}) => {\n\tconst collectionsQuery = useCollections();\n\tconst allCollections: CollectionInfo[] = collectionsQuery.data ?? [];\n\tconst addToCollection = useAddAssetsToCollection();\n\tconst removeFromCollection = useRemoveAssetsFromCollection();\n\tconst qc = useQueryClient();\n\n\tconst assigned = allCollections.filter((c) =>\n\t\tassignedCollectionIds.includes(c.id),\n\t);\n\tconst unassigned = allCollections.filter(\n\t\t(c) => !assignedCollectionIds.includes(c.id),\n\t);\n\n\tasync function handleAdd(collection: CollectionInfo) {\n\t\ttry {\n\t\t\tawait addToCollection.mutateAsync({\n\t\t\t\tcollectionId: collection.id,\n\t\t\t\tassetIds: [assetId],\n\t\t\t});\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collections\"] });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\tasync function handleRemove(collection: CollectionInfo) {\n\t\ttry {\n\t\t\tawait removeFromCollection.mutateAsync({\n\t\t\t\tcollectionId: collection.id,\n\t\t\t\tassetIds: [assetId],\n\t\t\t});\n\t\t\tqc.invalidateQueries({ queryKey: [\"mediahub\", \"collections\"] });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\treturn (\n\t\t<ChipPicker<CollectionInfo>\n\t\t\tassigned={assigned}\n\t\t\tavailable={unassigned}\n\t\t\tgetItemId={(c) => c.id}\n\t\t\tgetItemLabel={(c) => c.name}\n\t\t\tonAdd={handleAdd}\n\t\t\tonRemove={handleRemove}\n\t\t\taddLabel=\"Add to collection\"\n\t\t\temptyLabel=\"No collections\"\n\t\t\tsearchable\n\t\t\tloading={collectionsQuery.isLoading}\n\t\t/>\n\t);\n};\nCollectionChipField.displayName = \"CollectionChipField\";\n","import { InlineCreatableList } from \"@knkcs/anker/components\";\nimport { toaster } from \"@knkcs/anker/primitives\";\nimport { useCollections, useCreateCollection } from \"../hooks/use-collections\";\nimport { showRpcErrorToast } from \"../lib/rpc-errors\";\nimport type { CollectionInfo } from \"../types\";\n\ninterface CollectionPanelProps {\n\tactiveCollectionId: string;\n\tonSelectCollection: (collectionId: string) => void;\n}\n\nexport const CollectionPanel: React.FC<CollectionPanelProps> = ({\n\tactiveCollectionId,\n\tonSelectCollection,\n}) => {\n\tconst collectionsQuery = useCollections();\n\tconst collections: CollectionInfo[] = collectionsQuery.data ?? [];\n\tconst createCollection = useCreateCollection();\n\n\tasync function handleCreate(name: string) {\n\t\ttry {\n\t\t\tawait createCollection.mutateAsync({\n\t\t\t\tname,\n\t\t\t\tslug: name.toLowerCase().replace(/\\s+/g, \"-\"),\n\t\t\t\tdescription: \"\",\n\t\t\t\ttype: \"static\",\n\t\t\t\trules: \"\",\n\t\t\t});\n\t\t\ttoaster.success({ title: \"Collection created\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\treturn (\n\t\t<InlineCreatableList<CollectionInfo>\n\t\t\titems={collections}\n\t\t\tactiveIds={activeCollectionId ? [activeCollectionId] : []}\n\t\t\tonToggle={onSelectCollection}\n\t\t\tonCreate={handleCreate}\n\t\t\tgetItemId={(c) => c.id}\n\t\t\tgetItemLabel={(c) => c.name}\n\t\t\tvariant=\"list\"\n\t\t\tcreatePlaceholder=\"Collection name\"\n\t\t\tcreateLabel=\"New collection\"\n\t\t\temptyText=\"No collections\"\n\t\t/>\n\t);\n};\nCollectionPanel.displayName = \"CollectionPanel\";\n","import {\n\tBreadcrumbCurrentLink,\n\tBreadcrumbItem,\n\tBreadcrumbLink,\n\tBreadcrumbList,\n\tBreadcrumbRoot,\n\tBreadcrumbSeparator,\n} from \"@knkcs/anker/primitives\";\nimport { useMemo } from \"react\";\nimport { useFolder } from \"../hooks/use-folders\";\n\ninterface FolderBreadcrumbsProps {\n\tfolderId: string;\n\tonNavigate: (folderId: string) => void;\n}\n\n/**\n * Build ancestor chain by walking parent_id up to 3 levels.\n * Uses useFolder for each level. Since tree browsing caches folders,\n * most calls will resolve from TanStack Query cache.\n *\n * Limitation: Shows at most 3 breadcrumb segments (grandparent/parent/current).\n * For deeper nesting, the earliest ancestors are truncated. This is acceptable\n * for v1 — folder structures deeper than 3 levels are rare. If needed later,\n * add a GetFolderAncestors RPC to the backend for a single-call solution.\n */\nfunction useAncestorChain(folderId: string) {\n\tconst folderQuery = useFolder(folderId);\n\tconst folder = folderQuery.data;\n\n\tconst parentQuery = useFolder(folder?.parentId ?? \"\");\n\tconst parent = parentQuery.data;\n\n\tconst grandparentQuery = useFolder(parent?.parentId ?? \"\");\n\tconst grandparent = grandparentQuery.data;\n\n\treturn useMemo(() => {\n\t\tconst chain: Array<{ id: string; name: string }> = [];\n\t\tif (grandparent) chain.push({ id: grandparent.id, name: grandparent.name });\n\t\tif (parent) chain.push({ id: parent.id, name: parent.name });\n\t\tif (folder) chain.push({ id: folder.id, name: folder.name });\n\t\treturn chain;\n\t}, [folder, parent, grandparent]);\n}\n\nexport const FolderBreadcrumbs: React.FC<FolderBreadcrumbsProps> = ({\n\tfolderId,\n\tonNavigate,\n}) => {\n\tconst ancestors = useAncestorChain(folderId);\n\n\tif (!folderId || ancestors.length === 0) {\n\t\treturn null;\n\t}\n\n\treturn (\n\t\t<BreadcrumbRoot>\n\t\t\t<BreadcrumbList>\n\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\thref=\"#\"\n\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\tonNavigate(\"\");\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\t>\n\t\t\t\t\t\tAll Assets\n\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t</BreadcrumbItem>\n\t\t\t\t{ancestors.slice(0, -1).map((item) => (\n\t\t\t\t\t<BreadcrumbItem key={item.id}>\n\t\t\t\t\t\t<BreadcrumbLink\n\t\t\t\t\t\t\thref=\"#\"\n\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\t\t\tonNavigate(item.id);\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{item.name}\n\t\t\t\t\t\t</BreadcrumbLink>\n\t\t\t\t\t\t<BreadcrumbSeparator />\n\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t))}\n\t\t\t\t{ancestors.length > 0 && (\n\t\t\t\t\t<BreadcrumbItem>\n\t\t\t\t\t\t<BreadcrumbCurrentLink>\n\t\t\t\t\t\t\t{ancestors[ancestors.length - 1].name}\n\t\t\t\t\t\t</BreadcrumbCurrentLink>\n\t\t\t\t\t</BreadcrumbItem>\n\t\t\t\t)}\n\t\t\t</BreadcrumbList>\n\t\t</BreadcrumbRoot>\n\t);\n};\nFolderBreadcrumbs.displayName = \"FolderBreadcrumbs\";\n","import { Button } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Box, Flex, HStack, Link, Text } from \"@knkcs/anker/primitives\";\nimport type { ReactNode } from \"react\";\nimport type { RpcErrorDescription } from \"../lib/rpc-errors\";\nimport { useMediahubLinks } from \"../provider\";\n\nexport interface LeakGuardRefusalDialogProps {\n\t/** The mapped leak-guard failure to explain. Callers keep the last refusal\n\t * mounted while the dialog animates closed (same #66 semantics as the\n\t * other dialogs) — `null` renders nothing. */\n\trefusal: RpcErrorDescription | null;\n\topen: boolean;\n\tonClose: () => void;\n\tcloseLabel?: string;\n\t/** Line under the pair list telling the user how to proceed. */\n\tresolveHint?: string;\n}\n\nfunction MaybeLink({\n\thref,\n\tchildren,\n}: {\n\thref?: string;\n\tchildren: ReactNode;\n}): React.JSX.Element {\n\tif (!href) {\n\t\treturn (\n\t\t\t<Text as=\"span\" fontWeight=\"medium\">\n\t\t\t\t{children}\n\t\t\t</Text>\n\t\t);\n\t}\n\treturn (\n\t\t<Link\n\t\t\thref={href}\n\t\t\tfontWeight=\"medium\"\n\t\t\tcolor=\"colorPalette.fg\"\n\t\t\tcolorPalette=\"primary\"\n\t\t\ttextDecoration=\"underline\"\n\t\t>\n\t\t\t{children}\n\t\t</Link>\n\t);\n}\n\n/**\n * Explains a refused Restricted toggle (guardian#55): the refusing rule in\n * human copy plus every offending asset→collection pair, each side linked to\n * its surface when the host registered routes — never a raw error.\n */\nexport const LeakGuardRefusalDialog: React.FC<LeakGuardRefusalDialogProps> = ({\n\trefusal,\n\topen,\n\tonClose,\n\tcloseLabel,\n\tresolveHint,\n}) => {\n\tconst links = useMediahubLinks();\n\tif (!refusal) return null;\n\n\tconst exposures = refusal.exposures ?? [];\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tonClose={onClose}\n\t\t\tsize=\"md\"\n\t\t\theader={refusal.title}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\" justify=\"flex-end\">\n\t\t\t\t\t<Button variant=\"outline\" onClick={onClose}>\n\t\t\t\t\t\t{closeLabel ?? \"Close\"}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Flex direction=\"column\" gap={3}>\n\t\t\t\t<Text fontSize=\"sm\">{refusal.ruleText ?? refusal.description}</Text>\n\t\t\t\t{exposures.length > 0 && (\n\t\t\t\t\t<Box as=\"ul\" pl={4} display=\"flex\" flexDirection=\"column\" gap={1}>\n\t\t\t\t\t\t{exposures.map((e) => (\n\t\t\t\t\t\t\t<Box as=\"li\" key={`${e.assetId}:${e.collectionId}`} fontSize=\"sm\">\n\t\t\t\t\t\t\t\t<MaybeLink href={links.assetHref?.(e.assetId)}>\n\t\t\t\t\t\t\t\t\t{e.assetName}\n\t\t\t\t\t\t\t\t</MaybeLink>\n\t\t\t\t\t\t\t\t<Text as=\"span\" color=\"fg.muted\">\n\t\t\t\t\t\t\t\t\t{\" — in collection \"}\n\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t<MaybeLink href={links.collectionHref?.(e.collectionId)}>\n\t\t\t\t\t\t\t\t\t{e.collectionName}\n\t\t\t\t\t\t\t\t</MaybeLink>\n\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Box>\n\t\t\t\t)}\n\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\">\n\t\t\t\t\t{resolveHint ??\n\t\t\t\t\t\t\"Resolve these exposures, then try again — nothing was changed.\"}\n\t\t\t\t</Text>\n\t\t\t</Flex>\n\t\t</Modal>\n\t);\n};\nLeakGuardRefusalDialog.displayName = \"LeakGuardRefusalDialog\";\n","import type { AssetClient, FolderClient } from \"../clients\";\nimport type { AssetInfo, CollectionInfo, FolderInfo } from \"../types\";\n\n/**\n * Client-side mirror of the service move guards (asset-move and folder-move\n * into a Restricted chain, guardian ADR 0003): the move picker uses these to\n * disable leak-guarded destinations up front with the reason inline. The\n * server re-checks every move — a stale answer here degrades to the server's\n * refusal, never to a leak.\n */\n\n/** Bounds every chain walk, mirroring the service's maxFolderDepth: a chain\n * deeper than this is treated as invalid rather than walked forever. */\nconst maxFolderDepth = 100;\n\nexport function openCollectionIds(collections: CollectionInfo[]): string[] {\n\treturn collections.filter((c) => !c.restricted).map((c) => c.id);\n}\n\n/** Whether an open collection exposes the asset — the condition under which\n * moving it into a Restricted chain is refused. Collections the caller\n * cannot see are Restricted by definition and never count. */\nexport function assetExposedByOpenCollection(\n\tasset: AssetInfo,\n\tcollections: CollectionInfo[],\n): boolean {\n\tconst open = new Set(openCollectionIds(collections));\n\treturn asset.collectionIds.some((id) => open.has(id));\n}\n\n/** Whether the folder or any ancestor is Restricted. Fails closed at the\n * depth bound: an unwalkable chain is treated as confined. */\nexport async function folderChainRestricted(\n\tfolders: FolderClient,\n\tfolder: FolderInfo,\n): Promise<boolean> {\n\tlet f = folder;\n\tfor (let i = 0; i < maxFolderDepth; i++) {\n\t\tif (f.restricted) return true;\n\t\tif (!f.parentId) return false;\n\t\tf = await folders.get(f.parentId);\n\t}\n\treturn true;\n}\n\n/** Whether any asset filed under folderId (transitively) belongs to an open\n * collection — the condition under which moving the folder into a Restricted\n * chain is refused. Restricted sub-branches are pruned: their assets are\n * confined already, so a move changes nothing for them. */\nexport async function folderSubtreeExposed(\n\tclients: { folders: FolderClient; assets: AssetClient },\n\tworkspaceId: string,\n\tfolderId: string,\n\topenIds: string[],\n): Promise<boolean> {\n\tif (openIds.length === 0) return false;\n\tlet frontier = [folderId];\n\tfor (let depth = 0; frontier.length > 0 && depth < maxFolderDepth; depth++) {\n\t\tfor (const id of frontier) {\n\t\t\tconst page = await clients.assets.list(workspaceId, {\n\t\t\t\tfolderId: id,\n\t\t\t\tcollectionIds: openIds,\n\t\t\t});\n\t\t\tif (page.total > 0) return true;\n\t\t}\n\t\tconst next: string[] = [];\n\t\tfor (const id of frontier) {\n\t\t\tconst children = await clients.folders.list(workspaceId, id);\n\t\t\tnext.push(...children.filter((c) => !c.restricted).map((c) => c.id));\n\t\t}\n\t\tfrontier = next;\n\t}\n\treturn false;\n}\n","import { Button, IconButton, Persona } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport {\n\tBadge,\n\tBox,\n\tFlex,\n\tHStack,\n\tNativeSelect,\n\tSpinner,\n\tText,\n\ttoaster,\n} from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { Lock, X } from \"lucide-react\";\nimport { useEffect, useMemo, useState } from \"react\";\nimport {\n\tuseGrantAccess,\n\tuseGrants,\n\tuseRevokeAccess,\n} from \"../hooks/use-grants\";\nimport { useUsers, useWorkspaceMembers } from \"../hooks/use-users\";\nimport { folderChainRestricted } from \"../lib/move-guard\";\nimport { describeRpcError, showRpcErrorToast } from \"../lib/rpc-errors\";\nimport { useMediahubClients } from \"../provider\";\nimport type {\n\tAssetInfo,\n\tCollectionInfo,\n\tFolderInfo,\n\tGrantLevel,\n} from \"../types\";\n\n/** What the panel manages access to: the full record is carried so the\n * Derived-Access note can reason about Restricted chains without refetching\n * what the mount site already holds. */\nexport type ManageAccessSubject =\n\t| { kind: \"asset\"; asset: AssetInfo }\n\t| { kind: \"folder\"; folder: FolderInfo }\n\t| { kind: \"collection\"; collection: CollectionInfo };\n\nexport interface ManageAccessDialogProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tsubject: ManageAccessSubject;\n\theaderLabel?: string;\n\tdoneLabel?: string;\n\townerBadgeLabel?: string;\n\taddPersonLabel?: string;\n\tgrantLabel?: string;\n\tviewerLabel?: string;\n\teditorLabel?: string;\n\t/** Derived-Access note on open content. */\n\topenAccessNote?: string;\n\t/** Derived-Access note on Restricted content (explicit Grants only). */\n\trestrictedAccessNote?: string;\n}\n\nfunction subjectId(subject: ManageAccessSubject): string {\n\tswitch (subject.kind) {\n\t\tcase \"asset\":\n\t\t\treturn subject.asset.id;\n\t\tcase \"folder\":\n\t\t\treturn subject.folder.id;\n\t\tcase \"collection\":\n\t\t\treturn subject.collection.id;\n\t}\n}\n\nfunction subjectName(subject: ManageAccessSubject): string {\n\tswitch (subject.kind) {\n\t\tcase \"asset\":\n\t\t\treturn subject.asset.name;\n\t\tcase \"folder\":\n\t\t\treturn subject.folder.name;\n\t\tcase \"collection\":\n\t\t\treturn subject.collection.name;\n\t}\n}\n\n/**\n * \"Manage access\" panel for assets, folders, and collections (guardian#52):\n * a pinned Owner row, the roster of Grants with level dropdowns and revoke,\n * a member picker, and a Derived-Access note. The roster read doubles as the\n * authority gate — the server answers PermissionDenied to everyone but the\n * Owner and workspace admins, and those callers get the denial copy instead\n * of a roster (grantees see content, never who else was granted).\n */\nexport function ManageAccessDialog(\n\tprops: ManageAccessDialogProps,\n): React.JSX.Element {\n\tconst { open, onOpenChange, subject } = props;\n\tconst clients = useMediahubClients();\n\tconst kind = subject.kind;\n\tconst resourceId = subjectId(subject);\n\n\t// \"\" = nobody picked yet.\n\tconst [pickedUserId, setPickedUserId] = useState(\"\");\n\tconst [pickLevel, setPickLevel] = useState<GrantLevel>(\"viewer\");\n\n\tconst rosterQuery = useGrants(kind, resourceId, { enabled: open });\n\tconst roster = rosterQuery.data;\n\tconst denied =\n\t\trosterQuery.isError &&\n\t\tdescribeRpcError(rosterQuery.error, \"\").kind === \"permission-denied\";\n\n\t// Fetched only once the caller has proven authority via the roster read —\n\t// non-authorities get the denial copy and nothing else.\n\tconst membersQuery = useWorkspaceMembers({\n\t\tenabled: open && rosterQuery.isSuccess,\n\t});\n\n\tconst rosterUserIds = useMemo(() => {\n\t\tif (!roster) return [];\n\t\tconst ids = roster.grants.map((g) => g.userId);\n\t\tif (roster.ownerUserId) ids.push(roster.ownerUserId);\n\t\treturn ids;\n\t}, [roster]);\n\t// Resolved through the directory rather than the member listing so users\n\t// who since left the workspace still render by name where possible.\n\tconst namesQuery = useUsers(rosterUserIds);\n\tconst nameOf = (userId: string) => namesQuery.data?.[userId] ?? userId;\n\n\t// Whether Derived Access is severed: collections answer from their own\n\t// flag; folders and assets need their chain walked. An unwalkable chain\n\t// counts as Restricted (fail closed), matching the move-guard idiom.\n\tconst scopeQuery = useQuery({\n\t\tqueryKey: [\"mediahub\", \"access-scope\", kind, resourceId],\n\t\tenabled: open && subject.kind !== \"collection\" && rosterQuery.isSuccess,\n\t\tqueryFn: async () => {\n\t\t\tif (subject.kind === \"folder\") {\n\t\t\t\treturn folderChainRestricted(clients.folders, subject.folder);\n\t\t\t}\n\t\t\tif (subject.kind === \"asset\") {\n\t\t\t\tif (!subject.asset.folderId) return false;\n\t\t\t\tconst parent = await clients.folders.get(subject.asset.folderId);\n\t\t\t\treturn folderChainRestricted(clients.folders, parent);\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t});\n\tconst restricted =\n\t\tsubject.kind === \"collection\"\n\t\t\t? subject.collection.restricted\n\t\t\t: scopeQuery.isError\n\t\t\t\t? true\n\t\t\t\t: scopeQuery.data;\n\n\tconst grantAccess = useGrantAccess();\n\tconst revokeAccess = useRevokeAccess();\n\tconst mutating = grantAccess.isPending || revokeAccess.isPending;\n\n\t// Same mount semantics as MoveDialog: keep the Modal mounted, reset\n\t// ephemeral state on reopen.\n\tuseEffect(() => {\n\t\tif (!open) return;\n\t\tsetPickedUserId(\"\");\n\t\tsetPickLevel(\"viewer\");\n\t}, [open]);\n\n\tconst granteeIds = useMemo(\n\t\t() => new Set(roster?.grants.map((g) => g.userId)),\n\t\t[roster],\n\t);\n\t// Candidates: workspace members who are neither the Owner (structural,\n\t// never grantable) nor already on the roster (managed via their row).\n\tconst candidates = useMemo(\n\t\t() =>\n\t\t\t(membersQuery.data ?? []).filter(\n\t\t\t\t(m) => m.id !== roster?.ownerUserId && !granteeIds.has(m.id),\n\t\t\t),\n\t\t[membersQuery.data, roster, granteeIds],\n\t);\n\n\tconst names = namesQuery.data;\n\tconst sortedGrants = useMemo(() => {\n\t\tconst nm = (id: string) => names?.[id] ?? id;\n\t\treturn [...(roster?.grants ?? [])].sort((a, b) =>\n\t\t\tnm(a.userId).localeCompare(nm(b.userId)),\n\t\t);\n\t}, [roster, names]);\n\n\tasync function handleGrant() {\n\t\tif (!pickedUserId) return;\n\t\ttry {\n\t\t\tawait grantAccess.mutateAsync({\n\t\t\t\tresourceType: kind,\n\t\t\t\tresourceId,\n\t\t\t\tuserId: pickedUserId,\n\t\t\t\tlevel: pickLevel,\n\t\t\t});\n\t\t\tsetPickedUserId(\"\");\n\t\t\tsetPickLevel(\"viewer\");\n\t\t\ttoaster.success({ title: \"Access granted\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Grant failed\");\n\t\t}\n\t}\n\n\tasync function handleLevelChange(userId: string, level: GrantLevel) {\n\t\ttry {\n\t\t\tawait grantAccess.mutateAsync({\n\t\t\t\tresourceType: kind,\n\t\t\t\tresourceId,\n\t\t\t\tuserId,\n\t\t\t\tlevel,\n\t\t\t});\n\t\t\ttoaster.success({ title: \"Access updated\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Update failed\");\n\t\t}\n\t}\n\n\tasync function handleRevoke(userId: string) {\n\t\ttry {\n\t\t\tawait revokeAccess.mutateAsync({\n\t\t\t\tresourceType: kind,\n\t\t\t\tresourceId,\n\t\t\t\tuserId,\n\t\t\t});\n\t\t\ttoaster.success({ title: \"Access revoked\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Revoke failed\");\n\t\t}\n\t}\n\n\tconst viewerLabel = props.viewerLabel ?? \"Viewer\";\n\tconst editorLabel = props.editorLabel ?? \"Editor\";\n\n\tfunction renderBody() {\n\t\tif (rosterQuery.isLoading) {\n\t\t\treturn (\n\t\t\t\t<Flex justify=\"center\" py=\"8\">\n\t\t\t\t\t<Spinner />\n\t\t\t\t</Flex>\n\t\t\t);\n\t\t}\n\t\tif (denied) {\n\t\t\tconst d = describeRpcError(rosterQuery.error, \"\");\n\t\t\treturn (\n\t\t\t\t<Box py=\"4\">\n\t\t\t\t\t<Text fontWeight=\"medium\">{d.title}</Text>\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\" mt=\"1\">\n\t\t\t\t\t\t{d.description}\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\t\t\t);\n\t\t}\n\t\tif (rosterQuery.isError) {\n\t\t\treturn (\n\t\t\t\t<Box py=\"4\">\n\t\t\t\t\t<Text fontSize=\"sm\" color=\"fg.error\">\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tdescribeRpcError(rosterQuery.error, \"Couldn't load access\")\n\t\t\t\t\t\t\t\t.description\n\t\t\t\t\t\t}\n\t\t\t\t\t</Text>\n\t\t\t\t</Box>\n\t\t\t);\n\t\t}\n\t\tif (!roster) return null;\n\n\t\treturn (\n\t\t\t<Flex direction=\"column\" gap=\"4\">\n\t\t\t\t{restricted !== undefined && (\n\t\t\t\t\t<HStack\n\t\t\t\t\t\tgap=\"2\"\n\t\t\t\t\t\talign=\"flex-start\"\n\t\t\t\t\t\tpx=\"3\"\n\t\t\t\t\t\tpy=\"2\"\n\t\t\t\t\t\trounded=\"md\"\n\t\t\t\t\t\tbg=\"bg.muted\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{restricted && <Lock size={14} style={{ marginTop: 2 }} />}\n\t\t\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\">\n\t\t\t\t\t\t\t{restricted\n\t\t\t\t\t\t\t\t? (props.restrictedAccessNote ??\n\t\t\t\t\t\t\t\t\t`Restricted — only the Owner and people with Grants can access this ${kind}.`)\n\t\t\t\t\t\t\t\t: (props.openAccessNote ??\n\t\t\t\t\t\t\t\t\t`All workspace members can view this ${kind}. Grants add explicit access on top.`)}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</HStack>\n\t\t\t\t)}\n\n\t\t\t\t<Flex direction=\"column\" gap=\"2\">\n\t\t\t\t\t{roster.ownerUserId && (\n\t\t\t\t\t\t<Flex align=\"center\" gap=\"2\">\n\t\t\t\t\t\t\t<Box flex=\"1\" minW=\"0\">\n\t\t\t\t\t\t\t\t<Persona size=\"sm\" name={nameOf(roster.ownerUserId)} />\n\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t<Badge variant=\"subtle\">{props.ownerBadgeLabel ?? \"Owner\"}</Badge>\n\t\t\t\t\t\t</Flex>\n\t\t\t\t\t)}\n\t\t\t\t\t{sortedGrants.map((g) => {\n\t\t\t\t\t\tconst name = nameOf(g.userId);\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Flex key={g.userId} align=\"center\" gap=\"2\">\n\t\t\t\t\t\t\t\t<Box flex=\"1\" minW=\"0\">\n\t\t\t\t\t\t\t\t\t<Persona size=\"sm\" name={name} />\n\t\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\twidth=\"auto\"\n\t\t\t\t\t\t\t\t\taria-label={`Access level for ${name}`}\n\t\t\t\t\t\t\t\t\tvalue={g.level}\n\t\t\t\t\t\t\t\t\tdisabled={mutating}\n\t\t\t\t\t\t\t\t\tonChange={(e) =>\n\t\t\t\t\t\t\t\t\t\thandleLevelChange(g.userId, e.target.value as GrantLevel)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<option value=\"viewer\">{viewerLabel}</option>\n\t\t\t\t\t\t\t\t\t<option value=\"editor\">{editorLabel}</option>\n\t\t\t\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t\t\t\t<IconButton\n\t\t\t\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\taria-label={`Revoke access for ${name}`}\n\t\t\t\t\t\t\t\t\tdisabled={mutating}\n\t\t\t\t\t\t\t\t\tonClick={() => handleRevoke(g.userId)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<X size={14} />\n\t\t\t\t\t\t\t\t</IconButton>\n\t\t\t\t\t\t\t</Flex>\n\t\t\t\t\t\t);\n\t\t\t\t\t})}\n\t\t\t\t</Flex>\n\n\t\t\t\t<HStack gap=\"2\" align=\"center\">\n\t\t\t\t\t<Box flex=\"1\" minW=\"0\">\n\t\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\taria-label=\"Add a person\"\n\t\t\t\t\t\t\tplaceholder={props.addPersonLabel ?? \"Add a person…\"}\n\t\t\t\t\t\t\tvalue={pickedUserId}\n\t\t\t\t\t\t\tdisabled={membersQuery.isLoading}\n\t\t\t\t\t\t\tonChange={(e) => setPickedUserId(e.target.value)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{candidates.map((m) => (\n\t\t\t\t\t\t\t\t<option key={m.id} value={m.id}>\n\t\t\t\t\t\t\t\t\t{m.displayName}\n\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t</Box>\n\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\twidth=\"auto\"\n\t\t\t\t\t\taria-label=\"Access level\"\n\t\t\t\t\t\tvalue={pickLevel}\n\t\t\t\t\t\tonChange={(e) => setPickLevel(e.target.value as GrantLevel)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<option value=\"viewer\">{viewerLabel}</option>\n\t\t\t\t\t\t<option value=\"editor\">{editorLabel}</option>\n\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\t\tdisabled={!pickedUserId}\n\t\t\t\t\t\tloading={grantAccess.isPending}\n\t\t\t\t\t\tonClick={handleGrant}\n\t\t\t\t\t>\n\t\t\t\t\t\t{props.grantLabel ?? \"Grant access\"}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t</Flex>\n\t\t);\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tonClose={() => onOpenChange(false)}\n\t\t\tsize=\"md\"\n\t\t\theader={props.headerLabel ?? `Manage access to \"${subjectName(subject)}\"`}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\" justify=\"flex-end\">\n\t\t\t\t\t<Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n\t\t\t\t\t\t{props.doneLabel ?? \"Done\"}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t{renderBody()}\n\t\t</Modal>\n\t);\n}\nManageAccessDialog.displayName = \"ManageAccessDialog\";\n","import { Button, IconButton } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport {\n\tBox,\n\tFlex,\n\tHStack,\n\tSpinner,\n\tText,\n\ttoaster,\n} from \"@knkcs/anker/primitives\";\nimport { useQuery } from \"@tanstack/react-query\";\nimport { ChevronDown, ChevronRight, Folder, Lock } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useState } from \"react\";\nimport { useMoveAsset } from \"../hooks/use-assets\";\nimport { useCollections } from \"../hooks/use-collections\";\nimport { useFolders, useMoveFolder } from \"../hooks/use-folders\";\nimport {\n\tassetExposedByOpenCollection,\n\tfolderChainRestricted,\n\tfolderSubtreeExposed,\n\topenCollectionIds,\n} from \"../lib/move-guard\";\nimport { showRpcErrorToast } from \"../lib/rpc-errors\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\nimport type { AssetInfo, FolderInfo } from \"../types\";\n\n/** What the dialog moves: a folder (from the tree's context menu) or an\n * asset (from its detail view). */\nexport type MoveSubject =\n\t| { kind: \"folder\"; folder: FolderInfo }\n\t| { kind: \"asset\"; asset: AssetInfo };\n\nexport interface MoveDialogProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\tsubject: MoveSubject;\n\t/** Called after a successful move with the destination folder id\n\t * (\"\" = workspace root). */\n\tonMoved?: (destinationId: string) => void;\n\theaderLabel?: string;\n\tconfirmLabel?: string;\n\tcancelLabel?: string;\n\trootLabel?: string;\n\tcurrentLocationLabel?: string;\n\tselfLocationLabel?: string;\n\t/** Reason shown on leak-guarded destinations. */\n\tblockedLabel?: string;\n}\n\nfunction subjectName(subject: MoveSubject): string {\n\treturn subject.kind === \"folder\" ? subject.folder.name : subject.asset.name;\n}\n\n/** The destination the subject currently sits in (\"\" = workspace root). */\nfunction currentParentId(subject: MoveSubject): string {\n\treturn subject.kind === \"folder\"\n\t\t? subject.folder.parentId\n\t\t: subject.asset.folderId;\n}\n\ninterface RowContext {\n\tsubject: MoveSubject;\n\t/** The subject is exposed through an open collection, so Restricted\n\t * destinations would trip the server's leak guard. */\n\tguardActive: boolean;\n\tselectedId: string | null;\n\tonSelect: (id: string) => void;\n\t/** Drops the selection iff it still points at this id — rows call it\n\t * when they become disabled under an already-made selection. */\n\tonDeselect: (id: string) => void;\n\tcurrentLocationLabel: string;\n\tselfLocationLabel: string;\n\tblockedLabel: string;\n}\n\n/** Why a destination row is disabled, or null when it is selectable. */\nfunction rowDisabledReason(\n\tctx: RowContext,\n\tfolder: FolderInfo,\n\tchainRestricted: boolean,\n): string | null {\n\tif (ctx.subject.kind === \"folder\" && folder.id === ctx.subject.folder.id) {\n\t\treturn ctx.selfLocationLabel;\n\t}\n\tif (folder.id === currentParentId(ctx.subject)) {\n\t\treturn ctx.currentLocationLabel;\n\t}\n\tif (ctx.guardActive && chainRestricted) {\n\t\treturn ctx.blockedLabel;\n\t}\n\treturn null;\n}\n\ninterface DestinationRowButtonProps {\n\tname: string;\n\t/** Disabled-with-reason when set; selectable when null. */\n\treason: string | null;\n\tselected: boolean;\n\trestricted?: boolean;\n\temphasized?: boolean;\n\tonClick: () => void;\n}\n\n/** The selectable body shared by every destination row, root included. */\nfunction DestinationRowButton({\n\tname,\n\treason,\n\tselected,\n\trestricted,\n\temphasized,\n\tonClick,\n}: DestinationRowButtonProps): React.JSX.Element {\n\treturn (\n\t\t<Box\n\t\t\tasChild\n\t\t\tflex=\"1\"\n\t\t\tpx=\"2\"\n\t\t\tpy=\"1\"\n\t\t\trounded=\"md\"\n\t\t\ttextAlign=\"left\"\n\t\t\tcursor={reason ? \"not-allowed\" : \"pointer\"}\n\t\t\topacity={reason ? 0.5 : 1}\n\t\t\tbg={selected ? \"colorPalette.subtle\" : \"transparent\"}\n\t\t\tcolor={selected ? \"colorPalette.fg\" : \"fg.default\"}\n\t\t\tcolorPalette=\"primary\"\n\t\t\t_hover={{ bg: selected ? \"colorPalette.subtle\" : \"bg.muted\" }}\n\t\t>\n\t\t\t<button type=\"button\" disabled={!!reason} onClick={onClick}>\n\t\t\t\t<HStack gap=\"2\" align=\"center\">\n\t\t\t\t\t{restricted ? <Lock size={13} /> : <Folder size={13} />}\n\t\t\t\t\t<Text fontSize=\"sm\" fontWeight={emphasized ? \"medium\" : \"normal\"}>\n\t\t\t\t\t\t{name}\n\t\t\t\t\t</Text>\n\t\t\t\t</HStack>\n\t\t\t\t{reason && (\n\t\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\">\n\t\t\t\t\t\t{reason}\n\t\t\t\t\t</Text>\n\t\t\t\t)}\n\t\t\t</button>\n\t\t</Box>\n\t);\n}\n\ninterface DestinationRowProps {\n\tctx: RowContext;\n\tfolder: FolderInfo;\n\t/** Whether any ancestor in the picker walk is Restricted. */\n\tancestorRestricted: boolean;\n\tlevel: number;\n}\n\nfunction DestinationRow({\n\tctx,\n\tfolder,\n\tancestorRestricted,\n\tlevel,\n}: DestinationRowProps): React.JSX.Element {\n\tconst [expanded, setExpanded] = useState(false);\n\tconst childrenQuery = useFolders(folder.id, { enabled: expanded });\n\n\tconst chainRestricted = ancestorRestricted || folder.restricted;\n\tconst reason = rowDisabledReason(ctx, folder, chainRestricted);\n\tconst isSelf =\n\t\tctx.subject.kind === \"folder\" && folder.id === ctx.subject.folder.id;\n\tconst selected = ctx.selectedId === folder.id;\n\n\t// A selection must not survive its own disabling: the exposure probe can\n\t// resolve after the user already picked a Restricted destination.\n\tconst { onDeselect } = ctx;\n\tuseEffect(() => {\n\t\tif (selected && reason) onDeselect(folder.id);\n\t}, [selected, reason, folder.id, onDeselect]);\n\n\treturn (\n\t\t<>\n\t\t\t<Flex align=\"center\" gap=\"1\" pl={level * 4}>\n\t\t\t\t{/* The subject folder's subtree moves with it — never expandable. */}\n\t\t\t\t{isSelf ? (\n\t\t\t\t\t<Box w=\"6\" />\n\t\t\t\t) : (\n\t\t\t\t\t<IconButton\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"xs\"\n\t\t\t\t\t\taria-label={\n\t\t\t\t\t\t\texpanded ? `Collapse \"${folder.name}\"` : `Expand \"${folder.name}\"`\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonClick={() => setExpanded((e) => !e)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{expanded ? <ChevronDown size={14} /> : <ChevronRight size={14} />}\n\t\t\t\t\t</IconButton>\n\t\t\t\t)}\n\t\t\t\t<DestinationRowButton\n\t\t\t\t\tname={folder.name}\n\t\t\t\t\treason={reason}\n\t\t\t\t\tselected={selected}\n\t\t\t\t\trestricted={folder.restricted}\n\t\t\t\t\tonClick={() => ctx.onSelect(folder.id)}\n\t\t\t\t/>\n\t\t\t</Flex>\n\t\t\t{expanded && childrenQuery.isLoading && (\n\t\t\t\t<Flex justify=\"center\" py=\"1\">\n\t\t\t\t\t<Spinner size=\"xs\" />\n\t\t\t\t</Flex>\n\t\t\t)}\n\t\t\t{expanded &&\n\t\t\t\tchildrenQuery.data?.map((child) => (\n\t\t\t\t\t<DestinationRow\n\t\t\t\t\t\tkey={child.id}\n\t\t\t\t\t\tctx={ctx}\n\t\t\t\t\t\tfolder={child}\n\t\t\t\t\t\tancestorRestricted={chainRestricted}\n\t\t\t\t\t\tlevel={level + 1}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t</>\n\t);\n}\n\n/**\n * Destination folder picker for moving a folder or an asset. Destinations\n * that would trip the server's leak guard (moving exposed content into a\n * Restricted chain, guardian ADR 0003) render disabled with the reason\n * inline; the server remains authoritative and re-checks every move.\n */\nexport function MoveDialog(props: MoveDialogProps): React.JSX.Element {\n\tconst { open, onOpenChange, subject, onMoved } = props;\n\tconst workspaceId = useWorkspaceId();\n\tconst clients = useMediahubClients();\n\tconst [selectedId, setSelectedId] = useState<string | null>(null);\n\n\tconst rootQuery = useFolders(\"\");\n\tconst collectionsQuery = useCollections();\n\tconst collections = collectionsQuery.data ?? [];\n\tconst openIds = useMemo(() => openCollectionIds(collections), [collections]);\n\n\tconst moveFolder = useMoveFolder();\n\tconst moveAsset = useMoveAsset();\n\n\t// Whether moving the subject into a Restricted chain would trip the\n\t// server's leak guard. Assets carry their collection memberships, so the\n\t// answer is synchronous; folders need the subtree probed.\n\tconst subjectFolderId = subject.kind === \"folder\" ? subject.folder.id : \"\";\n\tconst folderGuardQuery = useQuery({\n\t\tqueryKey: [\"mediahub\", \"move-guard\", subjectFolderId, openIds],\n\t\tqueryFn: async () => {\n\t\t\tif (subject.kind !== \"folder\") return false;\n\t\t\t// A subject already confined by a Restricted chain can move\n\t\t\t// anywhere — the move changes nothing for its audience.\n\t\t\tif (await folderChainRestricted(clients.folders, subject.folder)) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn folderSubtreeExposed(\n\t\t\t\t{ folders: clients.folders, assets: clients.assets },\n\t\t\t\tworkspaceId,\n\t\t\t\tsubject.folder.id,\n\t\t\t\topenIds,\n\t\t\t);\n\t\t},\n\t\tenabled: open && subject.kind === \"folder\" && collectionsQuery.isSuccess,\n\t});\n\tconst guardActive =\n\t\tsubject.kind === \"asset\"\n\t\t\t? assetExposedByOpenCollection(subject.asset, collections)\n\t\t\t: folderGuardQuery.data === true;\n\n\t// Same mount semantics as CollectionPicker (#66): keep the Modal mounted,\n\t// reset ephemeral state on exit *and* on reopen.\n\tfunction resetEphemeralState() {\n\t\tsetSelectedId(null);\n\t}\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: reset only on open→true\n\tuseEffect(() => {\n\t\tif (!open) return;\n\t\tresetEphemeralState();\n\t}, [open]);\n\n\tasync function handleConfirm() {\n\t\tif (selectedId === null) return;\n\t\ttry {\n\t\t\tif (subject.kind === \"folder\") {\n\t\t\t\tawait moveFolder.mutateAsync({\n\t\t\t\t\tid: subject.folder.id,\n\t\t\t\t\tparentId: selectedId,\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tawait moveAsset.mutateAsync({\n\t\t\t\t\tid: subject.asset.id,\n\t\t\t\t\tfolderId: selectedId,\n\t\t\t\t});\n\t\t\t}\n\t\t\ttoaster.success({\n\t\t\t\ttitle: subject.kind === \"folder\" ? \"Folder moved\" : \"Asset moved\",\n\t\t\t});\n\t\t\tonMoved?.(selectedId);\n\t\t\tonOpenChange(false);\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Move failed\");\n\t\t}\n\t}\n\n\tconst handleDeselect = useCallback((id: string) => {\n\t\tsetSelectedId((current) => (current === id ? null : current));\n\t}, []);\n\n\tconst ctx: RowContext = {\n\t\tsubject,\n\t\tguardActive,\n\t\tselectedId,\n\t\tonSelect: setSelectedId,\n\t\tonDeselect: handleDeselect,\n\t\tcurrentLocationLabel: props.currentLocationLabel ?? \"Current location\",\n\t\tselfLocationLabel:\n\t\t\tprops.selfLocationLabel ?? \"You can't move a folder into itself\",\n\t\tblockedLabel:\n\t\t\tprops.blockedLabel ??\n\t\t\t(subject.kind === \"asset\"\n\t\t\t\t? \"Blocked: an open collection still exposes this asset\"\n\t\t\t\t: `Blocked: an open collection still exposes an asset in \"${subject.folder.name}\"`),\n\t};\n\n\tconst rootReason =\n\t\tcurrentParentId(subject) === \"\" ? ctx.currentLocationLabel : null;\n\tconst moving = moveFolder.isPending || moveAsset.isPending;\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tonExitComplete={resetEphemeralState}\n\t\t\tonClose={() => onOpenChange(false)}\n\t\t\tsize=\"md\"\n\t\t\theader={props.headerLabel ?? `Move \"${subjectName(subject)}\"`}\n\t\t\tfooter={\n\t\t\t\t<HStack gap=\"2\" justify=\"flex-end\">\n\t\t\t\t\t<Button variant=\"outline\" onClick={() => onOpenChange(false)}>\n\t\t\t\t\t\t{props.cancelLabel ?? \"Cancel\"}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\t\tdisabled={selectedId === null}\n\t\t\t\t\t\tloading={moving}\n\t\t\t\t\t\tonClick={handleConfirm}\n\t\t\t\t\t>\n\t\t\t\t\t\t{props.confirmLabel ?? \"Move here\"}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t>\n\t\t\t<Flex direction=\"column\" gap=\"0.5\" minH=\"240px\">\n\t\t\t\t<Flex align=\"center\" gap=\"1\">\n\t\t\t\t\t<Box w=\"6\" />\n\t\t\t\t\t<DestinationRowButton\n\t\t\t\t\t\tname={props.rootLabel ?? \"All Assets\"}\n\t\t\t\t\t\treason={rootReason}\n\t\t\t\t\t\tselected={selectedId === \"\"}\n\t\t\t\t\t\temphasized\n\t\t\t\t\t\tonClick={() => setSelectedId(\"\")}\n\t\t\t\t\t/>\n\t\t\t\t</Flex>\n\t\t\t\t{rootQuery.isLoading ? (\n\t\t\t\t\t<Flex justify=\"center\" py=\"6\">\n\t\t\t\t\t\t<Spinner />\n\t\t\t\t\t</Flex>\n\t\t\t\t) : (\n\t\t\t\t\t(rootQuery.data ?? []).map((folder) => (\n\t\t\t\t\t\t<DestinationRow\n\t\t\t\t\t\t\tkey={folder.id}\n\t\t\t\t\t\t\tctx={ctx}\n\t\t\t\t\t\t\tfolder={folder}\n\t\t\t\t\t\t\tancestorRestricted={false}\n\t\t\t\t\t\t\tlevel={0}\n\t\t\t\t\t\t/>\n\t\t\t\t\t))\n\t\t\t\t)}\n\t\t\t</Flex>\n\t\t</Modal>\n\t);\n}\nMoveDialog.displayName = \"MoveDialog\";\n","import { Box, Flex, Text } from \"@knkcs/anker/primitives\";\nimport { Lock } from \"lucide-react\";\n\n/** The shared Restricted-container warning (guardian#48): shown when creating\n * a Restricted folder and, with the other noun, on the collection dialog's\n * Restricted switch. */\nexport function restrictedContainerWarning(\n\tkind: \"folder\" | \"collection\",\n): string {\n\treturn `This ${kind} starts creator-only — no one else can see it or anything inside it until you grant access.`;\n}\n\n/** The explicit unrestrict disclosure (guardian#55): spelled out before the\n * toggle because it widens the audience to the whole workspace. */\nexport function unrestrictDisclosure(\n\tkind: \"folder\" | \"collection\",\n\tname: string,\n): string {\n\tconst contents =\n\t\tkind === \"folder\" ? \"everything inside it\" : \"every asset it contains\";\n\treturn `Unrestrict \"${name}\"? All workspace members will gain view access to this ${kind} and ${contents}.`;\n}\n\nexport interface RestrictedLockBadgeProps {\n\t/** Icon size in px. @default 12 */\n\tsize?: number;\n\t/** Optional left margin (spacing token) for sites without a gap parent. */\n\tml?: number;\n}\n\n/** Lock marker rendered wherever a Restricted container appears. The\n * `aria-label=\"Restricted\"` is the contract tests target — keep it stable. */\nexport const RestrictedLockBadge: React.FC<RestrictedLockBadgeProps> = ({\n\tsize = 12,\n\tml,\n}) => (\n\t<Box\n\t\trole=\"img\"\n\t\taria-label=\"Restricted\"\n\t\tcolor=\"fg.muted\"\n\t\tflexShrink={0}\n\t\tml={ml}\n\t>\n\t\t<Lock size={size} />\n\t</Box>\n);\nRestrictedLockBadge.displayName = \"RestrictedLockBadge\";\n\nexport interface RestrictedWarningNoticeProps {\n\tkind: \"folder\" | \"collection\";\n}\n\n/** Warning banner for the deliberate create-Restricted paths. */\nexport const RestrictedWarningNotice: React.FC<\n\tRestrictedWarningNoticeProps\n> = ({ kind }) => (\n\t<Flex\n\t\tgap={2}\n\t\tp={3}\n\t\trounded=\"md\"\n\t\tbg=\"bg.muted\"\n\t\tcolor=\"fg.muted\"\n\t\tfontSize=\"sm\"\n\t\talign=\"flex-start\"\n\t>\n\t\t<Box flexShrink={0} mt={0.5}>\n\t\t\t<Lock size={14} />\n\t\t</Box>\n\t\t<Text>{restrictedContainerWarning(kind)}</Text>\n\t</Flex>\n);\nRestrictedWarningNotice.displayName = \"RestrictedWarningNotice\";\n","import { TextInput } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { Flex, toaster } from \"@knkcs/anker/primitives\";\nimport { useEffect, useState } from \"react\";\nimport { useCreateFolder } from \"../hooks/use-folders\";\nimport { RestrictedWarningNotice } from \"./restricted\";\n\nexport interface RestrictedFolderDialogProps {\n\topen: boolean;\n\tonClose: () => void;\n\t/** Parent folder to create under; \"\" creates at the root. */\n\tparentId: string;\n\t/** Called after a successful create (e.g. to refresh the tree). */\n\tonCreated?: () => void;\n}\n\n/** Deliberate-path dialog for creating a Restricted folder. The everyday\n * inline \"New Folder\" input stays the fast path for ordinary folders. */\nexport const RestrictedFolderDialog: React.FC<RestrictedFolderDialogProps> = ({\n\topen,\n\tonClose,\n\tparentId,\n\tonCreated,\n}) => {\n\tconst [name, setName] = useState(\"\");\n\tconst createFolder = useCreateFolder();\n\n\t// Re-arm on open rather than clearing on close: zag presence can skip\n\t// onExitComplete when a reopen interrupts the exit animation (#73), and\n\t// clearing on the close transition would blank the field mid-fade.\n\tuseEffect(() => {\n\t\tif (open) setName(\"\");\n\t}, [open]);\n\n\tasync function handleCreate() {\n\t\tconst trimmed = name.trim();\n\t\tif (!trimmed) return;\n\t\ttry {\n\t\t\tawait createFolder.mutateAsync({\n\t\t\t\tname: trimmed,\n\t\t\t\tslug: trimmed.toLowerCase().replace(/\\s+/g, \"-\"),\n\t\t\t\tparentId,\n\t\t\t\trestricted: true,\n\t\t\t});\n\t\t\ttoaster.success({ title: \"Restricted folder created\" });\n\t\t\tonCreated?.();\n\t\t\tonClose();\n\t\t} catch (err) {\n\t\t\tconst msg = err instanceof Error ? err.message : String(err);\n\t\t\ttoaster.error({ title: \"Create failed\", description: msg });\n\t\t}\n\t}\n\n\t// Do NOT `return null` when closed: unmounting the open dialog machine\n\t// under StrictMode orphans its scroll-lock/aria-hidden cleanup and wedges\n\t// the whole app (#66). Keep Modal mounted; lazyMount/unmountOnExit keep\n\t// the fresh-content-per-open semantics.\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tonClose={onClose}\n\t\t\theader=\"New Restricted folder\"\n\t\t\tonSave={handleCreate}\n\t\t\tsaveLabel=\"Create\"\n\t\t\tsaveDisabled={!name.trim()}\n\t\t\tloading={createFolder.isPending}\n\t\t>\n\t\t\t<Flex direction=\"column\" gap={3}>\n\t\t\t\t<RestrictedWarningNotice kind=\"folder\" />\n\t\t\t\t<TextInput\n\t\t\t\t\tvalue={name}\n\t\t\t\t\tonChange={(e) => setName(e.target.value)}\n\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\tif (e.key === \"Enter\") handleCreate();\n\t\t\t\t\t}}\n\t\t\t\t\tautoFocus\n\t\t\t\t\tplaceholder=\"Folder name\"\n\t\t\t\t/>\n\t\t\t</Flex>\n\t\t</Modal>\n\t);\n};\nRestrictedFolderDialog.displayName = \"RestrictedFolderDialog\";\n","import { TextInput } from \"@knkcs/anker/atoms\";\nimport {\n\tTreeViewBranchControl,\n\tTreeViewBranchIndicator,\n\tTreeViewBranchText,\n\tTreeViewNode,\n\tTreeViewRoot,\n\tTreeViewTree,\n\tcreateTreeCollection,\n} from \"@knkcs/anker/components\";\nimport { useConfirmModal } from \"@knkcs/anker/feedback\";\nimport {\n\tBox,\n\tFlex,\n\tMenuContent,\n\tMenuItem,\n\tMenuRoot,\n\tMenuTrigger,\n\tText,\n\ttoaster,\n} from \"@knkcs/anker/primitives\";\nimport { Ellipsis, FolderPlus } from \"lucide-react\";\nimport { useCallback, useMemo, useRef, useState } from \"react\";\nimport { useCanManage } from \"../hooks/use-authz\";\nimport {\n\tuseCreateFolder,\n\tuseDeleteFolder,\n\tuseFolders,\n\tuseSetFolderRestricted,\n\tuseUpdateFolder,\n} from \"../hooks/use-folders\";\nimport {\n\ttype RpcErrorDescription,\n\tdescribeRpcError,\n\tshowRpcErrorToast,\n} from \"../lib/rpc-errors\";\nimport { useMediahubClients, useWorkspaceId } from \"../provider\";\nimport type { FolderInfo } from \"../types\";\nimport { LeakGuardRefusalDialog } from \"./leak-guard-refusal-dialog\";\nimport { ManageAccessDialog } from \"./manage-access-dialog\";\nimport { MoveDialog } from \"./move-dialog\";\nimport { RestrictedLockBadge, unrestrictDisclosure } from \"./restricted\";\nimport { RestrictedFolderDialog } from \"./restricted-folder-dialog\";\n\ninterface FolderTreeProps {\n\tactiveFolderId: string;\n\tonFolderSelect: (folderId: string) => void;\n}\n\ninterface FolderNode {\n\tid: string;\n\tname: string;\n\trestricted: boolean;\n\tchildren: FolderNode[];\n\t/** The full folder record, for actions that need more than id/name\n\t * (Move… hands it to the destination picker). Absent only on the\n\t * synthetic collection root, which never renders a row. */\n\tinfo?: FolderInfo;\n}\n\nexport const FolderTree: React.FC<FolderTreeProps> = ({\n\tactiveFolderId,\n\tonFolderSelect,\n}) => {\n\tconst workspaceId = useWorkspaceId();\n\tconst rootQuery = useFolders(\"\");\n\tconst rootFolders: FolderInfo[] = rootQuery.data ?? [];\n\tconst [treeKey, setTreeKey] = useState(0);\n\tconst [isCreating, setIsCreating] = useState(false);\n\tconst [newName, setNewName] = useState(\"\");\n\tconst [renamingId, setRenamingId] = useState<string | null>(null);\n\tconst [renameValue, setRenameValue] = useState(\"\");\n\tconst [moveSubject, setMoveSubject] = useState<FolderInfo | null>(null);\n\tconst [moveOpen, setMoveOpen] = useState(false);\n\tconst [accessSubject, setAccessSubject] = useState<FolderInfo | null>(null);\n\tconst [accessOpen, setAccessOpen] = useState(false);\n\t// Parent for the \"New Restricted folder…\" dialog; null = closed.\n\tconst [restrictedParentId, setRestrictedParentId] = useState<string | null>(\n\t\tnull,\n\t);\n\t// The node whose context menu was last opened — the authority probe runs\n\t// for it lazily, so the tree never probes every visible row.\n\tconst [menuNodeId, setMenuNodeId] = useState(\"\");\n\t// Kept mounted while a refusal exists (dialog machines must not unmount\n\t// mid-exit, see collection-picker / #66).\n\tconst [toggleRefusal, setToggleRefusal] =\n\t\tuseState<RpcErrorDescription | null>(null);\n\tconst [refusalOpen, setRefusalOpen] = useState(false);\n\tconst createFolder = useCreateFolder();\n\tconst updateFolder = useUpdateFolder();\n\tconst deleteFolder = useDeleteFolder();\n\tconst setFolderRestricted = useSetFolderRestricted();\n\tconst canManage = useCanManage(\"folder\", menuNodeId);\n\tconst { confirm } = useConfirmModal();\n\tconst creatingRef = useRef(false);\n\tconst renamingRef = useRef(false);\n\tconst { folders } = useMediahubClients();\n\n\tconst collection = useMemo(() => {\n\t\tconst rootChildren: FolderNode[] = rootFolders.map((f) => ({\n\t\t\tid: f.id,\n\t\t\tname: f.name,\n\t\t\trestricted: f.restricted,\n\t\t\tchildren: [],\n\t\t\tinfo: f,\n\t\t}));\n\t\treturn createTreeCollection<FolderNode>({\n\t\t\trootNode: {\n\t\t\t\tid: \"root\",\n\t\t\t\tname: \"Root\",\n\t\t\t\trestricted: false,\n\t\t\t\tchildren: rootChildren,\n\t\t\t},\n\t\t\tnodeToValue: (node) => node.id,\n\t\t\tnodeToString: (node) => node.name,\n\t\t\t// Return 1 for empty children so all folders are treated as branches\n\t\t\t// (expandable) even before their children are lazy-loaded.\n\t\t\tnodeToChildrenCount: (node) =>\n\t\t\t\tnode.children.length > 0 ? node.children.length : 1,\n\t\t});\n\t}, [rootFolders]);\n\n\tconst handleLoadChildren = useCallback(\n\t\tasync ({ node }: { node: FolderNode }) => {\n\t\t\tconst res = await folders.list(workspaceId, node.id);\n\t\t\treturn res.map(\n\t\t\t\t(f): FolderNode => ({\n\t\t\t\t\tid: f.id,\n\t\t\t\t\tname: f.name,\n\t\t\t\t\trestricted: f.restricted,\n\t\t\t\t\tchildren: [],\n\t\t\t\t\tinfo: f,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t\t[folders, workspaceId],\n\t);\n\n\tasync function handleDelete(folderId: string, folderName: string) {\n\t\tconst confirmed = await confirm({\n\t\t\ttitle: \"Delete Folder\",\n\t\t\tmessage: `Delete \"${folderName}\"? This cannot be undone.`,\n\t\t\tconfirmLabel: \"Delete\",\n\t\t});\n\t\tif (!confirmed) return;\n\t\ttry {\n\t\t\tawait deleteFolder.mutateAsync(folderId);\n\t\t\tif (activeFolderId === folderId) onFolderSelect(\"\");\n\t\t\tsetTreeKey((k) => k + 1);\n\t\t\ttoaster.success({ title: \"Folder deleted\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Delete failed\");\n\t\t}\n\t}\n\n\tasync function handleRenameSubmit(node: FolderNode) {\n\t\tif (renamingRef.current) return;\n\t\tconst trimmed = renameValue.trim();\n\t\tif (!trimmed || trimmed === node.name) {\n\t\t\tsetRenamingId(null);\n\t\t\treturn;\n\t\t}\n\t\trenamingRef.current = true;\n\t\ttry {\n\t\t\tawait updateFolder.mutateAsync({ id: node.id, name: trimmed });\n\t\t\tsetRenamingId(null);\n\t\t\tsetTreeKey((k) => k + 1);\n\t\t\ttoaster.success({ title: \"Folder renamed\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Rename failed\");\n\t\t} finally {\n\t\t\trenamingRef.current = false;\n\t\t}\n\t}\n\n\tasync function handleToggleRestricted(node: FolderNode) {\n\t\tconst restricting = !node.restricted;\n\t\tif (!restricting) {\n\t\t\tconst confirmed = await confirm({\n\t\t\t\ttitle: \"Unrestrict Folder\",\n\t\t\t\tmessage: unrestrictDisclosure(\"folder\", node.name),\n\t\t\t\tconfirmLabel: \"Unrestrict\",\n\t\t\t});\n\t\t\tif (!confirmed) return;\n\t\t}\n\t\ttry {\n\t\t\tawait setFolderRestricted.mutateAsync({\n\t\t\t\tid: node.id,\n\t\t\t\trestricted: restricting,\n\t\t\t});\n\t\t\tsetTreeKey((k) => k + 1);\n\t\t\ttoaster.success({\n\t\t\t\ttitle: restricting ? \"Folder restricted\" : \"Folder unrestricted\",\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconst fallback = restricting ? \"Restrict failed\" : \"Unrestrict failed\";\n\t\t\tconst described = describeRpcError(err, fallback);\n\t\t\t// A guard refusal gets the explanation dialog with the offending\n\t\t\t// pairs — never a raw error (guardian#55).\n\t\t\tif (described.kind === \"leak-guard\") {\n\t\t\t\tsetToggleRefusal(described);\n\t\t\t\tsetRefusalOpen(true);\n\t\t\t} else {\n\t\t\t\tshowRpcErrorToast(err, fallback);\n\t\t\t}\n\t\t}\n\t}\n\n\tasync function handleCreate() {\n\t\tif (creatingRef.current) return;\n\t\tconst trimmed = newName.trim();\n\t\tif (!trimmed) {\n\t\t\tsetIsCreating(false);\n\t\t\treturn;\n\t\t}\n\t\tcreatingRef.current = true;\n\t\ttry {\n\t\t\tawait createFolder.mutateAsync({\n\t\t\t\tname: trimmed,\n\t\t\t\tslug: trimmed.toLowerCase().replace(/\\s+/g, \"-\"),\n\t\t\t\tparentId: activeFolderId || \"\",\n\t\t\t});\n\t\t\tsetNewName(\"\");\n\t\t\tsetIsCreating(false);\n\t\t\tsetTreeKey((k) => k + 1);\n\t\t\ttoaster.success({ title: \"Folder created\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t} finally {\n\t\t\tcreatingRef.current = false;\n\t\t}\n\t}\n\n\treturn (\n\t\t<Flex direction=\"column\" flex={1} gap={0.5}>\n\t\t\t<Flex\n\t\t\t\talign=\"center\"\n\t\t\t\tpx={2}\n\t\t\t\tpy={1}\n\t\t\t\trounded=\"md\"\n\t\t\t\tcursor=\"pointer\"\n\t\t\t\tbg={!activeFolderId ? \"colorPalette.subtle\" : \"transparent\"}\n\t\t\t\tcolor={!activeFolderId ? \"colorPalette.fg\" : \"fg.default\"}\n\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t_hover={{\n\t\t\t\t\tbg: !activeFolderId ? \"colorPalette.subtle\" : \"bg.muted\",\n\t\t\t\t}}\n\t\t\t\tonClick={() => onFolderSelect(\"\")}\n\t\t\t\tfontSize=\"sm\"\n\t\t\t\tfontWeight=\"medium\"\n\t\t\t\tcss={{\n\t\t\t\t\t\"& > [data-folder-menu]\": { opacity: 0 },\n\t\t\t\t\t\"&:hover > [data-folder-menu]\": { opacity: 1 },\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\tAll Assets\n\t\t\t\t<Box data-folder-menu=\"\" transition=\"opacity 0.1s\" ml=\"auto\">\n\t\t\t\t\t<MenuRoot>\n\t\t\t\t\t\t<MenuTrigger asChild>\n\t\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\t\tasChild\n\t\t\t\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\t\t\t\tcolor=\"fg.muted\"\n\t\t\t\t\t\t\t\t_hover={{ color: \"fg.default\" }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\taria-label=\"Actions for All Assets\"\n\t\t\t\t\t\t\t\t\tonClick={(e) => e.stopPropagation()}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Ellipsis size={12} />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t</MenuTrigger>\n\t\t\t\t\t\t<MenuContent>\n\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\tvalue=\"new-restricted\"\n\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\tsetRestrictedParentId(\"\");\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tNew Restricted folder…\n\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t</MenuContent>\n\t\t\t\t\t</MenuRoot>\n\t\t\t\t</Box>\n\t\t\t</Flex>\n\n\t\t\t{rootFolders.length > 0 && (\n\t\t\t\t<TreeViewRoot\n\t\t\t\t\tkey={treeKey}\n\t\t\t\t\tcollection={collection}\n\t\t\t\t\tselectedValue={activeFolderId ? [activeFolderId] : []}\n\t\t\t\t\tonSelectionChange={(details) => {\n\t\t\t\t\t\tconst selected = details.selectedValue[0];\n\t\t\t\t\t\tif (selected) onFolderSelect(selected);\n\t\t\t\t\t}}\n\t\t\t\t\tloadChildren={handleLoadChildren}\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t>\n\t\t\t\t\t<TreeViewTree>\n\t\t\t\t\t\t<TreeViewNode<FolderNode>\n\t\t\t\t\t\t\trender={({ node }) =>\n\t\t\t\t\t\t\t\trenamingId === node.id ? (\n\t\t\t\t\t\t\t\t\t<TreeViewBranchControl>\n\t\t\t\t\t\t\t\t\t\t<TreeViewBranchIndicator />\n\t\t\t\t\t\t\t\t\t\t{/* Keep clicks and keystrokes out of the tree's\n\t\t\t\t\t\t\t\t\t\t selection/typeahead machinery. */}\n\t\t\t\t\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\t\t\t\t\tflex=\"1\"\n\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => e.stopPropagation()}\n\t\t\t\t\t\t\t\t\t\t\tonKeyDown={(e) => e.stopPropagation()}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<TextInput\n\t\t\t\t\t\t\t\t\t\t\t\tvalue={renameValue}\n\t\t\t\t\t\t\t\t\t\t\t\tonChange={(e) => setRenameValue(e.target.value)}\n\t\t\t\t\t\t\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (e.key === \"Enter\") handleRenameSubmit(node);\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (e.key === \"Escape\") setRenamingId(null);\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\tonBlur={() => handleRenameSubmit(node)}\n\t\t\t\t\t\t\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t\t\t</TreeViewBranchControl>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<TreeViewBranchControl\n\t\t\t\t\t\t\t\t\t\tcss={{\n\t\t\t\t\t\t\t\t\t\t\t\"& > [data-folder-menu]\": {\n\t\t\t\t\t\t\t\t\t\t\t\topacity: 0,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\"&:hover > [data-folder-menu]\": {\n\t\t\t\t\t\t\t\t\t\t\t\topacity: 1,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<TreeViewBranchIndicator />\n\t\t\t\t\t\t\t\t\t\t<TreeViewBranchText>{node.name}</TreeViewBranchText>\n\t\t\t\t\t\t\t\t\t\t{node.restricted && <RestrictedLockBadge ml={1} />}\n\t\t\t\t\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\t\t\t\t\tdata-folder-menu=\"\"\n\t\t\t\t\t\t\t\t\t\t\ttransition=\"opacity 0.1s\"\n\t\t\t\t\t\t\t\t\t\t\tml=\"auto\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<MenuRoot\n\t\t\t\t\t\t\t\t\t\t\t\tonOpenChange={({ open }) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (open) setMenuNodeId(node.id);\n\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t<MenuTrigger asChild>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tasChild\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcolor=\"fg.muted\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t_hover={{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tcolor: \"fg.default\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\taria-label={`Actions for ${node.name}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => e.stopPropagation()}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Ellipsis size={12} />\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t\t\t\t\t\t</MenuTrigger>\n\t\t\t\t\t\t\t\t\t\t\t\t<MenuContent>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue=\"rename\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetRenameValue(node.name);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetRenamingId(node.id);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tRename\n\t\t\t\t\t\t\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue=\"move\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (!node.info) return;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetMoveSubject(node.info);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetMoveOpen(true);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tMove…\n\t\t\t\t\t\t\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue=\"manage-access\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tif (!node.info) return;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetAccessSubject(node.info);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetAccessOpen(true);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tManage access…\n\t\t\t\t\t\t\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue=\"new-restricted\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tsetRestrictedParentId(node.id);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tNew Restricted folder…\n\t\t\t\t\t\t\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{/* Authority-only (Owner or workspace admin):\n\t\t\t\t\t\t\t\t\t\t\t\t\t appears once the lazy probe confirms. */}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{menuNodeId === node.id &&\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcanManage.data === true && (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue=\"toggle-restricted\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\thandleToggleRestricted(node);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{node.restricted ? \"Unrestrict\" : \"Restrict\"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tvalue=\"delete\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tcolor=\"fg.error\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tonClick={(e) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\te.stopPropagation();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\thandleDelete(node.id, node.name);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</MenuContent>\n\t\t\t\t\t\t\t\t\t\t\t</MenuRoot>\n\t\t\t\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t\t\t</TreeViewBranchControl>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</TreeViewTree>\n\t\t\t\t</TreeViewRoot>\n\t\t\t)}\n\n\t\t\t<Box flex={1} />\n\n\t\t\t{isCreating ? (\n\t\t\t\t<Box px={2} py={1}>\n\t\t\t\t\t<TextInput\n\t\t\t\t\t\tvalue={newName}\n\t\t\t\t\t\tonChange={(e) => setNewName(e.target.value)}\n\t\t\t\t\t\tonKeyDown={(e) => {\n\t\t\t\t\t\t\tif (e.key === \"Enter\") handleCreate();\n\t\t\t\t\t\t\tif (e.key === \"Escape\") {\n\t\t\t\t\t\t\t\tsetIsCreating(false);\n\t\t\t\t\t\t\t\tsetNewName(\"\");\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}}\n\t\t\t\t\t\tonBlur={handleCreate}\n\t\t\t\t\t\tautoFocus\n\t\t\t\t\t\tplaceholder=\"Folder name\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t/>\n\t\t\t\t</Box>\n\t\t\t) : (\n\t\t\t\t<Flex\n\t\t\t\t\talign=\"center\"\n\t\t\t\t\tgap={1}\n\t\t\t\t\tpx={2}\n\t\t\t\t\tpy={1}\n\t\t\t\t\trounded=\"md\"\n\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\tcolor=\"fg.muted\"\n\t\t\t\t\t_hover={{ bg: \"bg.muted\" }}\n\t\t\t\t\tonClick={() => setIsCreating(true)}\n\t\t\t\t\tfontSize=\"sm\"\n\t\t\t\t>\n\t\t\t\t\t<FolderPlus size={14} />\n\t\t\t\t\t<Text>New Folder</Text>\n\t\t\t\t</Flex>\n\t\t\t)}\n\n\t\t\t{/* Kept mounted while a subject exists (dialog machines must not\n\t\t\t unmount mid-exit, see collection-picker / #66). */}\n\t\t\t{moveSubject && (\n\t\t\t\t<MoveDialog\n\t\t\t\t\topen={moveOpen}\n\t\t\t\t\tonOpenChange={setMoveOpen}\n\t\t\t\t\tsubject={{ kind: \"folder\", folder: moveSubject }}\n\t\t\t\t\tonMoved={() => setTreeKey((k) => k + 1)}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t{accessSubject && (\n\t\t\t\t<ManageAccessDialog\n\t\t\t\t\topen={accessOpen}\n\t\t\t\t\tonOpenChange={setAccessOpen}\n\t\t\t\t\tsubject={{ kind: \"folder\", folder: accessSubject }}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<RestrictedFolderDialog\n\t\t\t\topen={restrictedParentId !== null}\n\t\t\t\tparentId={restrictedParentId ?? \"\"}\n\t\t\t\tonClose={() => setRestrictedParentId(null)}\n\t\t\t\tonCreated={() => setTreeKey((k) => k + 1)}\n\t\t\t/>\n\t\t\t<LeakGuardRefusalDialog\n\t\t\t\trefusal={toggleRefusal}\n\t\t\t\topen={refusalOpen}\n\t\t\t\tonClose={() => setRefusalOpen(false)}\n\t\t\t/>\n\t\t</Flex>\n\t);\n};\nFolderTree.displayName = \"FolderTree\";\n","import { InlineEdit } from \"@knkcs/anker/forms\";\nimport { useState } from \"react\";\n\ninterface InlineEditFieldProps {\n\tvalue: string;\n\tonSave: (newValue: string) => Promise<void>;\n\tas?: \"input\" | \"textarea\";\n\tplaceholder?: string;\n}\n\n/**\n * Thin wrapper around anker's InlineEdit that adds async save with error handling.\n * On error, the value reverts to the previous value automatically.\n */\nexport const InlineEditField: React.FC<InlineEditFieldProps> = ({\n\tvalue,\n\tonSave,\n\tas = \"input\",\n\tplaceholder,\n}) => {\n\tconst [disabled, setDisabled] = useState(false);\n\n\tasync function handleSubmit(nextValue: string) {\n\t\tconst trimmed = nextValue.trim();\n\t\tif (trimmed === value) return;\n\t\tsetDisabled(true);\n\t\ttry {\n\t\t\tawait onSave(trimmed);\n\t\t} catch {\n\t\t\t// Error handling done by caller (toast); InlineEdit reverts on its own\n\t\t} finally {\n\t\t\tsetDisabled(false);\n\t\t}\n\t}\n\n\treturn (\n\t\t<InlineEdit\n\t\t\tvalue={value}\n\t\t\tonSubmit={handleSubmit}\n\t\t\tvariant={as}\n\t\t\tplaceholder={placeholder}\n\t\t\tdisabled={disabled}\n\t\t\tfontSize=\"sm\"\n\t\t/>\n\t);\n};\nInlineEditField.displayName = \"InlineEditField\";\n","import { ChipPicker } from \"@knkcs/anker/components\";\nimport { useTagAssets, useTags, useUntagAssets } from \"../hooks/use-tags\";\nimport { showRpcErrorToast } from \"../lib/rpc-errors\";\nimport type { TagInfo } from \"../types\";\n\ninterface TagChipFieldProps {\n\tassetId: string;\n\tassignedTagIds: string[];\n}\n\nexport const TagChipField: React.FC<TagChipFieldProps> = ({\n\tassetId,\n\tassignedTagIds,\n}) => {\n\tconst tagsQuery = useTags();\n\tconst allTags: TagInfo[] = tagsQuery.data ?? [];\n\tconst tagAssets = useTagAssets();\n\tconst untagAssets = useUntagAssets();\n\n\tconst assignedTags = allTags.filter((t) => assignedTagIds.includes(t.id));\n\tconst unassignedTags = allTags.filter((t) => !assignedTagIds.includes(t.id));\n\n\tasync function handleAdd(tag: TagInfo) {\n\t\ttry {\n\t\t\tawait tagAssets.mutateAsync({ tagId: tag.id, assetIds: [assetId] });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\tasync function handleRemove(tag: TagInfo) {\n\t\ttry {\n\t\t\tawait untagAssets.mutateAsync({ tagId: tag.id, assetIds: [assetId] });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\treturn (\n\t\t<ChipPicker<TagInfo>\n\t\t\tassigned={assignedTags}\n\t\t\tavailable={unassignedTags}\n\t\t\tgetItemId={(t) => t.id}\n\t\t\tgetItemLabel={(t) => t.name}\n\t\t\tonAdd={handleAdd}\n\t\t\tonRemove={handleRemove}\n\t\t\taddLabel=\"Add tag\"\n\t\t\temptyLabel=\"No tags\"\n\t\t\tsearchable\n\t\t\tloading={tagsQuery.isLoading}\n\t\t/>\n\t);\n};\nTagChipField.displayName = \"TagChipField\";\n","import { InlineCreatableList } from \"@knkcs/anker/components\";\nimport { toaster } from \"@knkcs/anker/primitives\";\nimport { useCreateTag, useTags } from \"../hooks/use-tags\";\nimport { showRpcErrorToast } from \"../lib/rpc-errors\";\nimport type { TagInfo } from \"../types\";\n\ninterface TagPanelProps {\n\tactiveTags: string[];\n\tonToggleTag: (tagId: string) => void;\n}\n\nexport const TagPanel: React.FC<TagPanelProps> = ({\n\tactiveTags,\n\tonToggleTag,\n}) => {\n\tconst tagsQuery = useTags();\n\tconst tags: TagInfo[] = tagsQuery.data ?? [];\n\tconst createTag = useCreateTag();\n\n\tasync function handleCreate(name: string) {\n\t\ttry {\n\t\t\tawait createTag.mutateAsync({\n\t\t\t\tname,\n\t\t\t\tslug: name.toLowerCase().replace(/\\s+/g, \"-\"),\n\t\t\t});\n\t\t\ttoaster.success({ title: \"Tag created\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Error\");\n\t\t}\n\t}\n\n\treturn (\n\t\t<InlineCreatableList<TagInfo>\n\t\t\titems={tags}\n\t\t\tactiveIds={activeTags}\n\t\t\tonToggle={onToggleTag}\n\t\t\tonCreate={handleCreate}\n\t\t\tgetItemId={(t) => t.id}\n\t\t\tgetItemLabel={(t) => t.name}\n\t\t\tvariant=\"wrap\"\n\t\t\tcreatePlaceholder=\"Tag name\"\n\t\t\tcreateLabel=\"Add tag\"\n\t\t\temptyText=\"No tags\"\n\t\t/>\n\t);\n};\nTagPanel.displayName = \"TagPanel\";\n","import { Modal } from \"@knkcs/anker/components\";\nimport {\n\tBox,\n\tCheckbox,\n\tFlex,\n\tNativeSelect,\n\tText,\n} from \"@knkcs/anker/primitives\";\nimport { useState } from \"react\";\nimport { useAssetTypes } from \"../../hooks/use-asset-types\";\nimport { useWorkspaceId } from \"../../provider\";\nimport type { UploadFile } from \"../../stores/upload-store\";\nimport { useUploadStore } from \"../../stores/upload-store\";\n\ninterface UploadDialogProps {\n\topen: boolean;\n\tonClose: () => void;\n\tfolderId?: string;\n}\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nconst FileRow: React.FC<{\n\tentry: UploadFile;\n\tshowOverride: boolean;\n\tonToggleOverride: () => void;\n\tassetTypes: { id: string; name: string }[];\n}> = ({ entry, showOverride, onToggleOverride, assetTypes }) => {\n\tconst setAssetType = useUploadStore((s) => s.setAssetType);\n\n\treturn (\n\t\t<Flex\n\t\t\tpy={2.5}\n\t\t\tpx={3}\n\t\t\talign=\"center\"\n\t\t\tborderBottomWidth=\"1px\"\n\t\t\tborderColor=\"border\"\n\t\t\t_last={{ borderBottomWidth: 0 }}\n\t\t\tgap={3}\n\t\t>\n\t\t\t<Box flex={1} minW={0}>\n\t\t\t\t<Text fontSize=\"sm\" truncate>\n\t\t\t\t\t{entry.file.name}\n\t\t\t\t</Text>\n\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\">\n\t\t\t\t\t{formatFileSize(entry.file.size)}\n\t\t\t\t</Text>\n\t\t\t</Box>\n\n\t\t\t{showOverride ? (\n\t\t\t\t<NativeSelect\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvalue={entry.assetTypeId}\n\t\t\t\t\tonChange={(e) => setAssetType(entry.clientId, e.target.value)}\n\t\t\t\t\tw=\"160px\"\n\t\t\t\t>\n\t\t\t\t\t<option value=\"\">Select type...</option>\n\t\t\t\t\t{assetTypes.map((t) => (\n\t\t\t\t\t\t<option key={t.id} value={t.id}>\n\t\t\t\t\t\t\t{t.name}\n\t\t\t\t\t\t</option>\n\t\t\t\t\t))}\n\t\t\t\t</NativeSelect>\n\t\t\t) : (\n\t\t\t\t<Text\n\t\t\t\t\tfontSize=\"xs\"\n\t\t\t\t\tcolor=\"colorPalette.fg\"\n\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\tcursor=\"pointer\"\n\t\t\t\t\t_hover={{ textDecoration: \"underline\" }}\n\t\t\t\t\tonClick={onToggleOverride}\n\t\t\t\t>\n\t\t\t\t\tChange type\n\t\t\t\t</Text>\n\t\t\t)}\n\t\t</Flex>\n\t);\n};\nFileRow.displayName = \"FileRow\";\n\nexport const UploadDialog: React.FC<UploadDialogProps> = ({\n\topen,\n\tonClose,\n\tfolderId,\n}) => {\n\tconst workspaceId = useWorkspaceId();\n\tconst files = useUploadStore((s) => s.files);\n\tconst setBatchAssetType = useUploadStore((s) => s.setBatchAssetType);\n\tconst startUpload = useUploadStore((s) => s.startUpload);\n\tconst clearPending = useUploadStore((s) => s.clearPending);\n\tconst analyzeWithAi = useUploadStore((s) => s.analyzeWithAi);\n\tconst setAnalyzeWithAi = useUploadStore((s) => s.setAnalyzeWithAi);\n\tconst assetTypesQuery = useAssetTypes();\n\tconst assetTypes = assetTypesQuery.data ?? [];\n\tconst [batchType, setBatchType] = useState(\"\");\n\tconst [overrides, setOverrides] = useState<Set<string>>(new Set());\n\n\tconst pendingFiles = files.filter((f) => f.status === \"pending\");\n\n\tfunction handleBatchTypeChange(value: string) {\n\t\tsetBatchType(value);\n\t\tsetBatchAssetType(value);\n\t}\n\n\tfunction toggleOverride(clientId: string) {\n\t\tsetOverrides((prev) => {\n\t\t\tconst next = new Set(prev);\n\t\t\tif (next.has(clientId)) {\n\t\t\t\tnext.delete(clientId);\n\t\t\t} else {\n\t\t\t\tnext.add(clientId);\n\t\t\t}\n\t\t\treturn next;\n\t\t});\n\t}\n\n\tconst canUpload =\n\t\tpendingFiles.length > 0 && pendingFiles.every((f) => f.assetTypeId !== \"\");\n\n\tfunction handleUpload() {\n\t\tstartUpload(workspaceId, folderId);\n\t\tonClose();\n\t\tsetBatchType(\"\");\n\t\tsetOverrides(new Set());\n\t}\n\n\tfunction handleCancel() {\n\t\tclearPending();\n\t\tonClose();\n\t}\n\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tonClose={handleCancel}\n\t\t\theader={`Upload ${pendingFiles.length} file${pendingFiles.length !== 1 ? \"s\" : \"\"}`}\n\t\t\tsaveLabel=\"Upload\"\n\t\t\tonSave={handleUpload}\n\t\t\tsaveDisabled={!canUpload}\n\t\t>\n\t\t\t{/* Batch asset type selector */}\n\t\t\t<Box mb={4}>\n\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\" mb={2}>\n\t\t\t\t\tAsset Type\n\t\t\t\t</Text>\n\t\t\t\t<NativeSelect\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\tvalue={batchType}\n\t\t\t\t\tonChange={(e) => handleBatchTypeChange(e.target.value)}\n\t\t\t\t>\n\t\t\t\t\t<option value=\"\">Select asset type...</option>\n\t\t\t\t\t{assetTypes.map((t) => (\n\t\t\t\t\t\t<option key={t.id} value={t.id}>\n\t\t\t\t\t\t\t{t.name}\n\t\t\t\t\t\t</option>\n\t\t\t\t\t))}\n\t\t\t\t</NativeSelect>\n\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\" mt={1}>\n\t\t\t\t\tRequired. Applies to all files unless overridden.\n\t\t\t\t</Text>\n\t\t\t</Box>\n\n\t\t\t{/* AI analysis toggle */}\n\t\t\t<Box mb={4}>\n\t\t\t\t<Checkbox\n\t\t\t\t\tchecked={analyzeWithAi}\n\t\t\t\t\tonCheckedChange={(e) => setAnalyzeWithAi(!!e.checked)}\n\t\t\t\t>\n\t\t\t\t\tAnalyze with AI\n\t\t\t\t</Checkbox>\n\t\t\t</Box>\n\n\t\t\t{/* File list */}\n\t\t\t<Box\n\t\t\t\tborderWidth=\"1px\"\n\t\t\t\tborderColor=\"border\"\n\t\t\t\trounded=\"md\"\n\t\t\t\tmaxH=\"300px\"\n\t\t\t\toverflowY=\"auto\"\n\t\t\t>\n\t\t\t\t{pendingFiles.map((entry) => (\n\t\t\t\t\t<FileRow\n\t\t\t\t\t\tkey={entry.clientId}\n\t\t\t\t\t\tentry={entry}\n\t\t\t\t\t\tshowOverride={overrides.has(entry.clientId)}\n\t\t\t\t\t\tonToggleOverride={() => toggleOverride(entry.clientId)}\n\t\t\t\t\t\tassetTypes={assetTypes}\n\t\t\t\t\t/>\n\t\t\t\t))}\n\t\t\t</Box>\n\t\t</Modal>\n\t);\n};\nUploadDialog.displayName = \"UploadDialog\";\n","import { UploadDropZone as AnkerUploadDropZone } from \"@knkcs/anker/components\";\n\ninterface UploadDropZoneProps {\n\tonFilesSelected: (files: File[]) => void;\n\tcompact?: boolean;\n}\n\nexport const UploadDropZone: React.FC<UploadDropZoneProps> = ({\n\tonFilesSelected,\n\tcompact,\n}) => {\n\treturn (\n\t\t<AnkerUploadDropZone onFiles={onFilesSelected} compact={compact} multiple />\n\t);\n};\nUploadDropZone.displayName = \"UploadDropZone\";\n","import type { UploadFileStatus } from \"@knkcs/anker/feedback\";\nimport { UploadToastStack as AnkerUploadToastStack } from \"@knkcs/anker/feedback\";\nimport { useUploadStore } from \"../../stores/upload-store\";\n\n/** Map Zustand upload store statuses to anker's UploadFileStatus format. */\nfunction mapStatus(status: string): UploadFileStatus[\"status\"] {\n\tswitch (status) {\n\t\tcase \"done\":\n\t\t\treturn \"done\";\n\t\tcase \"error\":\n\t\t\treturn \"error\";\n\t\tcase \"uploading\":\n\t\t\treturn \"uploading\";\n\t\tcase \"creating\":\n\t\tcase \"finalizing\":\n\t\t\treturn \"processing\";\n\t\tdefault:\n\t\t\treturn \"pending\";\n\t}\n}\n\nexport const UploadToastStack: React.FC = () => {\n\tconst storeFiles = useUploadStore((s) => s.files);\n\tconst visible = useUploadStore((s) => s.visible);\n\tconst dismiss = useUploadStore((s) => s.dismiss);\n\n\tconst files: UploadFileStatus[] = storeFiles.map((f) => ({\n\t\tid: f.clientId,\n\t\tfilename: f.file.name,\n\t\tstatus: mapStatus(f.status),\n\t\tprogress: f.progress,\n\t\terror: f.error,\n\t}));\n\n\tif (!visible || files.length === 0) return null;\n\n\treturn (\n\t\t<AnkerUploadToastStack\n\t\t\tfiles={files}\n\t\t\tonDismiss={dismiss}\n\t\t\tautoDismissMs={5000}\n\t\t\tdefaultExpanded\n\t\t/>\n\t);\n};\nUploadToastStack.displayName = \"UploadToastStack\";\n","import type { AssetInfo, AssetTypeInfo } from \"./types\";\n\n/** Build an asset-type id -> display name map from the workspace's types. */\nexport function buildAssetTypeNameMap(\n\ttypes: AssetTypeInfo[],\n): Map<string, string> {\n\treturn new Map(types.map((t) => [t.id, t.name]));\n}\n\n/** Collect the unique, non-empty `updatedBy` user ids across the given assets. */\nexport function collectUpdatedByIds(assets: AssetInfo[]): string[] {\n\treturn [...new Set(assets.map((a) => a.updatedBy).filter(Boolean))];\n}\n","import { Button, EmptyState } from \"@knkcs/anker/atoms\";\nimport {\n\tActionCell,\n\tContextRail,\n\tDataTable,\n\tDateCell,\n\tToolbar,\n\tTruncatedTextCell,\n} from \"@knkcs/anker/components\";\nimport { useConfirmModal } from \"@knkcs/anker/feedback\";\nimport {\n\tBox,\n\tFlex,\n\tNativeSelect,\n\tSegmentedControl,\n\tSpinner,\n\tText,\n\ttoaster,\n} from \"@knkcs/anker/primitives\";\nimport {\n\tIndexPageTemplate,\n\tSubNavLayout,\n\tusePageRail,\n} from \"@knkcs/anker/templates\";\nimport { createColumnHelper } from \"@tanstack/react-table\";\nimport type {\n\tColumnDef,\n\tOnChangeFn,\n\tRowSelectionState,\n} from \"@tanstack/react-table\";\nimport { Download, Trash2, Upload } from \"lucide-react\";\nimport { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\n\nimport {\n\tbuildAssetTypeNameMap,\n\tcollectUpdatedByIds,\n} from \"./asset-library-resolve\";\nimport { AssetGrid } from \"./components/asset-grid\";\nimport { AssetStatusBadge } from \"./components/asset-status-badge\";\nimport { BulkActionBar } from \"./components/bulk-action-bar\";\nimport { CollectionPanel } from \"./components/collection-panel\";\nimport { FolderBreadcrumbs } from \"./components/folder-breadcrumbs\";\nimport { FolderTree } from \"./components/folder-tree\";\nimport { TagPanel } from \"./components/tag-panel\";\nimport { UploadDialog } from \"./components/upload/upload-dialog\";\nimport { UploadDropZone } from \"./components/upload/upload-drop-zone\";\nimport { useAssetTypes } from \"./hooks/use-asset-types\";\nimport { useAssets, useDeleteAsset } from \"./hooks/use-assets\";\nimport { useUsers } from \"./hooks/use-users\";\nimport {\n\tdescribeRpcError,\n\tisRetryableUnavailable,\n\tshowRpcErrorToast,\n} from \"./lib/rpc-errors\";\nimport { useAssetStatuses } from \"./statushub\";\nimport { usePreferencesStore } from \"./stores/preferences-store\";\nimport { useSelectionStore } from \"./stores/selection-store\";\nimport { useUploadStore } from \"./stores/upload-store\";\nimport type { AssetFilters, AssetInfo, AssetStatusBehavior } from \"./types\";\n\n// The behavior list is mediahub's own — the words it registers with statushub\n// (integration standard §1, statushub ADR 0002), which the server validates\n// this filter against. It stays local rather than coming from\n// statushub-ui's `useEntityType` because that hook reads\n// ServiceRegistryService, which the standalone shell's proxy deliberately does\n// NOT forward: the registry is unauthenticated by design and stays in-cluster.\n// Keep it in step with `AssetBehaviors()` in internal/service/statushub.go.\nconst BEHAVIOR_OPTIONS: { label: string; value: AssetStatusBehavior | \"\" }[] = [\n\t{ label: \"All\", value: \"\" },\n\t{ label: \"Active\", value: \"active\" },\n\t{ label: \"Archived\", value: \"archived\" },\n\t{ label: \"Inactive\", value: \"inactive\" },\n\t{ label: \"Deleted\", value: \"deleted\" },\n];\n\nconst VIEW_MODE_OPTIONS = [\n\t{ label: \"List\", value: \"list\" },\n\t{ label: \"Grid\", value: \"grid\" },\n];\n\n// Stable identity for \"no tag filter\": `filters.tagIds ?? []` would mint a\n// fresh array every render, invalidating the rail memo (and every callback\n// keyed on activeTags) even when nothing changed.\nconst NO_ACTIVE_TAGS: string[] = [];\n\nexport interface AssetLibraryProps {\n\tonAssetOpen?: (asset: AssetInfo) => void;\n\tinitialFilters?: AssetFilters;\n\tonFiltersChange?: (filters: AssetFilters) => void;\n}\n\nexport function AssetLibrary(props: AssetLibraryProps): React.JSX.Element {\n\tconst { onAssetOpen, initialFilters, onFiltersChange } = props;\n\n\tconst [filters, setFilters] = useState<AssetFilters>(initialFilters ?? {});\n\tconst [uploadDialogOpen, setUploadDialogOpen] = useState(false);\n\tconst fileInputRef = useRef<HTMLInputElement>(null);\n\n\t// Derived filter shorthands for convenience\n\tconst statusSlug = filters.statusSlug ?? \"\";\n\tconst behaviorFilter: AssetStatusBehavior | \"\" = filters.behavior ?? \"\";\n\tconst folderId = filters.folderId ?? \"\";\n\tconst activeTags = filters.tagIds ?? NO_ACTIVE_TAGS;\n\tconst activeCollectionId = filters.collectionIds?.[0] ?? \"\";\n\n\tconst updateFilter = useCallback(\n\t\t<K extends keyof AssetFilters>(key: K, value: AssetFilters[K]) => {\n\t\t\tsetFilters((prev) => {\n\t\t\t\tconst next: AssetFilters = { ...prev };\n\t\t\t\tif (\n\t\t\t\t\tvalue === undefined ||\n\t\t\t\t\tvalue === \"\" ||\n\t\t\t\t\t(Array.isArray(value) && value.length === 0)\n\t\t\t\t) {\n\t\t\t\t\tdelete next[key];\n\t\t\t\t} else {\n\t\t\t\t\tnext[key] = value;\n\t\t\t\t}\n\t\t\t\tonFiltersChange?.(next);\n\t\t\t\treturn next;\n\t\t\t});\n\t\t},\n\t\t[onFiltersChange],\n\t);\n\n\t// Local search text kept controlled for immediate input feedback, debounced\n\t// into the filter (and therefore the useAssets query) so we don't refetch on\n\t// every keystroke — preserves the old SearchInput debounce behaviour.\n\tconst [searchText, setSearchText] = useState(initialFilters?.search ?? \"\");\n\tconst searchPrimed = useRef(false);\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: debounce on searchText only\n\tuseEffect(() => {\n\t\tif (!searchPrimed.current) {\n\t\t\tsearchPrimed.current = true;\n\t\t\treturn;\n\t\t}\n\t\tconst t = setTimeout(\n\t\t\t() => updateFilter(\"search\", searchText || undefined),\n\t\t\t300,\n\t\t);\n\t\treturn () => clearTimeout(t);\n\t}, [searchText]);\n\n\tconst handleToggleTag = useCallback(\n\t\t(tagId: string) => {\n\t\t\tconst next = activeTags.includes(tagId)\n\t\t\t\t? activeTags.filter((id) => id !== tagId)\n\t\t\t\t: [...activeTags, tagId];\n\t\t\tupdateFilter(\"tagIds\", next.length > 0 ? next : undefined);\n\t\t},\n\t\t[activeTags, updateFilter],\n\t);\n\n\tconst handleSelectCollection = useCallback(\n\t\t(collectionId: string) => {\n\t\t\tupdateFilter(\"collectionIds\", collectionId ? [collectionId] : undefined);\n\t\t},\n\t\t[updateFilter],\n\t);\n\n\tfunction setStatusSlug(value: string) {\n\t\tupdateFilter(\"statusSlug\", value || undefined);\n\t}\n\n\tfunction setBehaviorFilter(value: string) {\n\t\tupdateFilter(\n\t\t\t\"behavior\",\n\t\t\tvalue ? (value as AssetStatusBehavior) : undefined,\n\t\t);\n\t}\n\n\tconst addFiles = useUploadStore((s) => s.addFiles);\n\tconst viewMode = usePreferencesStore((s) => s.viewMode);\n\tconst setViewMode = usePreferencesStore((s) => s.setViewMode);\n\n\tconst handleFilesSelected = useCallback(\n\t\t(files: File[]) => {\n\t\t\taddFiles(files);\n\t\t\tsetUploadDialogOpen(true);\n\t\t},\n\t\t[addFiles],\n\t);\n\n\tconst deleteAsset = useDeleteAsset();\n\tconst { confirm } = useConfirmModal();\n\n\tasync function handleDelete(assetId: string, assetName: string) {\n\t\tconst confirmed = await confirm({\n\t\t\ttitle: \"Delete Asset\",\n\t\t\tmessage: `Delete \"${assetName}\"? This cannot be undone.`,\n\t\t\tconfirmLabel: \"Delete\",\n\t\t});\n\t\tif (!confirmed) return;\n\t\ttry {\n\t\t\tawait deleteAsset.mutateAsync(assetId);\n\t\t\ttoaster.success({ title: \"Asset deleted\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Delete failed\");\n\t\t}\n\t}\n\n\tconst assetsQuery = useAssets({\n\t\tfolderId: folderId || undefined,\n\t\tstatusSlug: statusSlug || undefined,\n\t\tbehavior: behaviorFilter || undefined,\n\t\tsearch: filters.search || undefined,\n\t\ttagIds: activeTags.length > 0 ? activeTags : undefined,\n\t\tcollectionIds: activeCollectionId ? [activeCollectionId] : undefined,\n\t});\n\n\t// The filter's options are the workspace's own catalogue, read from\n\t// statushub (integration standard §10) — the order statushub answers in.\n\tconst statusOptions = useAssetStatuses().data ?? [];\n\tconst assets: AssetInfo[] = assetsQuery.data?.items ?? [];\n\n\t// A failed listing must SAY so. `assetsQuery.data?.items ?? []` alone would\n\t// render \"No assets found\" over a refusal — which is the false answer the\n\t// server refused to give, arriving through the UI's door instead\n\t// (knkCS/mediahub#120). The behavior filter is the one read the server\n\t// refuses while statushub is unreachable, and the reader clears it by\n\t// dropping the filter, so that is the action offered.\n\tconst listFailure = assetsQuery.isError ? assetsQuery.error : undefined;\n\tconst listFailureState = listFailure ? (\n\t\tisRetryableUnavailable(listFailure) && behaviorFilter ? (\n\t\t\t<EmptyState\n\t\t\t\theader=\"Statuses are unavailable\"\n\t\t\t\tdescription=\"Mediahub cannot reach the status service, so it cannot tell which statuses count as this group. Your assets are all still here — clear the filter to see them, or try again in a moment.\"\n\t\t\t\tactions={\n\t\t\t\t\t<Button size=\"sm\" onClick={() => setBehaviorFilter(\"\")}>\n\t\t\t\t\t\tClear status group\n\t\t\t\t\t</Button>\n\t\t\t\t}\n\t\t\t/>\n\t\t) : (\n\t\t\t<EmptyState\n\t\t\t\theader=\"Assets could not be loaded\"\n\t\t\t\tdescription={\n\t\t\t\t\tdescribeRpcError(listFailure, \"Assets could not be loaded\")\n\t\t\t\t\t\t.description\n\t\t\t\t}\n\t\t\t/>\n\t\t)\n\t) : undefined;\n\n\tconst assetTypesQuery = useAssetTypes();\n\tconst typeNames = useMemo(\n\t\t() => buildAssetTypeNameMap(assetTypesQuery.data ?? []),\n\t\t[assetTypesQuery.data],\n\t);\n\tconst updatedByIds = useMemo(() => collectUpdatedByIds(assets), [assets]);\n\tconst { data: userNames } = useUsers(updatedByIds);\n\n\tconst selectedIds = useSelectionStore((s) => s.selectedIds);\n\tconst setSelection = useSelectionStore((s) => s.setSelection);\n\n\t// Bridge Zustand selection <-> DataTable rowSelection\n\tconst rowSelection = useMemo(() => {\n\t\tconst sel: RowSelectionState = {};\n\t\tfor (const id of selectedIds) sel[id] = true;\n\t\treturn sel;\n\t}, [selectedIds]);\n\n\tconst handleRowSelectionChange: OnChangeFn<RowSelectionState> = useCallback(\n\t\t(updater) => {\n\t\t\tconst current: RowSelectionState = {};\n\t\t\tfor (const id of useSelectionStore.getState().selectedIds)\n\t\t\t\tcurrent[id] = true;\n\t\t\tconst next = typeof updater === \"function\" ? updater(current) : updater;\n\t\t\tsetSelection(Object.keys(next).filter((k) => next[k]));\n\t\t},\n\t\t[setSelection],\n\t);\n\n\t// Clear selection when filters change\n\tconst filtersKey = JSON.stringify(filters);\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: trigger on filters change\n\tuseEffect(() => {\n\t\tuseSelectionStore.getState().clearSelection();\n\t}, [filtersKey]);\n\n\t// DataTable columns for list view\n\tconst columnHelper = createColumnHelper<AssetInfo>();\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: columnHelper is stable, handleDelete is intentionally excluded\n\tconst listColumns = useMemo(\n\t\t() =>\n\t\t\t[\n\t\t\t\tcolumnHelper.accessor(\"name\", {\n\t\t\t\t\theader: \"Name\",\n\t\t\t\t\tcell: (info) => <TruncatedTextCell value={info.getValue()} />,\n\t\t\t\t}),\n\t\t\t\tcolumnHelper.accessor(\"assetTypeId\", {\n\t\t\t\t\theader: \"Type\",\n\t\t\t\t\tcell: (info) => (\n\t\t\t\t\t\t<Text color=\"fg.muted\">\n\t\t\t\t\t\t\t{typeNames.get(info.getValue()) ?? info.getValue()}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t\tcolumnHelper.accessor(\"statusSlug\", {\n\t\t\t\t\theader: \"Status\",\n\t\t\t\t\tcell: (info) => <AssetStatusBadge slug={info.getValue()} />,\n\t\t\t\t\tenableSorting: false,\n\t\t\t\t}),\n\t\t\t\tcolumnHelper.accessor(\"updatedAt\", {\n\t\t\t\t\theader: \"Updated\",\n\t\t\t\t\tcell: (info) => {\n\t\t\t\t\t\tconst date = info.getValue();\n\t\t\t\t\t\treturn <DateCell value={date ?? null} showRelative />;\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t\tcolumnHelper.accessor(\"updatedBy\", {\n\t\t\t\t\theader: \"Updated By\",\n\t\t\t\t\tcell: (info) => (\n\t\t\t\t\t\t<Text color=\"fg.muted\">\n\t\t\t\t\t\t\t{userNames?.[info.getValue()] ?? info.getValue()}\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t),\n\t\t\t\t}),\n\t\t\t\tcolumnHelper.display({\n\t\t\t\t\tid: \"actions\",\n\t\t\t\t\tcell: (info) => {\n\t\t\t\t\t\tconst asset = info.row.original;\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<ActionCell\n\t\t\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ticon: Download,\n\t\t\t\t\t\t\t\t\t\tlabel: \"Download\",\n\t\t\t\t\t\t\t\t\t\tonClick: () => {},\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\ticon: Trash2,\n\t\t\t\t\t\t\t\t\t\tlabel: \"Delete\",\n\t\t\t\t\t\t\t\t\t\tonClick: () => handleDelete(asset.id, asset.name),\n\t\t\t\t\t\t\t\t\t\tcolorPalette: \"red\",\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t]}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t);\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t] as ColumnDef<AssetInfo, unknown>[],\n\t\t[typeNames, userNames],\n\t);\n\n\t// Right rail — independently-collapsible upload / tags / collections sections.\n\t// Memoised so search/filter keystrokes don't re-push the slot and bounce an\n\t// extra AppShell render; recomputes only when the rail's own inputs change.\n\tconst rail = useMemo(\n\t\t() => (\n\t\t\t<ContextRail storageKey=\"asset-library-rail\">\n\t\t\t\t<ContextRail.Section id=\"upload\" label=\"Upload\" defaultOpen>\n\t\t\t\t\t<UploadDropZone onFilesSelected={handleFilesSelected} compact />\n\t\t\t\t</ContextRail.Section>\n\t\t\t\t<ContextRail.Section id=\"tags\" label=\"Tags\" defaultOpen>\n\t\t\t\t\t<TagPanel activeTags={activeTags} onToggleTag={handleToggleTag} />\n\t\t\t\t</ContextRail.Section>\n\t\t\t\t<ContextRail.Section id=\"collections\" label=\"Collections\" defaultOpen>\n\t\t\t\t\t<CollectionPanel\n\t\t\t\t\t\tactiveCollectionId={activeCollectionId}\n\t\t\t\t\t\tonSelectCollection={handleSelectCollection}\n\t\t\t\t\t/>\n\t\t\t\t</ContextRail.Section>\n\t\t\t</ContextRail>\n\t\t),\n\t\t[\n\t\t\tactiveTags,\n\t\t\tactiveCollectionId,\n\t\t\thandleFilesSelected,\n\t\t\thandleToggleTag,\n\t\t\thandleSelectCollection,\n\t\t],\n\t);\n\tusePageRail(rail);\n\n\t// Toolbar swaps for the BulkActionBar while rows are selected.\n\tconst toolbar =\n\t\tselectedIds.length > 0 ? (\n\t\t\t<BulkActionBar />\n\t\t) : (\n\t\t\t<Toolbar>\n\t\t\t\t<Toolbar.Search\n\t\t\t\t\tplaceholder=\"Search assets…\"\n\t\t\t\t\tvalue={searchText}\n\t\t\t\t\tonChange={setSearchText}\n\t\t\t\t/>\n\t\t\t\t<Toolbar.Filters>\n\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvalue={statusSlug}\n\t\t\t\t\t\tonChange={(e) => setStatusSlug(e.target.value ?? \"\")}\n\t\t\t\t\t>\n\t\t\t\t\t\t<option value=\"\">All</option>\n\t\t\t\t\t\t{statusOptions.map((s) => (\n\t\t\t\t\t\t\t<option key={s.id} value={s.slug}>\n\t\t\t\t\t\t\t\t{s.name}\n\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t<SegmentedControl\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvalue={behaviorFilter}\n\t\t\t\t\t\tonValueChange={(details) => setBehaviorFilter(details.value ?? \"\")}\n\t\t\t\t\t\titems={BEHAVIOR_OPTIONS}\n\t\t\t\t\t/>\n\t\t\t\t</Toolbar.Filters>\n\t\t\t\t<Toolbar.Right>\n\t\t\t\t\t<SegmentedControl\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tvalue={viewMode}\n\t\t\t\t\t\tonValueChange={(details) =>\n\t\t\t\t\t\t\tsetViewMode(details.value as \"list\" | \"grid\")\n\t\t\t\t\t\t}\n\t\t\t\t\t\titems={VIEW_MODE_OPTIONS}\n\t\t\t\t\t/>\n\t\t\t\t\t{/* A count is a claim about the whole set, so a failed\n\t\t\t\t\t listing has none to make: \"0 assets\" beside \"statuses\n\t\t\t\t\t are unavailable\" would be the same false answer in\n\t\t\t\t\t miniature. */}\n\t\t\t\t\t{listFailure ? null : (\n\t\t\t\t\t\t<Toolbar.Count>{assets.length} assets</Toolbar.Count>\n\t\t\t\t\t)}\n\t\t\t\t</Toolbar.Right>\n\t\t\t</Toolbar>\n\t\t);\n\n\treturn (\n\t\t<IndexPageTemplate\n\t\t\tbreadcrumbs={[{ label: \"Assets\" }]}\n\t\t\ttitle=\"Assets\"\n\t\t\tactions={\n\t\t\t\t<Button\n\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\tonClick={() => fileInputRef.current?.click()}\n\t\t\t\t>\n\t\t\t\t\t<Upload size={14} /> Upload\n\t\t\t\t</Button>\n\t\t\t}\n\t\t\ttoolbar={toolbar}\n\t\t>\n\t\t\t<SubNavLayout storageKey=\"mediahub-assets-subnav\">\n\t\t\t\t<SubNavLayout.Nav aria-label=\"Folders\">\n\t\t\t\t\t<Box overflow=\"hidden\">\n\t\t\t\t\t\t<FolderTree\n\t\t\t\t\t\t\tactiveFolderId={folderId}\n\t\t\t\t\t\t\tonFolderSelect={(id) => updateFilter(\"folderId\", id || undefined)}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</Box>\n\t\t\t\t</SubNavLayout.Nav>\n\t\t\t\t<SubNavLayout.Detail>\n\t\t\t\t\t<SubNavLayout.Toolbar>\n\t\t\t\t\t\t{folderId ? (\n\t\t\t\t\t\t\t<FolderBreadcrumbs\n\t\t\t\t\t\t\t\tfolderId={folderId}\n\t\t\t\t\t\t\t\tonNavigate={(id) => updateFilter(\"folderId\", id || undefined)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\">\n\t\t\t\t\t\t\t\tAll Assets\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</SubNavLayout.Toolbar>\n\t\t\t\t\t<Box flex=\"1\" overflow=\"auto\" p={4}>\n\t\t\t\t\t\t{/* Above the rows, not instead of them. A refused refetch\n\t\t\t\t\t\t leaves TanStack Query's previous `data` in place, so\n\t\t\t\t\t\t an error does NOT imply an empty list — hanging this\n\t\t\t\t\t\t on the table's `emptyState` would show stale rows\n\t\t\t\t\t\t under no notice at all, which is the silently-wrong\n\t\t\t\t\t\t listing the server refusal exists to prevent. */}\n\t\t\t\t\t\t{listFailureState}\n\t\t\t\t\t\t{listFailureState && assets.length === 0 ? null : viewMode ===\n\t\t\t\t\t\t\t\"grid\" ? (\n\t\t\t\t\t\t\tassetsQuery.isLoading ? (\n\t\t\t\t\t\t\t\t<Flex justify=\"center\" py={10}>\n\t\t\t\t\t\t\t\t\t<Spinner />\n\t\t\t\t\t\t\t\t</Flex>\n\t\t\t\t\t\t\t) : assets.length === 0 ? (\n\t\t\t\t\t\t\t\t<EmptyState header=\"No assets found\" />\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<AssetGrid\n\t\t\t\t\t\t\t\t\tassets={assets}\n\t\t\t\t\t\t\t\t\tonOpen={(asset) => onAssetOpen?.(asset)}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<DataTable\n\t\t\t\t\t\t\t\tcolumns={\n\t\t\t\t\t\t\t\t\tlistColumns as ColumnDef<Record<string, unknown>, unknown>[]\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tdata={assets as unknown as Record<string, unknown>[]}\n\t\t\t\t\t\t\t\tselectable\n\t\t\t\t\t\t\t\trowSelection={rowSelection}\n\t\t\t\t\t\t\t\tonRowSelectionChange={handleRowSelectionChange}\n\t\t\t\t\t\t\t\tgetRowId={(asset) => (asset as unknown as AssetInfo).id}\n\t\t\t\t\t\t\t\tonRowClick={(asset) =>\n\t\t\t\t\t\t\t\t\tonAssetOpen?.(asset as unknown as AssetInfo)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tloading={assetsQuery.isLoading}\n\t\t\t\t\t\t\t\temptyState={<EmptyState header=\"No assets found\" />}\n\t\t\t\t\t\t\t\tvariant=\"line\"\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Box>\n\t\t\t\t</SubNavLayout.Detail>\n\t\t\t</SubNavLayout>\n\n\t\t\t<input\n\t\t\t\tref={fileInputRef}\n\t\t\t\ttype=\"file\"\n\t\t\t\tmultiple\n\t\t\t\thidden\n\t\t\t\tonChange={(e) => {\n\t\t\t\t\tconst files = e.target.files;\n\t\t\t\t\tif (files && files.length > 0) {\n\t\t\t\t\t\thandleFilesSelected(Array.from(files));\n\t\t\t\t\t}\n\t\t\t\t\te.target.value = \"\";\n\t\t\t\t}}\n\t\t\t/>\n\n\t\t\t<UploadDialog\n\t\t\t\topen={uploadDialogOpen}\n\t\t\t\tonClose={() => setUploadDialogOpen(false)}\n\t\t\t\tfolderId={folderId || undefined}\n\t\t\t/>\n\t\t</IndexPageTemplate>\n\t);\n}\nAssetLibrary.displayName = \"AssetLibrary\";\n","import {\n\ttype FieldTypePlugin,\n\ttype Schema,\n\tgetDefaultValues,\n} from \"@knkcs/fieldkit/schema\";\nimport type { AssetInfo } from \"../types\";\n\n/** Structural field types carry no value — never composed or decomposed.\n * `card` (fieldkit 0.8.0) is a layout marker exactly like `section`, one\n * level down: a value squatting under a marker accessor must neither mount\n * into the form nor be written back by a save. */\nconst STRUCTURAL = new Set([\"section\", \"card\"]);\n\n/**\n * Compose the RHF form values for the spec-driven asset body. Schema-driven,\n * never hardcoded: the schema's own `system` flags decide whether a value\n * comes from an asset column or from the metadata document. Hidden fields\n * are included so their stored values survive the full-document round-trip.\n * Custom fields with no stored value fall back to fieldkit's defaults\n * (explicit `config.default_value`, then — when `plugins` is passed — the\n * plugin's per-type `defaultValue`, fieldkit ≥0.7.0). Types that declare no\n * `defaultValue` (radio, date, time, color, rich_text, toc_reference) have\n * their key omitted entirely so the field mounts undefined — never seed a\n * stand-in value fieldkit's own registry wouldn't produce.\n */\nexport function composeFormValues(\n\tschema: Schema,\n\tasset: AssetInfo,\n\tplugins?: FieldTypePlugin[],\n): Record<string, unknown> {\n\tconst assetRecord = asset as unknown as Record<string, unknown>;\n\tconst defaults = getDefaultValues(schema, plugins);\n\tconst values: Record<string, unknown> = {};\n\tfor (const f of schema) {\n\t\tif (STRUCTURAL.has(f.field_type)) continue;\n\t\tconst acc = f.config.api_accessor;\n\t\tconst stored = f.system ? assetRecord[acc] : asset.metadata[acc];\n\t\tif (stored !== undefined) {\n\t\t\tvalues[acc] = stored;\n\t\t} else if (acc in defaults) {\n\t\t\tvalues[acc] = defaults[acc];\n\t\t}\n\t\t// else: the type declares no defaultValue — omit the key so the field\n\t\t// mounts undefined instead of a zod-invalid stand-in.\n\t}\n\treturn values;\n}\n\n/**\n * Decompose submitted form values into the update patch: system accessors →\n * asset columns; everything else → the metadata document. Starts from the\n * asset's CURRENT metadata so orphaned keys (values of since-deleted fields)\n * are preserved by a full-document save.\n */\nexport function decomposePatch(\n\tschema: Schema,\n\tasset: AssetInfo,\n\tvalues: Record<string, unknown>,\n\t// NOTE: adding a future system field means extending this return shape and the proto patch — not just the Go canonical list.\n): { name: string; description: string; metadata: Record<string, unknown> } {\n\tconst metadata: Record<string, unknown> = { ...asset.metadata };\n\tconst columns: Record<string, unknown> = {};\n\tfor (const f of schema) {\n\t\tif (STRUCTURAL.has(f.field_type)) continue;\n\t\tconst acc = f.config.api_accessor;\n\t\tif (!(acc in values)) continue;\n\t\tif (f.system) {\n\t\t\tcolumns[acc] = values[acc];\n\t\t} else {\n\t\t\tmetadata[acc] = values[acc];\n\t\t}\n\t}\n\treturn {\n\t\tname: String(columns.name ?? asset.name),\n\t\tdescription: String(columns.description ?? asset.description),\n\t\tmetadata,\n\t};\n}\n","import { zodResolver } from \"@hookform/resolvers/zod\";\nimport { Button, EmptyState, IconButton } from \"@knkcs/anker/atoms\";\nimport {\n\tActionCell,\n\tContextRail,\n\tDataTable,\n\tDateCell,\n\tDescriptionList,\n\tStatusBadgeCell,\n\tTruncatedTextCell,\n\tUploadDropZone,\n} from \"@knkcs/anker/components\";\nimport { useConfirmModal } from \"@knkcs/anker/feedback\";\nimport {\n\tBadge,\n\tBox,\n\tFlex,\n\tHStack,\n\tMenuContent,\n\tMenuItem,\n\tMenuRoot,\n\tMenuTrigger,\n\tSpinner,\n\tStack,\n\tTabs,\n\tText,\n\ttoaster,\n} from \"@knkcs/anker/primitives\";\nimport { DetailPageTemplate, usePageRail } from \"@knkcs/anker/templates\";\nimport { FieldKitProvider, SpecForm } from \"@knkcs/fieldkit/renderer\";\nimport {\n\ttype Schema,\n\tbuiltInFieldTypes,\n\tspecToZodSchema,\n} from \"@knkcs/fieldkit/schema\";\nimport { useQueryClient } from \"@tanstack/react-query\";\nimport type { ColumnDef } from \"@tanstack/react-table\";\nimport { createColumnHelper } from \"@tanstack/react-table\";\nimport { ArrowLeft, Download, Ellipsis, Sparkles } from \"lucide-react\";\nimport type React from \"react\";\nimport { useCallback, useMemo, useState } from \"react\";\nimport { FormProvider, useForm } from \"react-hook-form\";\n\nimport { AssetPreview } from \"./components/asset-preview\";\nimport { AssetStatusBadge } from \"./components/asset-status-badge\";\nimport { AssetStatusControl } from \"./components/asset-status-control\";\nimport { CollectionChipField } from \"./components/collection-chip-field\";\nimport { ManageAccessDialog } from \"./components/manage-access-dialog\";\nimport { MoveDialog } from \"./components/move-dialog\";\nimport { TagChipField } from \"./components/tag-chip-field\";\nimport { useAddVersion } from \"./hooks/use-add-version\";\nimport { useAIProcessRuns } from \"./hooks/use-ai-process-runs\";\nimport { useAssetType } from \"./hooks/use-asset-types\";\nimport {\n\tuseAsset,\n\tuseDeleteAsset,\n\tuseEnhanceAssetMetadata,\n\tuseUpdateAsset,\n} from \"./hooks/use-assets\";\nimport { useUsers } from \"./hooks/use-users\";\nimport { composeFormValues, decomposePatch } from \"./lib/asset-metadata-form\";\nimport { showRpcErrorToast } from \"./lib/rpc-errors\";\nimport { useMediahubClients } from \"./provider\";\nimport type { AIProcessRunInfo, AssetVersionInfo } from \"./types\";\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatFileSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n\nconst versionColumnHelper = createColumnHelper<AssetVersionInfo>();\n\nfunction aiRunColorPalette(status: AIProcessRunInfo[\"status\"]): string {\n\tswitch (status) {\n\t\tcase \"running\":\n\t\t\treturn \"blue\";\n\t\tcase \"succeeded\":\n\t\t\treturn \"green\";\n\t\tcase \"failed\":\n\t\t\treturn \"red\";\n\t\tdefault:\n\t\t\treturn \"gray\"; // queued + unknown\n\t}\n}\n\n// ---------------------------------------------------------------------------\n// AssetDetailRail\n// ---------------------------------------------------------------------------\n\ninterface AssetDetailRailProps {\n\tassetId: string;\n\tassetName: string;\n\tcurrentVersionId: string | undefined;\n\tcurrentMimeType: string | undefined;\n\tcurrentFilename: string | undefined;\n\tcurrentFileSize: number | undefined;\n\tcurrentVersion: number;\n\tassetTypeId: string;\n\tcreatedBy: string;\n\tcreatedByName?: string;\n\tfolderId: string;\n\ttagIds: string[];\n\tcollectionIds: string[];\n\tstatusSlug: string;\n}\n\nexport function AssetDetailRail({\n\tassetId,\n\tassetName,\n\tcurrentVersionId,\n\tcurrentMimeType,\n\tcurrentFilename,\n\tcurrentFileSize,\n\tcurrentVersion,\n\tassetTypeId,\n\tcreatedBy,\n\tcreatedByName,\n\tfolderId,\n\ttagIds,\n\tcollectionIds,\n\tstatusSlug,\n}: AssetDetailRailProps): React.JSX.Element {\n\tconst addVersion = useAddVersion();\n\tconst assetType = useAssetType(assetTypeId);\n\tconst aiRuns = useAIProcessRuns(assetId);\n\tconst runs = aiRuns.data ?? [];\n\n\treturn (\n\t\t<ContextRail storageKey=\"asset-detail-rail\">\n\t\t\t<ContextRail.Header eyebrow=\"Asset\" title={assetName} />\n\n\t\t\t{/* Preview */}\n\t\t\t{currentVersionId && currentMimeType ? (\n\t\t\t\t<Box mx={4} mt={3}>\n\t\t\t\t\t<AssetPreview\n\t\t\t\t\t\tassetId={assetId}\n\t\t\t\t\t\tversionId={currentVersionId}\n\t\t\t\t\t\tmimeType={currentMimeType}\n\t\t\t\t\t\tfileName={currentFilename ?? assetName}\n\t\t\t\t\t/>\n\t\t\t\t</Box>\n\t\t\t) : null}\n\n\t\t\t{/* Status — omitted entirely when the asset has no status slug; the\n\t\t\t title-bar badge already conveys it. The catalogue and the moves\n\t\t\t away from the current status are statushub's; the change itself\n\t\t\t goes through mediahub's own RPC (integration standard §3). */}\n\t\t\t{statusSlug ? (\n\t\t\t\t<ContextRail.Section id=\"status\" label=\"Status\" defaultOpen>\n\t\t\t\t\t<AssetStatusControl assetId={assetId} statusSlug={statusSlug} />\n\t\t\t\t</ContextRail.Section>\n\t\t\t) : null}\n\n\t\t\t{/* New version — drop-to-version zone */}\n\t\t\t{/* usePageRail is a no-op without an <AppShell> ancestor — this rail\n\t\t\t renders inline when mounted directly. A future railMode:\"inline\"\n\t\t\t escape hatch is out of scope for now. */}\n\t\t\t<ContextRail.Section id=\"new-version\" label=\"New version\" defaultOpen>\n\t\t\t\t<UploadDropZone\n\t\t\t\t\tcompact\n\t\t\t\t\tdropHintText=\"Drop a file to add a version\"\n\t\t\t\t\tdisabled={addVersion.isPending}\n\t\t\t\t\tonFiles={(files) => {\n\t\t\t\t\t\tconst f = files[0];\n\t\t\t\t\t\tif (f) {\n\t\t\t\t\t\t\taddVersion.mutate({ assetId, file: f });\n\t\t\t\t\t\t}\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t{addVersion.isPending && (\n\t\t\t\t\t<Flex align=\"center\" gap={2} mt={2}>\n\t\t\t\t\t\t<Spinner size=\"xs\" />\n\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\">\n\t\t\t\t\t\t\tUploading… {addVersion.progress}%\n\t\t\t\t\t\t</Text>\n\t\t\t\t\t</Flex>\n\t\t\t\t)}\n\t\t\t</ContextRail.Section>\n\n\t\t\t{/* Details */}\n\t\t\t<ContextRail.Section id=\"details\" label=\"Details\">\n\t\t\t\t<DescriptionList orientation=\"horizontal\" gap=\"2\">\n\t\t\t\t\t<DescriptionList.Row label=\"Type\">\n\t\t\t\t\t\t{assetType.data?.name ?? assetTypeId}\n\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label=\"Format\">\n\t\t\t\t\t\t{currentMimeType ?? \"—\"}\n\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label=\"Size\">\n\t\t\t\t\t\t{currentFileSize !== undefined\n\t\t\t\t\t\t\t? formatFileSize(currentFileSize)\n\t\t\t\t\t\t\t: \"—\"}\n\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label=\"Version\">\n\t\t\t\t\t\tv{currentVersion}\n\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label=\"Created by\">\n\t\t\t\t\t\t{createdByName ?? createdBy}\n\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t\t<DescriptionList.Row label=\"Folder\">\n\t\t\t\t\t\t{folderId || \"—\"}\n\t\t\t\t\t</DescriptionList.Row>\n\t\t\t\t</DescriptionList>\n\t\t\t</ContextRail.Section>\n\n\t\t\t{/* Tags */}\n\t\t\t<ContextRail.Section id=\"tags\" label=\"Tags\">\n\t\t\t\t<TagChipField assetId={assetId} assignedTagIds={tagIds} />\n\t\t\t</ContextRail.Section>\n\n\t\t\t{/* Collections */}\n\t\t\t<ContextRail.Section id=\"collections\" label=\"Collections\">\n\t\t\t\t<CollectionChipField\n\t\t\t\t\tassetId={assetId}\n\t\t\t\t\tassignedCollectionIds={collectionIds}\n\t\t\t\t/>\n\t\t\t</ContextRail.Section>\n\n\t\t\t{/* AI Processing — only shown when there are runs */}\n\t\t\t{runs.length > 0 ? (\n\t\t\t\t<ContextRail.Section\n\t\t\t\t\tid=\"ai-processing\"\n\t\t\t\t\tlabel=\"AI Processing\"\n\t\t\t\t\tdefaultOpen\n\t\t\t\t>\n\t\t\t\t\t<Stack gap=\"2\">\n\t\t\t\t\t\t{runs.map((run) => (\n\t\t\t\t\t\t\t<Stack key={run.id} gap=\"1\">\n\t\t\t\t\t\t\t\t<HStack gap=\"2\" justify=\"space-between\">\n\t\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" flexShrink={1} truncate>\n\t\t\t\t\t\t\t\t\t\t{run.processName}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t<Badge\n\t\t\t\t\t\t\t\t\t\tcolorPalette={aiRunColorPalette(run.status)}\n\t\t\t\t\t\t\t\t\t\tvariant=\"subtle\"\n\t\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t\t\tflexShrink={0}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{run.status}\n\t\t\t\t\t\t\t\t\t</Badge>\n\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t\t{run.status === \"failed\" && run.error ? (\n\t\t\t\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"fg.error\">\n\t\t\t\t\t\t\t\t\t\t{run.error}\n\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</Stack>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Stack>\n\t\t\t\t</ContextRail.Section>\n\t\t\t) : null}\n\t\t</ContextRail>\n\t);\n}\nAssetDetailRail.displayName = \"AssetDetailRail\";\n\n// ---------------------------------------------------------------------------\n// AssetDetail\n// ---------------------------------------------------------------------------\n\nexport interface AssetDetailProps {\n\tassetId: string;\n\t/** Navigate back to the asset list. */\n\tonBack?: () => void;\n\t/** Called after a successful delete. */\n\tonDeleted?: () => void;\n}\n\nexport function AssetDetail({\n\tassetId,\n\tonBack,\n\tonDeleted,\n}: AssetDetailProps): React.JSX.Element {\n\tconst assetQuery = useAsset(assetId);\n\tconst asset = assetQuery.data;\n\n\tconst { assets: assetsClient } = useMediahubClients();\n\n\tconst updateAsset = useUpdateAsset();\n\tconst deleteAsset = useDeleteAsset();\n\tconst enhanceMetadata = useEnhanceAssetMetadata();\n\tconst qc = useQueryClient();\n\tconst { confirm } = useConfirmModal();\n\n\tconst assetTypeQuery = useAssetType(asset?.assetTypeId ?? \"\");\n\n\tconst schema = useMemo<Schema>(() => {\n\t\ttry {\n\t\t\treturn JSON.parse(assetTypeQuery.data?.metadataSchema || \"[]\") as Schema;\n\t\t} catch {\n\t\t\treturn [];\n\t\t}\n\t}, [assetTypeQuery.data?.metadataSchema]);\n\n\tconst composedValues = useMemo(\n\t\t() => (asset ? composeFormValues(schema, asset, builtInFieldTypes) : {}),\n\t\t[schema, asset],\n\t);\n\n\tconst zodSchema = useMemo(\n\t\t() => specToZodSchema(schema, builtInFieldTypes),\n\t\t[schema],\n\t);\n\n\t// Always-edit body form. `values` + keepDirtyValues: background refetches\n\t// update clean fields but never clobber in-progress edits.\n\tconst form = useForm({\n\t\tresolver: zodResolver(zodSchema),\n\t\tvalues: composedValues,\n\t\tresetOptions: { keepDirtyValues: true },\n\t});\n\n\tasync function handleSaveBody(values: Record<string, unknown>) {\n\t\tif (!asset) return;\n\t\tconst patch = decomposePatch(schema, asset, values);\n\t\ttry {\n\t\t\tawait updateAsset.mutateAsync({ id: asset.id, patch });\n\t\t\ttoaster.success({ title: \"Asset saved\" });\n\t\t\tform.reset(values); // re-baseline: the submitted values are committed\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Save failed\");\n\t\t}\n\t}\n\n\tasync function handleBack() {\n\t\tif (form.formState.isDirty) {\n\t\t\tconst confirmed = await confirm({\n\t\t\t\ttitle: \"Discard changes?\",\n\t\t\t\tmessage: \"The asset has unsaved changes. Leaving discards them.\",\n\t\t\t\tconfirmLabel: \"Discard\",\n\t\t\t});\n\t\t\tif (!confirmed) return;\n\t\t}\n\t\tonBack?.();\n\t}\n\n\tconst [activeTab, setActiveTab] = useState<\"overview\" | \"versions\">(\n\t\t\"overview\",\n\t);\n\tconst [moveOpen, setMoveOpen] = useState(false);\n\tconst [accessOpen, setAccessOpen] = useState(false);\n\n\t// Current version object\n\tconst currentVersion = useMemo(() => {\n\t\tif (!asset) return undefined;\n\t\treturn (\n\t\t\tasset.versions.find((v) => v.versionNumber === asset.currentVersion) ??\n\t\t\tasset.versions.at(-1)\n\t\t);\n\t}, [asset]);\n\n\t// Collect all user IDs referenced in this asset for a single batch lookup.\n\tconst allUserIds = useMemo(() => {\n\t\tif (!asset) return [];\n\t\tconst ids = new Set<string>();\n\t\tif (asset.createdBy) ids.add(asset.createdBy);\n\t\tfor (const v of asset.versions) {\n\t\t\tif (v.createdBy) ids.add(v.createdBy);\n\t\t}\n\t\treturn [...ids];\n\t}, [asset]);\n\n\tconst { data: userNames } = useUsers(allUserIds);\n\n\t// Download a specific version via its SAS URL.\n\tconst handleDownloadVersion = useCallback(\n\t\tasync (versionId: string) => {\n\t\t\tif (!asset) return;\n\t\t\ttry {\n\t\t\t\tconst url = await assetsClient.getDownloadUrl(asset.id, versionId);\n\t\t\t\twindow.open(url, \"_blank\");\n\t\t\t} catch (err) {\n\t\t\t\tshowRpcErrorToast(err, \"Download failed\");\n\t\t\t}\n\t\t},\n\t\t[asset, assetsClient],\n\t);\n\n\t// Versions table columns — every cell delegates to a provided anker *Cell\n\t// component (no inline JSX renderers).\n\tconst versionColumns = useMemo(() => {\n\t\tconst currentBadge: Record<string, string> = asset\n\t\t\t? { [`v${asset.currentVersion}`]: \"green\" }\n\t\t\t: {};\n\t\treturn [\n\t\t\tversionColumnHelper.accessor(\"versionNumber\", {\n\t\t\t\theader: \"Version\",\n\t\t\t\tcell: (info) => (\n\t\t\t\t\t<StatusBadgeCell\n\t\t\t\t\t\tvalue={`v${info.getValue()}`}\n\t\t\t\t\t\tcolorMap={currentBadge}\n\t\t\t\t\t\ttooltip={\n\t\t\t\t\t\t\tinfo.getValue() === asset?.currentVersion\n\t\t\t\t\t\t\t\t? \"Current version\"\n\t\t\t\t\t\t\t\t: undefined\n\t\t\t\t\t\t}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t}),\n\t\t\tversionColumnHelper.accessor(\"originalFilename\", {\n\t\t\t\theader: \"File\",\n\t\t\t\tcell: (info) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={info.getValue()}\n\t\t\t\t\t\tmaxLength={48}\n\t\t\t\t\t\tsubText={info.row.original.comment || info.row.original.mimeType}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t}),\n\t\t\tversionColumnHelper.accessor(\"fileSize\", {\n\t\t\t\theader: \"Size\",\n\t\t\t\tcell: (info) => (\n\t\t\t\t\t<TruncatedTextCell value={formatFileSize(info.getValue())} />\n\t\t\t\t),\n\t\t\t}),\n\t\t\tversionColumnHelper.accessor(\"createdBy\", {\n\t\t\t\theader: \"Author\",\n\t\t\t\tcell: (info) => (\n\t\t\t\t\t<TruncatedTextCell\n\t\t\t\t\t\tvalue={userNames?.[info.getValue()] ?? info.getValue()}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t}),\n\t\t\tversionColumnHelper.accessor(\"createdAt\", {\n\t\t\t\theader: \"Date\",\n\t\t\t\tcell: (info) => <DateCell value={info.getValue()} showRelative />,\n\t\t\t}),\n\t\t\tversionColumnHelper.display({\n\t\t\t\tid: \"actions\",\n\t\t\t\theader: \"\",\n\t\t\t\tcell: (info) => (\n\t\t\t\t\t<ActionCell\n\t\t\t\t\t\tactions={[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\ticon: Download,\n\t\t\t\t\t\t\t\tlabel: `Download version ${info.row.original.versionNumber}`,\n\t\t\t\t\t\t\t\tonClick: () => {\n\t\t\t\t\t\t\t\t\thandleDownloadVersion(info.row.original.id);\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t]}\n\t\t\t\t\t/>\n\t\t\t\t),\n\t\t\t}),\n\t\t] as ColumnDef<AssetVersionInfo, unknown>[];\n\t}, [asset, handleDownloadVersion, userNames]);\n\n\t// Register rail (Overview tab only) — no-op outside <AppShell>\n\tusePageRail(\n\t\tasset && activeTab === \"overview\" ? (\n\t\t\t<AssetDetailRail\n\t\t\t\tassetId={asset.id}\n\t\t\t\tassetName={asset.name}\n\t\t\t\tcurrentVersionId={currentVersion?.id}\n\t\t\t\tcurrentMimeType={currentVersion?.mimeType}\n\t\t\t\tcurrentFilename={currentVersion?.originalFilename}\n\t\t\t\tcurrentFileSize={currentVersion?.fileSize}\n\t\t\t\tcurrentVersion={asset.currentVersion}\n\t\t\t\tassetTypeId={asset.assetTypeId}\n\t\t\t\tcreatedBy={asset.createdBy}\n\t\t\t\tcreatedByName={userNames?.[asset.createdBy]}\n\t\t\t\tfolderId={asset.folderId}\n\t\t\t\ttagIds={asset.tagIds}\n\t\t\t\tcollectionIds={asset.collectionIds}\n\t\t\t\tstatusSlug={asset.statusSlug}\n\t\t\t/>\n\t\t) : null,\n\t);\n\n\t// -------------- handlers -----------------------------------------------\n\n\tasync function handleDownloadCurrent() {\n\t\tif (!asset || !currentVersion) return;\n\t\ttry {\n\t\t\tconst url = await assetsClient.getDownloadUrl(\n\t\t\t\tasset.id,\n\t\t\t\tcurrentVersion.id,\n\t\t\t);\n\t\t\twindow.open(url, \"_blank\");\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Download failed\");\n\t\t}\n\t}\n\n\tasync function handleEnhance() {\n\t\tif (!asset) return;\n\t\ttry {\n\t\t\tawait enhanceMetadata.mutateAsync(asset.id);\n\t\t\t// Kick off polling for the newly-queued process runs.\n\t\t\tqc.invalidateQueries({\n\t\t\t\tqueryKey: [\"mediahub\", \"ai-process-runs\", asset.id],\n\t\t\t});\n\t\t\ttoaster.success({ title: \"Metadata enhanced with AI\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Enhancement failed\");\n\t\t}\n\t}\n\n\tasync function handleDelete() {\n\t\tif (!asset) return;\n\t\tconst confirmed = await confirm({\n\t\t\ttitle: \"Delete Asset\",\n\t\t\tmessage: `Delete \"${asset.name}\"? This cannot be undone.`,\n\t\t\tconfirmLabel: \"Delete\",\n\t\t});\n\t\tif (!confirmed) return;\n\t\ttry {\n\t\t\tawait deleteAsset.mutateAsync(asset.id);\n\t\t\ttoaster.success({ title: \"Asset deleted\" });\n\t\t\tonDeleted?.();\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Delete failed\");\n\t\t}\n\t}\n\n\t// -------------- loading / not found ------------------------------------\n\n\tif (assetQuery.isLoading) {\n\t\treturn (\n\t\t\t<Flex justify=\"center\" align=\"center\" minH=\"400px\">\n\t\t\t\t<Spinner />\n\t\t\t</Flex>\n\t\t);\n\t}\n\n\tif (!asset) {\n\t\treturn <EmptyState header=\"Asset not found\" />;\n\t}\n\n\t// Sorted versions newest-first\n\tconst sortedVersions = [...asset.versions].sort(\n\t\t(a, b) => b.versionNumber - a.versionNumber,\n\t);\n\n\treturn (\n\t\t<DetailPageTemplate\n\t\t\tbreadcrumbs={[{ label: \"Assets\" }, { label: asset.name }]}\n\t\t\tavatar={\n\t\t\t\tonBack ? (\n\t\t\t\t\t<IconButton\n\t\t\t\t\t\tvariant=\"ghost\"\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\taria-label=\"Back to assets\"\n\t\t\t\t\t\tonClick={handleBack}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ArrowLeft size={18} />\n\t\t\t\t\t</IconButton>\n\t\t\t\t) : undefined\n\t\t\t}\n\t\t\ttitle={asset.name}\n\t\t\tbadges={\n\t\t\t\tasset.statusSlug ? (\n\t\t\t\t\t<AssetStatusBadge slug={asset.statusSlug} />\n\t\t\t\t) : undefined\n\t\t\t}\n\t\t\tmeta={\n\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\">\n\t\t\t\t\tv{asset.currentVersion}\n\t\t\t\t\t{asset.updatedAt ? ` · ${asset.updatedAt.toLocaleDateString()}` : \"\"}\n\t\t\t\t</Text>\n\t\t\t}\n\t\t\tactions={\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\t\tloading={enhanceMetadata.isPending}\n\t\t\t\t\t\tonClick={handleEnhance}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Sparkles size={16} /> Enhance with AI\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\t\tonClick={handleDownloadCurrent}\n\t\t\t\t\t>\n\t\t\t\t\t\tDownload\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\tdisabled={!form.formState.isDirty}\n\t\t\t\t\t\tonClick={() =>\n\t\t\t\t\t\t\t// Override the form's global keepDirtyValues:true (which exists\n\t\t\t\t\t\t\t// to protect in-progress edits from background refetches) —\n\t\t\t\t\t\t\t// Discard must revert every field, dirty or not.\n\t\t\t\t\t\t\tform.reset(composedValues, { keepDirtyValues: false })\n\t\t\t\t\t\t}\n\t\t\t\t\t>\n\t\t\t\t\t\tDiscard\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\t\tdisabled={!form.formState.isDirty}\n\t\t\t\t\t\tloading={updateAsset.isPending}\n\t\t\t\t\t\tonClick={form.handleSubmit(handleSaveBody)}\n\t\t\t\t\t>\n\t\t\t\t\t\tSave\n\t\t\t\t\t</Button>\n\t\t\t\t\t<MenuRoot>\n\t\t\t\t\t\t<MenuTrigger asChild>\n\t\t\t\t\t\t\t<IconButton variant=\"ghost\" size=\"sm\" aria-label=\"More actions\">\n\t\t\t\t\t\t\t\t<Ellipsis size={16} />\n\t\t\t\t\t\t\t</IconButton>\n\t\t\t\t\t\t</MenuTrigger>\n\t\t\t\t\t\t<MenuContent>\n\t\t\t\t\t\t\t<MenuItem value=\"move\" onClick={() => setMoveOpen(true)}>\n\t\t\t\t\t\t\t\tMove…\n\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t<MenuItem\n\t\t\t\t\t\t\t\tvalue=\"manage-access\"\n\t\t\t\t\t\t\t\tonClick={() => setAccessOpen(true)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tManage access…\n\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t\t<MenuItem value=\"delete\" color=\"fg.error\" onClick={handleDelete}>\n\t\t\t\t\t\t\t\tDelete\n\t\t\t\t\t\t\t</MenuItem>\n\t\t\t\t\t\t</MenuContent>\n\t\t\t\t\t</MenuRoot>\n\t\t\t\t</HStack>\n\t\t\t}\n\t\t\ttabs={\n\t\t\t\t<Tabs.Root\n\t\t\t\t\tvalue={activeTab}\n\t\t\t\t\tonValueChange={(e) =>\n\t\t\t\t\t\tsetActiveTab(e.value as \"overview\" | \"versions\")\n\t\t\t\t\t}\n\t\t\t\t>\n\t\t\t\t\t<Tabs.List>\n\t\t\t\t\t\t<Tabs.Trigger value=\"overview\">Overview</Tabs.Trigger>\n\t\t\t\t\t\t<Tabs.Trigger value=\"versions\">Versions</Tabs.Trigger>\n\t\t\t\t\t</Tabs.List>\n\t\t\t\t</Tabs.Root>\n\t\t\t}\n\t\t>\n\t\t\t<Stack gap=\"4\" px=\"8\" py=\"6\">\n\t\t\t\t{/* Renders into a portal; parked here so it stays mounted with\n\t\t\t\t the loaded asset (dialog machines must not unmount mid-exit,\n\t\t\t\t see collection-picker / #66). */}\n\t\t\t\t<MoveDialog\n\t\t\t\t\topen={moveOpen}\n\t\t\t\t\tonOpenChange={setMoveOpen}\n\t\t\t\t\tsubject={{ kind: \"asset\", asset }}\n\t\t\t\t/>\n\t\t\t\t<ManageAccessDialog\n\t\t\t\t\topen={accessOpen}\n\t\t\t\t\tonOpenChange={setAccessOpen}\n\t\t\t\t\tsubject={{ kind: \"asset\", asset }}\n\t\t\t\t/>\n\t\t\t\t{activeTab === \"overview\" ? (\n\t\t\t\t\t<FieldKitProvider plugins={builtInFieldTypes}>\n\t\t\t\t\t\t<FormProvider {...form}>\n\t\t\t\t\t\t\t<SpecForm schema={schema} loading={assetTypeQuery.isLoading} />\n\t\t\t\t\t\t</FormProvider>\n\t\t\t\t\t</FieldKitProvider>\n\t\t\t\t) : (\n\t\t\t\t\t<DataTable\n\t\t\t\t\t\tcolumns={\n\t\t\t\t\t\t\tversionColumns as ColumnDef<Record<string, unknown>, unknown>[]\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdata={sortedVersions as unknown as Record<string, unknown>[]}\n\t\t\t\t\t\tgetRowId={(r) => (r as unknown as AssetVersionInfo).id}\n\t\t\t\t\t\temptyState={<EmptyState header=\"No versions yet\" />}\n\t\t\t\t\t\tvariant=\"line\"\n\t\t\t\t\t/>\n\t\t\t\t)}\n\t\t\t</Stack>\n\t\t</DetailPageTemplate>\n\t);\n}\nAssetDetail.displayName = \"AssetDetail\";\n","// components/picker/picker-asset-card.tsx\nimport { SelectableCard } from \"@knkcs/anker/components\";\nimport { Skeleton, Text } from \"@knkcs/anker/primitives\";\nimport { FileText, Film, Image as ImageIcon, Music } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { usePreviewURL } from \"../../hooks/use-preview-url\";\nimport type { AssetInfo } from \"../../types\";\nimport { AssetStatusBadge } from \"../asset-status-badge\";\n\n/** Latest-version MIME category. Mirrors asset-grid.tsx. */\nexport function getMimeCategory(asset: AssetInfo): string {\n\tconst version = asset.versions[asset.versions.length - 1];\n\tif (!version) return \"unknown\";\n\tconst mime = version.mimeType;\n\tif (mime.startsWith(\"image/\")) return \"image\";\n\tif (mime.startsWith(\"video/\")) return \"video\";\n\tif (mime.startsWith(\"audio/\")) return \"audio\";\n\tif (mime === \"application/pdf\") return \"pdf\";\n\treturn \"unknown\";\n}\n\nfunction TypeIcon({ category }: { category: string }) {\n\tswitch (category) {\n\t\tcase \"image\":\n\t\t\treturn <ImageIcon size={32} opacity={0.3} />;\n\t\tcase \"video\":\n\t\t\treturn <Film size={32} opacity={0.3} />;\n\t\tcase \"audio\":\n\t\t\treturn <Music size={32} opacity={0.3} />;\n\t\tdefault:\n\t\t\treturn <FileText size={32} opacity={0.3} />;\n\t}\n}\nTypeIcon.displayName = \"TypeIcon\";\n\nexport interface PickerAssetCardProps {\n\tasset: AssetInfo;\n\tselected: boolean;\n\tselectionVisible: boolean;\n\tonToggle: (asset: AssetInfo) => void;\n}\n\nexport const PickerAssetCard: React.FC<PickerAssetCardProps> = ({\n\tasset,\n\tselected,\n\tselectionVisible,\n\tonToggle,\n}) => {\n\tconst category = getMimeCategory(asset);\n\tconst latestVersion = asset.versions[asset.versions.length - 1];\n\tconst previewQuery = usePreviewURL(\n\t\tcategory === \"image\" && latestVersion ? asset.id : \"\",\n\t\tlatestVersion?.id ?? \"\",\n\t);\n\tconst previewUrl = previewQuery.data;\n\tconst [imgError, setImgError] = useState(false);\n\n\treturn (\n\t\t<SelectableCard\n\t\t\tselected={selected}\n\t\t\tselectionVisible={selectionVisible}\n\t\t\tonSelect={() => onToggle(asset)}\n\t\t\tonClick={() => onToggle(asset)}\n\t\t>\n\t\t\t<SelectableCard.Thumbnail height=\"120px\">\n\t\t\t\t{category === \"image\" && previewUrl && !imgError ? (\n\t\t\t\t\t<img\n\t\t\t\t\t\tsrc={previewUrl}\n\t\t\t\t\t\talt={asset.name || \"Asset preview\"}\n\t\t\t\t\t\tonError={() => setImgError(true)}\n\t\t\t\t\t\tstyle={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n\t\t\t\t\t/>\n\t\t\t\t) : category === \"image\" && previewQuery.isLoading ? (\n\t\t\t\t\t<Skeleton w=\"full\" h=\"full\" />\n\t\t\t\t) : (\n\t\t\t\t\t<TypeIcon category={category} />\n\t\t\t\t)}\n\t\t\t</SelectableCard.Thumbnail>\n\t\t\t<SelectableCard.Body>\n\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\" truncate>\n\t\t\t\t\t{asset.name}\n\t\t\t\t</Text>\n\t\t\t</SelectableCard.Body>\n\t\t\t<SelectableCard.Footer>\n\t\t\t\t<AssetStatusBadge slug={asset.statusSlug} />\n\t\t\t</SelectableCard.Footer>\n\t\t</SelectableCard>\n\t);\n};\nPickerAssetCard.displayName = \"PickerAssetCard\";\n","// components/picker/picker-footer.tsx\nimport { Button } from \"@knkcs/anker/atoms\";\nimport { Box, Flex, HStack, Text } from \"@knkcs/anker/primitives\";\n\nexport interface PickerFooterProps {\n\tcount: number;\n\tconfirmLabel: string;\n\tcancelLabel: string;\n\tonConfirm: () => void;\n\tonCancel: () => void;\n\t/** Optional selection-strip content rendered on the left. */\n\tchildren?: React.ReactNode;\n}\n\nexport const PickerFooter: React.FC<PickerFooterProps> = ({\n\tcount,\n\tconfirmLabel,\n\tcancelLabel,\n\tonConfirm,\n\tonCancel,\n\tchildren,\n}) => {\n\treturn (\n\t\t<Flex align=\"center\" gap=\"3\" w=\"full\">\n\t\t\t<HStack gap=\"2\" minW=\"0\" flex=\"1\">\n\t\t\t\t{children}\n\t\t\t\t<Text fontSize=\"sm\" color=\"fg.muted\" flexShrink={0}>\n\t\t\t\t\t{count} selected\n\t\t\t\t</Text>\n\t\t\t</HStack>\n\t\t\t<Box flexShrink={0}>\n\t\t\t\t<HStack gap=\"2\">\n\t\t\t\t\t<Button variant=\"ghost\" onClick={onCancel}>\n\t\t\t\t\t\t{cancelLabel}\n\t\t\t\t\t</Button>\n\t\t\t\t\t<Button\n\t\t\t\t\t\tvariant=\"solid\"\n\t\t\t\t\t\tcolorPalette=\"primary\"\n\t\t\t\t\t\tdisabled={count === 0}\n\t\t\t\t\t\tonClick={onConfirm}\n\t\t\t\t\t>\n\t\t\t\t\t\t{confirmLabel}\n\t\t\t\t\t</Button>\n\t\t\t\t</HStack>\n\t\t\t</Box>\n\t\t</Flex>\n\t);\n};\nPickerFooter.displayName = \"PickerFooter\";\n","import { useCallback, useState } from \"react\";\n\nexport interface PickerSelection<T extends { id: string }> {\n\t/** Currently-selected full objects, in selection order. */\n\titems: T[];\n\tisSelected: (id: string) => boolean;\n\t/** Toggle an item. In single mode, selecting replaces any prior selection. */\n\ttoggle: (item: T) => void;\n\tremove: (id: string) => void;\n\tclear: () => void;\n}\n\nexport function usePickerSelection<T extends { id: string }>(\n\tmode: \"single\" | \"multi\",\n): PickerSelection<T> {\n\tconst [items, setItems] = useState<T[]>([]);\n\n\tconst toggle = useCallback(\n\t\t(item: T) => {\n\t\t\tsetItems((prev) => {\n\t\t\t\tconst exists = prev.some((i) => i.id === item.id);\n\t\t\t\tif (mode === \"single\") return exists ? [] : [item];\n\t\t\t\treturn exists ? prev.filter((i) => i.id !== item.id) : [...prev, item];\n\t\t\t});\n\t\t},\n\t\t[mode],\n\t);\n\n\tconst remove = useCallback(\n\t\t(id: string) => setItems((prev) => prev.filter((i) => i.id !== id)),\n\t\t[],\n\t);\n\tconst clear = useCallback(() => setItems([]), []);\n\tconst isSelected = useCallback(\n\t\t(id: string) => items.some((i) => i.id === id),\n\t\t[items],\n\t);\n\n\treturn { items, isSelected, toggle, remove, clear };\n}\n","// asset-picker.tsx\nimport { EmptyState } from \"@knkcs/anker/atoms\";\nimport { Modal } from \"@knkcs/anker/components\";\nimport { SearchInput } from \"@knkcs/anker/forms\";\nimport {\n\tBox,\n\tFlex,\n\tGrid,\n\tHStack,\n\tNativeSelect,\n\tSpinner,\n\tText,\n} from \"@knkcs/anker/primitives\";\nimport { useEffect, useMemo, useRef, useState } from \"react\";\nimport { FolderTree } from \"./components/folder-tree\";\nimport {\n\tPickerAssetCard,\n\tgetMimeCategory,\n} from \"./components/picker/picker-asset-card\";\nimport { PickerFooter } from \"./components/picker/picker-footer\";\nimport { usePickerSelection } from \"./components/picker/use-picker-selection\";\nimport { UploadDialog } from \"./components/upload/upload-dialog\";\nimport { UploadDropZone } from \"./components/upload/upload-drop-zone\";\nimport { useAssets } from \"./hooks/use-assets\";\nimport { usePreviewURL } from \"./hooks/use-preview-url\";\nimport { useAssetStatuses } from \"./statushub\";\nimport { useUploadStore } from \"./stores/upload-store\";\nimport type { AssetFilters, AssetInfo, AssetSelection } from \"./types\";\n\nexport interface AssetPickerProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\t/** @default \"single\" */\n\tmode?: \"single\" | \"multi\";\n\tonSelect: (selection: AssetSelection) => void;\n\t/** Enable upload-then-select (wired in Task 5). */\n\tallowUpload?: boolean;\n\t/** Client-side MIME filter, e.g. [\"image/*\"] or [\"application/pdf\"]. */\n\taccept?: string[];\n\t/** Initial/locked filters (e.g. a fixed assetTypeId). */\n\tinitialFilters?: AssetFilters;\n\theaderLabel?: string;\n\tsearchPlaceholder?: string;\n\tinsertLabel?: string;\n\tcancelLabel?: string;\n\temptyLabel?: string;\n}\n\nfunction matchesAccept(asset: AssetInfo, accept: string[]): boolean {\n\tconst v = asset.versions[asset.versions.length - 1];\n\tif (!v) return false;\n\tconst mime = v.mimeType;\n\treturn accept.some((a) =>\n\t\ta.endsWith(\"/*\")\n\t\t\t? mime.startsWith(a.slice(0, a.indexOf(\"/\") + 1))\n\t\t\t: mime === a,\n\t);\n}\n\nexport function AssetPicker(props: AssetPickerProps): React.JSX.Element {\n\tconst {\n\t\topen,\n\t\tonOpenChange,\n\t\tonSelect,\n\t\taccept,\n\t\tinitialFilters,\n\t\theaderLabel,\n\t\tsearchPlaceholder,\n\t\tinsertLabel,\n\t\tcancelLabel,\n\t\temptyLabel,\n\t} = props;\n\tconst mode = props.mode ?? \"single\";\n\n\tconst [filters, setFilters] = useState<AssetFilters>(initialFilters ?? {});\n\tconst folderId = filters.folderId ?? \"\";\n\tconst statusSlug = filters.statusSlug ?? \"\";\n\n\tconst selection = usePickerSelection<AssetInfo>(mode);\n\n\tfunction updateFilter<K extends keyof AssetFilters>(\n\t\tkey: K,\n\t\tvalue: AssetFilters[K],\n\t) {\n\t\tsetFilters((prev) => {\n\t\t\tconst next: AssetFilters = { ...prev };\n\t\t\tif (value === undefined || value === \"\") delete next[key];\n\t\t\telse next[key] = value;\n\t\t\treturn next;\n\t\t});\n\t}\n\n\tconst assetsQuery = useAssets(filters);\n\t// The workspace's own catalogue, read from statushub (§10).\n\tconst statusOptions = useAssetStatuses().data ?? [];\n\tconst allItems = assetsQuery.data?.items ?? [];\n\tconst items = useMemo(\n\t\t() =>\n\t\t\taccept?.length\n\t\t\t\t? allItems.filter((a) => matchesAccept(a, accept))\n\t\t\t\t: allItems,\n\t\t[allItems, accept],\n\t);\n\n\tconst allowUpload = props.allowUpload ?? false;\n\tconst addFiles = useUploadStore((s) => s.addFiles);\n\tconst uploadFiles = useUploadStore((s) => s.files);\n\tconst [uploadDialogOpen, setUploadDialogOpen] = useState(false);\n\t// assetIds already bridged this session — keeps the effect idempotent.\n\t// Not cleared on deselect, so re-uploading the same asset in one session\n\t// won't re-select it (acceptable for v1).\n\tconst bridgedRef = useRef<Set<string>>(new Set());\n\n\tfunction handleFilesSelected(files: File[]) {\n\t\taddFiles(files);\n\t\tsetUploadDialogOpen(true);\n\t}\n\n\t// Ephemeral picker state (selection/filters/upload dialog) is scrubbed in\n\t// the Modal's onExitComplete (not on `open` flipping false): the grid stays\n\t// visible through the exit animation, and an immediate reset would visibly\n\t// clear it mid-fade.\n\tfunction resetEphemeralState() {\n\t\tselection.clear();\n\t\tsetFilters(initialFilters ?? {});\n\t\tsetUploadDialogOpen(false);\n\t\tbridgedRef.current.clear();\n\t}\n\n\t// Fallback: zag presence skips onExitComplete when a reopen interrupts the\n\t// exit animation (fires only on the mounted→unmounted transition, not on\n\t// unmountSuspended→mounted) — reset again on open so a fast close-then-\n\t// reopen can't reopen with stale filters/selection/upload-dialog state.\n\t// Declared BEFORE the upload auto-select effect below: both run on the\n\t// same open-flip commit, and effects run in declaration order. This one\n\t// must go first — verified empirically, not just by inspection, because\n\t// the interaction is subtler than plain effect order: `bridgedRef` is a\n\t// ref (mutations are visible immediately to code in the same flush), but\n\t// `selection.isSelected` is a closure over the PRE-reset render, so\n\t// whichever effect runs second still sees the OLD selection value in that\n\t// same commit. What actually resolves it fresh is the cascade this reset\n\t// triggers: `selection.clear()` changes `usePickerSelection`'s `items`\n\t// state, which gives `isSelected` a new identity, which re-fires the\n\t// auto-select effect (it's in that effect's own deps) on the FOLLOWING\n\t// render — now with both `bridgedRef` and `selection.isSelected`\n\t// reflecting the real post-reset state. Swapping the order the other way\n\t// (auto-select first) was verified BY TEST to leave a stale bridge\n\t// re-selected after reopen instead of cleared — see the picker test file.\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: reset only on open→true\n\tuseEffect(() => {\n\t\tif (!open) return;\n\t\tresetEphemeralState();\n\t}, [open]);\n\n\t// Auto-select assets that finish uploading while the picker is open.\n\tuseEffect(() => {\n\t\tif (!open) return;\n\t\tconst byId = new Map(items.map((a) => [a.id, a]));\n\t\tfor (const f of uploadFiles) {\n\t\t\tif (\n\t\t\t\tf.status === \"done\" &&\n\t\t\t\tf.assetId &&\n\t\t\t\t!bridgedRef.current.has(f.assetId)\n\t\t\t) {\n\t\t\t\tconst a = byId.get(f.assetId);\n\t\t\t\tif (a) {\n\t\t\t\t\t// Process each finalized upload once. Select it unless the user\n\t\t\t\t\t// already has it selected (don't deselect a manual pick).\n\t\t\t\t\tbridgedRef.current.add(f.assetId);\n\t\t\t\t\tif (!selection.isSelected(a.id)) {\n\t\t\t\t\t\tselection.toggle(a);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}, [open, items, uploadFiles, selection.toggle, selection.isSelected]);\n\n\tfunction handleConfirm() {\n\t\tif (selection.items.length === 0) return;\n\t\tonSelect(\n\t\t\tmode === \"single\"\n\t\t\t\t? { mode: \"single\", asset: selection.items[0] }\n\t\t\t\t: { mode: \"multi\", assets: selection.items },\n\t\t);\n\t\tonOpenChange(false);\n\t}\n\n\tconst count = selection.items.length;\n\tconst confirmLabel =\n\t\tinsertLabel ??\n\t\t(mode === \"multi\" && count > 0 ? `Insert ${count}` : \"Insert\");\n\n\t// Do NOT `return null` when closed: unmounting the open dialog machine\n\t// under StrictMode orphans its scroll-lock/aria-hidden cleanup and wedges\n\t// the whole app (#66). Keep Modal mounted; lazyMount/unmountOnExit keep\n\t// the fresh-content-per-open semantics.\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tonExitComplete={resetEphemeralState}\n\t\t\tonClose={() => onOpenChange(false)}\n\t\t\t// Widest typed Modal size — the picker needs room for the folder rail\n\t\t\t// + multi-column grid. (anker's recipe-only \"7xl\" isn't in the type union.)\n\t\t\tsize=\"cover\"\n\t\t\theader={\n\t\t\t\theaderLabel ?? (mode === \"single\" ? \"Select an asset\" : \"Select assets\")\n\t\t\t}\n\t\t\tfooter={\n\t\t\t\t<PickerFooter\n\t\t\t\t\tcount={count}\n\t\t\t\t\tconfirmLabel={confirmLabel}\n\t\t\t\t\tcancelLabel={cancelLabel ?? \"Cancel\"}\n\t\t\t\t\tonConfirm={handleConfirm}\n\t\t\t\t\tonCancel={() => onOpenChange(false)}\n\t\t\t\t>\n\t\t\t\t\t<HStack gap=\"1\" minW=\"0\">\n\t\t\t\t\t\t{selection.items.slice(0, 8).map((a) => {\n\t\t\t\t\t\t\tconst v = a.versions[a.versions.length - 1];\n\t\t\t\t\t\t\tconst isImage = getMimeCategory(a) === \"image\";\n\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t<Box\n\t\t\t\t\t\t\t\t\tkey={a.id}\n\t\t\t\t\t\t\t\t\tposition=\"relative\"\n\t\t\t\t\t\t\t\t\tw=\"30px\"\n\t\t\t\t\t\t\t\t\th=\"30px\"\n\t\t\t\t\t\t\t\t\tborderRadius=\"md\"\n\t\t\t\t\t\t\t\t\toverflow=\"hidden\"\n\t\t\t\t\t\t\t\t\tborderWidth=\"1px\"\n\t\t\t\t\t\t\t\t\tborderColor=\"border\"\n\t\t\t\t\t\t\t\t\tflexShrink={0}\n\t\t\t\t\t\t\t\t\ttitle={a.name}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isImage && v ? (\n\t\t\t\t\t\t\t\t\t\t<PickerStripThumb\n\t\t\t\t\t\t\t\t\t\t\tassetId={a.id}\n\t\t\t\t\t\t\t\t\t\t\tversionId={v.id}\n\t\t\t\t\t\t\t\t\t\t\tname={a.name}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<Flex\n\t\t\t\t\t\t\t\t\t\t\tw=\"full\"\n\t\t\t\t\t\t\t\t\t\t\th=\"full\"\n\t\t\t\t\t\t\t\t\t\t\talign=\"center\"\n\t\t\t\t\t\t\t\t\t\t\tjustify=\"center\"\n\t\t\t\t\t\t\t\t\t\t\tbg=\"bg.muted\"\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Text fontSize=\"2xs\" color=\"fg.muted\">\n\t\t\t\t\t\t\t\t\t\t\t\t{a.name.slice(0, 2)}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t</Flex>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t})}\n\t\t\t\t\t\t{count > 8 && (\n\t\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\" flexShrink={0}>\n\t\t\t\t\t\t\t\t+{count - 8} more\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</HStack>\n\t\t\t\t</PickerFooter>\n\t\t\t}\n\t\t>\n\t\t\t<Flex h=\"full\" minH=\"0\">\n\t\t\t\t<Box\n\t\t\t\t\tw=\"188px\"\n\t\t\t\t\tflexShrink={0}\n\t\t\t\t\tborderRightWidth=\"1px\"\n\t\t\t\t\tborderColor=\"border\"\n\t\t\t\t\tbg=\"bg.subtle\"\n\t\t\t\t\toverflowY=\"auto\"\n\t\t\t\t\tp=\"2\"\n\t\t\t\t>\n\t\t\t\t\t<FolderTree\n\t\t\t\t\t\tactiveFolderId={folderId}\n\t\t\t\t\t\tonFolderSelect={(id) => updateFilter(\"folderId\", id || undefined)}\n\t\t\t\t\t/>\n\t\t\t\t</Box>\n\t\t\t\t<Flex direction=\"column\" flex=\"1\" minW=\"0\">\n\t\t\t\t\t<Flex\n\t\t\t\t\t\tgap=\"3\"\n\t\t\t\t\t\talign=\"center\"\n\t\t\t\t\t\tpx=\"4\"\n\t\t\t\t\t\tpy=\"2\"\n\t\t\t\t\t\tborderBottomWidth=\"1px\"\n\t\t\t\t\t\tborderColor=\"border\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<SearchInput\n\t\t\t\t\t\t\tonSearch={(value) => updateFilter(\"search\", value || undefined)}\n\t\t\t\t\t\t\tdefaultValue={filters.search ?? \"\"}\n\t\t\t\t\t\t\tplaceholder={searchPlaceholder ?? \"Search assets...\"}\n\t\t\t\t\t\t\tmaxWidth=\"260px\"\n\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<HStack gap=\"1\">\n\t\t\t\t\t\t\t<Text fontSize=\"xs\" color=\"fg.muted\">\n\t\t\t\t\t\t\t\tStatus:\n\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t<NativeSelect\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tvalue={statusSlug}\n\t\t\t\t\t\t\t\tonChange={(e) =>\n\t\t\t\t\t\t\t\t\tupdateFilter(\"statusSlug\", e.target.value || undefined)\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<option value=\"\">All</option>\n\t\t\t\t\t\t\t\t{statusOptions.map((s) => (\n\t\t\t\t\t\t\t\t\t<option key={s.id} value={s.slug}>\n\t\t\t\t\t\t\t\t\t\t{s.name}\n\t\t\t\t\t\t\t\t\t</option>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</NativeSelect>\n\t\t\t\t\t\t</HStack>\n\t\t\t\t\t</Flex>\n\t\t\t\t\t{allowUpload && (\n\t\t\t\t\t\t<Box px=\"4\" py=\"2\" borderBottomWidth=\"1px\" borderColor=\"border\">\n\t\t\t\t\t\t\t<UploadDropZone onFilesSelected={handleFilesSelected} compact />\n\t\t\t\t\t\t</Box>\n\t\t\t\t\t)}\n\t\t\t\t\t<Box flex=\"1\" overflow=\"auto\" p=\"4\">\n\t\t\t\t\t\t{assetsQuery.isLoading ? (\n\t\t\t\t\t\t\t<Flex justify=\"center\" py=\"10\">\n\t\t\t\t\t\t\t\t<Spinner />\n\t\t\t\t\t\t\t</Flex>\n\t\t\t\t\t\t) : items.length === 0 ? (\n\t\t\t\t\t\t\t<EmptyState header={emptyLabel ?? \"No assets found\"} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Grid\n\t\t\t\t\t\t\t\ttemplateColumns=\"repeat(auto-fill, minmax(150px, 1fr))\"\n\t\t\t\t\t\t\t\tgap=\"3\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{items.map((a) => (\n\t\t\t\t\t\t\t\t\t<PickerAssetCard\n\t\t\t\t\t\t\t\t\t\tkey={a.id}\n\t\t\t\t\t\t\t\t\t\tasset={a}\n\t\t\t\t\t\t\t\t\t\tselected={selection.isSelected(a.id)}\n\t\t\t\t\t\t\t\t\t\tselectionVisible={count > 0}\n\t\t\t\t\t\t\t\t\t\tonToggle={selection.toggle}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t</Grid>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</Box>\n\t\t\t\t</Flex>\n\t\t\t</Flex>\n\t\t\t{allowUpload && (\n\t\t\t\t<UploadDialog\n\t\t\t\t\topen={uploadDialogOpen}\n\t\t\t\t\tonClose={() => setUploadDialogOpen(false)}\n\t\t\t\t\tfolderId={folderId || undefined}\n\t\t\t\t/>\n\t\t\t)}\n\t\t</Modal>\n\t);\n}\nAssetPicker.displayName = \"AssetPicker\";\n\n/** Footer thumbnail — fetches a preview URL for one selected image. */\nfunction PickerStripThumb({\n\tassetId,\n\tversionId,\n\tname,\n}: { assetId: string; versionId: string; name: string }) {\n\tconst { data } = usePreviewURL(assetId, versionId);\n\tif (!data) return <Box w=\"full\" h=\"full\" bg=\"bg.muted\" />;\n\treturn (\n\t\t<img\n\t\t\tsrc={data}\n\t\t\talt={name}\n\t\t\tstyle={{ width: \"100%\", height: \"100%\", objectFit: \"cover\" }}\n\t\t/>\n\t);\n}\nPickerStripThumb.displayName = \"PickerStripThumb\";\n","// collection-picker.tsx\nimport { Button, EmptyState, TextInput } from \"@knkcs/anker/atoms\";\nimport { Modal, SelectableCard } from \"@knkcs/anker/components\";\nimport { SearchInput } from \"@knkcs/anker/forms\";\nimport {\n\tBox,\n\tFlex,\n\tGrid,\n\tHStack,\n\tSpinner,\n\tText,\n\ttoaster,\n} from \"@knkcs/anker/primitives\";\nimport { FolderOpen } from \"lucide-react\";\nimport { useEffect, useState } from \"react\";\nimport { PickerFooter } from \"./components/picker/picker-footer\";\nimport { usePickerSelection } from \"./components/picker/use-picker-selection\";\nimport { RestrictedLockBadge } from \"./components/restricted\";\nimport { useCollections, useCreateCollection } from \"./hooks/use-collections\";\nimport { showRpcErrorToast } from \"./lib/rpc-errors\";\nimport type { CollectionInfo, CollectionSelection } from \"./types\";\n\nexport interface CollectionPickerProps {\n\topen: boolean;\n\tonOpenChange: (open: boolean) => void;\n\t/** @default \"single\" */\n\tmode?: \"single\" | \"multi\";\n\tonSelect: (selection: CollectionSelection) => void;\n\t/** Show the inline \"New collection\" affordance. @default false */\n\tallowCreate?: boolean;\n\theaderLabel?: string;\n\tsearchPlaceholder?: string;\n\tconfirmLabel?: string;\n\tcancelLabel?: string;\n\temptyLabel?: string;\n\tcreateLabel?: string;\n}\n\nexport function CollectionPicker(\n\tprops: CollectionPickerProps,\n): React.JSX.Element {\n\tconst { open, onOpenChange, onSelect, allowCreate } = props;\n\tconst mode = props.mode ?? \"single\";\n\n\tconst [search, setSearch] = useState(\"\");\n\tconst [newName, setNewName] = useState(\"\");\n\tconst selection = usePickerSelection<CollectionInfo>(mode);\n\n\tconst collectionsQuery = useCollections();\n\tconst createCollection = useCreateCollection();\n\tconst all = collectionsQuery.data ?? [];\n\tconst items = search\n\t\t? all.filter((c) => c.name.toLowerCase().includes(search.toLowerCase()))\n\t\t: all;\n\n\t// Ephemeral picker state (selection/search/inline-create name) is scrubbed\n\t// in the Modal's onExitComplete (not on `open` flipping false): the grid\n\t// stays visible through the exit animation, and an immediate reset would\n\t// visibly clear it mid-fade.\n\tfunction resetEphemeralState() {\n\t\tselection.clear();\n\t\tsetSearch(\"\");\n\t\tsetNewName(\"\");\n\t}\n\n\t// Fallback: zag presence skips onExitComplete when a reopen interrupts the\n\t// exit animation (fires only on the mounted→unmounted transition, not on\n\t// unmountSuspended→mounted) — reset again on open so a fast close-then-\n\t// reopen can't reopen with stale search/selection/newName.\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: reset only on open→true\n\tuseEffect(() => {\n\t\tif (!open) return;\n\t\tresetEphemeralState();\n\t}, [open]);\n\n\tfunction handleConfirm() {\n\t\tif (selection.items.length === 0) return;\n\t\tonSelect(\n\t\t\tmode === \"single\"\n\t\t\t\t? { mode: \"single\", collection: selection.items[0] }\n\t\t\t\t: { mode: \"multi\", collections: selection.items },\n\t\t);\n\t\tonOpenChange(false);\n\t}\n\n\tasync function handleCreate() {\n\t\tconst name = newName.trim();\n\t\tif (!name) return;\n\t\ttry {\n\t\t\tawait createCollection.mutateAsync({\n\t\t\t\tname,\n\t\t\t\tslug: name.toLowerCase().replace(/\\s+/g, \"-\"),\n\t\t\t\tdescription: \"\",\n\t\t\t\ttype: \"static\",\n\t\t\t\trules: \"\",\n\t\t\t});\n\t\t\tsetNewName(\"\");\n\t\t\ttoaster.success({ title: \"Collection created\" });\n\t\t} catch (err) {\n\t\t\tshowRpcErrorToast(err, \"Create failed\");\n\t\t}\n\t}\n\n\tconst count = selection.items.length;\n\tconst confirmLabel =\n\t\tprops.confirmLabel ?? (count > 0 ? `Select ${count}` : \"Select\");\n\n\t// Do NOT `return null` when closed: unmounting the open dialog machine\n\t// under StrictMode orphans its scroll-lock/aria-hidden cleanup and wedges\n\t// the whole app (#66). Keep Modal mounted; lazyMount/unmountOnExit keep\n\t// the fresh-content-per-open semantics.\n\treturn (\n\t\t<Modal\n\t\t\topen={open}\n\t\t\tlazyMount\n\t\t\tunmountOnExit\n\t\t\tonExitComplete={resetEphemeralState}\n\t\t\tonClose={() => onOpenChange(false)}\n\t\t\tsize=\"lg\"\n\t\t\theader={\n\t\t\t\tprops.headerLabel ??\n\t\t\t\t(mode === \"single\" ? \"Select a collection\" : \"Select collections\")\n\t\t\t}\n\t\t\tfooter={\n\t\t\t\t<PickerFooter\n\t\t\t\t\tcount={count}\n\t\t\t\t\tconfirmLabel={confirmLabel}\n\t\t\t\t\tcancelLabel={props.cancelLabel ?? \"Cancel\"}\n\t\t\t\t\tonConfirm={handleConfirm}\n\t\t\t\t\tonCancel={() => onOpenChange(false)}\n\t\t\t\t/>\n\t\t\t}\n\t\t>\n\t\t\t<Flex direction=\"column\" gap=\"3\" minH=\"280px\">\n\t\t\t\t<Flex gap=\"2\" align=\"center\">\n\t\t\t\t\t<SearchInput\n\t\t\t\t\t\tonSearch={setSearch}\n\t\t\t\t\t\tplaceholder={props.searchPlaceholder ?? \"Search collections...\"}\n\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\tmaxWidth=\"full\"\n\t\t\t\t\t/>\n\t\t\t\t\t{allowCreate && (\n\t\t\t\t\t\t<HStack gap=\"2\" flexShrink={0}>\n\t\t\t\t\t\t\t<Box w=\"160px\">\n\t\t\t\t\t\t\t\t<TextInput\n\t\t\t\t\t\t\t\t\tvalue={newName}\n\t\t\t\t\t\t\t\t\tonChange={(e) => setNewName(e.target.value)}\n\t\t\t\t\t\t\t\t\tplaceholder={props.createLabel ?? \"New collection name\"}\n\t\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t<Button\n\t\t\t\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\t\t\t\tvariant=\"outline\"\n\t\t\t\t\t\t\t\tonClick={handleCreate}\n\t\t\t\t\t\t\t\tloading={createCollection.isPending}\n\t\t\t\t\t\t\t\tdisabled={!newName.trim()}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tCreate\n\t\t\t\t\t\t\t</Button>\n\t\t\t\t\t\t</HStack>\n\t\t\t\t\t)}\n\t\t\t\t</Flex>\n\n\t\t\t\t{collectionsQuery.isLoading ? (\n\t\t\t\t\t<Flex justify=\"center\" py=\"10\">\n\t\t\t\t\t\t<Spinner />\n\t\t\t\t\t</Flex>\n\t\t\t\t) : items.length === 0 ? (\n\t\t\t\t\t<EmptyState header={props.emptyLabel ?? \"No collections\"} />\n\t\t\t\t) : (\n\t\t\t\t\t<Grid templateColumns=\"repeat(2, 1fr)\" gap=\"3\">\n\t\t\t\t\t\t{items.map((c) => (\n\t\t\t\t\t\t\t<SelectableCard\n\t\t\t\t\t\t\t\tkey={c.id}\n\t\t\t\t\t\t\t\tselected={selection.isSelected(c.id)}\n\t\t\t\t\t\t\t\tselectionVisible={count > 0}\n\t\t\t\t\t\t\t\tonSelect={() => selection.toggle(c)}\n\t\t\t\t\t\t\t\tonClick={() => selection.toggle(c)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<SelectableCard.Body>\n\t\t\t\t\t\t\t\t\t<HStack gap=\"2\" align=\"center\">\n\t\t\t\t\t\t\t\t\t\t<FolderOpen size={16} />\n\t\t\t\t\t\t\t\t\t\t<Box minW=\"0\">\n\t\t\t\t\t\t\t\t\t\t\t<HStack gap=\"1\" align=\"center\">\n\t\t\t\t\t\t\t\t\t\t\t\t<Text fontSize=\"sm\" fontWeight=\"medium\" truncate>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{c.name}\n\t\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t\t\t{c.restricted && <RestrictedLockBadge />}\n\t\t\t\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t\t\t\t\t<Text\n\t\t\t\t\t\t\t\t\t\t\t\tfontSize=\"xs\"\n\t\t\t\t\t\t\t\t\t\t\t\tcolor=\"fg.muted\"\n\t\t\t\t\t\t\t\t\t\t\t\ttextTransform=\"capitalize\"\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{c.type}\n\t\t\t\t\t\t\t\t\t\t\t</Text>\n\t\t\t\t\t\t\t\t\t\t</Box>\n\t\t\t\t\t\t\t\t\t</HStack>\n\t\t\t\t\t\t\t\t</SelectableCard.Body>\n\t\t\t\t\t\t\t</SelectableCard>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</Grid>\n\t\t\t\t)}\n\t\t\t</Flex>\n\t\t</Modal>\n\t);\n}\nCollectionPicker.displayName = \"CollectionPicker\";\n","/**\n * @knkcs/mediahub-ui — reusable mediahub asset-management surfaces.\n *\n * Transport-agnostic clients + provider + TanStack Query hooks + stores,\n * plus the UI surfaces themselves (<AssetLibrary>, <AssetPicker>,\n * <CollectionPicker>, <AssetDetail>, …). A host's own tests reach the\n * `./testing` subpath instead of this one — see `src/testing`.\n */\nexport const MEDIAHUB_UI_VERSION = \"0.1.0\";\n\nexport * from \"./types\";\nexport * from \"./lib/rpc-errors\";\nexport * from \"./clients\";\nexport * from \"./connect-clients\";\nexport * from \"./provider\";\nexport * from \"./statushub\";\nexport * from \"./hooks\";\nexport * from \"./stores\";\nexport * from \"./components\";\nexport * from \"./asset-library\";\nexport * from \"./asset-detail\";\nexport * from \"./asset-picker\";\nexport * from \"./collection-picker\";\n"],"names":["CODE_PERMISSION_DENIED","CODE_FAILED_PRECONDITION","CODE_UNAVAILABLE","LEAK_GUARD_DETAIL_TYPE","PERMISSION_DENIED_TITLE","PERMISSION_DENIED_BODY","LEAK_GUARD_TITLE","LEAK_GUARD_GENERIC","LEAK_GUARD_RULES","connectCode","err","code","isPermissionDenied","isRetryableUnavailable","isLeakGuardDetailType","type","asExposure","raw","r","str","v","violationFrom","exposures","findLeakGuardViolation","details","d","entry","describeRpcError","fallbackTitle","violation","rule","items","e","showRpcErrorToast","toaster","mapTs","t","COLLTYPE_TO_NUM","NUM_TO_COLLTYPE","mapVersion","parseAssetMetadata","parsed","mapAsset","a","mapFolder","f","mapCollection","c","mapTag","mapAssetType","mapAIConnection","mapAIProcess","p","o","mapAIProcessRun","createConnectAssetClient","workspaceId","res","id","params","patch","versionId","assetId","folderId","fromStatusSlug","toStatusSlug","createConnectFolderClient","parentId","name","restricted","call","createConnectCollectionClient","collectionId","assetIds","createConnectTagClient","tagId","createConnectAssetTypeClient","createConnectDirectoryClient","ids","u","m","GRANT_RESOURCE_TO_NUM","NUM_TO_GRANT_LEVEL","GRANT_LEVEL_TO_NUM","createConnectGrantClient","resourceType","resourceId","grants","g","level","userId","createConnectAuthzClient","createConnectDashboardClient","s","layoutJson","createConnectAIConnectionClient","createConnectAIProcessClient","assetTypeId","createConnectMediahubClients","gen","MediahubContext","createContext","EMPTY_LINKS","MediahubProvider","clients","links","children","value","useMemo","jsx","useMediahubContext","ctx","useContext","useMediahubClients","useWorkspaceId","useMediahubLinks","ASSET_STATUS_CATALOGUE","useAssetStatuses","useStatuses","useAssetStatus","slug","data","isLoading","uploadFileToSAS","url","file","contentType","onProgress","resolve","reject","xhr","useAddVersion","assets","qc","useQueryClient","progress","setProgress","useState","useMutation","comment","uploadUrl","_data","vars","useAssets","filters","useQuery","useAsset","useCreateAsset","useUpdateAsset","useDeleteAsset","useMoveAsset","useTransitionAssetStatus","useEnhanceAssetMetadata","usePreviewURL","useCanManage","authz","useFolders","opts","folders","useFolder","useCreateFolder","useUpdateFolder","useDeleteFolder","useMoveFolder","useSetFolderRestricted","useGrants","failureCount","error","useGrantAccess","_err","useRevokeAccess","useCollections","collections","useCollection","useCreateCollection","useUpdateCollection","useDeleteCollection","useAddAssetsToCollection","useSetCollectionRestricted","useRemoveAssetsFromCollection","useTags","tags","useCreateTag","useUpdateTag","useDeleteTag","useTagAssets","useUntagAssets","useAssetTypes","assetTypes","useAssetType","useCreateAssetType","useUpdateAssetType","useDeleteAssetType","useUsers","directory","sorted","useWorkspaceMembers","useWorkspaceStats","dashboard","useGetDashboardLayout","useSaveDashboardLayout","useAIConnections","aiConnection","useAIConnection","useCreateAIConnection","useUpdateAIConnection","useDeleteAIConnection","useAIProcesses","aiProcess","useAIProcess","useCreateAIProcess","useUpdateAIProcess","useDeleteAIProcess","isActive","runs","useAIProcessRuns","wasActive","useRef","query","q","seenAssetId","useEffect","active","useSelectionStore","create","set","get","state","i","targetId","orderedIds","lastClickedId","selectedIds","startIdx","endIdx","low","high","rangeIds","merged","usePreferencesStore","persist","mode","updateFile","files","clientId","useUploadStore","newFiles","entries","client","pending","described","message","AssetStatusBadge","status","StatusBadge","Text","getMimeCategory","asset","version","mime","TypeIcon","category","Image","Film","Music","FileText","AssetCard","onOpen","isSelected","anySelected","toggle","latestVersion","previewQuery","previewUrl","imgError","setImgError","jsxs","SelectableCard","Skeleton","AssetGrid","Grid","mimeType","AssetPreview","fileName","setError","Flex","Button","Download","Box","AssetStatusControl","statusSlug","transition","StatusTransitionControl","to","BulkActionBar","clearSelection","count","deleteAsset","confirm","useConfirmModal","tagAssets","addToCollection","tagsQuery","collectionsQuery","handleBulkDelete","n","failed","firstErr","handleBulkTag","handleBulkAddToCollection","AnkerBulkActionBar","Tag","tag","FolderOpen","col","Trash2","CollectionChipField","assignedCollectionIds","allCollections","removeFromCollection","assigned","unassigned","handleAdd","collection","handleRemove","ChipPicker","CollectionPanel","activeCollectionId","onSelectCollection","createCollection","handleCreate","InlineCreatableList","useAncestorChain","folder","parent","grandparent","chain","FolderBreadcrumbs","onNavigate","ancestors","BreadcrumbRoot","BreadcrumbList","BreadcrumbItem","BreadcrumbLink","BreadcrumbSeparator","item","BreadcrumbCurrentLink","MaybeLink","href","Link","LeakGuardRefusalDialog","refusal","open","onClose","closeLabel","resolveHint","Modal","HStack","_a","_b","maxFolderDepth","openCollectionIds","assetExposedByOpenCollection","folderChainRestricted","folderSubtreeExposed","openIds","frontier","depth","next","subjectId","subject","subjectName","ManageAccessDialog","props","onOpenChange","kind","pickedUserId","setPickedUserId","pickLevel","setPickLevel","rosterQuery","roster","denied","membersQuery","rosterUserIds","namesQuery","nameOf","scopeQuery","grantAccess","revokeAccess","mutating","granteeIds","candidates","names","sortedGrants","nm","b","handleGrant","handleLevelChange","handleRevoke","viewerLabel","editorLabel","renderBody","Spinner","Lock","Persona","Badge","NativeSelect","IconButton","X","currentParentId","rowDisabledReason","chainRestricted","DestinationRowButton","reason","selected","emphasized","onClick","Folder","DestinationRow","ancestorRestricted","expanded","setExpanded","childrenQuery","isSelf","onDeselect","Fragment","ChevronDown","ChevronRight","child","MoveDialog","onMoved","selectedId","setSelectedId","rootQuery","moveFolder","moveAsset","subjectFolderId","folderGuardQuery","guardActive","resetEphemeralState","handleConfirm","handleDeselect","useCallback","current","rootReason","moving","restrictedContainerWarning","unrestrictDisclosure","RestrictedLockBadge","size","ml","RestrictedWarningNotice","RestrictedFolderDialog","onCreated","setName","createFolder","trimmed","msg","TextInput","FolderTree","activeFolderId","onFolderSelect","rootFolders","treeKey","setTreeKey","isCreating","setIsCreating","newName","setNewName","renamingId","setRenamingId","renameValue","setRenameValue","moveSubject","setMoveSubject","moveOpen","setMoveOpen","accessSubject","setAccessSubject","accessOpen","setAccessOpen","restrictedParentId","setRestrictedParentId","menuNodeId","setMenuNodeId","toggleRefusal","setToggleRefusal","refusalOpen","setRefusalOpen","updateFolder","deleteFolder","setFolderRestricted","canManage","creatingRef","renamingRef","rootChildren","createTreeCollection","node","handleLoadChildren","handleDelete","folderName","k","handleRenameSubmit","handleToggleRestricted","restricting","fallback","MenuRoot","MenuTrigger","Ellipsis","MenuContent","MenuItem","TreeViewRoot","TreeViewTree","TreeViewNode","TreeViewBranchControl","TreeViewBranchIndicator","TreeViewBranchText","FolderPlus","InlineEditField","onSave","as","placeholder","disabled","setDisabled","handleSubmit","nextValue","InlineEdit","TagChipField","assignedTagIds","allTags","untagAssets","assignedTags","unassignedTags","TagPanel","activeTags","onToggleTag","createTag","formatFileSize","bytes","FileRow","showOverride","onToggleOverride","setAssetType","UploadDialog","setBatchAssetType","startUpload","clearPending","analyzeWithAi","setAnalyzeWithAi","batchType","setBatchType","overrides","setOverrides","pendingFiles","handleBatchTypeChange","toggleOverride","prev","canUpload","handleUpload","handleCancel","Checkbox","UploadDropZone","onFilesSelected","compact","AnkerUploadDropZone","mapStatus","UploadToastStack","storeFiles","visible","dismiss","AnkerUploadToastStack","buildAssetTypeNameMap","types","collectUpdatedByIds","BEHAVIOR_OPTIONS","VIEW_MODE_OPTIONS","NO_ACTIVE_TAGS","AssetLibrary","onAssetOpen","initialFilters","onFiltersChange","setFilters","uploadDialogOpen","setUploadDialogOpen","fileInputRef","behaviorFilter","updateFilter","key","searchText","setSearchText","searchPrimed","handleToggleTag","handleSelectCollection","setStatusSlug","setBehaviorFilter","addFiles","viewMode","setViewMode","handleFilesSelected","assetName","assetsQuery","statusOptions","listFailure","listFailureState","EmptyState","assetTypesQuery","typeNames","updatedByIds","userNames","setSelection","rowSelection","sel","handleRowSelectionChange","updater","filtersKey","columnHelper","createColumnHelper","listColumns","info","TruncatedTextCell","date","DateCell","ActionCell","rail","ContextRail","usePageRail","toolbar","Toolbar","SegmentedControl","IndexPageTemplate","Upload","SubNavLayout","DataTable","STRUCTURAL","composeFormValues","schema","plugins","assetRecord","defaults","getDefaultValues","values","acc","stored","decomposePatch","metadata","columns","versionColumnHelper","aiRunColorPalette","AssetDetailRail","currentVersionId","currentMimeType","currentFilename","currentFileSize","currentVersion","createdBy","createdByName","tagIds","collectionIds","addVersion","assetType","DescriptionList","Stack","run","AssetDetail","onBack","onDeleted","assetQuery","assetsClient","updateAsset","enhanceMetadata","assetTypeQuery","composedValues","builtInFieldTypes","zodSchema","specToZodSchema","form","useForm","zodResolver","handleSaveBody","handleBack","activeTab","setActiveTab","allUserIds","handleDownloadVersion","versionColumns","currentBadge","StatusBadgeCell","handleDownloadCurrent","handleEnhance","sortedVersions","DetailPageTemplate","ArrowLeft","Sparkles","Tabs","FieldKitProvider","FormProvider","SpecForm","ImageIcon","PickerAssetCard","selectionVisible","onToggle","PickerFooter","confirmLabel","cancelLabel","onConfirm","onCancel","usePickerSelection","setItems","exists","remove","clear","matchesAccept","accept","AssetPicker","onSelect","headerLabel","searchPlaceholder","insertLabel","emptyLabel","selection","allItems","allowUpload","uploadFiles","bridgedRef","byId","isImage","PickerStripThumb","SearchInput","CollectionPicker","allowCreate","search","setSearch","all","MEDIAHUB_UI_VERSION"],"mappings":"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"}
|