@arbidocs/react 0.4.2 → 0.4.4

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.cts CHANGED
@@ -1,11 +1,12 @@
1
1
  import * as React$1 from 'react';
2
2
  import React__default, { ReactNode, ComponentType } from 'react';
3
- import { ArbiOptions, Arbi, SSEStreamResult, SSEStreamStartData, ResponseOutputItemDoneEvent, ArtifactEvent } from '@arbidocs/sdk/browser';
4
- export { AgentStepEvent, Arbi, ArbiError, ArbiOptions, ArtifactEvent, CreateFactRequest, CreateTaskRequest, FactResponse, FactSearchRequest, FactSearchResponse, MessageMetadataPayload, OutputTokensDetails, ProjectInvoicesResponse, ProjectUsageResponse, QueryOptions, ResponseCompletedEvent, ResponseContentPartAddedEvent, ResponseCreatedEvent, ResponseFailedEvent, ResponseOutputItemAddedEvent, ResponseOutputItemDoneEvent, ResponseOutputTextDeltaEvent, ResponseOutputTextDoneEvent, ResponseUsage, SSEStreamCallbacks, SSEStreamResult, SSEStreamStartData, TaskResponse, UpdateTaskRequest, UserDailyUsageResponse, UserInputRequestEvent, UserMessageEvent } from '@arbidocs/sdk/browser';
3
+ import { ArbiOptions, Arbi, SSEStreamResult, SSEStreamStartData, ResponseOutputItemDoneEvent, ArtifactEvent, UpdateTaskRequest } from '@arbidocs/sdk/browser';
4
+ export { AgentStepEvent, Arbi, ArbiError, ArbiOptions, ArtifactEvent, CreateFactRequest, CreateTaskRequest, FactResponse, FactSearchRequest, FactSearchResponse, MessageMetadataPayload, OutputTokensDetails, ProjectInvoicesResponse, ProjectUsageResponse, QueryOptions, ResponseCompletedEvent, ResponseContentPartAddedEvent, ResponseCreatedEvent, ResponseFailedEvent, ResponseOutputItemAddedEvent, ResponseOutputItemDoneEvent, ResponseOutputTextDeltaEvent, ResponseOutputTextDoneEvent, ResponseUsage, SSEStreamCallbacks, SSEStreamResult, SSEStreamStartData, SkillSummary, TaskResponse, UpdateTaskRequest, UserDailyUsageResponse, UserInputRequestEvent, UserMessageEvent } from '@arbidocs/sdk/browser';
5
5
  import * as _arbidocs_client from '@arbidocs/client';
6
6
  import { WebSocketServerMessage, WsTaskUpdateMessage, WsPresenceUpdateMessage, components } from '@arbidocs/client';
7
7
  export { WebSocketServerMessage, WsBatchCompleteMessage, WsNotificationResponse, WsPresenceUpdateMessage, WsResponseCompleteMessage, WsTaskUpdateMessage, isMessageType } from '@arbidocs/client';
8
8
  import * as zustand from 'zustand';
9
+ import * as _tanstack_query_core from '@tanstack/query-core';
9
10
  import * as _tanstack_react_query from '@tanstack/react-query';
10
11
  import { EntityIconComponent } from './ui/index.cjs';
11
12
  export { AgentBadge, AiMarkdown, Avatar, AvatarFallback, AvatarImage, BASE_COLORS, Badge, BadgeProps, Button, ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardProps, CardTitle, Checkbox, Collapsible, CollapsibleContent, CollapsibleTrigger, Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogPresentation, DialogTitle, DialogTrigger, DictateContextValue, DictateProvider, DocumentCard, DocumentCardProps, DocumentEntity, DocumentEntityProps, DocumentLike, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, ENTITY_MAPPINGS, EntityIcon, EntityPill, EntityRegistryOverride, EntityType, HoverCard, HoverCardContent, HoverCardTrigger, IconToggle, IconToggleProps, Input, InputProps, Label, MarkMenu, MarkMenuItem, MarkMenuProps, MarkdownRenderer, MarkdownRendererProps, MarkdownStreamingContext, NEUTRAL_GRAY, PLACEHOLDER_COLOR, PassageCard, PassageCardProps, Popover, PopoverAnchor, PopoverContent, PopoverTrigger, PresenceDisplayStatus, PresenceLabel, Progress, ProjectEntity, ProjectEntityProps, ProjectRelation, RadioGroup, RadioGroupItem, Rag, RagDot, RelevanceDot, ScrollArea, ScrollBar, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, Separator, Slider, StatusBadgeComponent, StatusBadgeProps, StatusPill, StatusPillProps, StatusVariant, Switch, TAG_TYPE_ICONS, TAG_TYPE_LABELS, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TagEntity, TagEntityProps, TagLike, Textarea, TextareaProps, Toggle, ToggleGroup, ToggleGroupItem, Tooltip, TooltipContent, TooltipProvider, TooltipTrigger, UserEntity, UserEntityProps, UserMenu, UserMenuItem, UserMenuProps, UserMenuStatus, VISIBILITY_ICONS, VisibilityIcon, badgeVariants, buttonVariants, cardVariants, cn, configureEntityRegistry, configureRagLabels, configureStatusRegistry, getDocIcon, getEntityColor, getEntityColorStyles, getEntityIcon, getEntityLabel, getStatusVariant, getTagTypeIcon, getTagTypeLabel, getWorkspaceColor, markdownBaseComponents, splitMarkdownBlocks, toggleVariants } from './ui/index.cjs';
@@ -40,149 +41,62 @@ interface ArbiProviderProps extends ArbiOptions {
40
41
  }
41
42
  declare function ArbiProvider({ children, ...options }: ArbiProviderProps): React$1.JSX.Element;
42
43
 
