@parall/sdk 1.36.1 → 1.38.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
@@ -583,6 +583,13 @@ export interface SendMessageRequest {
583
583
  agent_step_id?: string;
584
584
  agent_session_id?: string;
585
585
  hints?: MessageHints;
586
+ /**
587
+ * Binds this send to a claimed dispatch lane (agent senders only). Every
588
+ * lane-bound write passes the server's lane incumbency check; when
589
+ * idempotency_key carries a dispatch effect key ("reply:<dsp_id>") the
590
+ * write is arbitrated by the scoped dispatch effects ledger.
591
+ */
592
+ dispatch_lane?: string;
586
593
  }
587
594
 
588
595
  export interface SendDirectMessageRequest {
@@ -774,12 +781,26 @@ export interface Machine {
774
781
  // foreground runs that can't load the overlay or restart after exit(42).
775
782
  // Reported on heartbeat; gates the "Check for Update" affordance + API.
776
783
  self_update_capable?: boolean;
784
+ // Daemon-reported runtime CLIs found on the host (heartbeat-refreshed).
785
+ // Absent/null = never reported (pre-detection daemon — UNKNOWN, do not warn);
786
+ // [] = detection ran and found nothing. A signal for pickers only — attach /
787
+ // create are never gated on it (a CLI can be installed at any time).
788
+ detected_runtimes?: DetectedRuntime[] | null;
777
789
  region: string | null;
778
790
  created_by: string;
779
791
  created_at: string;
780
792
  updated_at: string;
781
793
  }
782
794
 
795
+ // One entry of Machine.detected_runtimes. status 'ok' = the CLI resolved and
796
+ // executed (`--version` succeeded); 'broken' = it resolved on disk but failed
797
+ // to run (present-but-unusable install).
798
+ export interface DetectedRuntime {
799
+ runtime_type: string;
800
+ version?: string;
801
+ status: 'ok' | 'broken';
802
+ }
803
+
783
804
  export type DaemonWorkspaceMode = 'default' | 'local_path' | 'git';
784
805
  export type DaemonWorkspaceSetupRunOn = 'first_attach' | 'config_change';
785
806
 
@@ -846,7 +867,7 @@ export interface AgentProfile {
846
867
  model_management: string | null; // "platform" | "self" | null
847
868
  permissions: string[];
848
869
  machine_id: string | null;
849
- hosting_mode?: 'hosted' | 'self_hosted';
870
+ hosting_mode?: 'hosted' | 'self_hosted' | 'platform_runtime';
850
871
  runtime_type: string;
851
872
  description: string | null;
852
873
  thinking_effort: string | null;
@@ -922,6 +943,17 @@ export interface MachineConfigUpdatedData {
922
943
  provider_enabled?: boolean;
923
944
  }
924
945
 
946
+ // Per-agent counterpart of MachineConfigUpdatedData: ONE local agent's
947
+ // explicit llm_source changed, so the daemon respawns just that agent's
948
+ // child. llm_source carries the agent's new EFFECTIVE source (explicit
949
+ // per-agent choice, else the machine default). Mirrors the Go
950
+ // MachineAgentConfigUpdatedData struct.
951
+ export interface MachineAgentConfigUpdatedData {
952
+ machine_id: string;
953
+ agent_id: string;
954
+ llm_source: string;
955
+ }
956
+
925
957
  export interface MachineWorkspaceSetupRequestedData {
926
958
  machine_id: string;
927
959
  agent_id: string;
@@ -958,6 +990,14 @@ export interface MachineBrowserProfileLifecycleData {
958
990
  profile_id: string;
959
991
  action: BrowserProfileLifecycleAction;
960
992
  start_url?: string;
993
+ /** Profile's lifecycle_generation after this transition's bump (PR #1650). The
994
+ * daemon acts under it and echoes it in its status report so the server can
995
+ * reject a stale report. Absent/0 from a pre-generation server. */
996
+ generation?: number;
997
+ /** Profile's reset_generation after this transition (bumped only by `reset`). On
998
+ * an online reset the daemon records it in its per-profile sidecar so a later
999
+ * reconnect doesn't redundantly re-wipe. */
1000
+ reset_generation?: number;
961
1001
  }
962
1002
 
963
1003
  /**
@@ -1078,6 +1118,13 @@ export interface Task {
1078
1118
  canceled_at: string | null;
1079
1119
  archived_at?: string | null;
1080
1120
  deleted_at?: string | null;
1121
+ /**
1122
+ * Per-viewer: whether the requesting user may manage OTHER members' comment
1123
+ * subscriptions for this task (creator / assignee / project lead / org
1124
+ * owner-admin). Populated on single-task GET; undefined elsewhere. Read this to
1125
+ * gate subscriber-management UI — do not re-derive the rule client-side.
1126
+ */
1127
+ can_manage_subscribers?: boolean;
1081
1128
  }
1082
1129
 
1083
1130
  export interface TaskWatcher {
@@ -1158,6 +1205,17 @@ export interface UpdateTaskRequest {
1158
1205
  parent_id?: string | null;
1159
1206
  project_id?: string | null;
1160
1207
  sort_order?: number;
1208
+ /**
1209
+ * Dispatch lane binding (agent senders during a typed dispatch turn).
1210
+ * dispatch_lane + dispatch_event_id bind the update to the claimed typed
1211
+ * lane (incumbency-checked); dispatch_effect_key — exactly
1212
+ * "task_update:<dispatch_event_id>" — additionally commits the update as
1213
+ * the dispatch's idempotent Effect and resolves the WorkItem in the same
1214
+ * transaction (first update only).
1215
+ */
1216
+ dispatch_lane?: string;
1217
+ dispatch_event_id?: string;
1218
+ dispatch_effect_key?: string;
1161
1219
  }
1162
1220
 
1163
1221
  export interface CreateTaskRelationRequest {
@@ -1537,6 +1595,19 @@ export interface Wiki {
1537
1595
  created_by: string;
1538
1596
  created_at: string;
1539
1597
  updated_at: string;
1598
+ /** Protected default wiki — cannot be deleted. */
1599
+ is_default?: boolean | null;
1600
+ /** Set when the wiki is soft-deleted (recoverable). */
1601
+ deleted_at?: string | null;
1602
+ /** User who soft-deleted the wiki. */
1603
+ deleted_by?: string | null;
1604
+ /** Set once purge is claimed — the wiki can no longer be restored. */
1605
+ purge_started_at?: string | null;
1606
+ /** deleted_at + retention window (server-computed) — the recycle-bin countdown
1607
+ * source. Past this, restore is rejected with 410 WIKI_RETENTION_EXPIRED. */
1608
+ purge_eligible_at?: string | null;
1609
+ /** Server-computed restore availability for recycle-bin rows. */
1610
+ restorable?: boolean | null;
1540
1611
  }
1541
1612
 
1542
1613
  export interface WikiFileChange {
@@ -1568,11 +1639,19 @@ export interface WikiTreeEntry {
1568
1639
  path: string;
1569
1640
  type: 'tree' | 'blob';
1570
1641
  size?: number;
1642
+ /**
1643
+ * Entry sits inside a read-gated private subtree (path restriction). Advisory
1644
+ * display flag — the caller already passed read authorization to receive the
1645
+ * entry; use it to badge private folders, never for access decisions.
1646
+ */
1647
+ restricted?: boolean;
1571
1648
  }
1572
1649
 
1573
1650
  export interface WikiTreeResponse {
1574
1651
  data: WikiTreeEntry[];
1575
1652
  path: string;
1653
+ /** Whether the listed directory itself sits inside a read-gated private subtree. */
1654
+ path_restricted?: boolean;
1576
1655
  }
1577
1656
 
1578
1657
  export interface WikiFileManifestEntry {
@@ -1835,6 +1914,11 @@ export interface CreateWikiPathRestrictionRequest {
1835
1914
  level?: 'read' | 'maintain' | 'admin';
1836
1915
  subjects: string[];
1837
1916
  apply_to_admins?: boolean;
1917
+ // When true, the server returns 409 RESTRICTION_EXISTS if a restriction already
1918
+ // exists at `path` instead of upserting its subjects. Set by the member "create
1919
+ // private space" flow so a stale/concurrent create can't silently overwrite an
1920
+ // existing space's share list; edit-access flows leave it unset (upsert).
1921
+ create_only?: boolean;
1838
1922
  }
1839
1923
 
1840
1924
  export interface WikiAccessStatus {
@@ -1881,6 +1965,24 @@ export interface WikiOperationsResponse {
1881
1965
  // Wiki Blob
1882
1966
  // ============================================================
1883
1967
 
1968
+ /**
1969
+ * Copy one wiki file to another path as an independent snapshot (no ongoing
1970
+ * sync). Primary use: "share a private file out" — copy from the caller's
1971
+ * personal namespace (`users/{userId}/…`) into the public wiki so the whole
1972
+ * org can read + edit the copy, leaving the private original untouched.
1973
+ */
1974
+ export interface CopyWikiFileRequest {
1975
+ source_path: string;
1976
+ dest_path: string;
1977
+ message?: string;
1978
+ }
1979
+
1980
+ export interface CopyWikiFileResponse {
1981
+ source_path: string;
1982
+ dest_path: string;
1983
+ commit_sha: string;
1984
+ }
1985
+
1884
1986
  export interface WikiBlob {
1885
1987
  path: string;
1886
1988
  ref: string;
@@ -1895,6 +1997,8 @@ export interface WikiBlob {
1895
1997
  content?: string;
1896
1998
  line_count?: number;
1897
1999
  sha256?: string;
2000
+ /** File sits inside a read-gated private subtree — advisory display flag. */
2001
+ restricted?: boolean;
1898
2002
  // Phase 2 additions for the binary response shape:
1899
2003
  mime?: string;
1900
2004
  is_lfs?: boolean;
@@ -2044,6 +2148,16 @@ export interface MembershipChangedData {
2044
2148
  action: 'added' | 'removed' | 'role_changed';
2045
2149
  }
2046
2150
 
2151
+ /**
2152
+ * A member was removed from an org — kicked by an admin or self-removal
2153
+ * ("leave org"). Delivered on org:{orgId} (remaining members refresh the
2154
+ * directory) and user:{userId} (the removed user's clients drop the org).
2155
+ */
2156
+ export interface OrgMemberRemovedData {
2157
+ org_id: string;
2158
+ user_id: string;
2159
+ }
2160
+
2047
2161
  // ---- Task Comment & Activity Types ----
2048
2162
 
2049
2163
  export type TaskActivityAction = 'created' | 'field_changed' | 'commented';
@@ -2085,7 +2199,15 @@ export interface UpdateTaskCommentRequest {
2085
2199
  export type TaskCreatedData = Task;
2086
2200
  export type TaskUpdatedData = Task;
2087
2201
  /** Sent to user:{agentID} channel when a task is assigned to an agent. Data is the full Task. */
2088
- export type TaskAssignedData = Task;
2202
+ export type TaskAssignedData = Task & {
2203
+ /**
2204
+ * Exact typed WorkItem this assignment enqueued. The runtime claims and
2205
+ * acks by it — never by the shared (task_activity, task_id) source tuple,
2206
+ * which sibling task_update WorkItems from the same PATCH may also carry.
2207
+ * Absent from older servers (fallback: claim by source).
2208
+ */
2209
+ dispatch_event_id?: string | null;
2210
+ };
2089
2211
  export interface TaskDeletedData {
2090
2212
  task_id: string;
2091
2213
  org_id: string;
@@ -2186,6 +2308,14 @@ export interface AgentStepNewData extends AgentStep {}
2186
2308
  export type WikiChangesetCreatedData = WikiChangeset & { org_id: string };
2187
2309
  export type WikiChangesetUpdatedData = WikiChangeset & { org_id: string };
2188
2310
 
2311
+ export interface WikiDeletedData {
2312
+ org_id: string;
2313
+ wiki_id: string;
2314
+ slug: string;
2315
+ name: string;
2316
+ }
2317
+ export type WikiRestoredData = WikiDeletedData;
2318
+
2189
2319
  // Wiki Comment
2190
2320
 
2191
2321
  // Unified Comment (replaces TaskComment and WikiComment)
@@ -2263,6 +2393,134 @@ export interface InboxItem {
2263
2393
  updated_at: string;
2264
2394
  }
2265
2395
 
2396
+ // ============================================================
2397
+ // External IM Channel Types (platform-mediated Feishu/Slack channel)
2398
+ // ============================================================
2399
+
2400
+ export type ChannelProvider = 'feishu' | 'slack';
2401
+ export type ChannelConnectionStatus = 'pending' | 'active' | 'disabled';
2402
+ /**
2403
+ * Inbound transport for a connection. Defaults to the provider's lowest-
2404
+ * onboarding-cost mode server-side (Feishu → socket, Slack → webhook) when
2405
+ * omitted on create; can be overridden per connection.
2406
+ */
2407
+ export type ChannelIngressMode = 'webhook' | 'socket';
2408
+ export type ChannelMessageStatus = 'received' | 'dispatched' | 'failed';
2409
+
2410
+ export interface ChannelConnection {
2411
+ id: string;
2412
+ org_id: string;
2413
+ agent_id: string;
2414
+ provider: ChannelProvider;
2415
+ ingress_mode: ChannelIngressMode;
2416
+ display_name: string;
2417
+ created_by: string;
2418
+ status: ChannelConnectionStatus;
2419
+ external_app_id?: string;
2420
+ external_team_id?: string;
2421
+ archived_at?: string | null;
2422
+ archive_reason?: string | null;
2423
+ /** Returned once at mint time (create / token regeneration). */
2424
+ ingress_url?: string;
2425
+ /** Returned once at mint time (create / token regeneration). */
2426
+ ingress_token?: string;
2427
+ created_at: string;
2428
+ updated_at: string;
2429
+ }
2430
+
2431
+ export interface ChannelCredentialsInput {
2432
+ app_id: string;
2433
+ app_secret: string;
2434
+ verification_token?: string;
2435
+ encrypt_key?: string;
2436
+ team_id?: string;
2437
+ }
2438
+
2439
+ export interface CreateChannelConnectionInput {
2440
+ agent_id: string;
2441
+ provider: ChannelProvider;
2442
+ display_name: string;
2443
+ /** Override the provider's default inbound transport (optional). */
2444
+ ingress_mode?: ChannelIngressMode;
2445
+ /** Manual provisioning: activates the connection immediately. */
2446
+ credentials?: ChannelCredentialsInput;
2447
+ }
2448
+
2449
+ export interface UpdateChannelConnectionInput {
2450
+ display_name?: string;
2451
+ status?: 'active' | 'disabled';
2452
+ }
2453
+
2454
+ export interface ChannelConversation {
2455
+ id: string;
2456
+ org_id: string;
2457
+ connection_id: string;
2458
+ agent_id: string;
2459
+ agent_session_id?: string | null;
2460
+ external_conversation_id: string;
2461
+ external_thread_id: string;
2462
+ conversation_type: string;
2463
+ external_user_id: string;
2464
+ external_user_name: string;
2465
+ last_inbound_at?: string | null;
2466
+ created_at: string;
2467
+ updated_at: string;
2468
+ }
2469
+
2470
+ export interface ChannelMessage {
2471
+ id: string;
2472
+ org_id: string;
2473
+ connection_id: string;
2474
+ conversation_id: string;
2475
+ external_message_id: string;
2476
+ text: string;
2477
+ external_user_id: string;
2478
+ external_user_name: string;
2479
+ status: ChannelMessageStatus;
2480
+ received_at: string;
2481
+ created_at: string;
2482
+ }
2483
+
2484
+ /**
2485
+ * Feishu one-click provisioning session (OAuth device flow). The client
2486
+ * renders `verification_url` as a QR code and lazily polls the status
2487
+ * endpoint every `poll_interval_seconds` — each poll may forward one
2488
+ * provider poll server-side, so respect the interval.
2489
+ */
2490
+ export type ChannelProvisioningStatus =
2491
+ | 'pending'
2492
+ | 'polling'
2493
+ | 'done'
2494
+ | 'expired'
2495
+ | 'denied'
2496
+ | 'canceled'
2497
+ | 'failed';
2498
+
2499
+ export interface ChannelProvisioningSession {
2500
+ id: string;
2501
+ org_id: string;
2502
+ agent_id: string;
2503
+ provider: ChannelProvider;
2504
+ created_by: string;
2505
+ status: ChannelProvisioningStatus;
2506
+ poll_interval_seconds: number;
2507
+ /** Set when status = 'done': the minted connection. */
2508
+ connection_id?: string;
2509
+ /** Terminal detail: access_denied / expired_token / domain_switched / connection_exists / alias_conflict / internal. */
2510
+ error_code?: string;
2511
+ expires_at: string;
2512
+ created_at: string;
2513
+ updated_at: string;
2514
+ /** QR target — present on live (pending/polling) sessions only. */
2515
+ verification_url?: string;
2516
+ user_code?: string;
2517
+ }
2518
+
2519
+ export interface InitiateChannelProvisioningInput {
2520
+ agent_id: string;
2521
+ provider: ChannelProvider;
2522
+ }
2523
+
2266
2524
  // ============================================================
2267
2525
  // Dispatch Types (agent event delivery)
2268
2526
  // ============================================================
@@ -2275,7 +2533,8 @@ export type DispatchEventType =
2275
2533
  | 'wiki_comment'
2276
2534
  | 'schedule.fire'
2277
2535
  | 'external_trigger'
2278
- | 'approval_decided';
2536
+ | 'approval_decided'
2537
+ | 'channel_message';
2279
2538
  export type DispatchStatus = 'pending' | 'received' | 'acked';
2280
2539
  export type DispatchDeliveryReason = 'mention' | 'watcher' | 'assignee' | 'creator';
2281
2540
 
@@ -2303,10 +2562,80 @@ export interface DispatchEvent {
2303
2562
  */
2304
2563
  delivery_reason: DispatchDeliveryReason | null;
2305
2564
  status: DispatchStatus;
2565
+ /**
2566
+ * Ledger fields (dispatch idempotency redesign). dedupe_key is the domain
2567
+ * identity of the source fact; lease_owner points at the lane the WorkItem
2568
+ * is folded into; target_uri / thread_root_id are queue-routing metadata
2569
+ * for message WorkItems; resolution_kind / resolved_by_effect record the
2570
+ * terminal outcome. Nullable — historical rows may predate the ledger.
2571
+ */
2572
+ dedupe_key?: string | null;
2573
+ lease_owner?: string | null;
2574
+ target_uri?: string | null;
2575
+ thread_root_id?: string | null;
2576
+ resolution_kind?: 'effect' | 'no_action' | 'cancelled' | 'legacy_ack' | null;
2577
+ resolved_by_effect?: string | null;
2578
+ /**
2579
+ * Reply-message provenance ("prll://msg_x") of the resolving Effect.
2580
+ * Populated only by GET /dispatch/by-messages (Effect join) on
2581
+ * effect-resolved rows; absent elsewhere.
2582
+ */
2583
+ result_uri?: string | null;
2306
2584
  acked_at: string | null;
2307
2585
  created_at: string;
2308
2586
  }
2309
2587
 
2588
+ /** POST /dispatch/claim — occupy a lane and fold claimable WorkItems into it. */
2589
+ export interface ClaimDispatchRequest {
2590
+ /** Message lane resource (e.g. "prll://cht_x"). Omit for typed claims. */
2591
+ target_uri?: string;
2592
+ thread_root_id?: string;
2593
+ /** Typed WorkItem claim: the lane resource is the WorkItem itself. */
2594
+ dispatch_event_id?: string;
2595
+ /**
2596
+ * Typed claim by source identity, for callers without the WorkItem id
2597
+ * (the live task.assigned event). The dedupe arbiter guarantees at most
2598
+ * one live WorkItem per source.
2599
+ */
2600
+ source_type?: string;
2601
+ source_id?: string;
2602
+ limit?: number;
2603
+ }
2604
+
2605
+ export interface ClaimDispatchResponse {
2606
+ claimed: boolean;
2607
+ lane?: string;
2608
+ lease_until?: string;
2609
+ events?: DispatchEvent[];
2610
+ }
2611
+
2612
+ /** POST /dispatch/steer — fold a pending same-target WorkItem into a live lane. */
2613
+ export interface SteerDispatchRequest {
2614
+ lane: string;
2615
+ target_uri: string;
2616
+ thread_root_id?: string;
2617
+ /** Either the WorkItem id or its (source_type, source_id) pair. */
2618
+ dispatch_event_id?: string;
2619
+ source_type?: string;
2620
+ source_id?: string;
2621
+ }
2622
+
2623
+ export interface SteerDispatchResponse {
2624
+ dispatch_event_id: string;
2625
+ }
2626
+
2627
+ /** POST /dispatch/complete — end a turn: no_action sweep + lane release + re-drive. */
2628
+ export interface CompleteDispatchRequest {
2629
+ lane: string;
2630
+ target_uri: string;
2631
+ thread_root_id?: string;
2632
+ }
2633
+
2634
+ export interface CompleteDispatchResult {
2635
+ swept_no_action: number;
2636
+ redriven: boolean;
2637
+ }
2638
+
2310
2639
  export type DispatchNewData = DispatchEvent;
2311
2640
 
2312
2641
  export interface DispatchExpiredGroup {
@@ -2333,6 +2662,28 @@ export interface DispatchReceivedData {
2333
2662
  org_id: string;
2334
2663
  }
2335
2664
 
2665
+ /**
2666
+ * Terminal counterpart of DispatchReceivedData: published on org:{orgId} when
2667
+ * a message WorkItem reaches a terminal resolution, so the message-level
2668
+ * Activity indicator flips active→done (or clears, for `cancelled`) without
2669
+ * inferring completion from agent session state. Message WorkItems only.
2670
+ */
2671
+ export interface DispatchResolvedData {
2672
+ agent_id: string;
2673
+ event_type: string;
2674
+ source_type: string;
2675
+ source_id: string;
2676
+ chat_id?: string | null;
2677
+ org_id: string;
2678
+ resolution_kind: 'effect' | 'no_action' | 'cancelled' | 'legacy_ack';
2679
+ /**
2680
+ * Reply-message provenance ("prll://msg_x") for effect resolutions —
2681
+ * the indicator's click-through resolves the agent session from this
2682
+ * message. Absent for no_action / legacy_ack.
2683
+ */
2684
+ result_uri?: string | null;
2685
+ }
2686
+
2336
2687
  export type InboxNewData = InboxItem;
2337
2688
 
2338
2689
  export interface InboxUpdateData {
@@ -2398,10 +2749,13 @@ export type WsEventMap = {
2398
2749
  'invitation.revoked': InvitationRevokedEventData;
2399
2750
  'org.join_request.new': OrgJoinRequestNewEventData;
2400
2751
  'org.invite_link.joined': OrgInviteLinkJoinedEventData;
2752
+ 'org.member.removed': OrgMemberRemovedData;
2401
2753
  'agent_config.update': AgentConfigUpdateData;
2402
2754
  'presence.update': PresenceUpdateData;
2403
2755
  'wiki.changeset.created': WikiChangesetCreatedData;
2404
2756
  'wiki.changeset.updated': WikiChangesetUpdatedData;
2757
+ 'wiki.deleted': WikiDeletedData;
2758
+ 'wiki.restored': WikiRestoredData;
2405
2759
  'comment.created': CommentCreatedData;
2406
2760
  'comment.updated': CommentUpdatedData;
2407
2761
  'comment.deleted': CommentDeletedData;
@@ -2412,6 +2766,7 @@ export type WsEventMap = {
2412
2766
  'read_position.updated': ReadPositionUpdateData;
2413
2767
  'dispatch.new': DispatchNewData;
2414
2768
  'dispatch.received': DispatchReceivedData;
2769
+ 'dispatch.resolved': DispatchResolvedData;
2415
2770
  'schedule.created': ScheduleCreatedData;
2416
2771
  'schedule.updated': ScheduleUpdatedData;
2417
2772
  'schedule.deleted': ScheduleDeletedData;
@@ -2425,6 +2780,7 @@ export type WsEventMap = {
2425
2780
  'machine.agent.attached': MachineAgentAttachedData;
2426
2781
  'machine.agent.detached': MachineAgentDetachedData;
2427
2782
  'machine.config.updated': MachineConfigUpdatedData;
2783
+ 'machine.agent_config.updated': MachineAgentConfigUpdatedData;
2428
2784
  'machine.workspace.setup.requested': MachineWorkspaceSetupRequestedData;
2429
2785
  'machine.stop': MachineStopData;
2430
2786
  'machine.filesystem.browse': MachineFilesystemBrowseData;
@@ -2494,7 +2850,14 @@ export interface PlatformConfigResponse {
2494
2850
  version: string;
2495
2851
  schema_version: number;
2496
2852
  min_plugin_version?: string;
2853
+ /** @deprecated V1-compat only — old bridges read this for override-vs-floor. New bridges read `model_is_pin`. */
2497
2854
  mode?: string;
2855
+ /**
2856
+ * Whether the delivered model is an operator PIN (override, beats the runtime's
2857
+ * env/default) vs a catalog FLOOR (loses to env). Optional: an old server omits
2858
+ * it and the bridge falls back to the legacy `model_management`-derived signal.
2859
+ */
2860
+ model_is_pin?: boolean;
2498
2861
  config: Record<string, unknown>;
2499
2862
  }
2500
2863
 
@@ -2843,6 +3206,61 @@ export interface ComputePricing {
2843
3206
  // component name ("cpu" | "memory" | "storage").
2844
3207
  export type ComputePricingResponse = Record<string, ComputePricing>;
2845
3208
 
3209
+ /**
3210
+ * Per-runtime capability row from GET /api/v1/runtimes (public, no auth).
3211
+ * Server SSOT: server/pkg/hosting/capabilities.go RuntimeCapability — the
3212
+ * data source for the create/settings interlock (which compute × intelligence
3213
+ * × model combinations are offerable per runtime).
3214
+ */
3215
+ export interface RuntimeCapability {
3216
+ runtime: string;
3217
+ /** Where the runtime can run: "hosted" and/or "local". Hermes is cloud-only. */
3218
+ compute_modes: string[];
3219
+ /**
3220
+ * Provider family the runtime's OWN credentials can serve ("anthropic" /
3221
+ * "openai"), or "any" for family-agnostic runtimes. Own-route restriction
3222
+ * only — see cross_family_via_parall.
3223
+ */
3224
+ native_model_family: string;
3225
+ /** On the Parall proxy route any catalog model is allowed regardless of family. */
3226
+ cross_family_via_parall: boolean;
3227
+ /** Whether a pinned model is delivered when the agent runs on its own credentials. */
3228
+ own_route_model_pin: boolean;
3229
+ /** Catalog default the UI pre-selects for this runtime. */
3230
+ recommended_model: string;
3231
+ }
3232
+
3233
+ /**
3234
+ * Catalog entry from GET /api/v1/models (public, no auth) — the DB-backed
3235
+ * platform model catalog. Server SSOT: handler.PlatformModelDTO
3236
+ * (docs/engineering-design/model-catalog-design.md §6.1). Replaces the
3237
+ * compile-time PLATFORM_MODELS constant as the picker data source.
3238
+ */
3239
+ export interface PlatformModelInfo {
3240
+ id: string;
3241
+ name: string;
3242
+ /** Provider family ("anthropic", "openai", "google", ...). */
3243
+ family: string;
3244
+ contextWindow: number;
3245
+ maxTokens: number;
3246
+ effortLevels?: string[];
3247
+ /** Runtime type → runtime-native CLI model name. */
3248
+ runtime_names?: Record<string, string>;
3249
+ /** Set on client-behavior variants (the "(1M)" entries) — see isPlatformModelSelectableForRuntime. */
3250
+ upstream_id?: string;
3251
+ /** Display hints: "recommended" / "new" / "beta". */
3252
+ tags?: string[];
3253
+ sort_order: number;
3254
+ /** True only for a legacy entry appended via include_model (not in the active catalog). */
3255
+ hidden?: boolean;
3256
+ }
3257
+
3258
+ export interface PlatformModelsResponse {
3259
+ data: PlatformModelInfo[];
3260
+ /** Catalog content hash — changes whenever the catalog changes. */
3261
+ version: string;
3262
+ }
3263
+
2846
3264
  export interface MachinePreset {
2847
3265
  key: string;
2848
3266
  cpu_cores: number;
@@ -2914,7 +3332,11 @@ export interface BillingInsufficientEvent {
2914
3332
  // Clip Types
2915
3333
  // ============================================================
2916
3334
 
2917
- export type ClipSourceType = 'registry' | 'custom' | 'builtin';
3335
+ // 'channel' is a platform-managed source: it appears on read (Clip.source_type)
3336
+ // but the server rejects it on create, so CreateClipRequest uses the narrower
3337
+ // UserClipSourceType.
3338
+ export type ClipSourceType = 'registry' | 'custom' | 'builtin' | 'channel';
3339
+ export type UserClipSourceType = 'registry' | 'custom' | 'builtin';
2918
3340
  export type ClipStatus = 'active' | 'disabled';
2919
3341
 
2920
3342
  export interface Clip {
@@ -2949,7 +3371,7 @@ export interface CreateClipRequest {
2949
3371
  display_name?: string;
2950
3372
  description?: string;
2951
3373
  manifest?: Record<string, unknown>;
2952
- source_type?: ClipSourceType;
3374
+ source_type?: UserClipSourceType;
2953
3375
  source_ref?: string;
2954
3376
  version?: string;
2955
3377
  machine_id: string;
@@ -3017,6 +3439,15 @@ export type BrowserProfileStatus = 'pending' | 'running' | 'stopped' | 'error' |
3017
3439
  */
3018
3440
  export type BrowserPlacement = 'byoc' | 'hosted';
3019
3441
 
3442
+ /** Deployment-wide hosted browser runtime availability (the controller startup
3443
+ * gate). Drives whether the create UI offers the platform-hosted placement; it
3444
+ * is org-scoped only for auth — the value itself is the same for every org.
3445
+ * Fail-closed: the server reports `available: false` if it cannot verify. */
3446
+ export interface BrowserRuntimeStatus {
3447
+ available: boolean;
3448
+ reason?: string;
3449
+ }
3450
+
3020
3451
  export interface BrowserProfile {
3021
3452
  id: string;
3022
3453
  org_id: string;
@@ -3091,6 +3522,12 @@ export interface MachineBrowserProfile {
3091
3522
  proxy_server?: string | null;
3092
3523
  proxy_username?: string | null;
3093
3524
  proxy_password?: string | null;
3525
+ /** Per-profile fencing tokens (PR #1650): lifecycle_generation bumps on every
3526
+ * open/stop/reset (daemon reports under it; stale reports rejected);
3527
+ * reset_generation bumps only on reset (daemon wipes local state on reconnect
3528
+ * when this is newer than what it last applied). Default 0. */
3529
+ lifecycle_generation: number;
3530
+ reset_generation: number;
3094
3531
  }
3095
3532
 
3096
3533
  export interface BrowserProfileConsent {
@@ -3240,10 +3677,18 @@ export type SearchParams = {
3240
3677
  types?: string;
3241
3678
  chat_id?: string;
3242
3679
  limit?: number;
3680
+ /** Page offset into the per-type candidate pool (default 0). Reachability is capped — past the pool, results are empty with `has_more` false. */
3681
+ offset?: number;
3243
3682
  /** Wiki document-type facet (frontmatter `type`) — a separate axis from `types`. */
3244
3683
  wiki_type?: string;
3245
- /** RFC3339 or YYYY-MM-DD; narrows messages (created_at) and tasks (updated_at). Not applied to wiki. */
3684
+ /** RFC3339 or YYYY-MM-DD lower bound; narrows messages (created_at) and tasks (updated_at). Not applied to wiki. */
3246
3685
  since?: string;
3686
+ /** Sender filter (Slack `from:`) — user id. Messages only; tasks/wiki carry no sender. */
3687
+ from?: string;
3688
+ /** Result order: `relevance` (default, RRF hybrid) or `recent` (newest-first). Recent applies to messages/tasks; wiki stays relevance (no authored timestamp). */
3689
+ order?: 'relevance' | 'recent';
3690
+ /** 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. */
3691
+ collapse_by_chat?: boolean;
3247
3692
  };
3248
3693
 
3249
3694
  export interface SearchMessageResult {
@@ -3285,4 +3730,6 @@ export interface SearchResponse {
3285
3730
  messages: SearchMessageResult[];
3286
3731
  tasks: SearchTaskResult[];
3287
3732
  wiki: SearchWikiResult[];
3733
+ /** 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. */
3734
+ has_more?: { messages: boolean; tasks: boolean; wiki: boolean };
3288
3735
  }