@parall/sdk 1.36.0 → 1.37.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/types.ts CHANGED
@@ -774,12 +774,26 @@ export interface Machine {
774
774
  // foreground runs that can't load the overlay or restart after exit(42).
775
775
  // Reported on heartbeat; gates the "Check for Update" affordance + API.
776
776
  self_update_capable?: boolean;
777
+ // Daemon-reported runtime CLIs found on the host (heartbeat-refreshed).
778
+ // Absent/null = never reported (pre-detection daemon — UNKNOWN, do not warn);
779
+ // [] = detection ran and found nothing. A signal for pickers only — attach /
780
+ // create are never gated on it (a CLI can be installed at any time).
781
+ detected_runtimes?: DetectedRuntime[] | null;
777
782
  region: string | null;
778
783
  created_by: string;
779
784
  created_at: string;
780
785
  updated_at: string;
781
786
  }
782
787
 
788
+ // One entry of Machine.detected_runtimes. status 'ok' = the CLI resolved and
789
+ // executed (`--version` succeeded); 'broken' = it resolved on disk but failed
790
+ // to run (present-but-unusable install).
791
+ export interface DetectedRuntime {
792
+ runtime_type: string;
793
+ version?: string;
794
+ status: 'ok' | 'broken';
795
+ }
796
+
783
797
  export type DaemonWorkspaceMode = 'default' | 'local_path' | 'git';
784
798
  export type DaemonWorkspaceSetupRunOn = 'first_attach' | 'config_change';
785
799
 
