@parall/sdk 1.33.0 → 1.35.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/constants.ts CHANGED
@@ -13,6 +13,41 @@ export const CLIP_BASE = '/clip/v1';
13
13
  // included for catalog completeness and agent runtime delivery; product UI
14
14
  // should continue to display canonical model IDs/names.
15
15
  export const PLATFORM_MODELS = [
16
+ // Fable 5 rejects an explicit thinking "disabled" param (400) — bridges must
17
+ // omit the thinking config entirely instead of disabling it.
18
+ // "(1M)" variants opt the claude-code runtime into the 1M-token context
19
+ // window via the CLI's [1m] model-name suffix; the server proxy aliases the
20
+ // catalog ID back to the base model upstream.
21
+ {
22
+ id: 'anthropic/claude-fable-5',
23
+ name: 'Claude Fable 5',
24
+ provider: 'anthropic',
25
+ effortLevels: ['low', 'medium', 'high', 'xhigh', 'max'],
26
+ runtime_names: { 'claude-code': 'claude-fable-5' },
27
+ },
28
+ {
29
+ id: 'anthropic/claude-fable-5-1m',
30
+ name: 'Claude Fable 5 (1M)',
31
+ provider: 'anthropic',
32
+ effortLevels: ['low', 'medium', 'high', 'xhigh', 'max'],
33
+ runtime_names: { 'claude-code': 'claude-fable-5[1m]' },
34
+ upstream_id: 'anthropic/claude-fable-5',
35
+ },
36
+ {
37
+ id: 'anthropic/claude-opus-4.8',
38
+ name: 'Claude Opus 4.8',
39
+ provider: 'anthropic',
40
+ effortLevels: ['low', 'medium', 'high', 'xhigh', 'max'],
41
+ runtime_names: { 'claude-code': 'claude-opus-4-8' },
42
+ },
43
+ {
44
+ id: 'anthropic/claude-opus-4.8-1m',
45
+ name: 'Claude Opus 4.8 (1M)',
46
+ provider: 'anthropic',
47
+ effortLevels: ['low', 'medium', 'high', 'xhigh', 'max'],
48
+ runtime_names: { 'claude-code': 'claude-opus-4-8[1m]' },
49
+ upstream_id: 'anthropic/claude-opus-4.8',
50
+ },
16
51
  {
17
52
  id: 'anthropic/claude-opus-4.7',
18
53
  name: 'Claude Opus 4.7',
@@ -34,6 +69,14 @@ export const PLATFORM_MODELS = [
34
69
  effortLevels: ['low', 'medium', 'high', 'max'],
35
70
  runtime_names: { 'claude-code': 'claude-sonnet-4-6' },
36
71
  },
72
+ {
73
+ id: 'anthropic/claude-sonnet-4.6-1m',
74
+ name: 'Claude Sonnet 4.6 (1M)',
75
+ provider: 'anthropic',
76
+ effortLevels: ['low', 'medium', 'high', 'max'],
77
+ runtime_names: { 'claude-code': 'claude-sonnet-4-6[1m]' },
78
+ upstream_id: 'anthropic/claude-sonnet-4.6',
79
+ },
37
80
  {
38
81
  id: 'anthropic/claude-sonnet-4.5',
39
82
  name: 'Claude Sonnet 4.5',
@@ -77,6 +120,12 @@ export const PLATFORM_MODELS = [
77
120
  effortLevels: ['medium', 'high', 'xhigh'],
78
121
  runtime_names: { codex: 'gpt-5.4-pro' },
79
122
  },
123
+ {
124
+ id: 'google/gemini-3.5-flash',
125
+ name: 'Gemini 3.5 Flash',
126
+ provider: 'google',
127
+ effortLevels: [],
128
+ },
80
129
  {
81
130
  id: 'google/gemini-3.1-pro-preview',
82
131
  name: 'Gemini 3.1 Pro Preview',
@@ -244,6 +293,19 @@ export const PLATFORM_DEFAULT_MODEL_BY_RUNTIME = {
244
293
  codex: 'openai/gpt-5.4',
245
294
  } as const;
246
295
 
296
+ // Mirrors Go llmproxy.IsAllowedModelForRuntime's upstream-alias rule:
297
+ // variants that alias upstream (`upstream_id` set — the "(1M)" entries) encode
298
+ // runtime-specific client behavior and are only selectable by runtimes with an
299
+ // explicit runtime_names mapping. Model pickers must filter with this in
300
+ // addition to provider filtering.
301
+ export function isPlatformModelSelectableForRuntime(
302
+ model: { id: string; upstream_id?: string; runtime_names?: Record<string, string> },
303
+ runtime: string | null | undefined,
304
+ ): boolean {
305
+ if (!model.upstream_id) return true;
306
+ return Boolean(runtime && model.runtime_names && runtime in model.runtime_names);
307
+ }
308
+
247
309
  export function platformDefaultModelForRuntime(runtime: string | null | undefined): string | null {
248
310
  switch (runtime?.trim()) {
249
311
  case undefined:
@@ -285,6 +347,7 @@ export const ENDPOINTS = {
285
347
  // Org-scoped
286
348
  ORG: (orgId: string) => `${API_BASE}/orgs/${orgId}`,
287
349
  ORG_MEMBERS: (orgId: string) => `${API_BASE}/orgs/${orgId}/members`,
350
+ TEAMS: (orgId: string) => `${API_BASE}/orgs/${orgId}/teams`,
288
351
  ORG_MEMBERS_ONLINE: (orgId: string) => `${API_BASE}/orgs/${orgId}/members/online`,
289
352
  ORG_MEMBER: (orgId: string, userId: string) => `${API_BASE}/orgs/${orgId}/members/${userId}`,
290
353
  ORG_MEMBER_CHATS: (orgId: string, memberId: string) =>
@@ -347,6 +410,8 @@ export const ENDPOINTS = {
347
410
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys`,
348
411
  AGENT_API_KEY: (orgId: string, agentId: string, key: string) =>
349
412
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys/${key}`,
413
+ AGENT_API_KEY_REGENERATE: (orgId: string, agentId: string) =>
414
+ `${API_BASE}/orgs/${orgId}/agents/${agentId}/api-keys/regenerate`,
350
415
  AGENT_AVATAR: (orgId: string, agentId: string) =>
351
416
  `${API_BASE}/orgs/${orgId}/agents/${agentId}/avatar`,
352
417
  AGENT_ACTIVITY: (orgId: string, agentId: string) =>
@@ -417,6 +482,8 @@ export const ENDPOINTS = {
417
482
  `${API_BASE}/orgs/${orgId}/machines/${machineId}/llm-source`,
418
483
  MACHINE_PROVIDER_ENABLED: (orgId: string, machineId: string) =>
419
484
  `${API_BASE}/orgs/${orgId}/machines/${machineId}/provider-enabled`,
485
+ MACHINE_CAPABILITIES: (orgId: string, machineId: string) =>
486
+ `${API_BASE}/orgs/${orgId}/machines/${machineId}/capabilities`,
420
487
  MACHINE_RUNTIME_AUTH: (orgId: string, machineId: string) =>
421
488
  `${API_BASE}/orgs/${orgId}/machines/${machineId}/runtime-auth`,
422
489
  MACHINE_KEYS: (orgId: string, machineId: string) =>
@@ -449,6 +516,13 @@ export const ENDPOINTS = {
449
516
  MACHINES_ME_WS_TICKET: `${API_BASE}/machines/me/ws/ticket`,
450
517
  MACHINES_ME_BROWSE_RESPONSE: (requestId: string) =>
451
518
  `${API_BASE}/machines/me/browse-response/${requestId}`,
519
+ // Hosted browser live-viewer control plane (api-server, NOT clip-service):
520
+ // the web client drives WebRTC signaling + tab nav through VIEWER_COMMAND;
521
+ // api-server brokers each command to the host daemon via the machine:{id}
522
+ // request/reply bridge (mirrors filesystem browse), and the daemon replies on
523
+ // VIEWER_RESPONSE. See docs/engineering-design/hosted-browser-provider-design.md.
524
+ MACHINES_ME_BROWSER_PROFILE_VIEWER_RESPONSE: (requestId: string) =>
525
+ `${API_BASE}/machines/me/browser-profiles/viewer-response/${requestId}`,
452
526
 
453
527
  // Tasks (org-scoped)
454
528
  TASKS: (orgId: string) => `${API_BASE}/orgs/${orgId}/tasks`,
@@ -555,6 +629,11 @@ export const ENDPOINTS = {
555
629
  `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/path-scopes`,
556
630
  WIKI_PATH_SCOPE: (orgId: string, wikiId: string, scopeId: string) =>
557
631
  `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/path-scopes/${scopeId}`,
632
+ // Wiki Path Restrictions (AFCS narrowing ACL — private subtrees)
633
+ WIKI_RESTRICTIONS: (orgId: string, wikiId: string) =>
634
+ `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions`,
635
+ WIKI_RESTRICTION: (orgId: string, wikiId: string, restrictionId: string) =>
636
+ `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/restrictions/${restrictionId}`,
558
637
  WIKI_ACCESS_STATUS: (orgId: string, wikiId: string) =>
559
638
  `${WIKI_BASE}/orgs/${orgId}/wikis/${wikiId}/access-status`,
560
639
  WIKI_ACCESS_REQUESTS: (orgId: string, wikiId: string) =>
@@ -622,6 +701,9 @@ export const ENDPOINTS = {
622
701
  // Notification preferences
623
702
  NOTIFICATION_PREFERENCES: `${API_BASE}/notification-preferences`,
624
703
 
704
+ // Unified search (messages + tasks + wiki, org-scoped)
705
+ SEARCH: (orgId: string) => `${API_BASE}/orgs/${orgId}/search`,
706
+
625
707
  // Feature flags (org-scoped, server-evaluated)
626
708
  FEATURE_FLAGS: (orgId: string) => `${API_BASE}/orgs/${orgId}/feature-flags`,
627
709
 
@@ -640,6 +722,7 @@ export const ENDPOINTS = {
640
722
  // Clips (org-scoped, served by clip-service)
641
723
  CLIPS: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/clips`,
642
724
  CLIP: (orgId: string, clipId: string) => `${CLIP_BASE}/orgs/${orgId}/clips/${clipId}`,
725
+ CLIPS_BULK_METADATA: (orgId: string) => `${CLIP_BASE}/orgs/${orgId}/clips/bulk-metadata`,
643
726
  CLIP_AGENTS: (orgId: string, clipId: string) =>
644
727
  `${CLIP_BASE}/orgs/${orgId}/clips/${clipId}/agents`,
645
728
  AGENT_CLIPS: (orgId: string, agentId: string) =>
@@ -661,6 +744,10 @@ export const ENDPOINTS = {
661
744
  `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents`,
662
745
  BROWSER_PROFILE_CONSENT: (orgId: string, profileId: string, clipId: string) =>
663
746
  `${CLIP_BASE}/orgs/${orgId}/browser-profiles/${profileId}/consents/${clipId}`,
747
+ // Live viewer command — on api-server (API_BASE), not clip-service: it rides
748
+ // the machine control-plane request/reply bridge that lives in api-server.
749
+ BROWSER_PROFILE_VIEWER_COMMAND: (orgId: string, profileId: string) =>
750
+ `${API_BASE}/orgs/${orgId}/browser-profiles/${profileId}/viewer/command`,
664
751
 
665
752
  // Clip registry (global, served by clip-service → Pinix Hub proxy)
666
753
  CLIP_REGISTRY: () => `${CLIP_BASE}/registry/clips`,
@@ -740,6 +827,7 @@ export const WS_EVENTS = {
740
827
  MACHINE_CONFIG_UPDATED: 'machine.config.updated',
741
828
  MACHINE_CLIP_SYNC: 'machine.clip.sync',
742
829
  MACHINE_BROWSER_PROFILE_LIFECYCLE: 'machine.browser_profile.lifecycle',
830
+ MACHINE_BROWSER_PROFILE_VIEWER: 'machine.browser_profile.viewer',
743
831
  AGENT_NEW_SESSION: 'agent.new_session',
744
832
  CLIP_CREATED: 'clip.created',
745
833
  CLIP_REMOVED: 'clip.removed',
package/src/types.ts CHANGED
@@ -362,6 +362,17 @@ export interface OrgMember {
362
362
  user?: User;
363
363
  }
364
364
 
365
+ // Team — a named group of org members, referenced in wiki ACLs as `@slug`.
366
+ export interface Team {
367
+ id: string;
368
+ org_id: string;
369
+ name: string;
370
+ slug: string;
371
+ created_by: string;
372
+ created_at: string;
373
+ updated_at: string;
374
+ }
375
+
365
376
  // Invitation
366
377
 
367
378
  export type InvitationStatus = 'pending' | 'accepted' | 'declined' | 'revoked';
@@ -441,11 +452,11 @@ export interface CreateInvitationRequest {
441
452
  role?: OrgMemberRole;
442
453
  }
443
454
 
455
+ // Response of agent API key create/regenerate. The plaintext `api_key` is
456
+ // returned exactly once at mint time and can never be fetched again.
444
457
  export interface ApiKey {
445
458
  id: string;
446
- key: string;
447
- agent_id: string;
448
- created_at: string;
459
+ api_key: string;
449
460
  }
450
461
 
451
462
  export interface CreateAgentResponse {
@@ -708,6 +719,10 @@ export type MachineStatus =
708
719
  | 'error'
709
720
  | 'terminated';
710
721
 
722
+ // What a Machine can provide. Composable (a BYOC daemon is typically both) and
723
+ // orthogonal to compute_mode. See hosted-browser-provider-design.md.
724
+ export type MachineCapability = 'agent_host' | 'browser_provider';
725
+
711
726
  export interface Machine {
712
727
  id: string;
713
728
  org_id: string;
@@ -725,6 +740,13 @@ export interface Machine {
725
740
  daemon_mode: boolean;
726
741
  llm_source?: string;
727
742
  compute_mode: 'hosted' | 'local';
743
+ // What this machine can provide — composable and orthogonal to compute_mode
744
+ // (which is lifecycle handoff, not BYOC/role). A BYOC daemon is typically
745
+ // agent_host + browser_provider; a hosted browser provider pod is browser-only.
746
+ // Filter agent-host pickers by includes('agent_host') — never by excluding
747
+ // 'browser_provider'. Absent on servers predating the field. See
748
+ // docs/engineering-design/hosted-browser-provider-design.md.
749
+ capabilities?: MachineCapability[];
728
750
  // Whether the machine contributes its local clips as a hub provider
729
751
  // (org-admin-toggleable via PATCH /machines/{id}/provider-enabled). Absent on
730
752
  // servers predating the field → treat as true (default-on). See
@@ -929,6 +951,21 @@ export interface MachineBrowserProfileLifecycleData {
929
951
  start_url?: string;
930
952
  }
931
953
 
954
+ /**
955
+ * Live-viewer control command relayed to the host daemon over `machine:{id}`.
956
+ * One command per WebRTC signaling / tab-nav step; the daemon replies via
957
+ * `POST /machines/me/browser-profiles/viewer-response/{request_id}`.
958
+ */
959
+ export interface MachineBrowserProfileViewerData {
960
+ request_id: string;
961
+ profile_id: string;
962
+ session_id: string;
963
+ command: string;
964
+ input?: Record<string, unknown>;
965
+ /** Short-lived managed TURN/ICE credentials, minted server-side per stream.start. */
966
+ turn?: { url: string; username?: string; credential?: string };
967
+ }
968
+
932
969
  export interface AgentNewSessionData {
933
970
  previous_session_id?: string;
934
971
  }
@@ -1370,6 +1407,10 @@ export interface WikiNodeSection {
1370
1407
  start_line: number;
1371
1408
  end_line: number;
1372
1409
  content: string;
1410
+ /** Frontmatter metadata (OKF-inspired, file-level, all optional). */
1411
+ type?: string;
1412
+ description?: string;
1413
+ tags?: string[];
1373
1414
  }
1374
1415
 
1375
1416
  export interface WikiNodeSectionArtifact {
@@ -1506,15 +1547,24 @@ export interface CreateWikiRequest {
1506
1547
  default_branch?: string;
1507
1548
  }
1508
1549
 
1550
+ export interface WikiFileChangeInput {
1551
+ path: string;
1552
+ action: 'create' | 'update' | 'delete';
1553
+ content_base64?: string;
1554
+ base_version?: number;
1555
+ /**
1556
+ * Git blob SHA of the default-branch version this change was authored
1557
+ * against. When set on update/delete, the server rejects the changeset
1558
+ * with 409 STALE_BASE if the file has since changed on the default branch
1559
+ * (prevents silently overwriting concurrent edits).
1560
+ */
1561
+ base_sha?: string;
1562
+ }
1563
+
1509
1564
  export interface CreateWikiChangesetRequest {
1510
1565
  title: string;
1511
1566
  message?: string;
1512
- file_changes: Array<{
1513
- path: string;
1514
- action: 'create' | 'update' | 'delete';
1515
- content_base64?: string;
1516
- base_version?: number;
1517
- }>;
1567
+ file_changes: WikiFileChangeInput[];
1518
1568
  source_chat_id?: string;
1519
1569
  source_message_id?: string;
1520
1570
  source_run_id?: string;
@@ -1523,12 +1573,15 @@ export interface CreateWikiChangesetRequest {
1523
1573
  export interface UpdateWikiChangesetRequest {
1524
1574
  title?: string;
1525
1575
  message?: string;
1526
- file_changes?: Array<{
1527
- path: string;
1528
- action: 'create' | 'update' | 'delete';
1529
- content_base64?: string;
1530
- base_version?: number;
1531
- }>;
1576
+ file_changes?: WikiFileChangeInput[];
1577
+ /**
1578
+ * When true, file_changes define the changeset's FULL content: the server
1579
+ * resets the feature branch to the current default-branch HEAD before
1580
+ * applying, so previously-proposed changes that are not re-sent are
1581
+ * dropped. Used by CLI re-propose (`changeset create --update`). Default
1582
+ * false preserves incremental merge semantics (binary-upload flow).
1583
+ */
1584
+ replace_files?: boolean;
1532
1585
  }
1533
1586
 
1534
1587
  export interface WikiCommit {
@@ -1572,11 +1625,42 @@ export interface CreateWikiPathScopeRequest {
1572
1625
  admins?: unknown;
1573
1626
  }
1574
1627
 
1628
+ // Narrowing ACL layer — gates a path subtree to `subjects`. Org owners/admins
1629
+ // are bound for CONTENT access too, and must be listed to view/edit restricted
1630
+ // content. They always keep rule management so they can add themselves, edit, or
1631
+ // delete the rule. `apply_to_admins` is retained for wire/data compatibility.
1632
+ // `level: read` = fully private folder. See authorization-design.md § Wiki.
1633
+ export interface WikiPathRestriction {
1634
+ id: string;
1635
+ wiki_id: string;
1636
+ path: string;
1637
+ level: 'read' | 'maintain' | 'admin';
1638
+ subjects: string[];
1639
+ apply_to_admins: boolean;
1640
+ created_by: string;
1641
+ created_at: string;
1642
+ }
1643
+
1644
+ export interface CreateWikiPathRestrictionRequest {
1645
+ path: string;
1646
+ level?: 'read' | 'maintain' | 'admin';
1647
+ subjects: string[];
1648
+ apply_to_admins?: boolean;
1649
+ }
1650
+
1575
1651
  export interface WikiAccessStatus {
1576
1652
  path: string;
1577
1653
  read: boolean;
1578
1654
  maintain: boolean;
1579
1655
  admin: boolean;
1656
+ // Management-surface capability on the requested path: true for org
1657
+ // owners/admins regardless of content restrictions (which narrow content
1658
+ // access above, never rule management). Gates the Activity tab (root-scoped
1659
+ // operation log).
1660
+ acl_manage: boolean;
1661
+ // True when the caller can administer at least one path in the wiki —
1662
+ // includes delegated sub-tree admins. Gates the Access tab.
1663
+ acl_manage_any: boolean;
1580
1664
  }
1581
1665
 
1582
1666
  export interface CreateWikiAccessRequest {
@@ -2157,6 +2241,7 @@ export type WsEventMap = {
2157
2241
  'machine.update': MachineUpdateData;
2158
2242
  'machine.clip.sync': MachineClipSyncData;
2159
2243
  'machine.browser_profile.lifecycle': MachineBrowserProfileLifecycleData;
2244
+ 'machine.browser_profile.viewer': MachineBrowserProfileViewerData;
2160
2245
  'clip.created': ClipCreatedData;
2161
2246
  'clip.removed': ClipRemovedData;
2162
2247
  'clip.updated': ClipUpdatedData;
@@ -2269,6 +2354,7 @@ export interface ResolvedRef {
2269
2354
  sender_avatar_url?: string | null;
2270
2355
  message_type?: string;
2271
2356
  created_at?: string;
2357
+ attachments?: Attachment[];
2272
2358
 
2273
2359
  // Range fields (cht_ + range anchor)
2274
2360
  range_messages?: Array<{
@@ -2280,6 +2366,7 @@ export interface ResolvedRef {
2280
2366
  message_type: string;
2281
2367
  preview: string;
2282
2368
  created_at: string;
2369
+ attachments?: Attachment[];
2283
2370
  }>;
2284
2371
  range_truncated?: boolean;
2285
2372
 
@@ -2646,6 +2733,8 @@ export interface CreateClipRequest {
2646
2733
  }
2647
2734
 
2648
2735
  export interface UpdateClipRequest {
2736
+ /** Rename the clip's org-local alias; uniqueness enforced per org. */
2737
+ alias?: string;
2649
2738
  name?: string;
2650
2739
  display_name?: string;
2651
2740
  description?: string;
@@ -2657,6 +2746,18 @@ export interface UpdateClipRequest {
2657
2746
  browser_profile_id?: string;
2658
2747
  }
2659
2748
 
2749
+ /**
2750
+ * Atomically set application-level metadata (`display_name` and/or
2751
+ * `description`) on every clip instance of an application. All-or-nothing on the
2752
+ * server (one transaction). At least one field must be present; omitted leaves
2753
+ * it unchanged, an empty `description` clears it.
2754
+ */
2755
+ export interface BulkUpdateClipMetadataRequest {
2756
+ clip_ids: string[];
2757
+ display_name?: string;
2758
+ description?: string;
2759
+ }
2760
+
2660
2761
  export interface BindAgentClipRequest {
2661
2762
  clip_id: string;
2662
2763
  config?: Record<string, unknown>;
@@ -2720,6 +2821,44 @@ export interface BrowserProfileLifecycleRequest {
2720
2821
  start_url?: string;
2721
2822
  }
2722
2823
 
2824
+ /** A WebRTC ICE server (STUN/TURN) for the live-viewer peer connection. */
2825
+ export interface BrowserViewerIceServer {
2826
+ urls: string[];
2827
+ username?: string;
2828
+ credential?: string;
2829
+ }
2830
+
2831
+ /** A serialized ICE candidate exchanged during live-viewer signaling. */
2832
+ export interface BrowserViewerIceCandidate {
2833
+ candidate: string;
2834
+ sdpMLineIndex?: number | null;
2835
+ sdpMid?: string | null;
2836
+ }
2837
+
2838
+ /**
2839
+ * One live-viewer control command. The web client drives the WebRTC handshake
2840
+ * (`stream.start` → `stream.answer` → `stream.close`/`stream.switch`) and tab
2841
+ * navigation (`tab_list`/`tab_new`/`open`/`reload`/`back`/`forward`) through a
2842
+ * single endpoint; api-server forwards `command` to the host daemon.
2843
+ */
2844
+ export interface BrowserViewerCommandRequest {
2845
+ /** Correlates a viewer session. Omit on `stream.start`; the server returns one. */
2846
+ session_id?: string;
2847
+ command: string;
2848
+ input?: Record<string, unknown>;
2849
+ }
2850
+
2851
+ export interface BrowserViewerCommandResponse {
2852
+ session_id: string;
2853
+ /**
2854
+ * Command-specific result. For `stream.start`:
2855
+ * `{ offer_sdp: string, candidates: BrowserViewerIceCandidate[], ice_servers: BrowserViewerIceServer[] }`.
2856
+ * May be `null` on the wire — a nil Go result map serializes as JSON null; the
2857
+ * viewer client coalesces it to `{}`.
2858
+ */
2859
+ result: Record<string, unknown> | null;
2860
+ }
2861
+
2723
2862
  export interface GrantBrowserProfileConsentRequest {
2724
2863
  clip_id: string;
2725
2864
  }
@@ -2779,3 +2918,53 @@ export interface ClipRemovedData {
2779
2918
  clip_id: string;
2780
2919
  org_id: string;
2781
2920
  }
2921
+
2922
+ // ─── Unified Search ───
2923
+
2924
+ export interface SearchParams {
2925
+ q: string;
2926
+ types?: string;
2927
+ chat_id?: string;
2928
+ limit?: number;
2929
+ }
2930
+
2931
+ export interface SearchMessageResult {
2932
+ message_id: string;
2933
+ chat_id: string;
2934
+ chat_name?: string;
2935
+ sender?: { id: string; display_name: string };
2936
+ content_snippet: string;
2937
+ score: number;
2938
+ created_at: string;
2939
+ }
2940
+
2941
+ export interface SearchTaskResult {
2942
+ task_id: string;
2943
+ project_id?: string;
2944
+ project_name?: string;
2945
+ title: string;
2946
+ content_snippet: string;
2947
+ score: number;
2948
+ updated_at?: string;
2949
+ }
2950
+
2951
+ export interface SearchWikiResult {
2952
+ /** Globally-unique section id (stable React key — file_path can repeat across matched sections). */
2953
+ section_id: string;
2954
+ wiki_id: string;
2955
+ wiki_name?: string;
2956
+ file_path: string;
2957
+ heading_path: string[];
2958
+ content_snippet: string;
2959
+ score: number;
2960
+ /** Frontmatter document type (OKF facet label), when the file declares one. */
2961
+ type?: string;
2962
+ /** Frontmatter summary; clients may prefer it over content_snippet. */
2963
+ description?: string;
2964
+ }
2965
+
2966
+ export interface SearchResponse {
2967
+ messages: SearchMessageResult[];
2968
+ tasks: SearchTaskResult[];
2969
+ wiki: SearchWikiResult[];
2970
+ }