@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.
@@ -0,0 +1,1686 @@
1
+ import { default as default_2 } from 'react';
2
+ import { JSX } from 'react';
3
+ import { PersistOptions } from 'zustand/middleware';
4
+ import { QueryClient } from '@tanstack/react-query';
5
+ import { ReactNode } from 'react';
6
+ import { StatusInfo } from '@knkcs/statushub-ui';
7
+ import { StoreApi } from 'zustand';
8
+ import { UseBoundStore } from 'zustand';
9
+ import { UseMutateAsyncFunction } from '@tanstack/react-query';
10
+ import { UseMutateFunction } from '@tanstack/react-query';
11
+ import { UseMutationResult } from '@tanstack/react-query';
12
+ import { UseQueryResult } from '@tanstack/react-query';
13
+
14
+ export declare interface AddVersionVars {
15
+ assetId: string;
16
+ file: File;
17
+ comment?: string;
18
+ }
19
+
20
+ export declare interface AIConnectionClient {
21
+ list(workspaceId: string): Promise<AIConnectionInfo[]>;
22
+ get(id: string): Promise<AIConnectionInfo>;
23
+ create(params: {
24
+ workspaceId: string;
25
+ name: string;
26
+ provider: string;
27
+ endpoint: string;
28
+ deployment: string;
29
+ apiVersion: string;
30
+ baseUrl: string;
31
+ model: string;
32
+ apiKey: string;
33
+ description: string;
34
+ }): Promise<AIConnectionInfo>;
35
+ update(id: string, patch: {
36
+ name?: string;
37
+ endpoint?: string;
38
+ deployment?: string;
39
+ apiVersion?: string;
40
+ baseUrl?: string;
41
+ model?: string;
42
+ apiKey?: string;
43
+ description?: string;
44
+ active?: boolean;
45
+ }): Promise<AIConnectionInfo>;
46
+ delete(id: string): Promise<void>;
47
+ }
48
+
49
+ export declare interface AIConnectionInfo {
50
+ id: string;
51
+ workspaceId: string;
52
+ name: string;
53
+ provider: string;
54
+ endpoint: string;
55
+ deployment: string;
56
+ apiVersion: string;
57
+ baseUrl: string;
58
+ model: string;
59
+ description: string;
60
+ active: boolean;
61
+ hasApiKey: boolean;
62
+ }
63
+
64
+ export declare interface AIProcessClient {
65
+ list(assetTypeId: string): Promise<AIProcessInfo[]>;
66
+ get(id: string): Promise<AIProcessInfo>;
67
+ create(params: {
68
+ assetTypeId: string;
69
+ connectionId: string;
70
+ name: string;
71
+ prompt: string;
72
+ outputs: {
73
+ key: string;
74
+ target: string;
75
+ metadataAccessor: string;
76
+ }[];
77
+ position: number;
78
+ workspaceId: string;
79
+ }): Promise<AIProcessInfo>;
80
+ update(id: string, patch: {
81
+ connectionId?: string;
82
+ name?: string;
83
+ prompt?: string;
84
+ outputs?: {
85
+ key: string;
86
+ target: string;
87
+ metadataAccessor: string;
88
+ }[];
89
+ position?: number;
90
+ active?: boolean;
91
+ }): Promise<AIProcessInfo>;
92
+ delete(id: string): Promise<void>;
93
+ }
94
+
95
+ export declare interface AIProcessInfo {
96
+ id: string;
97
+ workspaceId: string;
98
+ assetTypeId: string;
99
+ connectionId: string;
100
+ name: string;
101
+ prompt: string;
102
+ outputs: {
103
+ key: string;
104
+ target: string;
105
+ metadataAccessor: string;
106
+ }[];
107
+ position: number;
108
+ active: boolean;
109
+ }
110
+
111
+ export declare interface AIProcessRunInfo {
112
+ id: string;
113
+ aiProcessId: string;
114
+ processName: string;
115
+ status: "queued" | "running" | "succeeded" | "failed" | string;
116
+ error: string;
117
+ startedAt?: Date;
118
+ finishedAt?: Date;
119
+ }
120
+
121
+ /**
122
+ * The catalogue an asset's status belongs to: mediahub's `asset` entity type,
123
+ * as registered with statushub at startup (integration standard §1).
124
+ *
125
+ * Every statushub-ui component and hook this package uses is pinned to it, so
126
+ * a host never names it and can never point a mediahub surface at another
127
+ * service's statuses. Exported because a host's settings screen embeds
128
+ * `StatusSettings` pinned to the same catalogue (§10) — `<StatusSettings
129
+ * {...ASSET_STATUS_CATALOGUE} />` — and one constant is how the two cannot
130
+ * come to disagree.
131
+ */
132
+ export declare const ASSET_STATUS_CATALOGUE: {
133
+ readonly serviceSlug: "mediahub";
134
+ readonly entityTypeSlug: "asset";
135
+ };
136
+
137
+ export declare interface AssetClient {
138
+ list(workspaceId: string, filters: AssetFilters): Promise<Page<AssetInfo>>;
139
+ get(id: string): Promise<AssetInfo>;
140
+ create(workspaceId: string, params: CreateAssetParams): Promise<AssetInfo>;
141
+ update(id: string, patch: {
142
+ name?: string;
143
+ description?: string;
144
+ metadata?: Record<string, unknown>;
145
+ }): Promise<AssetInfo>;
146
+ delete(id: string): Promise<void>;
147
+ getUploadUrl(params: GetUploadUrlParams): Promise<UploadTarget>;
148
+ finalizeUpload(versionId: string): Promise<AssetInfo>;
149
+ getDownloadUrl(assetId: string, versionId: string): Promise<string>;
150
+ move(id: string, folderId: string): Promise<AssetInfo>;
151
+ /**
152
+ * Changes an asset's status (statushub's integration standard §3).
153
+ * `fromStatusSlug` is the slug the caller last saw: the server makes the
154
+ * change against it, so a stale screen is refused as a conflict instead of
155
+ * overwriting whatever happened in between. Pass `""` when there is
156
+ * nothing to compare against.
157
+ */
158
+ transitionStatus(id: string, fromStatusSlug: string, toStatusSlug: string): Promise<AssetInfo>;
159
+ enhanceMetadata(id: string): Promise<AssetInfo>;
160
+ listProcessRuns(assetId: string): Promise<AIProcessRunInfo[]>;
161
+ }
162
+
163
+ export declare function AssetDetail({ assetId, onBack, onDeleted, }: AssetDetailProps): default_2.JSX.Element;
164
+
165
+ export declare namespace AssetDetail {
166
+ var displayName: string;
167
+ }
168
+
169
+ export declare interface AssetDetailProps {
170
+ assetId: string;
171
+ /** Navigate back to the asset list. */
172
+ onBack?: () => void;
173
+ /** Called after a successful delete. */
174
+ onDeleted?: () => void;
175
+ }
176
+
177
+ export declare function AssetDetailRail({ assetId, assetName, currentVersionId, currentMimeType, currentFilename, currentFileSize, currentVersion, assetTypeId, createdBy, createdByName, folderId, tagIds, collectionIds, statusSlug, }: AssetDetailRailProps): default_2.JSX.Element;
178
+
179
+ export declare namespace AssetDetailRail {
180
+ var displayName: string;
181
+ }
182
+
183
+ declare interface AssetDetailRailProps {
184
+ assetId: string;
185
+ assetName: string;
186
+ currentVersionId: string | undefined;
187
+ currentMimeType: string | undefined;
188
+ currentFilename: string | undefined;
189
+ currentFileSize: number | undefined;
190
+ currentVersion: number;
191
+ assetTypeId: string;
192
+ createdBy: string;
193
+ createdByName?: string;
194
+ folderId: string;
195
+ tagIds: string[];
196
+ collectionIds: string[];
197
+ statusSlug: string;
198
+ }
199
+
200
+ export declare interface AssetFilters {
201
+ folderId?: string;
202
+ assetTypeId?: string;
203
+ statusSlug?: string;
204
+ behavior?: AssetStatusBehavior;
205
+ search?: string;
206
+ tagIds?: string[];
207
+ collectionIds?: string[];
208
+ }
209
+
210
+ export declare const AssetGrid: React.FC<AssetGridProps>;
211
+
212
+ export declare interface AssetGridProps {
213
+ assets: AssetInfo[];
214
+ onOpen: (asset: AssetInfo) => void;
215
+ }
216
+
217
+ export declare interface AssetInfo {
218
+ id: string;
219
+ workspaceId: string;
220
+ name: string;
221
+ description: string;
222
+ statusSlug: string;
223
+ currentVersion: number;
224
+ metadata: Record<string, unknown>;
225
+ assetTypeId: string;
226
+ folderId: string;
227
+ createdBy: string;
228
+ updatedBy: string;
229
+ createdAt?: Date;
230
+ updatedAt?: Date;
231
+ versions: AssetVersionInfo[];
232
+ tagIds: string[];
233
+ collectionIds: string[];
234
+ analyzeWithAi: boolean;
235
+ }
236
+
237
+ export declare function AssetLibrary(props: AssetLibraryProps): React.JSX.Element;
238
+
239
+ export declare namespace AssetLibrary {
240
+ var displayName: string;
241
+ }
242
+
243
+ export declare interface AssetLibraryProps {
244
+ onAssetOpen?: (asset: AssetInfo) => void;
245
+ initialFilters?: AssetFilters;
246
+ onFiltersChange?: (filters: AssetFilters) => void;
247
+ }
248
+
249
+ export declare function AssetPicker(props: AssetPickerProps): React.JSX.Element;
250
+
251
+ export declare namespace AssetPicker {
252
+ var displayName: string;
253
+ }
254
+
255
+ export declare interface AssetPickerProps {
256
+ open: boolean;
257
+ onOpenChange: (open: boolean) => void;
258
+ /** @default "single" */
259
+ mode?: "single" | "multi";
260
+ onSelect: (selection: AssetSelection) => void;
261
+ /** Enable upload-then-select (wired in Task 5). */
262
+ allowUpload?: boolean;
263
+ /** Client-side MIME filter, e.g. ["image/*"] or ["application/pdf"]. */
264
+ accept?: string[];
265
+ /** Initial/locked filters (e.g. a fixed assetTypeId). */
266
+ initialFilters?: AssetFilters;
267
+ headerLabel?: string;
268
+ searchPlaceholder?: string;
269
+ insertLabel?: string;
270
+ cancelLabel?: string;
271
+ emptyLabel?: string;
272
+ }
273
+
274
+ export declare const AssetPreview: React.FC<AssetPreviewProps>;
275
+
276
+ declare interface AssetPreviewProps {
277
+ assetId: string;
278
+ versionId: string;
279
+ mimeType: string;
280
+ fileName: string;
281
+ }
282
+
283
+ /** Result of confirming an AssetPicker selection. */
284
+ export declare type AssetSelection = {
285
+ mode: "single";
286
+ asset: AssetInfo;
287
+ } | {
288
+ mode: "multi";
289
+ assets: AssetInfo[];
290
+ };
291
+
292
+ /**
293
+ * An asset's status, named and coloured from statushub's catalogue.
294
+ *
295
+ * This is the one place mediahub turns a stored slug into something readable
296
+ * (statushub's integration standard §10: the consumer renders statuses itself,
297
+ * with statushub-ui's components — no host slot). A slug the catalogue does
298
+ * not carry — an **unknown status**, deleted or never answered for (§5) —
299
+ * prints as itself, because the asset has a status either way and saying
300
+ * nothing would read as having none.
301
+ */
302
+ export declare function AssetStatusBadge({ slug }: AssetStatusBadgeProps): JSX.Element | null;
303
+
304
+ export declare namespace AssetStatusBadge {
305
+ var displayName: string;
306
+ }
307
+
308
+ export declare interface AssetStatusBadgeProps {
309
+ /** The asset's stored status slug. Empty renders nothing. */
310
+ slug: string;
311
+ }
312
+
313
+ export declare type AssetStatusBehavior = "unspecified" | "active" | "archived" | "inactive" | "deleted";
314
+
315
+ /**
316
+ * An asset's status, and the moves statushub allows away from it.
317
+ *
318
+ * statushub-ui offers the moves; mediahub's own `TransitionAssetStatus` makes
319
+ * them (integration standard §3) — the browser never writes to statushub. The
320
+ * slug being shown travels with the change, so a screen drawn before somebody
321
+ * else moved this asset on is refused as a conflict instead of overwriting
322
+ * them.
323
+ *
324
+ * Guarded moves are shown (`canRevert`) and statushub decides them: its answer
325
+ * is per-caller, and mediahub keeps no who-may-revert rule of its own. The
326
+ * control swallows what `onTransition` throws — error handling is the
327
+ * consumer's — so the refusal is toasted here.
328
+ */
329
+ export declare function AssetStatusControl({ assetId, statusSlug, }: AssetStatusControlProps): JSX.Element;
330
+
331
+ export declare namespace AssetStatusControl {
332
+ var displayName: string;
333
+ }
334
+
335
+ export declare interface AssetStatusControlProps {
336
+ assetId: string;
337
+ /** The asset's stored status slug — what the viewer is looking at. */
338
+ statusSlug: string;
339
+ }
340
+
341
+ export declare interface AssetSummaryInfo {
342
+ id: string;
343
+ name: string;
344
+ assetTypeName: string;
345
+ statusName: string;
346
+ statusColor: string;
347
+ createdAt?: Date;
348
+ }
349
+
350
+ export declare interface AssetTypeClient {
351
+ list(workspaceId: string): Promise<AssetTypeInfo[]>;
352
+ get(id: string): Promise<AssetTypeInfo>;
353
+ create(params: {
354
+ workspaceId: string;
355
+ name: string;
356
+ slug: string;
357
+ description: string;
358
+ allowedMimeTypes: string[];
359
+ metadataSchema: string;
360
+ }): Promise<AssetTypeInfo>;
361
+ update(id: string, patch: {
362
+ name?: string;
363
+ description?: string;
364
+ allowedMimeTypes?: string[];
365
+ metadataSchema?: string;
366
+ active?: boolean;
367
+ }): Promise<AssetTypeInfo>;
368
+ delete(id: string): Promise<void>;
369
+ }
370
+
371
+ export declare interface AssetTypeInfo {
372
+ id: string;
373
+ workspaceId: string;
374
+ name: string;
375
+ slug: string;
376
+ description: string;
377
+ allowedMimeTypes: string[];
378
+ metadataSchema: string;
379
+ active: boolean;
380
+ }
381
+
382
+ export declare interface AssetVersionInfo {
383
+ id: string;
384
+ versionNumber: number;
385
+ originalFilename: string;
386
+ storageKey: string;
387
+ fileSize: number;
388
+ mimeType: string;
389
+ createdBy: string;
390
+ comment: string;
391
+ createdAt?: Date;
392
+ }
393
+
394
+ export declare interface AuthzClient {
395
+ /** Whether the current user holds toggle/grant authority — Owner of the
396
+ * resource or admin of its workspace (mediahub ADR-0001) — over the
397
+ * resource. A denial answers false; other failures reject so callers can
398
+ * fail closed without hiding real errors. */
399
+ canManage(resourceType: GrantResourceType, resourceId: string): Promise<boolean>;
400
+ }
401
+
402
+ export declare const BulkActionBar: React.FC<BulkActionBarProps>;
403
+
404
+ declare interface BulkActionBarProps {
405
+ }
406
+
407
+ export declare const CollectionChipField: React.FC<CollectionChipFieldProps>;
408
+
409
+ declare interface CollectionChipFieldProps {
410
+ assetId: string;
411
+ assignedCollectionIds: string[];
412
+ }
413
+
414
+ export declare interface CollectionClient {
415
+ list(workspaceId: string): Promise<CollectionInfo[]>;
416
+ get(id: string): Promise<CollectionInfo>;
417
+ create(params: {
418
+ workspaceId: string;
419
+ name: string;
420
+ slug: string;
421
+ description: string;
422
+ type: CollectionType;
423
+ rules: string;
424
+ /** Create as Restricted (creator-only until Grants are issued). @default false */
425
+ restricted?: boolean;
426
+ }): Promise<CollectionInfo>;
427
+ update(id: string, patch: {
428
+ name?: string;
429
+ description?: string;
430
+ rules?: string;
431
+ }): Promise<CollectionInfo>;
432
+ delete(id: string): Promise<void>;
433
+ addAssets(collectionId: string, assetIds: string[]): Promise<void>;
434
+ removeAssets(collectionId: string, assetIds: string[]): Promise<void>;
435
+ /** Toggle the Restricted flag (guardian#53). The server refuses with a
436
+ * leak-guard conflict when the toggle would create a leak state. */
437
+ setRestricted(id: string, restricted: boolean): Promise<CollectionInfo>;
438
+ }
439
+
440
+ export declare interface CollectionInfo {
441
+ id: string;
442
+ workspaceId: string;
443
+ name: string;
444
+ slug: string;
445
+ description: string;
446
+ type: CollectionType;
447
+ rules: string;
448
+ /** Restricted collections sever Derived Access: only Grants admit anyone. */
449
+ restricted: boolean;
450
+ }
451
+
452
+ export declare const CollectionPanel: React.FC<CollectionPanelProps>;
453
+
454
+ declare interface CollectionPanelProps {
455
+ activeCollectionId: string;
456
+ onSelectCollection: (collectionId: string) => void;
457
+ }
458
+
459
+ export declare function CollectionPicker(props: CollectionPickerProps): React.JSX.Element;
460
+
461
+ export declare namespace CollectionPicker {
462
+ var displayName: string;
463
+ }
464
+
465
+ export declare interface CollectionPickerProps {
466
+ open: boolean;
467
+ onOpenChange: (open: boolean) => void;
468
+ /** @default "single" */
469
+ mode?: "single" | "multi";
470
+ onSelect: (selection: CollectionSelection) => void;
471
+ /** Show the inline "New collection" affordance. @default false */
472
+ allowCreate?: boolean;
473
+ headerLabel?: string;
474
+ searchPlaceholder?: string;
475
+ confirmLabel?: string;
476
+ cancelLabel?: string;
477
+ emptyLabel?: string;
478
+ createLabel?: string;
479
+ }
480
+
481
+ /** Result of confirming a CollectionPicker selection. */
482
+ export declare type CollectionSelection = {
483
+ mode: "single";
484
+ collection: CollectionInfo;
485
+ } | {
486
+ mode: "multi";
487
+ collections: CollectionInfo[];
488
+ };
489
+
490
+ export declare type CollectionType = "unspecified" | "static" | "smart";
491
+
492
+ export declare interface ConnectAIConnectionServiceClient {
493
+ listAIConnections(req: any): Promise<{
494
+ connections: ProtoResponse[];
495
+ }>;
496
+ getAIConnection(req: any): Promise<ProtoResponse>;
497
+ createAIConnection(req: any): Promise<ProtoResponse>;
498
+ updateAIConnection(req: any): Promise<ProtoResponse>;
499
+ deleteAIConnection(req: {
500
+ id: string;
501
+ }): Promise<unknown>;
502
+ }
503
+
504
+ export declare interface ConnectAIProcessServiceClient {
505
+ listAIProcesses(req: any): Promise<{
506
+ processes: ProtoResponse[];
507
+ }>;
508
+ getAIProcess(req: any): Promise<ProtoResponse>;
509
+ createAIProcess(req: any): Promise<ProtoResponse>;
510
+ updateAIProcess(req: any): Promise<ProtoResponse>;
511
+ deleteAIProcess(req: {
512
+ id: string;
513
+ }): Promise<unknown>;
514
+ }
515
+
516
+ export declare interface ConnectAssetServiceClient {
517
+ listAssets(req: any): Promise<{
518
+ assets: ProtoResponse[];
519
+ pagination?: {
520
+ total: number;
521
+ page: number;
522
+ pageSize: number;
523
+ totalPages: number;
524
+ };
525
+ }>;
526
+ getAsset(req: {
527
+ id: string;
528
+ }): Promise<ProtoResponse>;
529
+ createAsset(req: any): Promise<ProtoResponse>;
530
+ updateAsset(req: any): Promise<ProtoResponse>;
531
+ deleteAsset(req: {
532
+ id: string;
533
+ }): Promise<unknown>;
534
+ getUploadURL(req: any): Promise<{
535
+ uploadUrl: string;
536
+ versionId: string;
537
+ }>;
538
+ finalizeUpload(req: {
539
+ versionId: string;
540
+ }): Promise<ProtoResponse>;
541
+ getDownloadURL(req: {
542
+ assetId: string;
543
+ versionId: string;
544
+ }): Promise<{
545
+ downloadUrl: string;
546
+ }>;
547
+ moveAsset(req: {
548
+ id: string;
549
+ folderId: string;
550
+ }): Promise<ProtoResponse>;
551
+ transitionAssetStatus(req: {
552
+ id: string;
553
+ fromStatusSlug: string;
554
+ toStatusSlug: string;
555
+ }): Promise<ProtoResponse>;
556
+ enhanceAssetMetadata(req: {
557
+ assetId: string;
558
+ }): Promise<ProtoResponse>;
559
+ listAIProcessRuns(req: {
560
+ assetId: string;
561
+ }): Promise<{
562
+ runs: ProtoResponse[];
563
+ }>;
564
+ }
565
+
566
+ export declare interface ConnectAssetTypeServiceClient {
567
+ listAssetTypes(req: {
568
+ workspaceId: string;
569
+ }): Promise<{
570
+ assetTypes: ProtoResponse[];
571
+ }>;
572
+ getAssetType(req: {
573
+ id: string;
574
+ }): Promise<ProtoResponse>;
575
+ createAssetType(req: any): Promise<ProtoResponse>;
576
+ updateAssetType(req: any): Promise<ProtoResponse>;
577
+ deleteAssetType(req: {
578
+ id: string;
579
+ }): Promise<unknown>;
580
+ }
581
+
582
+ export declare interface ConnectCollectionServiceClient {
583
+ listCollections(req: {
584
+ workspaceId: string;
585
+ }): Promise<{
586
+ collections: ProtoResponse[];
587
+ }>;
588
+ getCollection(req: {
589
+ id: string;
590
+ }): Promise<ProtoResponse>;
591
+ createCollection(req: any): Promise<ProtoResponse>;
592
+ updateCollection(req: any): Promise<ProtoResponse>;
593
+ deleteCollection(req: {
594
+ id: string;
595
+ }): Promise<unknown>;
596
+ addAssets(req: {
597
+ collectionId: string;
598
+ assetIds: string[];
599
+ }): Promise<unknown>;
600
+ removeAssets(req: {
601
+ collectionId: string;
602
+ assetIds: string[];
603
+ }): Promise<unknown>;
604
+ /** Restricted toggles — land with guardian#53; optional so the package
605
+ * keeps accepting pre-#53 generated clients. */
606
+ restrictCollection?(req: {
607
+ id: string;
608
+ }): Promise<ProtoResponse>;
609
+ unrestrictCollection?(req: {
610
+ id: string;
611
+ }): Promise<ProtoResponse>;
612
+ }
613
+
614
+ export declare interface ConnectDashboardServiceClient {
615
+ getWorkspaceStats(req: {
616
+ workspaceId: string;
617
+ }): Promise<{
618
+ totalAssets: bigint;
619
+ totalStorageBytes: bigint;
620
+ statusCounts: Array<{
621
+ statusSlug: string;
622
+ name: string;
623
+ color: string;
624
+ behavior: string;
625
+ count: bigint;
626
+ }>;
627
+ recentUploads: Array<{
628
+ id: string;
629
+ name: string;
630
+ assetTypeName: string;
631
+ statusName: string;
632
+ statusColor: string;
633
+ createdAt?: {
634
+ seconds: bigint;
635
+ nanos: number;
636
+ } | undefined;
637
+ }>;
638
+ }>;
639
+ getDashboardLayout(req: {
640
+ workspaceId: string;
641
+ }): Promise<{
642
+ layoutJson: string;
643
+ }>;
644
+ saveDashboardLayout(req: {
645
+ workspaceId: string;
646
+ layoutJson: string;
647
+ }): Promise<unknown>;
648
+ }
649
+
650
+ export declare interface ConnectFolderServiceClient {
651
+ listFolders(req: {
652
+ workspaceId: string;
653
+ parentId: string;
654
+ }): Promise<{
655
+ folders: ProtoResponse[];
656
+ }>;
657
+ getFolder(req: {
658
+ id: string;
659
+ }): Promise<ProtoResponse>;
660
+ createFolder(req: any): Promise<ProtoResponse>;
661
+ updateFolder(req: {
662
+ id: string;
663
+ name: string;
664
+ }): Promise<ProtoResponse>;
665
+ deleteFolder(req: {
666
+ id: string;
667
+ }): Promise<unknown>;
668
+ moveFolder(req: {
669
+ id: string;
670
+ parentId: string;
671
+ }): Promise<ProtoResponse>;
672
+ /** Restricted toggles — land with guardian#53; optional so the package
673
+ * keeps accepting pre-#53 generated clients. */
674
+ restrictFolder?(req: {
675
+ id: string;
676
+ }): Promise<ProtoResponse>;
677
+ unrestrictFolder?(req: {
678
+ id: string;
679
+ }): Promise<ProtoResponse>;
680
+ }
681
+
682
+ export declare interface ConnectGrantServiceClient {
683
+ grantAccess(req: {
684
+ resourceType: number;
685
+ resourceId: string;
686
+ userId: string;
687
+ level: number;
688
+ }): Promise<unknown>;
689
+ revokeAccess(req: {
690
+ resourceType: number;
691
+ resourceId: string;
692
+ userId: string;
693
+ }): Promise<unknown>;
694
+ listGrants(req: {
695
+ resourceType: number;
696
+ resourceId: string;
697
+ }): Promise<{
698
+ ownerUserId: string;
699
+ grants: any[];
700
+ }>;
701
+ }
702
+
703
+ export declare interface ConnectTagServiceClient {
704
+ listTags(req: {
705
+ workspaceId: string;
706
+ }): Promise<{
707
+ tags: ProtoResponse[];
708
+ }>;
709
+ createTag(req: any): Promise<ProtoResponse>;
710
+ updateTag(req: {
711
+ id: string;
712
+ name: string;
713
+ }): Promise<ProtoResponse>;
714
+ deleteTag(req: {
715
+ id: string;
716
+ }): Promise<unknown>;
717
+ tagAssets(req: {
718
+ tagId: string;
719
+ assetIds: string[];
720
+ }): Promise<unknown>;
721
+ untagAssets(req: {
722
+ tagId: string;
723
+ assetIds: string[];
724
+ }): Promise<unknown>;
725
+ }
726
+
727
+ export declare interface ConnectUserServiceClient {
728
+ resolveUsers(req: {
729
+ userIds: string[];
730
+ }): Promise<{
731
+ users: any[];
732
+ }>;
733
+ listWorkspaceMembers(req: {
734
+ workspaceId: string;
735
+ }): Promise<{
736
+ members: any[];
737
+ }>;
738
+ }
739
+
740
+ export declare interface CreateAssetParams {
741
+ name: string;
742
+ description?: string;
743
+ assetTypeId: string;
744
+ folderId?: string;
745
+ metadata?: Record<string, unknown>;
746
+ analyzeWithAi?: boolean;
747
+ }
748
+
749
+ export declare function createConnectAIConnectionClient(c: ConnectAIConnectionServiceClient): AIConnectionClient;
750
+
751
+ export declare function createConnectAIProcessClient(c: ConnectAIProcessServiceClient): AIProcessClient;
752
+
753
+ export declare function createConnectAssetClient(c: ConnectAssetServiceClient): AssetClient;
754
+
755
+ export declare function createConnectAssetTypeClient(c: ConnectAssetTypeServiceClient): AssetTypeClient;
756
+
757
+ /**
758
+ * Authority probe (guardian#55): GrantService gates every call — ListGrants
759
+ * included — on exactly the toggle/grant authority (Owner of the resource or
760
+ * admin of its workspace, mediahub ADR-0001), so a roster read doubles as the
761
+ * check. A denial means "not an authority"; other failures reject unchanged.
762
+ */
763
+ export declare function createConnectAuthzClient(c: ConnectGrantServiceClient): AuthzClient;
764
+
765
+ export declare function createConnectCollectionClient(c: ConnectCollectionServiceClient): CollectionClient;
766
+
767
+ export declare function createConnectDashboardClient(c: ConnectDashboardServiceClient): DashboardClient;
768
+
769
+ export declare function createConnectDirectoryClient(c: ConnectUserServiceClient): DirectoryClient;
770
+
771
+ export declare function createConnectFolderClient(c: ConnectFolderServiceClient): FolderClient;
772
+
773
+ export declare function createConnectGrantClient(c: ConnectGrantServiceClient): GrantClient;
774
+
775
+ export declare function createConnectMediahubClients(gen: {
776
+ asset: ConnectAssetServiceClient;
777
+ folder: ConnectFolderServiceClient;
778
+ collection: ConnectCollectionServiceClient;
779
+ tag: ConnectTagServiceClient;
780
+ assetType: ConnectAssetTypeServiceClient;
781
+ user: ConnectUserServiceClient;
782
+ grant: ConnectGrantServiceClient;
783
+ dashboard: ConnectDashboardServiceClient;
784
+ aiConnection: ConnectAIConnectionServiceClient;
785
+ aiProcess: ConnectAIProcessServiceClient;
786
+ }): MediahubClients;
787
+
788
+ export declare function createConnectTagClient(c: ConnectTagServiceClient): TagClient;
789
+
790
+ export declare interface DashboardClient {
791
+ getWorkspaceStats(workspaceId: string): Promise<WorkspaceStats>;
792
+ getDashboardLayout(workspaceId: string): Promise<string>;
793
+ saveDashboardLayout(workspaceId: string, layoutJson: string): Promise<void>;
794
+ }
795
+
796
+ /**
797
+ * Describes an RPC failure for the user. Permission denials and leak-guard
798
+ * conflicts get mapped copy (never the raw server string); anything else
799
+ * keeps the server's message under the caller's title, matching the previous
800
+ * toast behavior.
801
+ */
802
+ export declare function describeRpcError(err: unknown, fallbackTitle: string): RpcErrorDescription;
803
+
804
+ export declare interface DirectoryClient {
805
+ resolveUsers(ids: string[]): Promise<UserInfo[]>;
806
+ /** Every member of the workspace (union of admins and members), resolved
807
+ * display names, sorted by name. Backs the grant picker; deliberately
808
+ * unpaginated — the member set is workspace-bounded. */
809
+ listWorkspaceMembers(workspaceId: string): Promise<UserInfo[]>;
810
+ }
811
+
812
+ export declare const FolderBreadcrumbs: React.FC<FolderBreadcrumbsProps>;
813
+
814
+ declare interface FolderBreadcrumbsProps {
815
+ folderId: string;
816
+ onNavigate: (folderId: string) => void;
817
+ }
818
+
819
+ export declare interface FolderClient {
820
+ list(workspaceId: string, parentId: string): Promise<FolderInfo[]>;
821
+ get(id: string): Promise<FolderInfo>;
822
+ create(params: {
823
+ workspaceId: string;
824
+ name: string;
825
+ slug: string;
826
+ parentId: string;
827
+ /** Create as Restricted (creator-only until Grants are issued). @default false */
828
+ restricted?: boolean;
829
+ }): Promise<FolderInfo>;
830
+ update(id: string, name: string): Promise<FolderInfo>;
831
+ delete(id: string): Promise<void>;
832
+ move(id: string, parentId: string): Promise<FolderInfo>;
833
+ /** Toggle the Restricted flag (guardian#53). The server refuses with a
834
+ * leak-guard conflict when the toggle would create a leak state. */
835
+ setRestricted(id: string, restricted: boolean): Promise<FolderInfo>;
836
+ }
837
+
838
+ export declare interface FolderInfo {
839
+ id: string;
840
+ workspaceId: string;
841
+ name: string;
842
+ slug: string;
843
+ parentId: string;
844
+ /** Restricted folders sever Derived Access: only Grants admit anyone. */
845
+ restricted: boolean;
846
+ }
847
+
848
+ export declare const FolderTree: React.FC<FolderTreeProps>;
849
+
850
+ declare interface FolderTreeProps {
851
+ activeFolderId: string;
852
+ onFolderSelect: (folderId: string) => void;
853
+ }
854
+
855
+ export declare interface GetUploadUrlParams {
856
+ assetId: string;
857
+ filename: string;
858
+ contentType: string;
859
+ fileSize: number;
860
+ comment?: string;
861
+ }
862
+
863
+ /** Manages explicit Grants on assets, folders, and collections. Every call —
864
+ * mutations and roster reads alike — requires owner on the resource or admin
865
+ * on its workspace; the server answers PermissionDenied otherwise. */
866
+ export declare interface GrantClient {
867
+ list(resourceType: GrantResourceType, resourceId: string): Promise<GrantRoster>;
868
+ /** Upserts: a user holds at most one Grant per resource, so granting
869
+ * replaces any existing Grant at whatever level it had. */
870
+ grant(resourceType: GrantResourceType, resourceId: string, userId: string, level: GrantLevel): Promise<void>;
871
+ /** Level-less and idempotent: removes whatever the user held. */
872
+ revoke(resourceType: GrantResourceType, resourceId: string, userId: string): Promise<void>;
873
+ }
874
+
875
+ /** One explicit Grant on a roster: a named user holding a grantable level. */
876
+ export declare interface GrantEntry {
877
+ userId: string;
878
+ level: GrantLevel;
879
+ }
880
+
881
+ /** A grantable relation. Ownership is structural and never grantable. */
882
+ export declare type GrantLevel = "viewer" | "editor";
883
+
884
+ /** The kinds of resource a Grant applies to (guardian#52). */
885
+ export declare type GrantResourceType = "asset" | "folder" | "collection";
886
+
887
+ /** A resource's roster: the structural Owner plus explicit Grants only —
888
+ * Derived Access (workspace membership, folder chains, collection
889
+ * membership) is deliberately absent. */
890
+ export declare interface GrantRoster {
891
+ /** Empty for resources created before their owner tuples were
892
+ * backfilled — render no Owner row rather than an empty name. */
893
+ ownerUserId: string;
894
+ grants: GrantEntry[];
895
+ }
896
+
897
+ /**
898
+ * Thin wrapper around anker's InlineEdit that adds async save with error handling.
899
+ * On error, the value reverts to the previous value automatically.
900
+ */
901
+ export declare const InlineEditField: React.FC<InlineEditFieldProps>;
902
+
903
+ declare interface InlineEditFieldProps {
904
+ value: string;
905
+ onSave: (newValue: string) => Promise<void>;
906
+ as?: "input" | "textarea";
907
+ placeholder?: string;
908
+ }
909
+
910
+ export declare const isActive: (runs: AIProcessRunInfo[] | undefined) => boolean;
911
+
912
+ /** Whether an RPC failure is a Connect permission denial. Callers that probe
913
+ * for authority (a denial means "not an authority", not "broken") branch on
914
+ * this instead of re-implementing the structural code check. */
915
+ export declare function isPermissionDenied(err: unknown): boolean;
916
+
917
+ /**
918
+ * Whether an RPC failure is "try again in a moment" rather than a verdict.
919
+ *
920
+ * The server refuses a status change, and a behavior-filtered listing, with
921
+ * Unavailable while statushub cannot be reached (statushub integration
922
+ * standard §6, knkCS/mediahub#120) — the one code that means the same request,
923
+ * unchanged, will work once the service answers again. mediahub being
924
+ * unreachable itself arrives as the same code and means the same thing to the
925
+ * reader, so the two are deliberately not told apart.
926
+ */
927
+ export declare function isRetryableUnavailable(err: unknown): boolean;
928
+
929
+ /** One offending asset→collection pair behind a leak-guard refusal. */
930
+ export declare interface LeakGuardExposure {
931
+ assetId: string;
932
+ assetName: string;
933
+ collectionId: string;
934
+ collectionName: string;
935
+ }
936
+
937
+ /**
938
+ * Explains a refused Restricted toggle (guardian#55): the refusing rule in
939
+ * human copy plus every offending asset→collection pair, each side linked to
940
+ * its surface when the host registered routes — never a raw error.
941
+ */
942
+ export declare const LeakGuardRefusalDialog: React.FC<LeakGuardRefusalDialogProps>;
943
+
944
+ export declare interface LeakGuardRefusalDialogProps {
945
+ /** The mapped leak-guard failure to explain. Callers keep the last refusal
946
+ * mounted while the dialog animates closed (same #66 semantics as the
947
+ * other dialogs) — `null` renders nothing. */
948
+ refusal: RpcErrorDescription | null;
949
+ open: boolean;
950
+ onClose: () => void;
951
+ closeLabel?: string;
952
+ /** Line under the pair list telling the user how to proceed. */
953
+ resolveHint?: string;
954
+ }
955
+
956
+ /**
957
+ * "Manage access" panel for assets, folders, and collections (guardian#52):
958
+ * a pinned Owner row, the roster of Grants with level dropdowns and revoke,
959
+ * a member picker, and a Derived-Access note. The roster read doubles as the
960
+ * authority gate — the server answers PermissionDenied to everyone but the
961
+ * Owner and workspace admins, and those callers get the denial copy instead
962
+ * of a roster (grantees see content, never who else was granted).
963
+ */
964
+ export declare function ManageAccessDialog(props: ManageAccessDialogProps): React.JSX.Element;
965
+
966
+ export declare namespace ManageAccessDialog {
967
+ var displayName: string;
968
+ }
969
+
970
+ export declare interface ManageAccessDialogProps {
971
+ open: boolean;
972
+ onOpenChange: (open: boolean) => void;
973
+ subject: ManageAccessSubject;
974
+ headerLabel?: string;
975
+ doneLabel?: string;
976
+ ownerBadgeLabel?: string;
977
+ addPersonLabel?: string;
978
+ grantLabel?: string;
979
+ viewerLabel?: string;
980
+ editorLabel?: string;
981
+ /** Derived-Access note on open content. */
982
+ openAccessNote?: string;
983
+ /** Derived-Access note on Restricted content (explicit Grants only). */
984
+ restrictedAccessNote?: string;
985
+ }
986
+
987
+ /** What the panel manages access to: the full record is carried so the
988
+ * Derived-Access note can reason about Restricted chains without refetching
989
+ * what the mount site already holds. */
990
+ export declare type ManageAccessSubject = {
991
+ kind: "asset";
992
+ asset: AssetInfo;
993
+ } | {
994
+ kind: "folder";
995
+ folder: FolderInfo;
996
+ } | {
997
+ kind: "collection";
998
+ collection: CollectionInfo;
999
+ };
1000
+
1001
+ /**
1002
+ * @knkcs/mediahub-ui — reusable mediahub asset-management surfaces.
1003
+ *
1004
+ * Transport-agnostic clients + provider + TanStack Query hooks + stores,
1005
+ * plus the UI surfaces themselves (<AssetLibrary>, <AssetPicker>,
1006
+ * <CollectionPicker>, <AssetDetail>, …). A host's own tests reach the
1007
+ * `./testing` subpath instead of this one — see `src/testing`.
1008
+ */
1009
+ export declare const MEDIAHUB_UI_VERSION = "0.1.0";
1010
+
1011
+ export declare interface MediahubClients {
1012
+ assets: AssetClient;
1013
+ folders: FolderClient;
1014
+ collections: CollectionClient;
1015
+ tags: TagClient;
1016
+ assetTypes: AssetTypeClient;
1017
+ directory: DirectoryClient;
1018
+ grants: GrantClient;
1019
+ dashboard: DashboardClient;
1020
+ aiConnection: AIConnectionClient;
1021
+ aiProcess: AIProcessClient;
1022
+ authz: AuthzClient;
1023
+ }
1024
+
1025
+ /** Host-app routes for the places this package can only point at, never
1026
+ * navigate to itself (it has no router dependency). Rendered as plain
1027
+ * anchors; hosts include any basename in the returned href. */
1028
+ export declare interface MediahubLinks {
1029
+ /** Route to an asset's detail view. */
1030
+ assetHref?: (assetId: string) => string;
1031
+ /** Route to a collection's view. */
1032
+ collectionHref?: (collectionId: string) => string;
1033
+ }
1034
+
1035
+ export declare function MediahubProvider({ clients, workspaceId, links, children, }: MediahubProviderProps): JSX.Element;
1036
+
1037
+ export declare namespace MediahubProvider {
1038
+ var displayName: string;
1039
+ }
1040
+
1041
+ export declare interface MediahubProviderProps {
1042
+ clients: MediahubClients;
1043
+ /** Ambient workspace scope — every hook reads it. */
1044
+ workspaceId: string;
1045
+ /** Host routes for cross-surface references (e.g. the leak-guard refusal
1046
+ * dialog's pair links). Omitted routes render as plain text. */
1047
+ links?: MediahubLinks;
1048
+ children: ReactNode;
1049
+ }
1050
+
1051
+ /**
1052
+ * Destination folder picker for moving a folder or an asset. Destinations
1053
+ * that would trip the server's leak guard (moving exposed content into a
1054
+ * Restricted chain, guardian ADR 0003) render disabled with the reason
1055
+ * inline; the server remains authoritative and re-checks every move.
1056
+ */
1057
+ export declare function MoveDialog(props: MoveDialogProps): React.JSX.Element;
1058
+
1059
+ export declare namespace MoveDialog {
1060
+ var displayName: string;
1061
+ }
1062
+
1063
+ export declare interface MoveDialogProps {
1064
+ open: boolean;
1065
+ onOpenChange: (open: boolean) => void;
1066
+ subject: MoveSubject;
1067
+ /** Called after a successful move with the destination folder id
1068
+ * ("" = workspace root). */
1069
+ onMoved?: (destinationId: string) => void;
1070
+ headerLabel?: string;
1071
+ confirmLabel?: string;
1072
+ cancelLabel?: string;
1073
+ rootLabel?: string;
1074
+ currentLocationLabel?: string;
1075
+ selfLocationLabel?: string;
1076
+ /** Reason shown on leak-guarded destinations. */
1077
+ blockedLabel?: string;
1078
+ }
1079
+
1080
+ /** What the dialog moves: a folder (from the tree's context menu) or an
1081
+ * asset (from its detail view). */
1082
+ export declare type MoveSubject = {
1083
+ kind: "folder";
1084
+ folder: FolderInfo;
1085
+ } | {
1086
+ kind: "asset";
1087
+ asset: AssetInfo;
1088
+ };
1089
+
1090
+ export declare interface Page<T> {
1091
+ items: T[];
1092
+ total: number;
1093
+ page: number;
1094
+ pageSize: number;
1095
+ totalPages: number;
1096
+ }
1097
+
1098
+ declare interface PreferencesActions {
1099
+ toggleSidebar: () => void;
1100
+ setViewMode: (mode: "list" | "grid") => void;
1101
+ }
1102
+
1103
+ declare interface PreferencesState {
1104
+ sidebarCollapsed: boolean;
1105
+ viewMode: "list" | "grid";
1106
+ }
1107
+
1108
+ declare type PreferencesStore = PreferencesState & PreferencesActions;
1109
+
1110
+ declare type ProtoResponse = {
1111
+ [key: string]: any;
1112
+ };
1113
+
1114
+ /** The shared Restricted-container warning (guardian#48): shown when creating
1115
+ * a Restricted folder and, with the other noun, on the collection dialog's
1116
+ * Restricted switch. */
1117
+ export declare function restrictedContainerWarning(kind: "folder" | "collection"): string;
1118
+
1119
+ /** Deliberate-path dialog for creating a Restricted folder. The everyday
1120
+ * inline "New Folder" input stays the fast path for ordinary folders. */
1121
+ export declare const RestrictedFolderDialog: React.FC<RestrictedFolderDialogProps>;
1122
+
1123
+ export declare interface RestrictedFolderDialogProps {
1124
+ open: boolean;
1125
+ onClose: () => void;
1126
+ /** Parent folder to create under; "" creates at the root. */
1127
+ parentId: string;
1128
+ /** Called after a successful create (e.g. to refresh the tree). */
1129
+ onCreated?: () => void;
1130
+ }
1131
+
1132
+ /** Lock marker rendered wherever a Restricted container appears. The
1133
+ * `aria-label="Restricted"` is the contract tests target — keep it stable. */
1134
+ export declare const RestrictedLockBadge: React.FC<RestrictedLockBadgeProps>;
1135
+
1136
+ export declare interface RestrictedLockBadgeProps {
1137
+ /** Icon size in px. @default 12 */
1138
+ size?: number;
1139
+ /** Optional left margin (spacing token) for sites without a gap parent. */
1140
+ ml?: number;
1141
+ }
1142
+
1143
+ /** Warning banner for the deliberate create-Restricted paths. */
1144
+ export declare const RestrictedWarningNotice: React.FC<RestrictedWarningNoticeProps>;
1145
+
1146
+ export declare interface RestrictedWarningNoticeProps {
1147
+ kind: "folder" | "collection";
1148
+ }
1149
+
1150
+ export declare interface RpcErrorDescription {
1151
+ kind: "permission-denied" | "leak-guard" | "other";
1152
+ title: string;
1153
+ description: string;
1154
+ /** Present for leak-guard conflicts: the items the refusal involves. */
1155
+ exposures?: LeakGuardExposure[];
1156
+ /** Present for leak-guard conflicts: the refusing rule's explanation
1157
+ * without the joined item list — for surfaces that render `exposures`
1158
+ * themselves (e.g. the refusal dialog). */
1159
+ ruleText?: string;
1160
+ }
1161
+
1162
+ declare interface SelectionActions {
1163
+ toggle: (id: string) => void;
1164
+ selectAll: (ids: string[]) => void;
1165
+ setSelection: (ids: string[]) => void;
1166
+ selectRange: (targetId: string, orderedIds: string[]) => void;
1167
+ clearSelection: () => void;
1168
+ }
1169
+
1170
+ declare interface SelectionState {
1171
+ selectedIds: string[];
1172
+ lastClickedId: string | null;
1173
+ }
1174
+
1175
+ declare type SelectionStore = SelectionState & SelectionActions;
1176
+
1177
+ /**
1178
+ * The app-wide error toast: maps the failure with describeRpcError and shows
1179
+ * it. `fallbackTitle` is used only for errors outside the two mapped
1180
+ * families, preserving each call site's existing title.
1181
+ */
1182
+ export declare function showRpcErrorToast(err: unknown, fallbackTitle: string): void;
1183
+
1184
+ export declare interface StatusCountInfo {
1185
+ statusSlug: string;
1186
+ name: string;
1187
+ color: string;
1188
+ behavior: string;
1189
+ count: number;
1190
+ }
1191
+
1192
+ export declare const TagChipField: React.FC<TagChipFieldProps>;
1193
+
1194
+ declare interface TagChipFieldProps {
1195
+ assetId: string;
1196
+ assignedTagIds: string[];
1197
+ }
1198
+
1199
+ export declare interface TagClient {
1200
+ list(workspaceId: string): Promise<TagInfo[]>;
1201
+ create(params: {
1202
+ workspaceId: string;
1203
+ name: string;
1204
+ slug: string;
1205
+ }): Promise<TagInfo>;
1206
+ update(id: string, name: string): Promise<TagInfo>;
1207
+ delete(id: string): Promise<void>;
1208
+ tagAssets(tagId: string, assetIds: string[]): Promise<void>;
1209
+ untagAssets(tagId: string, assetIds: string[]): Promise<void>;
1210
+ }
1211
+
1212
+ export declare interface TagInfo {
1213
+ id: string;
1214
+ workspaceId: string;
1215
+ name: string;
1216
+ slug: string;
1217
+ }
1218
+
1219
+ export declare const TagPanel: React.FC<TagPanelProps>;
1220
+
1221
+ declare interface TagPanelProps {
1222
+ activeTags: string[];
1223
+ onToggleTag: (tagId: string) => void;
1224
+ }
1225
+
1226
+ /** The explicit unrestrict disclosure (guardian#55): spelled out before the
1227
+ * toggle because it widens the audience to the whole workspace. */
1228
+ export declare function unrestrictDisclosure(kind: "folder" | "collection", name: string): string;
1229
+
1230
+ declare interface UploadActions {
1231
+ addFiles: (files: File[]) => void;
1232
+ setAssetType: (clientId: string, assetTypeId: string) => void;
1233
+ setBatchAssetType: (assetTypeId: string) => void;
1234
+ setAnalyzeWithAi: (v: boolean) => void;
1235
+ startUpload: (workspaceId: string, folderId?: string) => void;
1236
+ setQueryClient: (qc: QueryClient) => void;
1237
+ setAssetClient: (client: AssetClient) => void;
1238
+ clearPending: () => void;
1239
+ dismiss: () => void;
1240
+ toggleExpanded: () => void;
1241
+ }
1242
+
1243
+ export declare const UploadDialog: React.FC<UploadDialogProps>;
1244
+
1245
+ declare interface UploadDialogProps {
1246
+ open: boolean;
1247
+ onClose: () => void;
1248
+ folderId?: string;
1249
+ }
1250
+
1251
+ export declare const UploadDropZone: React.FC<UploadDropZoneProps>;
1252
+
1253
+ declare interface UploadDropZoneProps {
1254
+ onFilesSelected: (files: File[]) => void;
1255
+ compact?: boolean;
1256
+ }
1257
+
1258
+ export declare interface UploadFile {
1259
+ clientId: string;
1260
+ file: File;
1261
+ assetTypeId: string;
1262
+ status: "pending" | "creating" | "uploading" | "finalizing" | "done" | "error";
1263
+ progress: number;
1264
+ error?: string;
1265
+ assetId?: string;
1266
+ versionId?: string;
1267
+ }
1268
+
1269
+ declare interface UploadState {
1270
+ files: UploadFile[];
1271
+ visible: boolean;
1272
+ expanded: boolean;
1273
+ analyzeWithAi: boolean;
1274
+ queryClient: QueryClient | null;
1275
+ assetClient: AssetClient | null;
1276
+ }
1277
+
1278
+ declare type UploadStore = UploadState & UploadActions;
1279
+
1280
+ export declare interface UploadTarget {
1281
+ uploadUrl: string;
1282
+ versionId: string;
1283
+ }
1284
+
1285
+ export declare const UploadToastStack: React.FC;
1286
+
1287
+ export declare function useAddAssetsToCollection(): UseMutationResult<void, Error, {
1288
+ collectionId: string;
1289
+ assetIds: string[];
1290
+ }, unknown>;
1291
+
1292
+ export declare function useAddVersion(): {
1293
+ progress: number;
1294
+ data: undefined;
1295
+ variables: undefined;
1296
+ error: null;
1297
+ isError: false;
1298
+ isIdle: true;
1299
+ isPending: false;
1300
+ isSuccess: false;
1301
+ status: "idle";
1302
+ mutate: UseMutateFunction<AssetInfo, Error, AddVersionVars, unknown>;
1303
+ reset: () => void;
1304
+ context: unknown;
1305
+ failureCount: number;
1306
+ failureReason: Error | null;
1307
+ isPaused: boolean;
1308
+ submittedAt: number;
1309
+ mutateAsync: UseMutateAsyncFunction<AssetInfo, Error, AddVersionVars, unknown>;
1310
+ } | {
1311
+ progress: number;
1312
+ data: undefined;
1313
+ variables: AddVersionVars;
1314
+ error: null;
1315
+ isError: false;
1316
+ isIdle: false;
1317
+ isPending: true;
1318
+ isSuccess: false;
1319
+ status: "pending";
1320
+ mutate: UseMutateFunction<AssetInfo, Error, AddVersionVars, unknown>;
1321
+ reset: () => void;
1322
+ context: unknown;
1323
+ failureCount: number;
1324
+ failureReason: Error | null;
1325
+ isPaused: boolean;
1326
+ submittedAt: number;
1327
+ mutateAsync: UseMutateAsyncFunction<AssetInfo, Error, AddVersionVars, unknown>;
1328
+ } | {
1329
+ progress: number;
1330
+ data: undefined;
1331
+ error: Error;
1332
+ variables: AddVersionVars;
1333
+ isError: true;
1334
+ isIdle: false;
1335
+ isPending: false;
1336
+ isSuccess: false;
1337
+ status: "error";
1338
+ mutate: UseMutateFunction<AssetInfo, Error, AddVersionVars, unknown>;
1339
+ reset: () => void;
1340
+ context: unknown;
1341
+ failureCount: number;
1342
+ failureReason: Error | null;
1343
+ isPaused: boolean;
1344
+ submittedAt: number;
1345
+ mutateAsync: UseMutateAsyncFunction<AssetInfo, Error, AddVersionVars, unknown>;
1346
+ } | {
1347
+ progress: number;
1348
+ data: AssetInfo;
1349
+ error: null;
1350
+ variables: AddVersionVars;
1351
+ isError: false;
1352
+ isIdle: false;
1353
+ isPending: false;
1354
+ isSuccess: true;
1355
+ status: "success";
1356
+ mutate: UseMutateFunction<AssetInfo, Error, AddVersionVars, unknown>;
1357
+ reset: () => void;
1358
+ context: unknown;
1359
+ failureCount: number;
1360
+ failureReason: Error | null;
1361
+ isPaused: boolean;
1362
+ submittedAt: number;
1363
+ mutateAsync: UseMutateAsyncFunction<AssetInfo, Error, AddVersionVars, unknown>;
1364
+ };
1365
+
1366
+ export declare function useAIConnection(id: string): UseQueryResult<AIConnectionInfo, Error>;
1367
+
1368
+ export declare function useAIConnections(): UseQueryResult<AIConnectionInfo[], Error>;
1369
+
1370
+ export declare function useAIProcess(id: string): UseQueryResult<AIProcessInfo, Error>;
1371
+
1372
+ export declare function useAIProcesses(assetTypeId: string): UseQueryResult<AIProcessInfo[], Error>;
1373
+
1374
+ export declare function useAIProcessRuns(assetId: string): UseQueryResult<AIProcessRunInfo[], Error>;
1375
+
1376
+ export declare function useAsset(id: string): UseQueryResult<AssetInfo, Error>;
1377
+
1378
+ export declare function useAssets(filters?: AssetFilters): UseQueryResult<Page<AssetInfo>, Error>;
1379
+
1380
+ /**
1381
+ * The status a slug names.
1382
+ *
1383
+ * `isLoading` is reported separately on purpose: "not answered yet" and
1384
+ * "answered, and this slug is not in the catalogue" look the same in the data
1385
+ * and mean opposite things. Collapsing them makes every list paint its raw
1386
+ * slugs for one frame before the names arrive.
1387
+ *
1388
+ * Once the catalogue has answered, a missing status is an **unknown status** —
1389
+ * the slug was deleted, or statushub had never answered at birth (§5) — and
1390
+ * callers render the raw slug rather than nothing: the asset still has a
1391
+ * status, mediahub just cannot name it.
1392
+ */
1393
+ export declare function useAssetStatus(slug: string): {
1394
+ status: StatusInfo | undefined;
1395
+ isLoading: boolean;
1396
+ };
1397
+
1398
+ /** The asset catalogue's statuses in the viewer's workspace. */
1399
+ export declare function useAssetStatuses(): UseQueryResult<NoInfer<StatusInfo[]>, Error>;
1400
+
1401
+ export declare function useAssetType(id: string): UseQueryResult<AssetTypeInfo, Error>;
1402
+
1403
+ export declare function useAssetTypes(): UseQueryResult<AssetTypeInfo[], Error>;
1404
+
1405
+ /**
1406
+ * Whether the current user may manage a resource — toggle its Restricted
1407
+ * flag, grant or revoke access (Owner of the resource or admin of its
1408
+ * workspace, mediahub ADR-0001). Consumers read `data === true`; a pending or
1409
+ * failed probe hides authority-only actions (fail closed).
1410
+ */
1411
+ export declare function useCanManage(resourceType: GrantResourceType, resourceId: string): UseQueryResult<boolean, Error>;
1412
+
1413
+ export declare function useCollection(id: string): UseQueryResult<CollectionInfo, Error>;
1414
+
1415
+ export declare function useCollections(): UseQueryResult<CollectionInfo[], Error>;
1416
+
1417
+ export declare function useCreateAIConnection(): UseMutationResult<AIConnectionInfo, Error, {
1418
+ name: string;
1419
+ provider: string;
1420
+ endpoint: string;
1421
+ deployment: string;
1422
+ apiVersion: string;
1423
+ baseUrl: string;
1424
+ model: string;
1425
+ apiKey: string;
1426
+ description: string;
1427
+ }, unknown>;
1428
+
1429
+ export declare function useCreateAIProcess(): UseMutationResult<AIProcessInfo, Error, {
1430
+ assetTypeId: string;
1431
+ connectionId: string;
1432
+ name: string;
1433
+ prompt: string;
1434
+ outputs: {
1435
+ key: string;
1436
+ target: string;
1437
+ metadataAccessor: string;
1438
+ }[];
1439
+ position: number;
1440
+ workspaceId: string;
1441
+ }, unknown>;
1442
+
1443
+ export declare function useCreateAsset(): UseMutationResult<AssetInfo, Error, CreateAssetParams, unknown>;
1444
+
1445
+ export declare function useCreateAssetType(): UseMutationResult<AssetTypeInfo, Error, {
1446
+ name: string;
1447
+ slug: string;
1448
+ description: string;
1449
+ allowedMimeTypes: string[];
1450
+ metadataSchema: string;
1451
+ }, unknown>;
1452
+
1453
+ export declare function useCreateCollection(): UseMutationResult<CollectionInfo, Error, {
1454
+ name: string;
1455
+ slug: string;
1456
+ description: string;
1457
+ type: CollectionType;
1458
+ rules: string;
1459
+ restricted?: boolean;
1460
+ }, unknown>;
1461
+
1462
+ export declare function useCreateFolder(): UseMutationResult<FolderInfo, Error, {
1463
+ name: string;
1464
+ slug: string;
1465
+ parentId: string;
1466
+ restricted?: boolean;
1467
+ }, unknown>;
1468
+
1469
+ export declare function useCreateTag(): UseMutationResult<TagInfo, Error, {
1470
+ name: string;
1471
+ slug: string;
1472
+ }, unknown>;
1473
+
1474
+ export declare function useDeleteAIConnection(): UseMutationResult<void, Error, string, unknown>;
1475
+
1476
+ export declare function useDeleteAIProcess(): UseMutationResult<void, Error, string, unknown>;
1477
+
1478
+ export declare function useDeleteAsset(): UseMutationResult<void, Error, string, unknown>;
1479
+
1480
+ export declare function useDeleteAssetType(): UseMutationResult<void, Error, string, unknown>;
1481
+
1482
+ export declare function useDeleteCollection(): UseMutationResult<void, Error, string, unknown>;
1483
+
1484
+ export declare function useDeleteFolder(): UseMutationResult<void, Error, string, unknown>;
1485
+
1486
+ export declare function useDeleteTag(): UseMutationResult<void, Error, string, unknown>;
1487
+
1488
+ export declare function useEnhanceAssetMetadata(): UseMutationResult<AssetInfo, Error, string, unknown>;
1489
+
1490
+ export declare function useFolder(id: string): UseQueryResult<FolderInfo, Error>;
1491
+
1492
+ export declare function useFolders(parentId?: string, opts?: {
1493
+ enabled?: boolean;
1494
+ }): UseQueryResult<FolderInfo[], Error>;
1495
+
1496
+ export declare function useGetDashboardLayout(): UseQueryResult<string, Error>;
1497
+
1498
+ export declare function useGrantAccess(): UseMutationResult<void, Error, {
1499
+ resourceType: GrantResourceType;
1500
+ resourceId: string;
1501
+ userId: string;
1502
+ level: GrantLevel;
1503
+ }, unknown>;
1504
+
1505
+ /**
1506
+ * The roster read doubles as the sharing panel's authority gate: the server
1507
+ * answers PermissionDenied for everyone but the resource's Owner and
1508
+ * workspace admins, and that denial is a final answer — never retried.
1509
+ */
1510
+ export declare function useGrants(resourceType: GrantResourceType, resourceId: string, opts?: {
1511
+ enabled?: boolean;
1512
+ }): UseQueryResult<GrantRoster, Error>;
1513
+
1514
+ export declare function useMediahubClients(): MediahubClients;
1515
+
1516
+ /** Host-supplied routes. Empty object when the host didn't pass `links` to
1517
+ * `<MediahubProvider>` — consumers degrade to plain text. */
1518
+ export declare function useMediahubLinks(): MediahubLinks;
1519
+
1520
+ export declare function useMoveAsset(): UseMutationResult<AssetInfo, Error, {
1521
+ id: string;
1522
+ folderId: string;
1523
+ }, unknown>;
1524
+
1525
+ export declare function useMoveFolder(): UseMutationResult<FolderInfo, Error, {
1526
+ id: string;
1527
+ parentId: string;
1528
+ }, unknown>;
1529
+
1530
+ export declare const usePreferencesStore: UseBoundStore<Omit<StoreApi<PreferencesStore>, "setState" | "persist"> & {
1531
+ setState(partial: PreferencesStore | Partial<PreferencesStore> | ((state: PreferencesStore) => PreferencesStore | Partial<PreferencesStore>), replace?: false | undefined): unknown;
1532
+ setState(state: PreferencesStore | ((state: PreferencesStore) => PreferencesStore), replace: true): unknown;
1533
+ persist: {
1534
+ setOptions: (options: Partial<PersistOptions<PreferencesStore, PreferencesStore, unknown>>) => void;
1535
+ clearStorage: () => void;
1536
+ rehydrate: () => Promise<void> | void;
1537
+ hasHydrated: () => boolean;
1538
+ onHydrate: (fn: (state: PreferencesStore) => void) => () => void;
1539
+ onFinishHydration: (fn: (state: PreferencesStore) => void) => () => void;
1540
+ getOptions: () => Partial<PersistOptions<PreferencesStore, PreferencesStore, unknown>>;
1541
+ };
1542
+ }>;
1543
+
1544
+ export declare function usePreviewURL(assetId: string, versionId: string): UseQueryResult<string, Error>;
1545
+
1546
+ export declare function useRemoveAssetsFromCollection(): UseMutationResult<void, Error, {
1547
+ collectionId: string;
1548
+ assetIds: string[];
1549
+ }, unknown>;
1550
+
1551
+ export declare function useRevokeAccess(): UseMutationResult<void, Error, {
1552
+ resourceType: GrantResourceType;
1553
+ resourceId: string;
1554
+ userId: string;
1555
+ }, unknown>;
1556
+
1557
+ export declare interface UserInfo {
1558
+ id: string;
1559
+ displayName: string;
1560
+ }
1561
+
1562
+ export declare function useSaveDashboardLayout(): UseMutationResult<void, Error, string, unknown>;
1563
+
1564
+ export declare const useSelectionStore: UseBoundStore<StoreApi<SelectionStore>>;
1565
+
1566
+ export declare function useSetCollectionRestricted(): UseMutationResult<CollectionInfo, Error, {
1567
+ id: string;
1568
+ restricted: boolean;
1569
+ }, unknown>;
1570
+
1571
+ export declare function useSetFolderRestricted(): UseMutationResult<FolderInfo, Error, {
1572
+ id: string;
1573
+ restricted: boolean;
1574
+ }, unknown>;
1575
+
1576
+ export declare function useTagAssets(): UseMutationResult<void, Error, {
1577
+ tagId: string;
1578
+ assetIds: string[];
1579
+ }, unknown>;
1580
+
1581
+ export declare function useTags(): UseQueryResult<TagInfo[], Error>;
1582
+
1583
+ export declare function useTransitionAssetStatus(): UseMutationResult<AssetInfo, Error, {
1584
+ id: string;
1585
+ /** The slug the caller last saw — the change is made against it. */
1586
+ fromStatusSlug: string;
1587
+ toStatusSlug: string;
1588
+ }, unknown>;
1589
+
1590
+ export declare function useUntagAssets(): UseMutationResult<void, Error, {
1591
+ tagId: string;
1592
+ assetIds: string[];
1593
+ }, unknown>;
1594
+
1595
+ export declare function useUpdateAIConnection(): UseMutationResult<AIConnectionInfo, Error, {
1596
+ id: string;
1597
+ patch: {
1598
+ name?: string;
1599
+ endpoint?: string;
1600
+ deployment?: string;
1601
+ apiVersion?: string;
1602
+ baseUrl?: string;
1603
+ model?: string;
1604
+ apiKey?: string;
1605
+ description?: string;
1606
+ active?: boolean;
1607
+ };
1608
+ }, unknown>;
1609
+
1610
+ export declare function useUpdateAIProcess(): UseMutationResult<AIProcessInfo, Error, {
1611
+ id: string;
1612
+ patch: {
1613
+ connectionId?: string;
1614
+ name?: string;
1615
+ prompt?: string;
1616
+ outputs?: {
1617
+ key: string;
1618
+ target: string;
1619
+ metadataAccessor: string;
1620
+ }[];
1621
+ position?: number;
1622
+ active?: boolean;
1623
+ };
1624
+ }, unknown>;
1625
+
1626
+ export declare function useUpdateAsset(): UseMutationResult<AssetInfo, Error, {
1627
+ id: string;
1628
+ patch: {
1629
+ name?: string;
1630
+ description?: string;
1631
+ metadata?: Record<string, unknown>;
1632
+ };
1633
+ }, unknown>;
1634
+
1635
+ export declare function useUpdateAssetType(): UseMutationResult<AssetTypeInfo, Error, {
1636
+ id: string;
1637
+ patch: {
1638
+ name?: string;
1639
+ description?: string;
1640
+ allowedMimeTypes?: string[];
1641
+ metadataSchema?: string;
1642
+ active?: boolean;
1643
+ };
1644
+ }, unknown>;
1645
+
1646
+ export declare function useUpdateCollection(): UseMutationResult<CollectionInfo, Error, {
1647
+ id: string;
1648
+ patch: {
1649
+ name?: string;
1650
+ description?: string;
1651
+ rules?: string;
1652
+ };
1653
+ }, unknown>;
1654
+
1655
+ export declare function useUpdateFolder(): UseMutationResult<FolderInfo, Error, {
1656
+ id: string;
1657
+ name: string;
1658
+ }, unknown>;
1659
+
1660
+ export declare function useUpdateTag(): UseMutationResult<TagInfo, Error, {
1661
+ id: string;
1662
+ name: string;
1663
+ }, unknown>;
1664
+
1665
+ export declare const useUploadStore: UseBoundStore<StoreApi<UploadStore>>;
1666
+
1667
+ export declare function useUsers(ids: string[]): UseQueryResult<Record<string, string>, Error>;
1668
+
1669
+ export declare function useWorkspaceId(): string;
1670
+
1671
+ /** The active workspace's member listing — backs the grant picker
1672
+ * (guardian#52). Server-sorted by display name; unpaginated by design. */
1673
+ export declare function useWorkspaceMembers(opts?: {
1674
+ enabled?: boolean;
1675
+ }): UseQueryResult<UserInfo[], Error>;
1676
+
1677
+ export declare function useWorkspaceStats(): UseQueryResult<WorkspaceStats, Error>;
1678
+
1679
+ export declare interface WorkspaceStats {
1680
+ totalAssets: number;
1681
+ totalStorageBytes: number;
1682
+ statusCounts: StatusCountInfo[];
1683
+ recentUploads: AssetSummaryInfo[];
1684
+ }
1685
+
1686
+ export { }