@@ -846,7 +860,7 @@ export interface AgentProfile {
846
860
  model_management: string | null; // "platform" | "self" | null
847
861
  permissions: string[];
848
862
  machine_id: string | null;
849
- hosting_mode?: 'hosted' | 'self_hosted';
863
+ hosting_mode?: 'hosted' | 'self_hosted' | 'platform_runtime';
850
864
  runtime_type: string;
851
865
  description: string | null;
852
866
  thinking_effort: string | null;
@@ -922,6 +936,17 @@ export interface MachineConfigUpdatedData {
922
936
  provider_enabled?: boolean;
923
937
  }
924
938
 
939
+ // Per-agent counterpart of MachineConfigUpdatedData: ONE local agent's
940
+ // explicit llm_source changed, so the daemon respawns just that agent's
941
+ // child. llm_source carries the agent's new EFFECTIVE source (explicit
942
+ // per-agent choice, else the machine default). Mirrors the Go
943
+ // MachineAgentConfigUpdatedData struct.
944
+ export interface MachineAgentConfigUpdatedData {
945
+ machine_id: string;
946
+ agent_id: string;
947
+ llm_source: string;
948
+ }
949
+
925
950
  export interface MachineWorkspaceSetupRequestedData {
926
951
  machine_id: string;
927
952
  agent_id: string;
@@ -958,6 +983,14 @@ export interface MachineBrowserProfileLifecycleData {
958
983
  profile_id: string;
959
984
  action: BrowserProfileLifecycleAction;
960
985
  start_url?: string;
986
+ /** Profile's lifecycle_generation after this transition's bump (PR #1650). The
987
+ * daemon acts under it and echoes it in its status report so the server can
988
+ * reject a stale report. Absent/0 from a pre-generation server. */
989
+ generation?: number;
990
+ /** Profile's reset_generation after this transition (bumped only by `reset`). On
991
+ * an online reset the daemon records it in its per-profile sidecar so a later
992
+ * reconnect doesn't redundantly re-wipe. */
993
+ reset_generation?: number;
961
994
  }
962
995
 
963
996
  /**
@@ -1078,6 +1111,13 @@ export interface Task {
1078
1111
  canceled_at: string | null;
1079
1112
  archived_at?: string | null;
1080
1113
  deleted_at?: string | null;
1114
+ /**
1115
+ * Per-viewer: whether the requesting user may manage OTHER members' comment
1116
+ * subscriptions for this task (creator / assignee / project lead / org
1117
+ * owner-admin). Populated on single-task GET; undefined elsewhere. Read this to
1118
+ * gate subscriber-management UI — do not re-derive the rule client-side.
1119
+ */
1120
+ can_manage_subscribers?: boolean;
1081
1121
  }
1082
1122
 
1083
1123
  export interface TaskWatcher {
@@ -1537,6 +1577,19 @@ export interface Wiki {
1537
1577
  created_by: string;
1538
1578
  created_at: string;
1539
1579
  updated_at: string;
1580
+ /** Protected default wiki — cannot be deleted. */
1581
+ is_default?: boolean | null;
1582
+ /** Set when the wiki is soft-deleted (recoverable). */
1583
+ deleted_at?: string | null;
1584
+ /** User who soft-deleted the wiki. */
1585
+ deleted_by?: string | null;
1586
+ /** Set once purge is claimed — the wiki can no longer be restored. */
1587
+ purge_started_at?: string | null;
1588
+ /** deleted_at + retention window (server-computed) — the recycle-bin countdown
1589
+ * source. Past this, restore is rejected with 410 WIKI_RETENTION_EXPIRED. */
1590
+ purge_eligible_at?: string | null;
1591
+ /** Server-computed restore availability for recycle-bin rows. */
1592
+ restorable?: boolean | null;
1540
1593
  }
1541
1594
 
1542
1595
  export interface WikiFileChange {
@@ -1568,11 +1621,19 @@ export interface WikiTreeEntry {
1568
1621
  path: string;
1569
1622
  type: 'tree' | 'blob';
1570
1623
  size?: number;
1624
+ /**
1625
+ * Entry sits inside a read-gated private subtree (path restriction). Advisory
1626
+ * display flag — the caller already passed read authorization to receive the
1627
+ * entry; use it to badge private folders, never for access decisions.
1628
+ */
1629
+ restricted?: boolean;
1571
1630
  }
1572
1631
 
1573
1632
  export interface WikiTreeResponse {
1574
1633
  data: WikiTreeEntry[];
1575
1634
  path: string;
1635
+ /** Whether the listed directory itself sits inside a read-gated private subtree. */
1636
+ path_restricted?: boolean;
1576
1637
  }
1577
1638
 
1578
1639
  export interface WikiFileManifestEntry {
@@ -1835,6 +1896,11 @@ export interface CreateWikiPathRestrictionRequest {
1835
1896
  level?: 'read' | 'maintain' | 'admin';
1836
1897
  subjects: string[];
1837
1898
  apply_to_admins?: boolean;
1899
+ // When true, the server returns 409 RESTRICTION_EXISTS if a restriction already
1900
+ // exists at `path` instead of upserting its subjects. Set by the member "create
1901
+ // private space" flow so a stale/concurrent create can't silently overwrite an
1902
+ // existing space's share list; edit-access flows leave it unset (upsert).
1903
+ create_only?: boolean;
1838
1904
  }
1839
1905
 
1840
1906
  export interface WikiAccessStatus {
@@ -1881,6 +1947,24 @@ export interface WikiOperationsResponse {
1881
1947
  // Wiki Blob
1882
1948
  // ============================================================
1883
1949
 
1950
+ /**
1951
+ * Copy one wiki file to another path as an independent snapshot (no ongoing
1952
+ * sync). Primary use: "share a private file out" — copy from the caller's
1953
+ * personal namespace (`users/{userId}/…`) into the public wiki so the whole
1954
+ * org can read + edit the copy, leaving the private original untouched.
1955
+ */
1956
+ export interface CopyWikiFileRequest {
1957
+ source_path: string;
1958
+ dest_path: string;
1959
+ message?: string;
1960
+ }
1961
+
1962
+ export interface CopyWikiFileResponse {
1963
+ source_path: string;
1964
+ dest_path: string;
1965
+ commit_sha: string;
1966
+ }
1967
+
1884
1968
  export interface WikiBlob {
1885
1969
  path: string;
1886
1970
  ref: string;
@@ -1895,6 +1979,8 @@ export interface WikiBlob {
1895
1979
  content?: string;
1896
1980
  line_count?: number;
1897
1981
  sha256?: string;
1982
+ /** File sits inside a read-gated private subtree — advisory display flag. */
1983
+ restricted?: boolean;
1898
1984
  // Phase 2 additions for the binary response shape:
1899
1985
  mime?: string;
1900
1986
  is_lfs?: boolean;
@@ -2044,6 +2130,16 @@ export interface MembershipChangedData {
2044
2130
  action: 'added' | 'removed' | 'role_changed';
2045
2131
  }
2046
2132
 
2133
+ /**
2134
+ * A member was removed from an org — kicked by an admin or self-removal
2135
+ * ("leave org"). Delivered on org:{orgId} (remaining members refresh the
2136
+ * directory) and user:{userId} (the removed user's clients drop the org).
2137
+ */
2138
+ export interface OrgMemberRemovedData {
2139
+ org_id: string;
2140
+ user_id: string;
2141
+ }
2142
+
2047
2143
  // ---- Task Comment & Activity Types ----
2048
2144
 
2049
2145
  export type TaskActivityAction = 'created' | 'field_changed' | 'commented';
@@ -2186,6 +2282,14 @@ export interface AgentStepNewData extends AgentStep {}
2186
2282
  export type WikiChangesetCreatedData = WikiChangeset & { org_id: string };
2187
2283
  export type WikiChangesetUpdatedData = WikiChangeset & { org_id: string };
2188
2284
 
2285
+ export interface WikiDeletedData {
2286
+ org_id: string;
2287
+ wiki_id: string;
2288
+ slug: string;
2289
+ name: string;
2290
+ }
2291
+ export type WikiRestoredData = WikiDeletedData;
2292
+
2189
2293
  // Wiki Comment
2190
2294
 
2191
2295
  // Unified Comment (replaces TaskComment and WikiComment)
@@ -2263,6 +2367,134 @@ export interface InboxItem {
2263
2367
  updated_at: string;
2264
2368
  }
2265
2369
 
2370
+ // ============================================================
2371
+ // External IM Channel Types (platform-mediated Feishu/Slack channel)
2372
+ // ============================================================
2373
+
2374
+ export type ChannelProvider = 'feishu' | 'slack';
2375
+ export type ChannelConnectionStatus = 'pending' | 'active' | 'disabled';
2376
+ /**
2377
+ * Inbound transport for a connection. Defaults to the provider's lowest-
2378
+ * onboarding-cost mode server-side (Feishu → socket, Slack → webhook) when
2379
+ * omitted on create; can be overridden per connection.
2380
+ */
2381
+ export type ChannelIngressMode = 'webhook' | 'socket';
2382
+ export type ChannelMessageStatus = 'received' | 'dispatched' | 'failed';
2383
+
2384
+ export interface ChannelConnection {
2385
+ id: string;
2386
+ org_id: string;
2387
+ agent_id: string;
2388
+ provider: ChannelProvider;
2389
+ ingress_mode: ChannelIngressMode;
2390
+ display_name: string;
2391
+ created_by: string;
2392
+ status: ChannelConnectionStatus;
2393
+ external_app_id?: string;
2394
+ external_team_id?: string;
2395
+ archived_at?: string | null;
2396
+ archive_reason?: string | null;
2397
+ /** Returned once at mint time (create / token regeneration). */
2398
+ ingress_url?: string;
2399
+ /** Returned once at mint time (create / token regeneration). */
2400
+ ingress_token?: string;
2401
+ created_at: string;
2402
+ updated_at: string;
2403
+ }
2404
+
2405
+ export interface ChannelCredentialsInput {
2406
+ app_id: string;
2407
+ app_secret: string;
2408
+ verification_token?: string;
2409
+ encrypt_key?: string;
2410
+ team_id?: string;
2411
+ }
2412
+
2413
+ export interface CreateChannelConnectionInput {
2414
+ agent_id: string;
2415
+ provider: ChannelProvider;
2416
+ display_name: string;
2417
+ /** Override the provider's default inbound transport (optional). */
2418
+ ingress_mode?: ChannelIngressMode;
2419
+ /** Manual provisioning: activates the connection immediately. */
2420
+ credentials?: ChannelCredentialsInput;
2421
+ }
2422
+
2423
+ export interface UpdateChannelConnectionInput {
2424
+ display_name?: string;
2425
+ status?: 'active' | 'disabled';
2426
+ }
2427
+
2428
+ export interface ChannelConversation {
2429
+ id: string;
2430
+ org_id: string;
2431
+ connection_id: string;
2432
+ agent_id: string;
2433
+ agent_session_id?: string | null;
2434
+ external_conversation_id: string;
2435
+ external_thread_id: string;
2436
+ conversation_type: string;
2437
+ external_user_id: string;
2438
+ external_user_name: string;
2439
+ last_inbound_at?: string | null;
2440
+ created_at: string;
2441
+ updated_at: string;
2442
+ }
2443
+
2444
+ export interface ChannelMessage {
2445
+ id: string;
2446
+ org_id: string;
2447
+ connection_id: string;
2448
+ conversation_id: string;
2449
+ external_message_id: string;
2450
+ text: string;
2451
+ external_user_id: string;
2452
+ external_user_name: string;
2453
+ status: ChannelMessageStatus;
2454
+ received_at: string;
2455
+ created_at: string;
2456
+ }
2457
+
2458
+ /**
2459
+ * Feishu one-click provisioning session (OAuth device flow). The client
2460
+ * renders `verification_url` as a QR code and lazily polls the status
2461
+ * endpoint every `poll_interval_seconds` — each poll may forward one
2462
+ * provider poll server-side, so respect the interval.
2463
+ */
2464
+ export type ChannelProvisioningStatus =
2465
+ | 'pending'
2466
+ | 'polling'
2467
+ | 'done'
2468
+ | 'expired'
2469
+ | 'denied'
2470
+ | 'canceled'
2471
+ | 'failed';
2472
+
2473
+ export interface ChannelProvisioningSession {
2474
+ id: string;
2475
+ org_id: string;
2476
+ agent_id: string;
2477
+ provider: ChannelProvider;
2478
+ created_by: string;
2479
+ status: ChannelProvisioningStatus;
2480
+ poll_interval_seconds: number;
2481
+ /** Set when status = 'done': the minted connection. */
2482
+ connection_id?: string;
2483
+ /** Terminal detail: access_denied / expired_token / domain_switched / connection_exists / alias_conflict / internal. */
2484
+ error_code?: string;
2485
+ expires_at: string;
2486
+ created_at: string;
2487
+ updated_at: string;
2488
+ /** QR target — present on live (pending/polling) sessions only. */
2489
+ verification_url?: string;
2490
+ user_code?: string;
2491
+ }
2492
+
2493
+ export interface InitiateChannelProvisioningInput {
2494
+ agent_id: string;
2495
+ provider: ChannelProvider;
2496
+ }
2497
+
2266
2498
  // ============================================================
2267
2499
  // Dispatch Types (agent event delivery)
2268
2500
  // ============================================================
@@ -2275,7 +2507,8 @@ export type DispatchEventType =
2275
2507
  | 'wiki_comment'
2276
2508
  | 'schedule.fire'
2277
2509
  | 'external_trigger'
2278
- | 'approval_decided';
2510
+ | 'approval_decided'
2511
+ | 'channel_message';
2279
2512
  export type DispatchStatus = 'pending' | 'received' | 'acked';
2280
2513
  export type DispatchDeliveryReason = 'mention' | 'watcher' | 'assignee' | 'creator';
2281
2514
 
@@ -2398,10 +2631,13 @@ export type WsEventMap = {
2398
2631
  'invitation.revoked': InvitationRevokedEventData;
2399
2632
  'org.join_request.new': OrgJoinRequestNewEventData;
2400
2633
  'org.invite_link.joined': OrgInviteLinkJoinedEventData;
2634
+ 'org.member.removed': OrgMemberRemovedData;
2401
2635
  'agent_config.update': AgentConfigUpdateData;
2402
2636
  'presence.update': PresenceUpdateData;
2403
2637
  'wiki.changeset.created': WikiChangesetCreatedData;
2404
2638
  'wiki.changeset.updated': WikiChangesetUpdatedData;
2639
+ 'wiki.deleted': WikiDeletedData;
2640
+ 'wiki.restored': WikiRestoredData;
2405
2641
  'comment.created': CommentCreatedData;
2406
2642
  'comment.updated': CommentUpdatedData;
2407
2643
  'comment.deleted': CommentDeletedData;
@@ -2425,6 +2661,7 @@ export type WsEventMap = {
2425
2661
  'machine.agent.attached': MachineAgentAttachedData;
2426
2662
  'machine.agent.detached': MachineAgentDetachedData;
2427
2663
  'machine.config.updated': MachineConfigUpdatedData;
2664
+ 'machine.agent_config.updated': MachineAgentConfigUpdatedData;
2428
2665
  'machine.workspace.setup.requested': MachineWorkspaceSetupRequestedData;
2429
2666
  'machine.stop': MachineStopData;
2430
2667
  'machine.filesystem.browse': MachineFilesystemBrowseData;
@@ -2494,7 +2731,14 @@ export interface PlatformConfigResponse {
2494
2731
  version: string;
2495
2732
  schema_version: number;
2496
2733
  min_plugin_version?: string;
2734
+ /** @deprecated V1-compat only — old bridges read this for override-vs-floor. New bridges read `model_is_pin`. */
2497
2735
  mode?: string;
2736
+ /**
2737
+ * Whether the delivered model is an operator PIN (override, beats the runtime's
2738
+ * env/default) vs a catalog FLOOR (loses to env). Optional: an old server omits
2739
+ * it and the bridge falls back to the legacy `model_management`-derived signal.
2740
+ */
2741
+ model_is_pin?: boolean;
2498
2742
  config: Record<string, unknown>;
2499
2743
  }
2500
2744
 
@@ -2603,6 +2847,38 @@ export interface BacklinksResponse {
2603
2847
  next_cursor?: string;
2604
2848
  }
2605
2849
 
2850
+ /**
2851
+ * One entity in a multi-hop ref-graph traversal (GET /refs/graph). `id`/`uri` are
2852
+ * the ref_links endpoint identifier: a bare prll:// entity id for most nodes
2853
+ * (`tsk_abc` → `prll://tsk_abc`), but a wiki_file source node carries its file
2854
+ * path (`wik_abc/docs/a.md` → `prll://wik_abc/docs/a.md`, type `wik`). The query
2855
+ * root must be entity-level (refined path/anchor URIs are rejected 400), yet
2856
+ * interior wiki_file nodes can legitimately be path-bearing.
2857
+ */
2858
+ export interface RefGraphNode {
2859
+ uri: string; // prll://<id>; a wiki_file node's id includes its file path
2860
+ type: string; // bare prefix: msg, tsk, wik, …
2861
+ id: string; // ref_links endpoint id: bare entity id, or "<wikiID>/<path>" for wiki_file nodes
2862
+ depth: number; // BFS distance from root (0 = root)
2863
+ }
2864
+
2865
+ /** One directed prll:// reference between two nodes in the graph. */
2866
+ export interface RefGraphEdge {
2867
+ source_uri: string;
2868
+ target_uri: string;
2869
+ source_type: string; // full word: message, task, …
2870
+ target_type: string; // bare prefix: msg, tsk, …
2871
+ context?: string;
2872
+ }
2873
+
2874
+ export interface RefGraphResponse {
2875
+ root: string; // prll://<rootId>
2876
+ depth: number; // effective hop limit used (after server clamping)
2877
+ nodes: RefGraphNode[];
2878
+ edges: RefGraphEdge[];
2879
+ truncated: boolean; // a node/edge cap clipped the result
2880
+ }
2881
+
2606
2882
  export interface BrokenRefItem {
2607
2883
  ref_link_id: string;
2608
2884
  source_type: string;
@@ -2811,6 +3087,61 @@ export interface ComputePricing {
2811
3087
  // component name ("cpu" | "memory" | "storage").
2812
3088
  export type ComputePricingResponse = Record<string, ComputePricing>;
2813
3089
 
3090
+ /**
3091
+ * Per-runtime capability row from GET /api/v1/runtimes (public, no auth).
3092
+ * Server SSOT: server/pkg/hosting/capabilities.go RuntimeCapability — the
3093
+ * data source for the create/settings interlock (which compute × intelligence
3094
+ * × model combinations are offerable per runtime).
3095
+ */
3096
+ export interface RuntimeCapability {
3097
+ runtime: string;
3098
+ /** Where the runtime can run: "hosted" and/or "local". Hermes is cloud-only. */
3099
+ compute_modes: string[];
3100
+ /**
3101
+ * Provider family the runtime's OWN credentials can serve ("anthropic" /
3102
+ * "openai"), or "any" for family-agnostic runtimes. Own-route restriction
3103
+ * only — see cross_family_via_parall.
3104
+ */
3105
+ native_model_family: string;
3106
+ /** On the Parall proxy route any catalog model is allowed regardless of family. */
3107
+ cross_family_via_parall: boolean;
3108
+ /** Whether a pinned model is delivered when the agent runs on its own credentials. */
3109
+ own_route_model_pin: boolean;
3110
+ /** Catalog default the UI pre-selects for this runtime. */
3111
+ recommended_model: string;
3112
+ }
3113
+
3114
+ /**
3115
+ * Catalog entry from GET /api/v1/models (public, no auth) — the DB-backed
3116
+ * platform model catalog. Server SSOT: handler.PlatformModelDTO
3117
+ * (docs/engineering-design/model-catalog-design.md §6.1). Replaces the
3118
+ * compile-time PLATFORM_MODELS constant as the picker data source.
3119
+ */
3120
+ export interface PlatformModelInfo {
3121
+ id: string;
3122
+ name: string;
3123
+ /** Provider family ("anthropic", "openai", "google", ...). */
3124
+ family: string;
3125
+ contextWindow: number;
3126
+ maxTokens: number;
3127
+ effortLevels?: string[];
3128
+ /** Runtime type → runtime-native CLI model name. */
3129
+ runtime_names?: Record<string, string>;
3130
+ /** Set on client-behavior variants (the "(1M)" entries) — see isPlatformModelSelectableForRuntime. */
3131
+ upstream_id?: string;
3132
+ /** Display hints: "recommended" / "new" / "beta". */
3133
+ tags?: string[];
3134
+ sort_order: number;
3135
+ /** True only for a legacy entry appended via include_model (not in the active catalog). */
3136
+ hidden?: boolean;
3137
+ }
3138
+
3139
+ export interface PlatformModelsResponse {
3140
+ data: PlatformModelInfo[];
3141
+ /** Catalog content hash — changes whenever the catalog changes. */
3142
+ version: string;
3143
+ }
3144
+
2814
3145
  export interface MachinePreset {
2815
3146
  key: string;
2816
3147
  cpu_cores: number;
@@ -2882,7 +3213,11 @@ export interface BillingInsufficientEvent {
2882
3213
  // Clip Types
2883
3214
  // ============================================================
2884
3215
 
2885
- export type ClipSourceType = 'registry' | 'custom' | 'builtin';
3216
+ // 'channel' is a platform-managed source: it appears on read (Clip.source_type)
3217
+ // but the server rejects it on create, so CreateClipRequest uses the narrower
3218
+ // UserClipSourceType.
3219
+ export type ClipSourceType = 'registry' | 'custom' | 'builtin' | 'channel';
3220
+ export type UserClipSourceType = 'registry' | 'custom' | 'builtin';
2886
3221
  export type ClipStatus = 'active' | 'disabled';
2887
3222
 
2888
3223
  export interface Clip {
@@ -2917,7 +3252,7 @@ export interface CreateClipRequest {
2917
3252
  display_name?: string;
2918
3253
  description?: string;
2919
3254
  manifest?: Record<string, unknown>;
2920
- source_type?: ClipSourceType;
3255
+ source_type?: UserClipSourceType;
2921
3256
  source_ref?: string;
2922
3257
  version?: string;
2923
3258
  machine_id: string;
@@ -2985,6 +3320,15 @@ export type BrowserProfileStatus = 'pending' | 'running' | 'stopped' | 'error' |
2985
3320
  */
2986
3321
  export type BrowserPlacement = 'byoc' | 'hosted';
2987
3322
 
3323
+ /** Deployment-wide hosted browser runtime availability (the controller startup
3324
+ * gate). Drives whether the create UI offers the platform-hosted placement; it
3325
+ * is org-scoped only for auth — the value itself is the same for every org.
3326
+ * Fail-closed: the server reports `available: false` if it cannot verify. */
3327
+ export interface BrowserRuntimeStatus {
3328
+ available: boolean;
3329
+ reason?: string;
3330
+ }
3331
+
2988
3332
  export interface BrowserProfile {
2989
3333
  id: string;
2990
3334
  org_id: string;
@@ -3005,6 +3349,14 @@ export interface BrowserProfile {
3005
3349
  * or control gate and owner/admin can always control. The org-wide list uses
3006
3350
  * {@link BrowserProfileListItem.can_open} (per-viewer) instead. */
3007
3351
  can_open?: boolean;
3352
+ /** Per-profile outbound proxy (BYO provider credentials). Returned to the owner /
3353
+ * org admin (Get) for the edit form. The password is NEVER returned —
3354
+ * {@link proxy_password_set} reports only whether one is configured. */
3355
+ proxy_server?: string | null;
3356
+ proxy_username?: string | null;
3357
+ /** True when a proxy password is stored. Drives the edit form's "leave blank to
3358
+ * keep" affordance; the value itself is never sent to a human-facing client. */
3359
+ proxy_password_set?: boolean;
3008
3360
  }
3009
3361
 
3010
3362
  /** Sanitized row from `GET /orgs/{orgId}/browser-profiles` (org-wide discovery).
@@ -3028,6 +3380,35 @@ export interface BrowserProfileListItem {
3028
3380
  can_open?: boolean;
3029
3381
  error_msg?: string | null;
3030
3382
  last_seen?: string | null;
3383
+ /** Non-sensitive discovery flag: does this profile egress through a proxy. The
3384
+ * proxy server / credentials are NOT in the org-wide list (owner/admin Get only). */
3385
+ proxy_configured?: boolean;
3386
+ }
3387
+
3388
+ /** Daemon-facing browser profile returned by `GET /machines/me/browser-profiles`
3389
+ * (mck_-authed, machine-scoped). Unlike {@link BrowserProfile} it carries
3390
+ * `proxy_password`: the local BYOC daemon must replay it to bb-browser. This is the
3391
+ * single intended channel for the credential to leave the server — never surface it
3392
+ * on a human-facing path. */
3393
+ export interface MachineBrowserProfile {
3394
+ id: string;
3395
+ org_id: string;
3396
+ placement: BrowserPlacement;
3397
+ machine_id: string | null;
3398
+ owner_user_id: string;
3399
+ display_name: string;
3400
+ status: BrowserProfileStatus;
3401
+ error_msg?: string | null;
3402
+ last_seen?: string | null;
3403
+ proxy_server?: string | null;
3404
+ proxy_username?: string | null;
3405
+ proxy_password?: string | null;
3406
+ /** Per-profile fencing tokens (PR #1650): lifecycle_generation bumps on every
3407
+ * open/stop/reset (daemon reports under it; stale reports rejected);
3408
+ * reset_generation bumps only on reset (daemon wipes local state on reconnect
3409
+ * when this is newer than what it last applied). Default 0. */
3410
+ lifecycle_generation: number;
3411
+ reset_generation: number;
3031
3412
  }
3032
3413
 
3033
3414
  export interface BrowserProfileConsent {
@@ -3048,10 +3429,21 @@ export interface CreateBrowserProfileRequest {
3048
3429
  machine_id?: string | null;
3049
3430
  owner_user_id: string;
3050
3431
  display_name: string;
3432
+ /** Optional BYO proxy. Omit all for direct egress. proxy_server is `host:port`
3433
+ * (optional http/https/socks5 scheme); proxy_username/password are sent together. */
3434
+ proxy_server?: string | null;
3435
+ proxy_username?: string | null;
3436
+ proxy_password?: string | null;
3051
3437
  }
3052
3438
 
3053
3439
  export interface UpdateBrowserProfileRequest {
3054
3440
  display_name?: string;
3441
+ /** Per-field proxy edit (tri-state): omit = leave unchanged, "" = clear (an empty
3442
+ * proxy_server clears the whole proxy), value = set. Omitting proxy_password keeps
3443
+ * the stored one (never re-entered / echoed). */
3444
+ proxy_server?: string | null;
3445
+ proxy_username?: string | null;
3446
+ proxy_password?: string | null;
3055
3447
  }
3056
3448
 
3057
3449
  export interface BrowserProfileLifecycleRequest {
@@ -3158,12 +3550,27 @@ export interface ClipRemovedData {
3158
3550
 
3159
3551
  // ─── Unified Search ───
3160
3552
 
3161
- export interface SearchParams {
3553
+ // A type alias (not an interface) so it carries an implicit index signature and
3554
+ // can be passed straight to the query-string serializer in client.ts.
3555
+ export type SearchParams = {
3162
3556
  q: string;
3557
+ /** Entity selector CSV: message / task / wiki. Distinct from `wiki_type`. */
3163
3558
  types?: string;
3164
3559
  chat_id?: string;
3165
3560
  limit?: number;
3166
- }
3561
+ /** Page offset into the per-type candidate pool (default 0). Reachability is capped — past the pool, results are empty with `has_more` false. */
3562
+ offset?: number;
3563
+ /** Wiki document-type facet (frontmatter `type`) — a separate axis from `types`. */
3564
+ wiki_type?: string;
3565
+ /** RFC3339 or YYYY-MM-DD lower bound; narrows messages (created_at) and tasks (updated_at). Not applied to wiki. */
3566
+ since?: string;
3567
+ /** Sender filter (Slack `from:`) — user id. Messages only; tasks/wiki carry no sender. */
3568
+ from?: string;
3569
+ /** Result order: `relevance` (default, RRF hybrid) or `recent` (newest-first). Recent applies to messages/tasks; wiki stays relevance (no authored timestamp). */
3570
+ order?: 'relevance' | 'recent';
3571
+ /** Collapse cross-chat message results to one hit per chat (default true). Pass false on the full results page to page every match. No effect when `chat_id` is set. */
3572
+ collapse_by_chat?: boolean;
3573
+ };
3167
3574
 
3168
3575
  export interface SearchMessageResult {
3169
3576
  message_id: string;
@@ -3204,4 +3611,6 @@ export interface SearchResponse {
3204
3611
  messages: SearchMessageResult[];
3205
3612
  tasks: SearchTaskResult[];
3206
3613
  wiki: SearchWikiResult[];
3614
+ /** Per-type flag: more results remain past the returned page (within the reachable pool). Lets a tabbed results UI page each type independently. Optional for resilience to older payloads; clients default to all-false. */
3615
+ has_more?: { messages: boolean; tasks: boolean; wiki: boolean };
3207
3616
  }