43
- interface ArbiChatTheme {
44
- /** Primary action color — buttons, links (default: '#00adef' ARBI cyan) */
45
- primaryColor: string;
46
- /** Widget background (default: '#ffffff') */
47
- backgroundColor: string;
48
- /** Surface / muted background (default: '#f9fafb') */
49
- surfaceColor: string;
50
- /** Primary text color (default: '#111827') */
51
- textColor: string;
52
- /** Secondary / muted text (default: '#6b7280') */
53
- mutedColor: string;
54
- /** Border color (default: '#e5e7eb') */
55
- borderColor: string;
56
- /** User message bubble background (default: '#f3f4f6') */
57
- userBubbleColor: string;
58
- /** User message text color (default: '#111827') */
59
- userBubbleTextColor: string;
60
- /** Assistant message bubble background (default: 'rgba(0, 173, 239, 0.08)') */
61
- assistantBubbleColor: string;
62
- /** Assistant message text color (default: '#111827') */
63
- assistantBubbleTextColor: string;
64
- /** Border radius for the outer container (default: '8px') */
65
- borderRadius: string;
66
- /** Font family stack (default: system fonts) */
67
- fontFamily: string;
68
- }
69
- interface ArbiChatLabels {
70
- /** Header title (default: 'Chat') */
71
- title?: string;
72
- /** Email field label (default: 'Email') */
73
- email?: string;
74
- /** Password field label (default: 'Password') */
75
- password?: string;
76
- /** Login button text (default: 'Log in') */
77
- loginButton?: string;
78
- /** Logging in button text (default: 'Logging in...') */
79
- loginButtonLoading?: string;
80
- /** Register button text (default: 'Create account') */
81
- registerButton?: string;
82
- /** Send verification code button text (default: 'Email me a code') */
83
- sendCodeButton?: string;
84
- /** Already have a code button text (default: 'I have an invitation code') */
85
- haveCodeButton?: string;
86
- /** Verification code field label (default: 'Verification code') */
87
- verificationCode?: string;
88
- /** Confirm password field label (default: 'Confirm password') */
89
- confirmPassword?: string;
90
- /** First name field label (default: 'First name') */
91
- firstName?: string;
92
- /** Last name field label (default: 'Last name') */
93
- lastName?: string;
94
- /** Link to switch to register view (default: 'Create account') */
95
- switchToRegister?: string;
96
- /** Link to switch back to login view (default: 'Back to login') */
97
- switchToLogin?: string;
98
- /** Workspace selector label (default: 'Select a workspace') */
99
- selectWorkspace?: string;
100
- /** Workspace selector placeholder (default: 'Choose...') */
101
- workspacePlaceholder?: string;
102
- /** Continue button after workspace select (default: 'Continue') */
103
- continueButton?: string;
104
- /** Create workspace button label (default: 'Create new workspace') */
105
- createWorkspace?: string;
106
- /** Workspace name field label (default: 'Workspace name') */
107
- workspaceName?: string;
108
- /** Generic create button text (default: 'Create') */
109
- createButton?: string;
110
- /** Change workspace link text (default: 'Change workspace') */
111
- changeWorkspace?: string;
112
- /** Documents section label (default: 'Documents') */
113
- documents?: string;
114
- /** Send button text (default: 'Send') */
115
- sendButton?: string;
116
- /** Input placeholder (default: 'Ask a question...') */
117
- placeholder?: string;
118
- /** Upload button text (default: 'Upload') */
119
- uploadButton?: string;
120
- /** Uploading state text (default: 'Uploading...') */
121
- uploading?: string;
122
- /** Empty state when no documents (default: 'No documents found in this workspace.') */
123
- emptyNoDocs?: string;
124
- /** Empty state when no docs selected (default: 'Select at least one document to start chatting.') */
125
- emptyNoSelection?: string;
126
- /** Empty state ready to chat (default: 'Ask a question about your documents.') */
127
- emptyReady?: string;
128
- }
129
- interface ArbiChatProps {
130
- /** Backend URL (required) */
131
- url: string;
132
- /** Skip workspace selection — go straight to chat */
133
- workspaceId?: string;
134
- /** Customize colors and appearance */
135
- theme?: Partial<ArbiChatTheme>;
136
- /** Customize text labels */
137
- labels?: ArbiChatLabels;
138
- /** Widget width (default: '400px') */
139
- width?: string | number;
140
- /** Widget height (default: '600px') */
141
- height?: string | number;
142
- }
143
-
144
- /** Props for {@link ArbiChatPanel} — the provider-less embeddable panel. */
145
- interface ArbiChatPanelProps {
146
- /** Skip workspace selection — go straight to chat */
147
- workspaceId?: string;
148
- /** Customize colors and appearance */
149
- theme?: Partial<ArbiChatTheme>;
150
- /** Customize text labels */
151
- labels?: ArbiChatLabels;
152
- /** Widget width (default: '100%') */
153
- width?: string | number;
154
- /** Widget height (default: '100%') */
155
- height?: string | number;
44
+ type ArbiChatRole = 'user' | 'assistant';
45
+ type ArbiChatMessageStatus = 'streaming' | 'complete' | 'error';
46
+ interface ArbiChatMessage {
47
+ id: string;
48
+ role: ArbiChatRole;
49
+ /** Markdown for an assistant message, plain text for a user message. */
50
+ content: string;
51
+ status: ArbiChatMessageStatus;
52
+ /** Why an assistant message failed. */
53
+ error?: string;
54
+ /** Agent steps (tool calls, reasoning) the answer took. */
55
+ stepCount?: number;
156
56
  }
157
- /**
158
- * The ARBI chat panel **without** its own providers.
159
- *
160
- * Drop it inside an app that already renders `<ArbiProvider>` and a
161
- * `<QueryClientProvider>` to reuse the host's authenticated session — no second
162
- * login. When the ambient session is already signed in, the panel skips the
163
- * login screen and opens straight into chat.
164
- *
165
- * ```tsx
166
- * // inside your authenticated app tree
167
- * <ArbiChatPanel workspaceId="wrk-…" theme={myTheme} />
168
- * ```
169
- *
170
- * For a fully self-contained widget (its own providers + login), use {@link ArbiChat}.
171
- */
172
- declare function ArbiChatPanel({ workspaceId, theme: themeOverrides, labels: labelOverrides, width, height, }: ArbiChatPanelProps): React$1.JSX.Element;
173
- /**
174
- * Self-contained ARBI chat widget.
175
- *
176
- * Wraps its own QueryClientProvider and ArbiProvider so it works
177
- * anywhere — no setup required from the host app.
178
- *
179
- * ```tsx
180
- * import { ArbiChat } from '@arbidocs/react'
181
- *
182
- * <ArbiChat url="https://www.arbidocs.com" />
183
- * ```
184
- */
185
- declare function ArbiChat({ url, workspaceId, theme: themeOverrides, labels: labelOverrides, width, height, }: ArbiChatProps): React$1.JSX.Element;
57
+ interface ArbiChatThread {
58
+ id: string;
59
+ /** Auto-titled from the first question; empty until there is one. */
60
+ title: string;
61
+ }
62
+ interface ArbiChatDocument {
63
+ id: string;
64
+ name: string;
65
+ isSelected: boolean;
66
+ }
67
+ interface UseArbiChatOptions {
68
+ /** The workspace to chat in. Threads and the document selection reset when it changes. */
69
+ workspaceId?: string;
70
+ /** Assistant configuration or model id passed to every query. */
71
+ model?: string;
72
+ /** Longest auto-title in characters. Default 48. */
73
+ titleLength?: number;
74
+ }
75
+ interface ArbiChat {
76
+ threads: ArbiChatThread[];
77
+ activeThreadId: string;
78
+ messages: ArbiChatMessage[];
79
+ /** An answer is streaming. */
80
+ isRunning: boolean;
81
+ /** The last turn failed (the message list also carries the failed message). */
82
+ error: string | null;
83
+ documents: ArbiChatDocument[];
84
+ isLoadingDocuments: boolean;
85
+ isUploading: boolean;
86
+ uploadError: string | null;
87
+ send: (text: string) => Promise<void>;
88
+ /** Re-ask the question whose answer failed. */
89
+ retry: () => Promise<void>;
90
+ selectThread: (id: string) => void;
91
+ newThread: () => void;
92
+ deleteThread: (id: string) => void;
93
+ toggleDocument: (id: string) => void;
94
+ selectAllDocuments: () => void;
95
+ upload: (files: File[]) => Promise<void>;
96
+ }
97
+ /** First words of a question as a title: whole words, no trailing punctuation, ellipsis when cut. */
98
+ declare function titleFromQuestion(question: string, maxLength?: number): string;
99
+ declare function useArbiChat(options?: UseArbiChatOptions): ArbiChat;
186
100
 
187
101
  /** Animated typing indicator (three bouncing dots) */
188
102
  declare const TypingIndicator: React$1.NamedExoticComponent<object>;
@@ -336,6 +250,161 @@ declare function useArbiWsTask(docId: string): {
336
250
  */
337
251
  declare function useArbiDocumentSync(workspaceId: string | undefined): void;
338
252
 
253
+ /**
254
+ * Pure workspace adapters: an SDK `WorkspaceResponse` (or the host's own copy of it) to the view
255
+ * models the shell and the workspaces gallery show. No React state, no SDK calls, so a host that
256
+ * does not mount an `<ArbiProvider>` can use them too.
257
+ */
258
+
259
+ /** Workspace visibility: public = common, several members = shared, else private. */
260
+ type ShellWorkspaceKind = 'private' | 'shared' | 'common';
261
+ /** One face on a workspace card. */
262
+ interface ShellWorkspaceMember {
263
+ name: string;
264
+ picture?: string | null;
265
+ }
266
+ /**
267
+ * The fields of an SDK workspace the adapters read. Every field but the id and the name is
268
+ * optional, so the SDK's `WorkspaceResponse` and a host's own copy of it are both assignable.
269
+ */
270
+ interface ShellWorkspaceSource {
271
+ external_id: string;
272
+ name: string;
273
+ description?: string | null;
274
+ is_public?: boolean;
275
+ project_name?: string | null;
276
+ updated_at?: string;
277
+ shared_document_count?: number;
278
+ private_document_count?: number;
279
+ users?: ReadonlyArray<{
280
+ user?: {
281
+ given_name?: string | null;
282
+ family_name?: string | null;
283
+ email?: string | null;
284
+ picture?: string | null;
285
+ };
286
+ /** Set when the member is an agent: agents are not people and are left off the faces. */
287
+ agent_ext_id?: string | null;
288
+ }>;
289
+ }
290
+ /**
291
+ * A workspace as the shell and the gallery see it. Structurally a superset of blocks'
292
+ * `ShellWorkspace` and `WorkspaceSummary`, so it is passed to both unchanged.
293
+ */
294
+ interface ShellWorkspaceItem {
295
+ id: string;
296
+ name: string;
297
+ kind: ShellWorkspaceKind;
298
+ description?: string | null;
299
+ projectName?: string | null;
300
+ /** A rendered project pill; the host supplies it (see `decorate`). */
301
+ projectLine?: ReactNode;
302
+ /** Shared plus private documents. */
303
+ docCount: number;
304
+ /** People in the workspace (agents excluded). */
305
+ memberCount: number;
306
+ members: ShellWorkspaceMember[];
307
+ /** ISO timestamp. */
308
+ updatedAt?: string;
309
+ }
310
+ /** A workspace offered in the switcher menu. */
311
+ interface ShellRecentWorkspaceItem extends ShellWorkspaceItem {
312
+ /** Pre-formatted "last seen" text, when the host supplies `formatLastSeen`. */
313
+ lastSeen?: string;
314
+ }
315
+ /** Public, several members: shared. Otherwise private. */
316
+ declare function getWorkspaceKind(workspace: Pick<ShellWorkspaceSource, 'is_public' | 'users'>): ShellWorkspaceKind;
317
+ /** Adapt one SDK workspace to the shell and gallery view model. */
318
+ declare function toShellWorkspace(workspace: ShellWorkspaceSource): ShellWorkspaceItem;
319
+ /**
320
+ * The workspace the app is in. Order: the host's selection if it is in the list; else the first
321
+ * workspace of a live list; else the seed's active one; else the first workspace.
322
+ */
323
+ declare function resolveActiveWorkspace(items: readonly ShellWorkspaceItem[], selectedId: string | null | undefined, options?: {
324
+ isSeed?: boolean;
325
+ seedActiveId?: string;
326
+ }): ShellWorkspaceItem | undefined;
327
+ /** The other workspaces for the quick-switch menu, most recently opened first, capped. */
328
+ declare function pickRecentWorkspaces(items: readonly ShellWorkspaceItem[], activeId: string | undefined, options?: {
329
+ limit?: number;
330
+ lastOpened?: Readonly<Record<string, number>>;
331
+ formatLastSeen?: (timestamp: number) => string;
332
+ }): ShellRecentWorkspaceItem[];
333
+
334
+ /**
335
+ * `useShellWorkspaces`: the user's workspaces as the shell's switcher and the workspaces gallery
336
+ * show them, the one the app is in, and `open(workspace)`.
337
+ *
338
+ * Source-agnostic on purpose: the host hands in the list and the selection mechanism it already
339
+ * has (ARBI-frontend its React Query hook and workspace store, a connected app `useWorkspaces`
340
+ * plus the connection's `setWorkspace`). `useArbiShellWorkspaces` is the same hook wired to an
341
+ * `<ArbiProvider>`.
342
+ */
343
+
344
+ /** Workspaces to show while the account has none (a demo); the host owns the data. */
345
+ interface ShellWorkspaceSeed {
346
+ workspaces: readonly ShellWorkspaceItem[];
347
+ /** The seed workspace that counts as the current one when nothing is selected. */
348
+ activeId?: string;
349
+ }
350
+ interface UseShellWorkspacesOptions<S extends ShellWorkspaceSource = ShellWorkspaceSource> {
351
+ /** The account's workspaces (SDK shape). `undefined` while loading. */
352
+ workspaces: readonly S[] | undefined;
353
+ isLoading?: boolean;
354
+ /** The list query's error, passed through as `error`. */
355
+ loadError?: unknown;
356
+ /** The workspace the host says the app is in (the connection's selection). */
357
+ selectedId?: string | null;
358
+ /**
359
+ * Make the workspace the app's current one: open it on the server and record the selection.
360
+ * Throw (reject) to report failure. Called for EVERY open, including the current workspace, so
361
+ * a click on the current card still re-opens it and then navigates.
362
+ */
363
+ select: (workspace: ShellWorkspaceItem) => Promise<unknown> | unknown;
364
+ /** After a successful select: navigate, toast, close a menu. The "switch, then navigate" hook. */
365
+ onOpened?: (workspace: ShellWorkspaceItem) => void;
366
+ /** When select rejects. The active workspace is unchanged. Without it the error is in `error`. */
367
+ onOpenError?: (error: unknown, workspace: ShellWorkspaceItem) => void;
368
+ /** Demo list for an account that has no workspaces (never while loading). */
369
+ seed?: ShellWorkspaceSeed;
370
+ /** Host decoration per workspace, e.g. a rendered project pill. Merged over the adapter. */
371
+ decorate?: (item: ShellWorkspaceItem, source: S) => Partial<ShellWorkspaceItem>;
372
+ /** How many recent workspaces the switcher offers. Default 4. */
373
+ recentLimit?: number;
374
+ /** `workspace id -> epoch ms` last opened here; orders `recent`, falling back to `updatedAt`. */
375
+ lastOpened?: Readonly<Record<string, number>>;
376
+ /** Format a recency timestamp into `recent[].lastSeen`. */
377
+ formatLastSeen?: (timestamp: number) => string;
378
+ }
379
+ interface UseShellWorkspacesResult {
380
+ /** All workspaces: the account's, or the seed when it has none. */
381
+ items: ShellWorkspaceItem[];
382
+ /** The single current workspace; undefined only when there are no workspaces at all. */
383
+ active: ShellWorkspaceItem | undefined;
384
+ /** The other workspaces, most recently opened first, for the quick-switch menu. */
385
+ recent: ShellRecentWorkspaceItem[];
386
+ /** The account's own workspaces: false while `items` is the seed. */
387
+ isLive: boolean;
388
+ isLoading: boolean;
389
+ /** The list query's error or the last failed open; cleared by the next open. */
390
+ error: unknown;
391
+ /** Id of the workspace being opened, else null (for a spinner on its card). */
392
+ openingId: string | null;
393
+ /** Select the workspace (always, even the current one), then `onOpened`. False if select threw. */
394
+ open: (workspace: Pick<ShellWorkspaceItem, 'id'> | string) => Promise<boolean>;
395
+ }
396
+ declare function useShellWorkspaces<S extends ShellWorkspaceSource = ShellWorkspaceSource>(options: UseShellWorkspacesOptions<S>): UseShellWorkspacesResult;
397
+ interface UseArbiShellWorkspacesOptions extends Omit<UseShellWorkspacesOptions, 'workspaces' | 'isLoading' | 'loadError' | 'select'> {
398
+ /**
399
+ * Override how a workspace is made current. Default: `arbi.selectWorkspace(id)`, which opens it
400
+ * on the server for the session. A host with its own selection state (the connection layer's
401
+ * `setWorkspace`) passes it here.
402
+ */
403
+ select?: UseShellWorkspacesOptions['select'];
404
+ }
405
+ /** `useShellWorkspaces` over the `<ArbiProvider>`'s workspace list and `selectWorkspace`. */
406
+ declare function useArbiShellWorkspaces(options?: UseArbiShellWorkspacesOptions): UseShellWorkspacesResult;
407
+
339
408
  /**
340
409
  * Types for a document's parsed content (`GET /v1/document/{id}/parsed-{stage}`).
341
410
  *
@@ -391,6 +460,13 @@ declare const arbiQueryKeys: {
391
460
  projectUsage: (projectExtId: string, monthsBack: number) => readonly ["arbi", "projectUsage", string, number];
392
461
  projectInvoices: (projectExtId: string) => readonly ["arbi", "projectInvoices", string];
393
462
  userUsageToday: () => readonly ["arbi", "userUsageToday"];
463
+ contacts: () => readonly ["arbi", "contacts"];
464
+ skills: () => readonly ["arbi", "skills"];
465
+ taskRuns: (taskId: string) => readonly ["arbi", "taskRuns", string];
466
+ /** An agent's pinned config; `undefined` = the library default config. */
467
+ agentConfig: (agentExtId?: string) => readonly ["arbi", "agentConfig", string];
468
+ agentWorkspaces: (agentExtId: string) => readonly ["arbi", "agentWorkspaces", string];
469
+ models: () => readonly ["arbi", "models"];
394
470
  };
395
471
  /** List the logged-in user's workspaces. */
396
472
  declare function useWorkspaces(options?: {
@@ -680,32 +756,1501 @@ declare function useConfigs(options?: {
680
756
  title: string | null;
681
757
  created_at: string;
682
758
  }[];
683
- }>, Error>;
759
+ }>, Error>;
760
+ /**
761
+ * List the caller's durable activity feed, newest first.
762
+ *
763
+ * Activity entries are backend-originated, to-self log lines that are always
764
+ * read — they are deliberately kept out of the normal notifications/DM feed and
765
+ * never affect the unread badge, so this is a separate, opt-in query.
766
+ */
767
+ declare function useActivity(options?: {
768
+ enabled?: boolean;
769
+ limit?: number;
770
+ offset?: number;
771
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
772
+ type: _arbidocs_client.components["schemas"]["NotificationType"];
773
+ external_id: string;
774
+ sender: {
775
+ external_id: string;
776
+ parent_ext_id?: string | null | undefined;
777
+ email: string;
778
+ given_name: string;
779
+ family_name?: string | null | undefined;
780
+ picture?: string | null | undefined;
781
+ encryption_public_key: string;
782
+ is_sso: boolean;
783
+ };
784
+ recipient: {
785
+ external_id: string;
786
+ parent_ext_id?: string | null | undefined;
787
+ email: string;
788
+ given_name: string;
789
+ family_name?: string | null | undefined;
790
+ picture?: string | null | undefined;
791
+ encryption_public_key: string;
792
+ is_sso: boolean;
793
+ };
794
+ workspace_ext_id?: string | null | undefined;
795
+ content?: string | null | undefined;
796
+ conversation_ext_id?: string | null | undefined;
797
+ task_ext_id?: string | null | undefined;
798
+ read: boolean;
799
+ created_at: string;
800
+ updated_at: string;
801
+ }[]>, Error>;
802
+ /** List the logged-in user's projects (billing accounts). */
803
+ declare function useProjects(options?: {
804
+ enabled?: boolean;
805
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
806
+ external_id: string;
807
+ name: string;
808
+ created_by: string;
809
+ packs: number;
810
+ subscription: string;
811
+ created_at: string;
812
+ quotas: {
813
+ storage_gb: {
814
+ used: number;
815
+ limit: number;
816
+ };
817
+ ai_credits: {
818
+ used: number;
819
+ limit: number;
820
+ };
821
+ collaborators: {
822
+ used: number;
823
+ limit: number;
824
+ };
825
+ budget_reset_at?: number | null | undefined;
826
+ };
827
+ daily_cap_per_user?: number | null | undefined;
828
+ price_id?: string | null | undefined;
829
+ plan?: string | null | undefined;
830
+ amount?: number | null | undefined;
831
+ currency?: string | null | undefined;
832
+ current_period_end?: number | null | undefined;
833
+ cancel_at_period_end?: boolean | null | undefined;
834
+ portal_url?: string | null | undefined;
835
+ }[]>, Error>;
836
+ /**
837
+ * AI usage breakdown for a project's billing period. `monthsBack` selects the period (0 =
838
+ * current, 1 = previous month, …).
839
+ *
840
+ * The response's `total_spend` / `spend` fields are CREDITS, not dollars (see `formatCredits`).
841
+ * `metered` is `false` when the deployment does not record usage (a `dev`-plan project with all
842
+ * zeros): show "usage is not metered here" instead of zeros. It is `undefined` until the usage
843
+ * has loaded.
844
+ */
845
+ declare function useProjectUsage(projectExtId: string | undefined, monthsBack?: number, options?: {
846
+ enabled?: boolean;
847
+ }): {
848
+ metered: boolean | undefined;
849
+ data: NoInfer<{
850
+ project_ext_id: string;
851
+ period_start: string;
852
+ period_end: string;
853
+ total_spend: number;
854
+ total_tokens: number;
855
+ total_requests: number;
856
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
857
+ model_groups: {
858
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
859
+ };
860
+ by_workspace: {
861
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
862
+ };
863
+ by_user: {
864
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
865
+ };
866
+ by_feature: {
867
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
868
+ };
869
+ invoice_pdf?: string | null;
870
+ }>;
871
+ error: Error;
872
+ isError: true;
873
+ isPending: false;
874
+ isLoading: false;
875
+ isLoadingError: false;
876
+ isRefetchError: true;
877
+ isSuccess: false;
878
+ isPlaceholderData: false;
879
+ status: "error";
880
+ dataUpdatedAt: number;
881
+ errorUpdatedAt: number;
882
+ failureCount: number;
883
+ failureReason: Error | null;
884
+ errorUpdateCount: number;
885
+ isFetched: boolean;
886
+ isFetchedAfterMount: boolean;
887
+ isFetching: boolean;
888
+ isInitialLoading: boolean;
889
+ isPaused: boolean;
890
+ isRefetching: boolean;
891
+ isStale: boolean;
892
+ isEnabled: boolean;
893
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
894
+ project_ext_id: string;
895
+ period_start: string;
896
+ period_end: string;
897
+ total_spend: number;
898
+ total_tokens: number;
899
+ total_requests: number;
900
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
901
+ model_groups: {
902
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
903
+ };
904
+ by_workspace: {
905
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
906
+ };
907
+ by_user: {
908
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
909
+ };
910
+ by_feature: {
911
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
912
+ };
913
+ invoice_pdf?: string | null;
914
+ }>, Error>>;
915
+ fetchStatus: _tanstack_query_core.FetchStatus;
916
+ promise: Promise<NoInfer<{
917
+ project_ext_id: string;
918
+ period_start: string;
919
+ period_end: string;
920
+ total_spend: number;
921
+ total_tokens: number;
922
+ total_requests: number;
923
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
924
+ model_groups: {
925
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
926
+ };
927
+ by_workspace: {
928
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
929
+ };
930
+ by_user: {
931
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
932
+ };
933
+ by_feature: {
934
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
935
+ };
936
+ invoice_pdf?: string | null;
937
+ }>>;
938
+ } | {
939
+ metered: boolean | undefined;
940
+ data: NoInfer<{
941
+ project_ext_id: string;
942
+ period_start: string;
943
+ period_end: string;
944
+ total_spend: number;
945
+ total_tokens: number;
946
+ total_requests: number;
947
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
948
+ model_groups: {
949
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
950
+ };
951
+ by_workspace: {
952
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
953
+ };
954
+ by_user: {
955
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
956
+ };
957
+ by_feature: {
958
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
959
+ };
960
+ invoice_pdf?: string | null;
961
+ }>;
962
+ error: null;
963
+ isError: false;
964
+ isPending: false;
965
+ isLoading: false;
966
+ isLoadingError: false;
967
+ isRefetchError: false;
968
+ isSuccess: true;
969
+ isPlaceholderData: false;
970
+ status: "success";
971
+ dataUpdatedAt: number;
972
+ errorUpdatedAt: number;
973
+ failureCount: number;
974
+ failureReason: Error | null;
975
+ errorUpdateCount: number;
976
+ isFetched: boolean;
977
+ isFetchedAfterMount: boolean;
978
+ isFetching: boolean;
979
+ isInitialLoading: boolean;
980
+ isPaused: boolean;
981
+ isRefetching: boolean;
982
+ isStale: boolean;
983
+ isEnabled: boolean;
984
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
985
+ project_ext_id: string;
986
+ period_start: string;
987
+ period_end: string;
988
+ total_spend: number;
989
+ total_tokens: number;
990
+ total_requests: number;
991
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
992
+ model_groups: {
993
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
994
+ };
995
+ by_workspace: {
996
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
997
+ };
998
+ by_user: {
999
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1000
+ };
1001
+ by_feature: {
1002
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1003
+ };
1004
+ invoice_pdf?: string | null;
1005
+ }>, Error>>;
1006
+ fetchStatus: _tanstack_query_core.FetchStatus;
1007
+ promise: Promise<NoInfer<{
1008
+ project_ext_id: string;
1009
+ period_start: string;
1010
+ period_end: string;
1011
+ total_spend: number;
1012
+ total_tokens: number;
1013
+ total_requests: number;
1014
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1015
+ model_groups: {
1016
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1017
+ };
1018
+ by_workspace: {
1019
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1020
+ };
1021
+ by_user: {
1022
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1023
+ };
1024
+ by_feature: {
1025
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1026
+ };
1027
+ invoice_pdf?: string | null;
1028
+ }>>;
1029
+ } | {
1030
+ metered: boolean | undefined;
1031
+ data: undefined;
1032
+ error: Error;
1033
+ isError: true;
1034
+ isPending: false;
1035
+ isLoading: false;
1036
+ isLoadingError: true;
1037
+ isRefetchError: false;
1038
+ isSuccess: false;
1039
+ isPlaceholderData: false;
1040
+ status: "error";
1041
+ dataUpdatedAt: number;
1042
+ errorUpdatedAt: number;
1043
+ failureCount: number;
1044
+ failureReason: Error | null;
1045
+ errorUpdateCount: number;
1046
+ isFetched: boolean;
1047
+ isFetchedAfterMount: boolean;
1048
+ isFetching: boolean;
1049
+ isInitialLoading: boolean;
1050
+ isPaused: boolean;
1051
+ isRefetching: boolean;
1052
+ isStale: boolean;
1053
+ isEnabled: boolean;
1054
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
1055
+ project_ext_id: string;
1056
+ period_start: string;
1057
+ period_end: string;
1058
+ total_spend: number;
1059
+ total_tokens: number;
1060
+ total_requests: number;
1061
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1062
+ model_groups: {
1063
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1064
+ };
1065
+ by_workspace: {
1066
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1067
+ };
1068
+ by_user: {
1069
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1070
+ };
1071
+ by_feature: {
1072
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1073
+ };
1074
+ invoice_pdf?: string | null;
1075
+ }>, Error>>;
1076
+ fetchStatus: _tanstack_query_core.FetchStatus;
1077
+ promise: Promise<NoInfer<{
1078
+ project_ext_id: string;
1079
+ period_start: string;
1080
+ period_end: string;
1081
+ total_spend: number;
1082
+ total_tokens: number;
1083
+ total_requests: number;
1084
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1085
+ model_groups: {
1086
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1087
+ };
1088
+ by_workspace: {
1089
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1090
+ };
1091
+ by_user: {
1092
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1093
+ };
1094
+ by_feature: {
1095
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1096
+ };
1097
+ invoice_pdf?: string | null;
1098
+ }>>;
1099
+ } | {
1100
+ metered: boolean | undefined;
1101
+ data: undefined;
1102
+ error: null;
1103
+ isError: false;
1104
+ isPending: true;
1105
+ isLoading: true;
1106
+ isLoadingError: false;
1107
+ isRefetchError: false;
1108
+ isSuccess: false;
1109
+ isPlaceholderData: false;
1110
+ status: "pending";
1111
+ dataUpdatedAt: number;
1112
+ errorUpdatedAt: number;
1113
+ failureCount: number;
1114
+ failureReason: Error | null;
1115
+ errorUpdateCount: number;
1116
+ isFetched: boolean;
1117
+ isFetchedAfterMount: boolean;
1118
+ isFetching: boolean;
1119
+ isInitialLoading: boolean;
1120
+ isPaused: boolean;
1121
+ isRefetching: boolean;
1122
+ isStale: boolean;
1123
+ isEnabled: boolean;
1124
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
1125
+ project_ext_id: string;
1126
+ period_start: string;
1127
+ period_end: string;
1128
+ total_spend: number;
1129
+ total_tokens: number;
1130
+ total_requests: number;
1131
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1132
+ model_groups: {
1133
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1134
+ };
1135
+ by_workspace: {
1136
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1137
+ };
1138
+ by_user: {
1139
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1140
+ };
1141
+ by_feature: {
1142
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1143
+ };
1144
+ invoice_pdf?: string | null;
1145
+ }>, Error>>;
1146
+ fetchStatus: _tanstack_query_core.FetchStatus;
1147
+ promise: Promise<NoInfer<{
1148
+ project_ext_id: string;
1149
+ period_start: string;
1150
+ period_end: string;
1151
+ total_spend: number;
1152
+ total_tokens: number;
1153
+ total_requests: number;
1154
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1155
+ model_groups: {
1156
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1157
+ };
1158
+ by_workspace: {
1159
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1160
+ };
1161
+ by_user: {
1162
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1163
+ };
1164
+ by_feature: {
1165
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1166
+ };
1167
+ invoice_pdf?: string | null;
1168
+ }>>;
1169
+ } | {
1170
+ metered: boolean | undefined;
1171
+ data: undefined;
1172
+ error: null;
1173
+ isError: false;
1174
+ isPending: true;
1175
+ isLoadingError: false;
1176
+ isRefetchError: false;
1177
+ isSuccess: false;
1178
+ isPlaceholderData: false;
1179
+ status: "pending";
1180
+ dataUpdatedAt: number;
1181
+ errorUpdatedAt: number;
1182
+ failureCount: number;
1183
+ failureReason: Error | null;
1184
+ errorUpdateCount: number;
1185
+ isFetched: boolean;
1186
+ isFetchedAfterMount: boolean;
1187
+ isFetching: boolean;
1188
+ isLoading: boolean;
1189
+ isInitialLoading: boolean;
1190
+ isPaused: boolean;
1191
+ isRefetching: boolean;
1192
+ isStale: boolean;
1193
+ isEnabled: boolean;
1194
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
1195
+ project_ext_id: string;
1196
+ period_start: string;
1197
+ period_end: string;
1198
+ total_spend: number;
1199
+ total_tokens: number;
1200
+ total_requests: number;
1201
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1202
+ model_groups: {
1203
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1204
+ };
1205
+ by_workspace: {
1206
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1207
+ };
1208
+ by_user: {
1209
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1210
+ };
1211
+ by_feature: {
1212
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1213
+ };
1214
+ invoice_pdf?: string | null;
1215
+ }>, Error>>;
1216
+ fetchStatus: _tanstack_query_core.FetchStatus;
1217
+ promise: Promise<NoInfer<{
1218
+ project_ext_id: string;
1219
+ period_start: string;
1220
+ period_end: string;
1221
+ total_spend: number;
1222
+ total_tokens: number;
1223
+ total_requests: number;
1224
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1225
+ model_groups: {
1226
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1227
+ };
1228
+ by_workspace: {
1229
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1230
+ };
1231
+ by_user: {
1232
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1233
+ };
1234
+ by_feature: {
1235
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1236
+ };
1237
+ invoice_pdf?: string | null;
1238
+ }>>;
1239
+ } | {
1240
+ metered: boolean | undefined;
1241
+ data: NoInfer<{
1242
+ project_ext_id: string;
1243
+ period_start: string;
1244
+ period_end: string;
1245
+ total_spend: number;
1246
+ total_tokens: number;
1247
+ total_requests: number;
1248
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1249
+ model_groups: {
1250
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1251
+ };
1252
+ by_workspace: {
1253
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1254
+ };
1255
+ by_user: {
1256
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1257
+ };
1258
+ by_feature: {
1259
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1260
+ };
1261
+ invoice_pdf?: string | null;
1262
+ }>;
1263
+ isError: false;
1264
+ error: null;
1265
+ isPending: false;
1266
+ isLoading: false;
1267
+ isLoadingError: false;
1268
+ isRefetchError: false;
1269
+ isSuccess: true;
1270
+ isPlaceholderData: true;
1271
+ status: "success";
1272
+ dataUpdatedAt: number;
1273
+ errorUpdatedAt: number;
1274
+ failureCount: number;
1275
+ failureReason: Error | null;
1276
+ errorUpdateCount: number;
1277
+ isFetched: boolean;
1278
+ isFetchedAfterMount: boolean;
1279
+ isFetching: boolean;
1280
+ isInitialLoading: boolean;
1281
+ isPaused: boolean;
1282
+ isRefetching: boolean;
1283
+ isStale: boolean;
1284
+ isEnabled: boolean;
1285
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
1286
+ project_ext_id: string;
1287
+ period_start: string;
1288
+ period_end: string;
1289
+ total_spend: number;
1290
+ total_tokens: number;
1291
+ total_requests: number;
1292
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1293
+ model_groups: {
1294
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1295
+ };
1296
+ by_workspace: {
1297
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1298
+ };
1299
+ by_user: {
1300
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1301
+ };
1302
+ by_feature: {
1303
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1304
+ };
1305
+ invoice_pdf?: string | null;
1306
+ }>, Error>>;
1307
+ fetchStatus: _tanstack_query_core.FetchStatus;
1308
+ promise: Promise<NoInfer<{
1309
+ project_ext_id: string;
1310
+ period_start: string;
1311
+ period_end: string;
1312
+ total_spend: number;
1313
+ total_tokens: number;
1314
+ total_requests: number;
1315
+ daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
1316
+ model_groups: {
1317
+ [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
1318
+ };
1319
+ by_workspace: {
1320
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1321
+ };
1322
+ by_user: {
1323
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1324
+ };
1325
+ by_feature: {
1326
+ [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
1327
+ };
1328
+ invoice_pdf?: string | null;
1329
+ }>>;
1330
+ };
1331
+ /** One day of aggregated usage across projects (for a spend/token trend). */
1332
+ interface AggregatedDailyUsage {
1333
+ date: string;
1334
+ /** Credits used that day (not dollars). */
1335
+ credits: number;
1336
+ totalTokens: number;
1337
+ apiRequests: number;
1338
+ }
1339
+ /** One model group's aggregated usage across projects (for a breakdown). */
1340
+ interface AggregatedModelGroupUsage {
1341
+ model: string;
1342
+ /** Credits used by this model group (not dollars). */
1343
+ credits: number;
1344
+ totalTokens: number;
1345
+ promptTokens: number;
1346
+ completionTokens: number;
1347
+ successfulRequests: number;
1348
+ }
1349
+ /** Aggregated AI usage + spend across several projects. */
1350
+ interface ProjectsUsageAggregate {
1351
+ /** Summed usage across the projects, in CREDITS (1 credit = $0.01 by default), not dollars. */
1352
+ totalCredits: number;
1353
+ /** Summed token count across the projects. */
1354
+ totalTokens: number;
1355
+ /** Summed API request count across the projects. */
1356
+ totalRequests: number;
1357
+ /** Per-day totals merged across every project, oldest first. */
1358
+ daily: AggregatedDailyUsage[];
1359
+ /** Per-model-group totals merged across every project, most credits first. */
1360
+ modelGroups: AggregatedModelGroupUsage[];
1361
+ /**
1362
+ * False when none of the loaded projects records usage (billing is off on this deployment), so
1363
+ * zeros mean "not metered". True while anything real was recorded, or before data arrived.
1364
+ */
1365
+ metered: boolean;
1366
+ /** True while any per-project query is still loading. */
1367
+ isLoading: boolean;
1368
+ /** True if any per-project query errored. */
1369
+ isError: boolean;
1370
+ }
1371
+ /**
1372
+ * Firm-wide AI usage + spend: aggregates {@link useProjectUsage} across several
1373
+ * projects (e.g. all of a firm's matters) in parallel and merges the real totals,
1374
+ * the daily trend, and the per-model breakdown. Shares the per-project query
1375
+ * cache, so it costs nothing extra where a project's usage is already loaded.
1376
+ * Numbers are genuine — zero projects (or zero billed work) yields zero totals;
1377
+ * callers render that honestly.
1378
+ */
1379
+ declare function useProjectsUsage(projectExtIds: string[], monthsBack?: number, options?: {
1380
+ enabled?: boolean;
1381
+ }): ProjectsUsageAggregate;
1382
+ /** List the Stripe invoices for a project's subscription. */
1383
+ declare function useProjectInvoices(projectExtId: string | undefined, options?: {
1384
+ enabled?: boolean;
1385
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
1386
+ project_ext_id: string;
1387
+ invoices: _arbidocs_client.components["schemas"]["ProjectInvoice"][];
1388
+ }>, Error>;
1389
+ /** Today's deployment-wide credit use for the current user (`credits_used`, in credits). */
1390
+ declare function useUserUsageToday(options?: {
1391
+ enabled?: boolean;
1392
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
1393
+ credits_used: number;
1394
+ }>, Error>;
1395
+
1396
+ /** An agent or deployment config: section name (`Agents`, `QueryLLM`, ...) to its parameters. */
1397
+ type AgentConfigSections = Record<string, Record<string, unknown>>;
1398
+ /** Create a task from a `CreateTaskRequest`. Resolves with the created task. */
1399
+ declare function useCreateTask(): _tanstack_react_query.UseMutationResult<{
1400
+ external_id: string;
1401
+ name: string;
1402
+ trigger_type: string;
1403
+ rrule: string | null;
1404
+ run_at: string | null;
1405
+ timezone: string;
1406
+ event_kind: string | null;
1407
+ action_type: string;
1408
+ prompt: string;
1409
+ skill_ref: string | null;
1410
+ status: string;
1411
+ next_run_at: string | null;
1412
+ last_run_at: string | null;
1413
+ last_error: string | null;
1414
+ in_progress: boolean;
1415
+ active_run_id: string | null;
1416
+ agent_session: string | null;
1417
+ active_response_id?: string | null;
1418
+ active_conversation_ext_id?: string | null;
1419
+ run_started_at: string | null;
1420
+ notify_on_complete: boolean;
1421
+ auth_mode: _arbidocs_client.components["schemas"]["AuthMode"];
1422
+ pending_auth_request_id?: string | null;
1423
+ pending_auth_session_pubkey?: string | null;
1424
+ pending_auth_agent_email?: string | null;
1425
+ created_by_kind: string;
1426
+ workspace_ext_id?: string | null;
1427
+ agent_ext_id?: string | null;
1428
+ task_plan?: _arbidocs_client.components["schemas"]["TaskPlan"] | null;
1429
+ is_goal_task: boolean;
1430
+ goal_state?: {
1431
+ [key: string]: unknown;
1432
+ } | null;
1433
+ created_at: string;
1434
+ updated_at: string;
1435
+ }, Error, {
1436
+ name: string;
1437
+ trigger_type: _arbidocs_client.components["schemas"]["TriggerType"];
1438
+ rrule?: string | null;
1439
+ run_at?: string | null;
1440
+ timezone: string;
1441
+ event_kind?: string | null;
1442
+ action_type: _arbidocs_client.components["schemas"]["ActionType"];
1443
+ prompt: string;
1444
+ skill_ref?: string | null;
1445
+ notify_on_complete?: boolean | null;
1446
+ auth_mode: _arbidocs_client.components["schemas"]["AuthMode"];
1447
+ workspace_ext_id?: string | null;
1448
+ agent_ext_id?: string | null;
1449
+ task_plan?: _arbidocs_client.components["schemas"]["TaskPlan"] | null;
1450
+ }, unknown>;
1451
+ /** Patch a task; also pause / resume with `{ status }`. */
1452
+ declare function useUpdateTask(): _tanstack_react_query.UseMutationResult<{
1453
+ external_id: string;
1454
+ name: string;
1455
+ trigger_type: string;
1456
+ rrule: string | null;
1457
+ run_at: string | null;
1458
+ timezone: string;
1459
+ event_kind: string | null;
1460
+ action_type: string;
1461
+ prompt: string;
1462
+ skill_ref: string | null;
1463
+ status: string;
1464
+ next_run_at: string | null;
1465
+ last_run_at: string | null;
1466
+ last_error: string | null;
1467
+ in_progress: boolean;
1468
+ active_run_id: string | null;
1469
+ agent_session: string | null;
1470
+ active_response_id?: string | null;
1471
+ active_conversation_ext_id?: string | null;
1472
+ run_started_at: string | null;
1473
+ notify_on_complete: boolean;
1474
+ auth_mode: _arbidocs_client.components["schemas"]["AuthMode"];
1475
+ pending_auth_request_id?: string | null;
1476
+ pending_auth_session_pubkey?: string | null;
1477
+ pending_auth_agent_email?: string | null;
1478
+ created_by_kind: string;
1479
+ workspace_ext_id?: string | null;
1480
+ agent_ext_id?: string | null;
1481
+ task_plan?: _arbidocs_client.components["schemas"]["TaskPlan"] | null;
1482
+ is_goal_task: boolean;
1483
+ goal_state?: {
1484
+ [key: string]: unknown;
1485
+ } | null;
1486
+ created_at: string;
1487
+ updated_at: string;
1488
+ }, Error, {
1489
+ taskId: string;
1490
+ patch: UpdateTaskRequest;
1491
+ }, unknown>;
1492
+ /**
1493
+ * Run a task now, without moving its schedule. A run parked waiting for workspace access (a
1494
+ * temporary authorization tier) is granted a temporary, session-scoped key and run again, so the
1495
+ * owner clicking Run is the approval. Resolves with the updated task.
1496
+ */
1497
+ declare function useRunTask(): _tanstack_react_query.UseMutationResult<{
1498
+ external_id: string;
1499
+ name: string;
1500
+ trigger_type: string;
1501
+ rrule: string | null;
1502
+ run_at: string | null;
1503
+ timezone: string;
1504
+ event_kind: string | null;
1505
+ action_type: string;
1506
+ prompt: string;
1507
+ skill_ref: string | null;
1508
+ status: string;
1509
+ next_run_at: string | null;
1510
+ last_run_at: string | null;
1511
+ last_error: string | null;
1512
+ in_progress: boolean;
1513
+ active_run_id: string | null;
1514
+ agent_session: string | null;
1515
+ active_response_id?: string | null;
1516
+ active_conversation_ext_id?: string | null;
1517
+ run_started_at: string | null;
1518
+ notify_on_complete: boolean;
1519
+ auth_mode: _arbidocs_client.components["schemas"]["AuthMode"];
1520
+ pending_auth_request_id?: string | null;
1521
+ pending_auth_session_pubkey?: string | null;
1522
+ pending_auth_agent_email?: string | null;
1523
+ created_by_kind: string;
1524
+ workspace_ext_id?: string | null;
1525
+ agent_ext_id?: string | null;
1526
+ task_plan?: _arbidocs_client.components["schemas"]["TaskPlan"] | null;
1527
+ is_goal_task: boolean;
1528
+ goal_state?: {
1529
+ [key: string]: unknown;
1530
+ } | null;
1531
+ created_at: string;
1532
+ updated_at: string;
1533
+ }, Error, string, unknown>;
1534
+ declare function useDeleteTask(): _tanstack_react_query.UseMutationResult<void, Error, string, unknown>;
1535
+ /** A task's run history, newest first; polls every 3 s while a run is in flight. */
1536
+ declare function useTaskRuns(taskId: string | undefined, options?: {
1537
+ enabled?: boolean;
1538
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
1539
+ run_id?: string | null;
1540
+ conversation_ext_id?: string | null;
1541
+ status: string;
1542
+ error?: string | null;
1543
+ started_at?: string | null;
1544
+ finished_at?: string | null;
1545
+ }[]>, Error>;
1546
+ /** Create an agent by name. The one-time `signing_private_key` is in the result. */
1547
+ declare function useCreateAgent(): _tanstack_react_query.UseMutationResult<{
1548
+ external_id: string;
1549
+ parent_ext_id?: string | null;
1550
+ email: string;
1551
+ given_name: string;
1552
+ family_name?: string | null;
1553
+ picture?: string | null;
1554
+ encryption_public_key: string;
1555
+ is_sso: boolean;
1556
+ signing_private_key: string;
1557
+ }, Error, string, unknown>;
1558
+ /**
1559
+ * An agent's pinned config (persona, model, tool switches), or the library default config when
1560
+ * `agentExtId` is omitted: edit forms seed from the first, create forms from the second.
1561
+ */
1562
+ declare function useAgentConfig(agentExtId?: string, options?: {
1563
+ enabled?: boolean;
1564
+ }): _tanstack_react_query.UseQueryResult<NoInfer<AgentConfigSections | null>, Error>;
1565
+ /** The model names an agent may be pinned to. */
1566
+ declare function useAgentModels(options?: {
1567
+ enabled?: boolean;
1568
+ }): _tanstack_react_query.UseQueryResult<NoInfer<string[]>, Error>;
1569
+ interface SaveAgentConfigVars {
1570
+ agentExtId: string;
1571
+ /** Config title; defaults to `agent-<agentExtId>`. */
1572
+ title?: string;
1573
+ /**
1574
+ * Parameters to set, per section, e.g. `{ Agents: { PERSONA: '...', WEB_SEARCH_ENABLED: true } }`.
1575
+ * Merged key by key over the agent's current config (or the default one for a new agent).
1576
+ */
1577
+ sections: AgentConfigSections;
1578
+ }
1579
+ /** Pin a behaviour config to an agent: read its current config, merge `sections` over it, save. */
1580
+ declare function useSaveAgentConfig(): _tanstack_react_query.UseMutationResult<{
1581
+ external_id: string;
1582
+ title: string | null;
1583
+ created_at: string;
1584
+ }, Error, SaveAgentConfigVars, unknown>;
1585
+ /** The workspaces an agent can currently open (`permanent` tells standing from temporary). */
1586
+ declare function useAgentWorkspaces(agentExtId: string | undefined, options?: {
1587
+ enabled?: boolean;
1588
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
1589
+ workspace_ext_id: string;
1590
+ name: string;
1591
+ role: _arbidocs_client.components["schemas"]["WorkspaceRole"];
1592
+ joined_at: string;
1593
+ permanent: boolean;
1594
+ is_default: boolean;
1595
+ }[]>, Error>;
1596
+ /** How an agent is given a workspace. */
1597
+ type AgentAccessMode =
1598
+ /** A standing member: the agent can open the workspace while the owner is away. */
1599
+ {
1600
+ kind: 'standing';
1601
+ }
1602
+ /** A TTL'd, session-scoped key: gone when the run session ends. `ttlSeconds` omitted = default. */
1603
+ | {
1604
+ kind: 'temporary';
1605
+ ttlSeconds?: number;
1606
+ };
1607
+ interface GrantAgentAccessVars {
1608
+ agentExtId: string;
1609
+ workspaceId: string;
1610
+ /** Default `{ kind: 'standing' }`. */
1611
+ mode?: AgentAccessMode;
1612
+ }
1613
+ /**
1614
+ * Give an agent access to a workspace you own. Standing access adds the agent as a member without
1615
+ * switching the open workspace; temporary access mints the agent's run session and deposits a
1616
+ * session-scoped key on it (the `session_pubkey_b64` path).
1617
+ */
1618
+ declare function useGrantAgentAccess(): _tanstack_react_query.UseMutationResult<{
1619
+ session_pubkey_b64: string;
1620
+ agent_email: string;
1621
+ ttl: number;
1622
+ } | {
1623
+ user: {
1624
+ external_id: string;
1625
+ parent_ext_id?: string | null | undefined;
1626
+ email: string;
1627
+ given_name: string;
1628
+ family_name?: string | null | undefined;
1629
+ picture?: string | null | undefined;
1630
+ encryption_public_key: string;
1631
+ is_sso: boolean;
1632
+ };
1633
+ role: _arbidocs_client.components["schemas"]["WorkspaceRole"];
1634
+ joined_at: string;
1635
+ conversation_count: number;
1636
+ document_count: number;
1637
+ files_mb: number;
1638
+ agent_ext_id?: string | null | undefined;
1639
+ is_temporary: boolean;
1640
+ }[], Error, GrantAgentAccessVars, unknown>;
1641
+ /** Take an agent out of a workspace (owner only). Restores the previously open workspace. */
1642
+ declare function useRevokeAgentAccess(): _tanstack_react_query.UseMutationResult<void, Error, {
1643
+ agentExtId: string;
1644
+ workspaceId: string;
1645
+ }, unknown>;
1646
+ /**
1647
+ * The skills the user can run (own plus the shared marketplace), metadata only. Skills live in the
1648
+ * deployment marketplace, so the list does not depend on the open workspace.
1649
+ */
1650
+ declare function useSkills(options?: {
1651
+ enabled?: boolean;
1652
+ includeHidden?: boolean;
1653
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
1654
+ name: string;
1655
+ slug: string;
1656
+ description: string;
1657
+ user_invocable: boolean;
1658
+ arg_hint: string;
1659
+ skill_type: string;
1660
+ workspace_ext_id: string;
1661
+ doc_ext_id: string;
1662
+ updated_at: string;
1663
+ visibility: string;
1664
+ is_owner: boolean;
1665
+ }[]>, Error>;
1666
+
1667
+ /**
1668
+ * Contacts: the user's colleagues and pending invitations.
1669
+ *
1670
+ * Shares `arbiQueryKeys.contacts()` with `useDirectMessages`, so a change made here refreshes the
1671
+ * conversation rail on its own. The parts that turn an email list into a request and the backend
1672
+ * outcome into a sentence live in `@arbidocs/blocks/collaboration` (`AddContactsForm`).
1673
+ */
1674
+ /** The user's contacts, registered and pending. */
1675
+ declare function useContacts(options?: {
1676
+ enabled?: boolean;
1677
+ }): _tanstack_react_query.UseQueryResult<NoInfer<{
1678
+ external_id?: string | null | undefined;
1679
+ email: string;
1680
+ user?: {
1681
+ external_id: string;
1682
+ parent_ext_id?: string | null | undefined;
1683
+ email: string;
1684
+ given_name: string;
1685
+ family_name?: string | null | undefined;
1686
+ picture?: string | null | undefined;
1687
+ encryption_public_key: string;
1688
+ is_sso: boolean;
1689
+ } | null | undefined;
1690
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1691
+ created_at: string;
1692
+ shared_workspace_ext_id?: string | null | undefined;
1693
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1694
+ outcome_detail?: string | null | undefined;
1695
+ }[]>, Error>;
1696
+ /** Contacts still waiting to join (an invitation sent or expired); `Invite again` re-adds them. */
1697
+ declare function usePendingContacts(options?: {
1698
+ enabled?: boolean;
1699
+ }): {
1700
+ pending: {
1701
+ external_id?: string | null | undefined;
1702
+ email: string;
1703
+ user?: {
1704
+ external_id: string;
1705
+ parent_ext_id?: string | null | undefined;
1706
+ email: string;
1707
+ given_name: string;
1708
+ family_name?: string | null | undefined;
1709
+ picture?: string | null | undefined;
1710
+ encryption_public_key: string;
1711
+ is_sso: boolean;
1712
+ } | null | undefined;
1713
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1714
+ created_at: string;
1715
+ shared_workspace_ext_id?: string | null | undefined;
1716
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1717
+ outcome_detail?: string | null | undefined;
1718
+ }[];
1719
+ data: NoInfer<{
1720
+ external_id?: string | null | undefined;
1721
+ email: string;
1722
+ user?: {
1723
+ external_id: string;
1724
+ parent_ext_id?: string | null | undefined;
1725
+ email: string;
1726
+ given_name: string;
1727
+ family_name?: string | null | undefined;
1728
+ picture?: string | null | undefined;
1729
+ encryption_public_key: string;
1730
+ is_sso: boolean;
1731
+ } | null | undefined;
1732
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1733
+ created_at: string;
1734
+ shared_workspace_ext_id?: string | null | undefined;
1735
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1736
+ outcome_detail?: string | null | undefined;
1737
+ }[]>;
1738
+ error: Error;
1739
+ isError: true;
1740
+ isPending: false;
1741
+ isLoading: false;
1742
+ isLoadingError: false;
1743
+ isRefetchError: true;
1744
+ isSuccess: false;
1745
+ isPlaceholderData: false;
1746
+ status: "error";
1747
+ dataUpdatedAt: number;
1748
+ errorUpdatedAt: number;
1749
+ failureCount: number;
1750
+ failureReason: Error | null;
1751
+ errorUpdateCount: number;
1752
+ isFetched: boolean;
1753
+ isFetchedAfterMount: boolean;
1754
+ isFetching: boolean;
1755
+ isInitialLoading: boolean;
1756
+ isPaused: boolean;
1757
+ isRefetching: boolean;
1758
+ isStale: boolean;
1759
+ isEnabled: boolean;
1760
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
1761
+ external_id?: string | null | undefined;
1762
+ email: string;
1763
+ user?: {
1764
+ external_id: string;
1765
+ parent_ext_id?: string | null | undefined;
1766
+ email: string;
1767
+ given_name: string;
1768
+ family_name?: string | null | undefined;
1769
+ picture?: string | null | undefined;
1770
+ encryption_public_key: string;
1771
+ is_sso: boolean;
1772
+ } | null | undefined;
1773
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1774
+ created_at: string;
1775
+ shared_workspace_ext_id?: string | null | undefined;
1776
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1777
+ outcome_detail?: string | null | undefined;
1778
+ }[]>, Error>>;
1779
+ fetchStatus: _tanstack_query_core.FetchStatus;
1780
+ promise: Promise<NoInfer<{
1781
+ external_id?: string | null | undefined;
1782
+ email: string;
1783
+ user?: {
1784
+ external_id: string;
1785
+ parent_ext_id?: string | null | undefined;
1786
+ email: string;
1787
+ given_name: string;
1788
+ family_name?: string | null | undefined;
1789
+ picture?: string | null | undefined;
1790
+ encryption_public_key: string;
1791
+ is_sso: boolean;
1792
+ } | null | undefined;
1793
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1794
+ created_at: string;
1795
+ shared_workspace_ext_id?: string | null | undefined;
1796
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1797
+ outcome_detail?: string | null | undefined;
1798
+ }[]>>;
1799
+ } | {
1800
+ pending: {
1801
+ external_id?: string | null | undefined;
1802
+ email: string;
1803
+ user?: {
1804
+ external_id: string;
1805
+ parent_ext_id?: string | null | undefined;
1806
+ email: string;
1807
+ given_name: string;
1808
+ family_name?: string | null | undefined;
1809
+ picture?: string | null | undefined;
1810
+ encryption_public_key: string;
1811
+ is_sso: boolean;
1812
+ } | null | undefined;
1813
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1814
+ created_at: string;
1815
+ shared_workspace_ext_id?: string | null | undefined;
1816
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1817
+ outcome_detail?: string | null | undefined;
1818
+ }[];
1819
+ data: NoInfer<{
1820
+ external_id?: string | null | undefined;
1821
+ email: string;
1822
+ user?: {
1823
+ external_id: string;
1824
+ parent_ext_id?: string | null | undefined;
1825
+ email: string;
1826
+ given_name: string;
1827
+ family_name?: string | null | undefined;
1828
+ picture?: string | null | undefined;
1829
+ encryption_public_key: string;
1830
+ is_sso: boolean;
1831
+ } | null | undefined;
1832
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1833
+ created_at: string;
1834
+ shared_workspace_ext_id?: string | null | undefined;
1835
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1836
+ outcome_detail?: string | null | undefined;
1837
+ }[]>;
1838
+ error: null;
1839
+ isError: false;
1840
+ isPending: false;
1841
+ isLoading: false;
1842
+ isLoadingError: false;
1843
+ isRefetchError: false;
1844
+ isSuccess: true;
1845
+ isPlaceholderData: false;
1846
+ status: "success";
1847
+ dataUpdatedAt: number;
1848
+ errorUpdatedAt: number;
1849
+ failureCount: number;
1850
+ failureReason: Error | null;
1851
+ errorUpdateCount: number;
1852
+ isFetched: boolean;
1853
+ isFetchedAfterMount: boolean;
1854
+ isFetching: boolean;
1855
+ isInitialLoading: boolean;
1856
+ isPaused: boolean;
1857
+ isRefetching: boolean;
1858
+ isStale: boolean;
1859
+ isEnabled: boolean;
1860
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
1861
+ external_id?: string | null | undefined;
1862
+ email: string;
1863
+ user?: {
1864
+ external_id: string;
1865
+ parent_ext_id?: string | null | undefined;
1866
+ email: string;
1867
+ given_name: string;
1868
+ family_name?: string | null | undefined;
1869
+ picture?: string | null | undefined;
1870
+ encryption_public_key: string;
1871
+ is_sso: boolean;
1872
+ } | null | undefined;
1873
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1874
+ created_at: string;
1875
+ shared_workspace_ext_id?: string | null | undefined;
1876
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1877
+ outcome_detail?: string | null | undefined;
1878
+ }[]>, Error>>;
1879
+ fetchStatus: _tanstack_query_core.FetchStatus;
1880
+ promise: Promise<NoInfer<{
1881
+ external_id?: string | null | undefined;
1882
+ email: string;
1883
+ user?: {
1884
+ external_id: string;
1885
+ parent_ext_id?: string | null | undefined;
1886
+ email: string;
1887
+ given_name: string;
1888
+ family_name?: string | null | undefined;
1889
+ picture?: string | null | undefined;
1890
+ encryption_public_key: string;
1891
+ is_sso: boolean;
1892
+ } | null | undefined;
1893
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1894
+ created_at: string;
1895
+ shared_workspace_ext_id?: string | null | undefined;
1896
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1897
+ outcome_detail?: string | null | undefined;
1898
+ }[]>>;
1899
+ } | {
1900
+ pending: {
1901
+ external_id?: string | null | undefined;
1902
+ email: string;
1903
+ user?: {
1904
+ external_id: string;
1905
+ parent_ext_id?: string | null | undefined;
1906
+ email: string;
1907
+ given_name: string;
1908
+ family_name?: string | null | undefined;
1909
+ picture?: string | null | undefined;
1910
+ encryption_public_key: string;
1911
+ is_sso: boolean;
1912
+ } | null | undefined;
1913
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1914
+ created_at: string;
1915
+ shared_workspace_ext_id?: string | null | undefined;
1916
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1917
+ outcome_detail?: string | null | undefined;
1918
+ }[];
1919
+ data: undefined;
1920
+ error: Error;
1921
+ isError: true;
1922
+ isPending: false;
1923
+ isLoading: false;
1924
+ isLoadingError: true;
1925
+ isRefetchError: false;
1926
+ isSuccess: false;
1927
+ isPlaceholderData: false;
1928
+ status: "error";
1929
+ dataUpdatedAt: number;
1930
+ errorUpdatedAt: number;
1931
+ failureCount: number;
1932
+ failureReason: Error | null;
1933
+ errorUpdateCount: number;
1934
+ isFetched: boolean;
1935
+ isFetchedAfterMount: boolean;
1936
+ isFetching: boolean;
1937
+ isInitialLoading: boolean;
1938
+ isPaused: boolean;
1939
+ isRefetching: boolean;
1940
+ isStale: boolean;
1941
+ isEnabled: boolean;
1942
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
1943
+ external_id?: string | null | undefined;
1944
+ email: string;
1945
+ user?: {
1946
+ external_id: string;
1947
+ parent_ext_id?: string | null | undefined;
1948
+ email: string;
1949
+ given_name: string;
1950
+ family_name?: string | null | undefined;
1951
+ picture?: string | null | undefined;
1952
+ encryption_public_key: string;
1953
+ is_sso: boolean;
1954
+ } | null | undefined;
1955
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1956
+ created_at: string;
1957
+ shared_workspace_ext_id?: string | null | undefined;
1958
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1959
+ outcome_detail?: string | null | undefined;
1960
+ }[]>, Error>>;
1961
+ fetchStatus: _tanstack_query_core.FetchStatus;
1962
+ promise: Promise<NoInfer<{
1963
+ external_id?: string | null | undefined;
1964
+ email: string;
1965
+ user?: {
1966
+ external_id: string;
1967
+ parent_ext_id?: string | null | undefined;
1968
+ email: string;
1969
+ given_name: string;
1970
+ family_name?: string | null | undefined;
1971
+ picture?: string | null | undefined;
1972
+ encryption_public_key: string;
1973
+ is_sso: boolean;
1974
+ } | null | undefined;
1975
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1976
+ created_at: string;
1977
+ shared_workspace_ext_id?: string | null | undefined;
1978
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1979
+ outcome_detail?: string | null | undefined;
1980
+ }[]>>;
1981
+ } | {
1982
+ pending: {
1983
+ external_id?: string | null | undefined;
1984
+ email: string;
1985
+ user?: {
1986
+ external_id: string;
1987
+ parent_ext_id?: string | null | undefined;
1988
+ email: string;
1989
+ given_name: string;
1990
+ family_name?: string | null | undefined;
1991
+ picture?: string | null | undefined;
1992
+ encryption_public_key: string;
1993
+ is_sso: boolean;
1994
+ } | null | undefined;
1995
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
1996
+ created_at: string;
1997
+ shared_workspace_ext_id?: string | null | undefined;
1998
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
1999
+ outcome_detail?: string | null | undefined;
2000
+ }[];
2001
+ data: undefined;
2002
+ error: null;
2003
+ isError: false;
2004
+ isPending: true;
2005
+ isLoading: true;
2006
+ isLoadingError: false;
2007
+ isRefetchError: false;
2008
+ isSuccess: false;
2009
+ isPlaceholderData: false;
2010
+ status: "pending";
2011
+ dataUpdatedAt: number;
2012
+ errorUpdatedAt: number;
2013
+ failureCount: number;
2014
+ failureReason: Error | null;
2015
+ errorUpdateCount: number;
2016
+ isFetched: boolean;
2017
+ isFetchedAfterMount: boolean;
2018
+ isFetching: boolean;
2019
+ isInitialLoading: boolean;
2020
+ isPaused: boolean;
2021
+ isRefetching: boolean;
2022
+ isStale: boolean;
2023
+ isEnabled: boolean;
2024
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
2025
+ external_id?: string | null | undefined;
2026
+ email: string;
2027
+ user?: {
2028
+ external_id: string;
2029
+ parent_ext_id?: string | null | undefined;
2030
+ email: string;
2031
+ given_name: string;
2032
+ family_name?: string | null | undefined;
2033
+ picture?: string | null | undefined;
2034
+ encryption_public_key: string;
2035
+ is_sso: boolean;
2036
+ } | null | undefined;
2037
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2038
+ created_at: string;
2039
+ shared_workspace_ext_id?: string | null | undefined;
2040
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2041
+ outcome_detail?: string | null | undefined;
2042
+ }[]>, Error>>;
2043
+ fetchStatus: _tanstack_query_core.FetchStatus;
2044
+ promise: Promise<NoInfer<{
2045
+ external_id?: string | null | undefined;
2046
+ email: string;
2047
+ user?: {
2048
+ external_id: string;
2049
+ parent_ext_id?: string | null | undefined;
2050
+ email: string;
2051
+ given_name: string;
2052
+ family_name?: string | null | undefined;
2053
+ picture?: string | null | undefined;
2054
+ encryption_public_key: string;
2055
+ is_sso: boolean;
2056
+ } | null | undefined;
2057
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2058
+ created_at: string;
2059
+ shared_workspace_ext_id?: string | null | undefined;
2060
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2061
+ outcome_detail?: string | null | undefined;
2062
+ }[]>>;
2063
+ } | {
2064
+ pending: {
2065
+ external_id?: string | null | undefined;
2066
+ email: string;
2067
+ user?: {
2068
+ external_id: string;
2069
+ parent_ext_id?: string | null | undefined;
2070
+ email: string;
2071
+ given_name: string;
2072
+ family_name?: string | null | undefined;
2073
+ picture?: string | null | undefined;
2074
+ encryption_public_key: string;
2075
+ is_sso: boolean;
2076
+ } | null | undefined;
2077
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2078
+ created_at: string;
2079
+ shared_workspace_ext_id?: string | null | undefined;
2080
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2081
+ outcome_detail?: string | null | undefined;
2082
+ }[];
2083
+ data: undefined;
2084
+ error: null;
2085
+ isError: false;
2086
+ isPending: true;
2087
+ isLoadingError: false;
2088
+ isRefetchError: false;
2089
+ isSuccess: false;
2090
+ isPlaceholderData: false;
2091
+ status: "pending";
2092
+ dataUpdatedAt: number;
2093
+ errorUpdatedAt: number;
2094
+ failureCount: number;
2095
+ failureReason: Error | null;
2096
+ errorUpdateCount: number;
2097
+ isFetched: boolean;
2098
+ isFetchedAfterMount: boolean;
2099
+ isFetching: boolean;
2100
+ isLoading: boolean;
2101
+ isInitialLoading: boolean;
2102
+ isPaused: boolean;
2103
+ isRefetching: boolean;
2104
+ isStale: boolean;
2105
+ isEnabled: boolean;
2106
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
2107
+ external_id?: string | null | undefined;
2108
+ email: string;
2109
+ user?: {
2110
+ external_id: string;
2111
+ parent_ext_id?: string | null | undefined;
2112
+ email: string;
2113
+ given_name: string;
2114
+ family_name?: string | null | undefined;
2115
+ picture?: string | null | undefined;
2116
+ encryption_public_key: string;
2117
+ is_sso: boolean;
2118
+ } | null | undefined;
2119
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2120
+ created_at: string;
2121
+ shared_workspace_ext_id?: string | null | undefined;
2122
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2123
+ outcome_detail?: string | null | undefined;
2124
+ }[]>, Error>>;
2125
+ fetchStatus: _tanstack_query_core.FetchStatus;
2126
+ promise: Promise<NoInfer<{
2127
+ external_id?: string | null | undefined;
2128
+ email: string;
2129
+ user?: {
2130
+ external_id: string;
2131
+ parent_ext_id?: string | null | undefined;
2132
+ email: string;
2133
+ given_name: string;
2134
+ family_name?: string | null | undefined;
2135
+ picture?: string | null | undefined;
2136
+ encryption_public_key: string;
2137
+ is_sso: boolean;
2138
+ } | null | undefined;
2139
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2140
+ created_at: string;
2141
+ shared_workspace_ext_id?: string | null | undefined;
2142
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2143
+ outcome_detail?: string | null | undefined;
2144
+ }[]>>;
2145
+ } | {
2146
+ pending: {
2147
+ external_id?: string | null | undefined;
2148
+ email: string;
2149
+ user?: {
2150
+ external_id: string;
2151
+ parent_ext_id?: string | null | undefined;
2152
+ email: string;
2153
+ given_name: string;
2154
+ family_name?: string | null | undefined;
2155
+ picture?: string | null | undefined;
2156
+ encryption_public_key: string;
2157
+ is_sso: boolean;
2158
+ } | null | undefined;
2159
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2160
+ created_at: string;
2161
+ shared_workspace_ext_id?: string | null | undefined;
2162
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2163
+ outcome_detail?: string | null | undefined;
2164
+ }[];
2165
+ data: NoInfer<{
2166
+ external_id?: string | null | undefined;
2167
+ email: string;
2168
+ user?: {
2169
+ external_id: string;
2170
+ parent_ext_id?: string | null | undefined;
2171
+ email: string;
2172
+ given_name: string;
2173
+ family_name?: string | null | undefined;
2174
+ picture?: string | null | undefined;
2175
+ encryption_public_key: string;
2176
+ is_sso: boolean;
2177
+ } | null | undefined;
2178
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2179
+ created_at: string;
2180
+ shared_workspace_ext_id?: string | null | undefined;
2181
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2182
+ outcome_detail?: string | null | undefined;
2183
+ }[]>;
2184
+ isError: false;
2185
+ error: null;
2186
+ isPending: false;
2187
+ isLoading: false;
2188
+ isLoadingError: false;
2189
+ isRefetchError: false;
2190
+ isSuccess: true;
2191
+ isPlaceholderData: true;
2192
+ status: "success";
2193
+ dataUpdatedAt: number;
2194
+ errorUpdatedAt: number;
2195
+ failureCount: number;
2196
+ failureReason: Error | null;
2197
+ errorUpdateCount: number;
2198
+ isFetched: boolean;
2199
+ isFetchedAfterMount: boolean;
2200
+ isFetching: boolean;
2201
+ isInitialLoading: boolean;
2202
+ isPaused: boolean;
2203
+ isRefetching: boolean;
2204
+ isStale: boolean;
2205
+ isEnabled: boolean;
2206
+ refetch: (options?: _tanstack_query_core.RefetchOptions) => Promise<_tanstack_query_core.QueryObserverResult<NoInfer<{
2207
+ external_id?: string | null | undefined;
2208
+ email: string;
2209
+ user?: {
2210
+ external_id: string;
2211
+ parent_ext_id?: string | null | undefined;
2212
+ email: string;
2213
+ given_name: string;
2214
+ family_name?: string | null | undefined;
2215
+ picture?: string | null | undefined;
2216
+ encryption_public_key: string;
2217
+ is_sso: boolean;
2218
+ } | null | undefined;
2219
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2220
+ created_at: string;
2221
+ shared_workspace_ext_id?: string | null | undefined;
2222
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2223
+ outcome_detail?: string | null | undefined;
2224
+ }[]>, Error>>;
2225
+ fetchStatus: _tanstack_query_core.FetchStatus;
2226
+ promise: Promise<NoInfer<{
2227
+ external_id?: string | null | undefined;
2228
+ email: string;
2229
+ user?: {
2230
+ external_id: string;
2231
+ parent_ext_id?: string | null | undefined;
2232
+ email: string;
2233
+ given_name: string;
2234
+ family_name?: string | null | undefined;
2235
+ picture?: string | null | undefined;
2236
+ encryption_public_key: string;
2237
+ is_sso: boolean;
2238
+ } | null | undefined;
2239
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
2240
+ created_at: string;
2241
+ shared_workspace_ext_id?: string | null | undefined;
2242
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2243
+ outcome_detail?: string | null | undefined;
2244
+ }[]>>;
2245
+ };
684
2246
  /**
685
- * List the caller's durable activity feed, newest first.
686
- *
687
- * Activity entries are backend-originated, to-self log lines that are always
688
- * read — they are deliberately kept out of the normal notifications/DM feed and
689
- * never affect the unread badge, so this is a separate, opt-in query.
2247
+ * Add contacts by email. An address not yet on ARBI is invited. Resolves with one row per
2248
+ * address (`outcome`, `status`); map it with `toAddContactsRows` from `@arbidocs/blocks/collaboration`.
690
2249
  */
691
- declare function useActivity(options?: {
692
- enabled?: boolean;
693
- limit?: number;
694
- offset?: number;
695
- }): _tanstack_react_query.UseQueryResult<NoInfer<{
696
- type: _arbidocs_client.components["schemas"]["NotificationType"];
697
- external_id: string;
698
- sender: {
699
- external_id: string;
700
- parent_ext_id?: string | null | undefined;
701
- email: string;
702
- given_name: string;
703
- family_name?: string | null | undefined;
704
- picture?: string | null | undefined;
705
- encryption_public_key: string;
706
- is_sso: boolean;
707
- };
708
- recipient: {
2250
+ declare function useAddContacts(): _tanstack_react_query.UseMutationResult<{
2251
+ external_id?: string | null | undefined;
2252
+ email: string;
2253
+ user?: {
709
2254
  external_id: string;
710
2255
  parent_ext_id?: string | null | undefined;
711
2256
  email: string;
@@ -714,134 +2259,50 @@ declare function useActivity(options?: {
714
2259
  picture?: string | null | undefined;
715
2260
  encryption_public_key: string;
716
2261
  is_sso: boolean;
717
- };
718
- workspace_ext_id?: string | null | undefined;
719
- content?: string | null | undefined;
720
- conversation_ext_id?: string | null | undefined;
721
- task_ext_id?: string | null | undefined;
722
- read: boolean;
723
- created_at: string;
724
- updated_at: string;
725
- }[]>, Error>;
726
- /** List the logged-in user's projects (billing accounts). */
727
- declare function useProjects(options?: {
728
- enabled?: boolean;
729
- }): _tanstack_react_query.UseQueryResult<NoInfer<{
730
- external_id: string;
731
- name: string;
732
- created_by: string;
733
- packs: number;
734
- subscription: string;
2262
+ } | null | undefined;
2263
+ status: "invitation_pending" | "invitation_expired" | "registered" | "failed";
735
2264
  created_at: string;
736
- quotas: {
737
- storage_gb: {
738
- used: number;
739
- limit: number;
740
- };
741
- ai_credits: {
742
- used: number;
743
- limit: number;
744
- };
745
- collaborators: {
746
- used: number;
747
- limit: number;
748
- };
749
- budget_reset_at?: number | null | undefined;
750
- };
751
- daily_cap_per_user?: number | null | undefined;
752
- price_id?: string | null | undefined;
753
- plan?: string | null | undefined;
754
- amount?: number | null | undefined;
755
- currency?: string | null | undefined;
756
- current_period_end?: number | null | undefined;
757
- cancel_at_period_end?: boolean | null | undefined;
758
- portal_url?: string | null | undefined;
759
- }[]>, Error>;
2265
+ shared_workspace_ext_id?: string | null | undefined;
2266
+ outcome?: ("invited" | "reinvited" | "not_resent_still_pending" | "contact_added" | "already_contact" | "failed") | null | undefined;
2267
+ outcome_detail?: string | null | undefined;
2268
+ }[], Error, string[], unknown>;
2269
+ /** Remove contacts, or withdraw invitations, by contact id. */
2270
+ declare function useRemoveContacts(): _tanstack_react_query.UseMutationResult<void, Error, string[], unknown>;
2271
+
760
2272
  /**
761
- * AI usage + spend breakdown for a project's billing period. `monthsBack`
762
- * selects the period (0 = current, 1 = previous month, …).
763
- */
764
- declare function useProjectUsage(projectExtId: string | undefined, monthsBack?: number, options?: {
765
- enabled?: boolean;
766
- }): _tanstack_react_query.UseQueryResult<NoInfer<{
767
- project_ext_id: string;
768
- period_start: string;
769
- period_end: string;
2273
+ * Credits: the unit the ARBI backend reports AI usage in.
2274
+ *
2275
+ * The usage endpoints (`/v1/user/projects/{id}/usage`, `/me/usage/today`) convert the metered USD
2276
+ * spend into whole credits at the API boundary: 1 credit = `CREDITS_TO_AI_USD`, which is $0.01 on
2277
+ * a default deployment. The fields are still named `spend` / `total_spend` in the schema, but they
2278
+ * hold CREDITS, never dollars. Label them as credits; use {@link creditsToUsd} only when a
2279
+ * dollar figure is genuinely wanted, with the deployment's own rate.
2280
+ */
2281
+ /** Dollars per credit on a default deployment (`CREDITS_TO_AI_USD`). */
2282
+ declare const DEFAULT_USD_PER_CREDIT = 0.01;
2283
+ interface FormatCreditsOptions {
2284
+ /** Append the unit ("12 credits"). Default true; pass false inside a column headed "Credits". */
2285
+ unit?: boolean;
2286
+ /** BCP 47 locale for the digit grouping. Default `en-US`. */
2287
+ locale?: string;
2288
+ }
2289
+ /** "1,234 credits" / "1 credit". The backend reports whole credits; this rounds away float dust. */
2290
+ declare function formatCredits(credits: number, options?: FormatCreditsOptions): string;
2291
+ /** The dollar value of an amount of credits. `usdPerCredit` defaults to {@link DEFAULT_USD_PER_CREDIT}. */
2292
+ declare function creditsToUsd(credits: number, usdPerCredit?: number): number;
2293
+ /** The slice of a usage response that tells whether anything was recorded. */
2294
+ interface UsageTotals {
770
2295
  total_spend: number;
771
2296
  total_tokens: number;
772
2297
  total_requests: number;
773
- daily: _arbidocs_client.components["schemas"]["DailyUsage"][];
774
- model_groups: {
775
- [key: string]: _arbidocs_client.components["schemas"]["ModelGroupUsage"];
776
- };
777
- by_workspace: {
778
- [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
779
- };
780
- by_user: {
781
- [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
782
- };
783
- by_feature: {
784
- [key: string]: _arbidocs_client.components["schemas"]["TagBreakdown"];
785
- };
786
- invoice_pdf?: string | null;
787
- }>, Error>;
788
- /** One day of aggregated usage across projects (for a spend/token trend). */
789
- interface AggregatedDailyUsage {
790
- date: string;
791
- spend: number;
792
- totalTokens: number;
793
- apiRequests: number;
794
- }
795
- /** One model group's aggregated usage across projects (for a breakdown). */
796
- interface AggregatedModelGroupUsage {
797
- model: string;
798
- spend: number;
799
- totalTokens: number;
800
- promptTokens: number;
801
- completionTokens: number;
802
- successfulRequests: number;
803
- }
804
- /** Aggregated AI usage + spend across several projects. */
805
- interface ProjectsUsageAggregate {
806
- /** Summed spend across the projects, in USD (the metered currency). */
807
- totalSpend: number;
808
- /** Summed token count across the projects. */
809
- totalTokens: number;
810
- /** Summed API request count across the projects. */
811
- totalRequests: number;
812
- /** Per-day totals merged across every project, oldest first. */
813
- daily: AggregatedDailyUsage[];
814
- /** Per-model-group totals merged across every project, biggest spend first. */
815
- modelGroups: AggregatedModelGroupUsage[];
816
- /** True while any per-project query is still loading. */
817
- isLoading: boolean;
818
- /** True if any per-project query errored. */
819
- isError: boolean;
820
2298
  }
821
2299
  /**
822
- * Firm-wide AI usage + spend: aggregates {@link useProjectUsage} across several
823
- * projects (e.g. all of a firm's matters) in parallel and merges the real totals,
824
- * the daily trend, and the per-model breakdown. Shares the per-project query
825
- * cache, so it costs nothing extra where a project's usage is already loaded.
826
- * Numbers are genuine — zero projects (or zero billed work) yields zero totals;
827
- * callers render that honestly.
2300
+ * Was this usage actually metered? A project on the `dev` plan belongs to a deployment with
2301
+ * billing switched off: the backend only records AI usage per project when billing is enabled, so
2302
+ * an all-zero response there means "not metered", not "nothing happened". Show a note instead of
2303
+ * silent zeros.
828
2304
  */
829
- declare function useProjectsUsage(projectExtIds: string[], monthsBack?: number, options?: {
830
- enabled?: boolean;
831
- }): ProjectsUsageAggregate;
832
- /** List the Stripe invoices for a project's subscription. */
833
- declare function useProjectInvoices(projectExtId: string | undefined, options?: {
834
- enabled?: boolean;
835
- }): _tanstack_react_query.UseQueryResult<NoInfer<{
836
- project_ext_id: string;
837
- invoices: _arbidocs_client.components["schemas"]["ProjectInvoice"][];
838
- }>, Error>;
839
- /** Today's deployment-wide credit spend for the current user. */
840
- declare function useUserUsageToday(options?: {
841
- enabled?: boolean;
842
- }): _tanstack_react_query.UseQueryResult<NoInfer<{
843
- credits_used: number;
844
- }>, Error>;
2305
+ declare function isUsageMetered(usage: UsageTotals, subscription: string | null | undefined): boolean;
845
2306
 
846
2307
  /**
847
2308
  * The AI engine — domain-agnostic hooks for building an AI-native app on ARBI.
@@ -998,6 +2459,27 @@ declare function textToArtifact(title: string, content: string, opts?: {
998
2459
  id?: string;
999
2460
  }): ArtifactEvent;
1000
2461
 
2462
+ /**
2463
+ * Citation markup normaliser.
2464
+ *
2465
+ * The backend marks a cited statement as a markdown link, `[statement](#cite-N)`, and the
2466
+ * statement can include the markdown that surrounds it: a list marker, a heading marker or the
2467
+ * opener of a bold/italic span whose closer sits after the link. Inside link text those tokens
2468
+ * are not parsed as block or inline syntax, so they show literally and break lists and bold:
2469
+ *
2470
+ * [- **Claimed quantum (by Claimant)](#cite-1):** **USD 47 million**
2471
+ *
2472
+ * `normalizeCitationMarkup` hoists the leading tokens out of the link text (and a trailing
2473
+ * emphasis closer after it), so the link only wraps the words:
2474
+ *
2475
+ * - **[Claimed quantum (by Claimant)](#cite-1):** **USD 47 million**
2476
+ *
2477
+ * It is conservative: emphasis that opens and closes inside the link text is valid markdown and
2478
+ * is left alone, an opener is only hoisted when its closer follows on the same line, and fenced
2479
+ * code blocks are never touched. The result is idempotent.
2480
+ */
2481
+ declare function normalizeCitationMarkup(markdown: string): string;
2482
+
1001
2483
  /**
1002
2484
  * Renders the live state of a single agentic task: streaming tokens, a "thinking"
1003
2485
  * indicator with the running step count, errors, and a grounded/cited footer with
@@ -1618,6 +3100,27 @@ interface DmConversation {
1618
3100
  sectionLabel?: string;
1619
3101
  }
1620
3102
 
3103
+ interface StartByEmailLabels {
3104
+ email: string;
3105
+ emailPlaceholder: string;
3106
+ message: string;
3107
+ messagePlaceholder: string;
3108
+ send: string;
3109
+ sending: string;
3110
+ invalidEmail: string;
3111
+ }
3112
+ declare const DEFAULT_START_BY_EMAIL_LABELS: StartByEmailLabels;
3113
+ interface StartByEmailProps {
3114
+ /** Send the first message to `email`. Reject to keep the form and show the error. */
3115
+ onStart: (email: string, text: string) => Promise<unknown>;
3116
+ /** Called after a successful send, with the value `onStart` resolved to. */
3117
+ onStarted?: (result: unknown) => void;
3118
+ classNames?: Pick<DmClassNames, 'sendButton'>;
3119
+ labels?: Partial<StartByEmailLabels>;
3120
+ className?: string;
3121
+ }
3122
+ declare function StartByEmail({ onStart, onStarted, classNames, labels, className, }: StartByEmailProps): React$1.JSX.Element;
3123
+
1621
3124
  interface DirectMessagesProps {
1622
3125
  /** Extra classes for the outer card (e.g. a page-specific height). */
1623
3126
  className?: string;
@@ -1627,8 +3130,29 @@ interface DirectMessagesProps {
1627
3130
  emptyThread?: React.ReactNode;
1628
3131
  /** Rendered in the rail when there are no conversations. */
1629
3132
  emptyList?: React.ReactNode;
3133
+ /**
3134
+ * Replaces the rail's "Conversations / N colleagues" heading. `null` for no heading.
3135
+ */
3136
+ listHeader?: React.ReactNode;
3137
+ /**
3138
+ * Pinned at the top of the rail, e.g. `<DmInviteChip onClick={...} />` from
3139
+ * `@arbidocs/blocks/collaboration`. Shown even when there are no conversations.
3140
+ */
3141
+ listLead?: React.ReactNode;
3142
+ /**
3143
+ * Offer a form at the top of the rail to message an address that is not in the list yet
3144
+ * (email plus first message). The new conversation opens once it is sent.
3145
+ */
3146
+ startByEmail?: boolean | {
3147
+ labels?: Partial<StartByEmailLabels>;
3148
+ };
3149
+ /**
3150
+ * Hide the signed-in user's own row. A contact list that includes the owner would otherwise
3151
+ * offer a conversation with yourself.
3152
+ */
3153
+ hideOwnContact?: boolean;
1630
3154
  }
1631
- declare function DirectMessages({ className, classNames, emptyThread, emptyList, }: DirectMessagesProps): React$1.JSX.Element;
3155
+ declare function DirectMessages({ className, classNames, emptyThread, emptyList, listHeader, listLead, startByEmail, hideOwnContact, }: DirectMessagesProps): React$1.JSX.Element;
1632
3156
 
1633
3157
  interface ConversationListProps {
1634
3158
  conversations: DmConversation[];
@@ -1642,6 +3166,11 @@ interface ConversationListProps {
1642
3166
  * call to action. Pass `null` for no heading at all.
1643
3167
  */
1644
3168
  header?: React.ReactNode;
3169
+ /**
3170
+ * Pinned above the rows, below the heading: a call to action such as `DmInviteChip` from
3171
+ * `@arbidocs/blocks/collaboration`, or a start-by-email form. Shown even when the list is empty.
3172
+ */
3173
+ lead?: React.ReactNode;
1645
3174
  /**
1646
3175
  * Overrides the rail's own sizing. The default is a fixed-width column beside
1647
3176
  * a thread; a consumer showing the list on its own needs it to fill instead,
@@ -1650,7 +3179,7 @@ interface ConversationListProps {
1650
3179
  */
1651
3180
  className?: string;
1652
3181
  }
1653
- declare function ConversationList({ conversations, selectedPeerId, onSelect, classNames, emptyState, header, className, }: ConversationListProps): React$1.JSX.Element;
3182
+ declare function ConversationList({ conversations, selectedPeerId, onSelect, classNames, emptyState, header, lead, className, }: ConversationListProps): React$1.JSX.Element;
1654
3183
 
1655
3184
  interface MessageThreadProps {
1656
3185
  conversation: DmConversation | null;
@@ -2447,4 +3976,4 @@ interface ArbiUiState {
2447
3976
  }
2448
3977
  declare const useArbiUiStore: zustand.UseBoundStore<zustand.StoreApi<ArbiUiState>>;
2449
3978
 
2450
- export { type ActivityContent, type ActivityDescription, ActivityFeed, type ActivityFeedProps, type AggregatedDailyUsage, type AggregatedModelGroupUsage, AiActionCard, AiAnswer, type AiRunOptions, type AiTaskStatus, AppleIcon, ArbiBotHeadIcon, ArbiBotIcon, ArbiChat, type ArbiChatLabels, ArbiChatPanel, type ArbiChatPanelProps, type ArbiChatProps, type ArbiChatTheme, ArbiIcon, ArbiProvider, type ArbiProviderProps, type ArbiUiState, ArbiWebSocketProvider, type ArbiWebSocketProviderProps, type ArbiWsState, type ArbiWsStatus, ArtifactCanvas, type AspectOption, AudIcon, type AudioRecorderState, ChatBubble, type ChatBubbleProps, type Chunk, type ChunkActivation, CitationRenderer, type CitationRendererProps, type CitationState, ClaudeIcon, CommandPalette, type CommandPaletteClassNames, type CommandPaletteProps, CommandPaletteProvider, type CommandPaletteProviderProps, type CommandPaletteValue, ConversationList, type ConversationListProps, type CropArea, type CropOutput, type CropResult, DEFAULT_ASPECT_OPTIONS, DateSeparator, type DateSeparatorProps, DirectMessages, type DirectMessagesProps, DmAvatar, type DmAvatarProps, type DmClassNames, DmComposer, type DmComposerProps, type DmConversation, type DmMessage, type DmNotification, type DmUser, DocIcon, DocQaPanel, DocSearch, DocumentCardMenu, type DocumentCardMenuProps, DocumentGallery, type DocumentGalleryProps, DocumentReview, type DocumentReviewProps, DocumentTable, type DocumentTableProps, DraftTitleControls, type DraftTitleControlsProps, EmlIcon, EntityIconComponent, FILE_TYPE_COLORS, FileIcon, FireworksIcon, GeminiIcon, GitHubIcon, GoogleIcon, HtmlIcon, ImageCropModal, type ImageCropModalProps, ImageCropper, type ImageCropperProps, ImgIcon, InlineMicButton, type InlineMicButtonProps, LinkedInIcon, type MessageArtifact, MessageArtifactCard, MessageBubble, type MessageBubbleProps, MessageThread, type MessageThreadProps, MicRecordingOverlay, type MicRecordingOverlayProps, MicWaveformIndicator, type MicWaveformIndicatorProps, type NotificationTypeMeta, OpenAIIcon, type PaletteNavItem, type ParsedChunk, type ParsedChunkMetadata, type ParsedDocument, type ParsedDocumentMetadata, PdfIcon, PhotoCapture, type PhotoCaptureProps, type ProjectsUsageAggregate, ProviderIcon, RUN_WINDOW_MS, type RenderMarkdown, type SearchChunk, SemanticSearch, type SemanticSearchProps, type ThreadAccessors, type ThreadItem, type ToolResponses, TxtIcon, TypingIndicator, type UseAudioRecorderResult, type UseCameraStreamResult, type UseDirectMessagesResult, type UseVideoRecorderResult, VidIcon, VideoCapture, type VideoCaptureProps, type VideoRecorderState, VoiceNoteRecorder, type VoiceNoteRecorderProps, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, cropImage, dayKey, describeActivity, formatElapsed, formatRelativeTime, getNotificationTypeMeta, getWorkspaceActionText, getWorkspaceSentPhrase, hasVideoTrack, isWorkspaceNotificationType, parseActivityContent, redlineStats, textToArtifact, toRedlineMarkdown, useActivity, useAgents, useAiTask, useArbi, useArbiConnected, useArbiDocumentSync, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useAudioRecorder, useCameraStream, useCommandPalette, useConfigs, useConversations, useDeleteAgents, useDirectMessages, useDocuments, useFacts, useHealth, useParsedDocument, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useSemanticSearch, useSessions, useTags, useTasks, useThumbnails, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };
3979
+ export { type ActivityContent, type ActivityDescription, ActivityFeed, type ActivityFeedProps, type AgentAccessMode, type AgentConfigSections, type AggregatedDailyUsage, type AggregatedModelGroupUsage, AiActionCard, AiAnswer, type AiRunOptions, type AiTaskStatus, AppleIcon, ArbiBotHeadIcon, ArbiBotIcon, type ArbiChat, type ArbiChatDocument, type ArbiChatMessage, type ArbiChatMessageStatus, type ArbiChatRole, type ArbiChatThread, ArbiIcon, ArbiProvider, type ArbiProviderProps, type ArbiUiState, ArbiWebSocketProvider, type ArbiWebSocketProviderProps, type ArbiWsState, type ArbiWsStatus, ArtifactCanvas, type AspectOption, AudIcon, type AudioRecorderState, ChatBubble, type ChatBubbleProps, type Chunk, type ChunkActivation, CitationRenderer, type CitationRendererProps, type CitationState, ClaudeIcon, CommandPalette, type CommandPaletteClassNames, type CommandPaletteProps, CommandPaletteProvider, type CommandPaletteProviderProps, type CommandPaletteValue, ConversationList, type ConversationListProps, type CropArea, type CropOutput, type CropResult, DEFAULT_ASPECT_OPTIONS, DEFAULT_START_BY_EMAIL_LABELS, DEFAULT_USD_PER_CREDIT, DateSeparator, type DateSeparatorProps, DirectMessages, type DirectMessagesProps, DmAvatar, type DmAvatarProps, type DmClassNames, DmComposer, type DmComposerProps, type DmConversation, type DmMessage, type DmNotification, type DmUser, DocIcon, DocQaPanel, DocSearch, DocumentCardMenu, type DocumentCardMenuProps, DocumentGallery, type DocumentGalleryProps, DocumentReview, type DocumentReviewProps, DocumentTable, type DocumentTableProps, DraftTitleControls, type DraftTitleControlsProps, EmlIcon, EntityIconComponent, FILE_TYPE_COLORS, FileIcon, FireworksIcon, type FormatCreditsOptions, GeminiIcon, GitHubIcon, GoogleIcon, type GrantAgentAccessVars, HtmlIcon, ImageCropModal, type ImageCropModalProps, ImageCropper, type ImageCropperProps, ImgIcon, InlineMicButton, type InlineMicButtonProps, LinkedInIcon, type MessageArtifact, MessageArtifactCard, MessageBubble, type MessageBubbleProps, MessageThread, type MessageThreadProps, MicRecordingOverlay, type MicRecordingOverlayProps, MicWaveformIndicator, type MicWaveformIndicatorProps, type NotificationTypeMeta, OpenAIIcon, type PaletteNavItem, type ParsedChunk, type ParsedChunkMetadata, type ParsedDocument, type ParsedDocumentMetadata, PdfIcon, PhotoCapture, type PhotoCaptureProps, type ProjectsUsageAggregate, ProviderIcon, RUN_WINDOW_MS, type RenderMarkdown, type SaveAgentConfigVars, type SearchChunk, SemanticSearch, type SemanticSearchProps, type ShellRecentWorkspaceItem, type ShellWorkspaceItem, type ShellWorkspaceKind, type ShellWorkspaceMember, type ShellWorkspaceSeed, type ShellWorkspaceSource, StartByEmail, type StartByEmailLabels, type StartByEmailProps, type ThreadAccessors, type ThreadItem, type ToolResponses, TxtIcon, TypingIndicator, type UsageTotals, type UseArbiChatOptions, type UseArbiShellWorkspacesOptions, type UseAudioRecorderResult, type UseCameraStreamResult, type UseDirectMessagesResult, type UseShellWorkspacesOptions, type UseShellWorkspacesResult, type UseVideoRecorderResult, VidIcon, VideoCapture, type VideoCaptureProps, type VideoRecorderState, VoiceNoteRecorder, type VoiceNoteRecorderProps, XlsIcon, annotateThread, arbiQueryKeys, captureFrameAsBlob, creditsToUsd, cropImage, dayKey, describeActivity, formatCredits, formatElapsed, formatRelativeTime, getNotificationTypeMeta, getWorkspaceActionText, getWorkspaceKind, getWorkspaceSentPhrase, hasVideoTrack, isUsageMetered, isWorkspaceNotificationType, normalizeCitationMarkup, parseActivityContent, pickRecentWorkspaces, redlineStats, resolveActiveWorkspace, textToArtifact, titleFromQuestion, toRedlineMarkdown, toShellWorkspace, useActivity, useAddContacts, useAgentConfig, useAgentModels, useAgentWorkspaces, useAgents, useAiTask, useArbi, useArbiChat, useArbiConnected, useArbiDocumentSync, useArbiShellWorkspaces, useArbiUiStore, useArbiWebSocket, useArbiWsContext, useArbiWsMessage, useArbiWsStatus, useArbiWsStore, useArbiWsTask, useArbiWsTasks, useAssistantQuery, useAudioRecorder, useCameraStream, useCommandPalette, useConfigs, useContacts, useConversations, useCreateAgent, useCreateTask, useDeleteAgents, useDeleteTask, useDirectMessages, useDocuments, useFacts, useGrantAgentAccess, useHealth, useParsedDocument, usePendingContacts, useProjectInvoices, useProjectUsage, useProjects, useProjectsUsage, useRemoveContacts, useRevokeAgentAccess, useRunTask, useSaveAgentConfig, useSemanticSearch, useSessions, useShellWorkspaces, useSkills, useTags, useTaskRuns, useTasks, useThumbnails, useUpdateTask, useUserUsageToday, useVideoRecorder, useWorkspaceDocs, useWorkspaces, userDisplayName, userInitials };