// GENERATED by scripts/gen_gateway_contracts.py from tui_gateway/contracts — DO NOT EDIT.
// Regenerate: .venv/bin/python scripts/gen_gateway_contracts.py
// tests/tui_gateway/contracts/test_generated.py fails when this file is stale.
/* eslint-disable */
// ── Types ──
/** Any method the desktop may route to a named profile (``requestGatewayForProfile`` adds ``profile``). */
export interface ProfileParams {
  profile?: string | null
}
/** ``_serialize_usage_model`` — also embedded as ``usage`` in the billing / subscription states, where the fail-open form is a bare ``{available: false}`` (no ``ok``). */
export interface UsageModel {
  ok?: boolean | null
  available: boolean
  status?: string | null
  plan_name?: string | null
  renews_at?: string | null
  renews_display?: string | null
  subscription_remaining_display?: string | null
  topup_remaining_display?: string | null
  total_spendable_display?: string | null
  has_topup?: boolean | null
  plan_bar?: UsageBar | null
  topup_bar?: UsageBar | null
}
/** ``_serialize_usage_bar``: one bar, magnitudes pre-formatted; ``pct_used`` only for ``plan``. */
export interface UsageBar {
  kind: UsageBarKind
  remaining_display: string
  total_display: string
  spent_display: string
  pct_used?: number | null
  fill_fraction: number
}
export type UsageBarKind = 'plan' | 'topup'
/** ``_serialize_billing_state`` (money as strings); the ``except`` fallback emits only ``ok / logged_in / free_tier / error``, so everything else is optional. */
export interface BillingStateResult {
  ok: boolean
  logged_in: boolean
  free_tier?: boolean
  free_tier_model?: string | null
  org_name?: string | null
  org_slug?: string | null
  role?: string | null
  is_admin?: boolean | null
  can_change_plan?: boolean | null
  can_charge?: boolean | null
  balance_usd?: string | null
  balance_display?: string | null
  cli_billing_enabled?: boolean | null
  charge_presets?: string[] | null
  charge_presets_display?: string[] | null
  min_usd?: string | null
  max_usd?: string | null
  card?: BillingCardInfo | null
  payment_method?: BillingPaymentMethod | null
  monthly_cap?: BillingMonthlyCap | null
  auto_reload?: BillingAutoReload | null
  portal_url?: string | null
  error?: string | null
  usage?: UsageModel | null
}
export interface BillingCardInfo {
  brand: string
  last4: string
  masked: string
  display?: string | null
  resolved_via?: string | null
}
/** ``_serialize_payment_method``: each kind emits only its own fields (a ``card`` never carries ``email``; ``unknown`` carries what the server called it in ``raw_kind``). */
export interface BillingPaymentMethod {
  kind: PaymentMethodKind
  brand?: string | null
  last4?: string | null
  wallet?: string | null
  email?: string | null
  raw_kind?: string | null
  resolved_via?: string | null
}
export type PaymentMethodKind = 'card' | 'link' | 'unknown'
export interface BillingMonthlyCap {
  limit_usd?: string | null
  limit_display: string
  spent_this_month_usd?: string | null
  spent_display: string
  is_default_ceiling: boolean
}
export interface BillingAutoReload {
  enabled: boolean
  threshold_usd?: string | null
  threshold_display: string
  reload_to_usd?: string | null
  reload_to_display: string
  card?: BillingAutoReloadCard | null
}
/** Only ``distinct`` carries the payment-method identity. */
export interface BillingAutoReloadCard {
  kind: AutoReloadCardKind
  payment_method_id?: string | null
  brand?: string | null
  last4?: string | null
}
export type AutoReloadCardKind = 'canonical' | 'distinct' | 'none'
/** ``_serialize_subscription_state``; the view's fallback emits only ``ok / logged_in / error``. */
export interface SubscriptionStateResult {
  ok: boolean
  logged_in: boolean
  is_admin?: boolean | null
  can_change_plan?: boolean | null
  org_name?: string | null
  org_id?: string | null
  role?: string | null
  context?: SubscriptionContext | null
  current?: CurrentSubscription | null
  tiers?: SubscriptionTierOption[] | null
  portal_url?: string | null
  error?: string | null
  usage?: UsageModel | null
}
export type SubscriptionContext = 'personal' | 'team'
export interface CurrentSubscription {
  tier_id?: string | null
  tier_name?: string | null
  monthly_credits?: string | null
  credits_remaining?: string | null
  cycle_ends_at?: string | null
  pending_downgrade_tier_name?: string | null
  pending_downgrade_at?: string | null
  pending_downgrade_display?: string | null
  cancel_at_period_end: boolean
  cancellation_effective_at?: string | null
  cancellation_effective_display?: string | null
}
export interface SubscriptionTierOption {
  tier_id: string
  name: string
  tier_order: number
  dollars_per_month_display: string
  monthly_credits?: string | null
  is_current: boolean
  is_enabled: boolean
}
export interface SubscriptionPreviewParams {
  profile?: string | null
  subscription_type_id?: string | null
}
/** ``_serialize_subscription_preview`` on success; ``effect`` drives the confirm copy. */
export interface SubscriptionPreviewResult {
  ok: boolean
  error?: string | null
  message?: string | null
  portal_url?: string | null
  retry_after?: number | null
  payload?: Record<string, unknown> | null
  actor?: string | null
  code?: string | null
  recovery?: string | null
  effect?: SubscriptionChangeEffect | null
  reason?: string | null
  current_tier_id?: string | null
  current_tier_name?: string | null
  target_tier_id?: string | null
  target_tier_name?: string | null
  monthly_credits_delta?: string | null
  amount_due_now_cents?: number | null
  effective_at?: string | null
}
export type SubscriptionChangeEffect = 'charge_now' | 'scheduled' | 'no_op' | 'blocked'
/** Either a target tier (downgrade / same-price change) or ``cancel`` (period-end cancellation). */
export interface SubscriptionChangeParams {
  profile?: string | null
  subscription_type_id?: string | null
  cancel?: boolean
}
/** ``_billing_pending_change``: ``message`` + the raw NAS body in ``payload`` on success. */
export interface BillingPendingChangeResult {
  ok: boolean
  error?: string | null
  message?: string | null
  portal_url?: string | null
  retry_after?: number | null
  payload?: Record<string, unknown> | null
  actor?: string | null
  code?: string | null
  recovery?: string | null
}
export interface SubscriptionUpgradeParams {
  profile?: string | null
  subscription_type_id?: string | null
  idempotency_key?: string | null
}
/** The money route: ``status`` separates a completed upgrade from an SCA / decline that must finish in the portal at ``recovery_url``; ``idempotency_key`` is echoed (also on error) so a retry reuses it. */
export interface SubscriptionUpgradeResult {
  ok: boolean
  error?: string | null
  message?: string | null
  portal_url?: string | null
  retry_after?: number | null
  payload?: Record<string, unknown> | null
  actor?: string | null
  code?: string | null
  recovery?: string | null
  status?: string | null
  target_tier_name?: string | null
  recovery_url?: string | null
  reason?: string | null
  idempotency_key?: string | null
}
export interface BillingChargeParams {
  profile?: string | null
  amount_usd?: number | string | null
  idempotency_key?: string | null
}
/** ``202 {chargeId}`` — money is not confirmed yet; poll ``billing.charge_status``. */
export interface BillingChargeResult {
  ok: boolean
  error?: string | null
  message?: string | null
  portal_url?: string | null
  retry_after?: number | null
  payload?: Record<string, unknown> | null
  actor?: string | null
  code?: string | null
  recovery?: string | null
  charge_id?: string | null
  idempotency_key?: string | null
}
export interface BillingChargeStatusParams {
  profile?: string | null
  charge_id?: string | null
}
/** Single status read (pending | settled | failed); the caller drives the poll cadence. */
export interface BillingChargeStatusResult {
  ok: boolean
  error?: string | null
  message?: string | null
  portal_url?: string | null
  retry_after?: number | null
  payload?: Record<string, unknown> | null
  actor?: string | null
  code?: string | null
  recovery?: string | null
  status?: string | null
  amount_usd?: string | number | null
  settled_at?: string | null
  reason?: string | null
}
export interface BillingAutoReloadParams {
  profile?: string | null
  enabled?: boolean
  threshold?: number | string | null
  top_up_amount?: number | string | null
}
/** A write with no success payload beyond ``ok``. */
export interface BillingMutationResult {
  ok: boolean
  error?: string | null
  message?: string | null
  portal_url?: string | null
  retry_after?: number | null
  payload?: Record<string, unknown> | null
  actor?: string | null
  code?: string | null
  recovery?: string | null
}
export interface BillingStepUpParams {
  profile?: string | null
  session_id?: string | null
}
/** ``granted`` false when the server downscopes (also on every error envelope). */
export interface BillingStepUpResult {
  ok: boolean
  error?: string | null
  message?: string | null
  portal_url?: string | null
  retry_after?: number | null
  payload?: Record<string, unknown> | null
  actor?: string | null
  code?: string | null
  recovery?: string | null
  granted?: boolean | null
}
export interface DelegationStatusResult {
  active: ActiveSubagent[]
  paused: boolean
  max_spawn_depth: number
  max_concurrent_children: number
}
/** One live child from ``tools/delegate_tool_registry.py::list_active_subagents`` (the record is extended by the child runner — ``missed_steer`` etc. — so it stays open). */
export interface ActiveSubagent {
  subagent_id: string
  parent_id?: string | null
  depth?: number | null
  goal?: string | null
  delegation_id?: string | null
  model?: string | null
  started_at?: number | null
  status?: string | null
  tool_count?: number | null
  owner_agent_session_id?: string | null
  [key: string]: unknown
}
export interface DelegationPauseParams {
  profile?: string | null
  paused?: boolean
}
export interface DelegationPauseResult {
  paused: boolean
}
export interface SubagentSteerParams {
  session_id: string
  profile?: string | null
  subagent_id: string
  text: string
}
/** ``queued`` is not ``delivered``: a child past its final tool batch surfaces ``missed_steer``. */
export interface SubagentSteerResult {
  status: SteerStatus
  subagent_id: string
  text: string
}
export type SteerStatus = 'queued' | 'rejected'
export interface HandoffRequestParams {
  session_id: string
  profile?: string | null
  platform: string
}
export interface HandoffRequestResult {
  queued: boolean
  session_key: string
  platform: string
  home_name: string
}
/** Any method addressed at one live session. */
export interface SessionParams {
  session_id: string
  profile?: string | null
}
/** ``state`` is pending | running | completed | failed, or '' when nothing was requested. */
export interface HandoffStateResult {
  state: string
  platform: string
  error: string
}
export interface HandoffFailParams {
  session_id: string
  profile?: string | null
  error?: string | null
}
/** ``failed`` false when the watcher already claimed the row; ``state`` is what it is now. */
export interface HandoffFailResult {
  failed: boolean
  state: string
}
/** ``row_id`` is ``messages.id``; a not-yet-persisted live message names ``newest_role`` instead. ``emoji`` null clears; the same emoji again retracts. */
export interface MessageReactParams {
  session_id: string
  profile?: string | null
  row_id?: number | null
  newest_role?: string | null
  emoji?: string | null
  author?: ReactionAuthor | null
}
export type ReactionAuthor = 'user' | 'agent'
export interface MessageReactResult {
  row_id: number
  reactions: MessageReaction[]
}
/** One persisted reaction row (``hermes_state_messages.set_message_reaction``); ``seen`` is stamped once announced. */
export interface MessageReaction {
  emoji: string
  author: string
  at?: number | null
  seen?: boolean | null
  [key: string]: unknown
}
export interface PetCancelParams {
  profile?: string | null
  token?: string | null
}
export interface PetCancelResult {
  ok: boolean
}
export interface PetGenerateStatusResult {
  available: boolean
  providers: PetGenProvider[]
}
/** ``agent/pet/generate/imagegen.py::list_sprite_providers`` row. */
export interface PetGenProvider {
  name: string
  label: string
  default: boolean
}
/** ``prompt`` or a ``referenceImage`` data URL is required (the handler answers 4004 without one). */
export interface PetGenerateParams {
  profile?: string | null
  prompt?: string | null
  referenceImage?: string | null
  count?: number | null
  style?: string | null
  provider?: string | null
}
export interface PetGenerateResult {
  ok: boolean
  token: string
  drafts: PetDraft[]
}
export interface PetDraft {
  index: number
  dataUri: string
}
export interface PetHatchParams {
  profile?: string | null
  token: string
  name: string
  cancelToken?: string | null
  index?: number | null
  description?: string | null
  prompt?: string | null
  style?: string | null
  provider?: string | null
}
/** The hatched pet is installed but NOT active (``pet.select`` adopts, ``pet.remove`` discards). */
export interface PetHatchResult {
  ok: boolean
  slug: string
  displayName: string
  warnings?: unknown[]
  pet: PetSpritePayload
}
export interface PetSpritePayload {
  slug?: string | null
  displayName?: string | null
  mime?: string | null
  spritesheetBase64?: string | null
  spritesheetRevision?: string | null
  frameW?: number | null
  frameH?: number | null
  framesPerState?: number | null
  framesByState?: Record<string, number> | null
  framesByRow?: Record<string, number> | null
  loopMs?: number | null
  scale?: number | null
  stateRows?: string[] | null
}
export interface ProjectFactsParams {
  profile?: string | null
  cwd?: string | null
}
/** ``facts`` null outside a workspace (or when detection failed). */
export interface ProjectFactsResult {
  facts?: ProjectFacts | null
}
/** ``agent/coding_context.py::project_facts_for`` — the system prompt's coding-context detection. */
export interface ProjectFacts {
  root: string
  manifests: string[]
  packageManagers: string[]
  verifyCommands: string[]
  contextFiles: string[]
}
/** ``key`` selects one getter from ``_CONFIG_GETTERS``; ``cwd`` feeds the ``project`` getter, ``session_id`` lets ``reasoning`` / ``fast`` answer with the session's live pin. */
export interface ConfigGetParams {
  profile?: string | null
  key: string
  cwd?: string | null
  session_id?: string | null
}
/** Union of every getter's payload: ``value`` for the simple words, ``config`` for ``full``, ``mtime`` / ``mcp_rev`` for the poller, ``model`` / ``provider`` / ``providers`` for ``provider``, ``home`` / ``display`` for ``profile``, ``cwd`` / ``branch`` for ``project``, ``prompt``. */
export interface ConfigGetResult {
  value?: string | null
  display?: string | null
  tool_progress?: string | null
  model?: string | null
  provider?: string | null
  providers?: ConfigProviderRef[] | null
  home?: string | null
  cwd?: string | null
  branch?: string | null
  config?: Record<string, unknown> | null
  prompt?: string | null
  mtime?: number | null
  mcp_rev?: string | null
}
/** ``hermes_cli/models.py::list_available_providers`` row. */
export interface ConfigProviderRef {
  id: string
  label: string
  aliases?: string[]
  authenticated?: boolean
  [key: string]: unknown
}
/** ``key`` picks the setter (``_CONFIG_SETTERS``, ``details_mode.<section>``, display toggles); ``value`` is the raw word/string the setter normalises (falsy non-strings are reported back in the error). ``scope`` applies to ``yolo`` / ``reasoning``; ``confirm_expensive_model`` to ``model``. */
export interface ConfigSetParams {
  profile?: string | null
  key: string
  value?: unknown
  session_id?: string | null
  scope?: string | null
  confirm_expensive_model?: boolean
}
/** ``{key, value}`` plus the setter's extras: model switches add ``warning`` / ``confirm_required`` / ``confirm_message`` / ``scope`` / ``deferred``; ``focus`` adds ``tool_progress``; ``cwd`` adds ``cwd`` / ``branch``; ``personality`` adds ``history_reset`` / ``info``; ``yolo`` reports its ``scope``. ``value`` is a bool only for the display toggles. */
export interface ConfigSetResult {
  key: string
  value?: string | boolean | null
  warning?: string | null
  confirm_required?: boolean | null
  confirm_message?: string | null
  scope?: string | null
  deferred?: boolean | null
  tool_progress?: string | null
  cwd?: string | null
  branch?: string | null
  history_reset?: boolean | null
  info?: SessionLiveInfo | null
}
/** ``tui_gateway/server.py::_session_info`` — the ``session.info`` event and the ``info`` field of ``session.create`` / ``session.resume`` / ``session.activate`` results. */
export interface SessionLiveInfo {
  model?: string
  provider?: string
  reasoning_effort?: string
  reasoning_effort_wire?: string
  service_tier?: string
  fast?: boolean
  yolo?: boolean
  approval_mode?: string
  tools?: Record<string, string[]>
  skills?: Record<string, string[]>
  cwd?: string
  branch?: string | null
  project?: ProjectRef | null
  terminal_backend?: string
  personality?: string
  running?: boolean
  turn_started_at?: number | null
  title?: string
  stored_session_id?: string
  desktop_contract?: number | string | null
  version?: string
  release_date?: string
  update_behind?: unknown | null
  update_command?: string
  usage?: Usage | null
  profile_name?: string | null
  mcp_servers?: McpServerStatus[]
  system_prompt?: string | null
  credential_warning?: string | null
  lazy?: boolean | null
  [key: string]: unknown
}
/** ``tui_gateway/server.py::_project_info_for_cwd``. */
export interface ProjectRef {
  id: string
  slug: string
  name: string
  primary_path?: string | null
}
/** ``tui_gateway/server.py::_get_usage`` + ``agent/context_breakdown.py::context_usage_fields``. */
export interface Usage {
  model?: string
  input?: number
  output?: number
  reasoning?: number
  prompt?: number
  completion?: number
  total?: number
  calls?: number
  compressions?: number | null
  context_used?: number | null
  context_max?: number | null
  context_percent?: number | null
  context_source?: string | null
  context_estimated?: boolean | null
  cache_hit_pct?: number | null
  cache_read?: number | null
  cache_write?: number | null
  avg_latency_s?: number | null
  avg_tps?: number | null
  active_subagents?: number | null
  dev_credits_spent_micros?: number | null
  cost_usd?: number | null
  cost_status?: string | null
  [key: string]: unknown
}
export interface McpServerStatus {
  name?: string
  status?: string | null
  tool_count?: number | null
  error?: string | null
  [key: string]: unknown
}
/** ``provider_configured`` is the loose answer; the boot record's fields (``ready``, ``free_tier``, ``other_providers``, ``inference_provider``) ride along on the launch profile. An unknown ``profile`` answers ``ok=False`` + ``error``. */
export interface SetupStatusResult {
  provider_configured?: boolean | null
  ready?: boolean | null
  free_tier?: boolean | null
  other_providers?: boolean | null
  inference_provider?: string | null
  profile?: string | null
  ok?: boolean | null
  error?: string | null
}
export interface SetupRuntimeCheckParams {
  profile?: string | null
  provider?: string | null
}
/** ``ok=False`` + ``error`` when the resolved model can't be served; ``free_tier`` says the selected route is the welcome host. */
export interface SetupRuntimeCheckResult {
  ok: boolean
  provider?: string | null
  model?: string | null
  source?: string | null
  error?: string | null
  free_tier?: boolean | null
  profile?: string | null
}
export interface DiagnosticsShareNousParams {
  error_context?: string | null
  extra_files?: Record<string, string> | null
  log_lines?: number | null
}
/** Structured envelope: ``ok=False`` + ``error`` renders inline instead of failing the RPC. */
export interface DiagnosticsShareNousResult {
  ok: boolean
  view_url?: string | null
  upload_id?: string | null
  expires_at?: string | null
  error?: string | null
}
/** ``available`` = an identity exists AND the tier is on; whether inference runs on it is ``setup.runtime_check.free_tier``'s question. */
export interface FreeTierStatusResult {
  has_guest: boolean
  enabled: boolean
  available: boolean
  notice_pending: boolean
  model: string
  label: string
}
export interface FreeTierProvisionResult {
  has_guest: boolean
  enabled: boolean
  error?: string | null
}
export interface FreeTierAckNoticeResult {
  acked: boolean
}
export interface ModelOptionsParams {
  profile?: string | null
  session_id?: string | null
  explicit_only?: boolean
  include_unconfigured?: boolean
  refresh?: boolean
}
export interface ModelOptionsResult {
  providers: ModelOptionProvider[]
  model?: string
  provider?: string
}
/** One ``hermes_cli/inventory.py::build_models_payload`` provider row (the union of every field the builder sets; ``pricing_pending`` / ``free_tier_pending`` mark the cached-only path). */
export interface ModelOptionProvider {
  slug: string
  name: string
  models?: string[]
  total_models?: number | null
  is_current?: boolean | null
  is_user_defined?: boolean | null
  source?: string | null
  aliases?: string[] | null
  api_url?: string | null
  auth_type?: string | null
  authenticated?: boolean | null
  key_env?: string | null
  warning?: string | null
  featured_models?: string[] | null
  capabilities?: Record<string, ModelCapabilities> | null
  pricing?: Record<string, ModelPricing> | null
  pricing_pending?: boolean | null
  free_tier?: boolean | null
  free_tier_pending?: boolean | null
  free_tier_row?: boolean | null
  unavailable_models?: string[] | null
  [key: string]: unknown
}
/** ``hermes_cli/inventory.py::_apply_capabilities``. */
export interface ModelCapabilities {
  fast: boolean
  reasoning: boolean
  can_disable_reasoning?: boolean | null
}
/** ``hermes_cli/inventory.py::_apply_pricing`` — formatted $/Mtok strings (``""`` unknown, ``"free"``); the sale fields are Nous Portal-only. */
export interface ModelPricing {
  input: string
  output: string
  cache?: string | null
  free: boolean
  discount_percent?: number | null
  was_input?: string | null
  was_output?: string | null
}
export interface ImageGenerateParams {
  prompt?: string | null
  aspect_ratio?: string | null
  probe?: unknown | null
  max_bytes?: number | null
}
/** ``probe`` answers ``{available}`` alone; ``image_data`` (data URL) is omitted when the download failed or exceeded ``max_bytes`` so callers fall back to ``image``. */
export interface ImageGenerateResult {
  available: boolean
  success?: boolean | null
  image?: string | null
  image_data?: string | null
  error?: string | null
}
export interface SessionControlReadParams {
  profile?: string | null
  session_id: string
}
export interface SessionControlReadResult {
  control: SessionControlSnapshot
}
/** ``_snapshot_control`` — ``revision`` is a hash of the visible state (``""`` when empty); ``updated_at`` is the newest persisted timestamp (``0`` when none). */
export interface SessionControlSnapshot {
  goal: GoalSnapshot | null
  loop: LoopSnapshot | null
  heartbeat: HeartbeatSnapshot | null
  revision: string
  updated_at: number
}
/** ``methods_session_control.py::_safe_goal_snapshot`` — the frontend-safe GoalState subset. */
export interface GoalSnapshot {
  title: string
  status: string
  turns_used: number
  max_turns: number
  contract: GoalContractSnapshot
  subgoals: string[]
  gates: GoalGateSnapshot[]
  created_at?: number | null
  updated_at?: number | null
  paused_reason?: string | null
  last_verdict?: string | null
  last_reason?: string | null
  wait_barrier?: WaitBarrierUntil | WaitBarrierTarget | null
}
/** ``hermes_cli/goals.py::GoalContract.to_dict``. */
export interface GoalContractSnapshot {
  outcome?: string
  verification?: string
  constraints?: string
  boundaries?: string
  stop_when?: string
}
export interface GoalGateSnapshot {
  command: string
  timeout_seconds: number
  max_retries: number
  attempts: number
  last_exit_code?: number | null
}
export interface WaitBarrierUntil {
  type: 'until'
  until_at: number
  reason?: string
}
export interface WaitBarrierTarget {
  type: 'session' | 'pid'
  target: string | number
  reason?: string
}
/** ``_safe_loop_snapshot`` — persisted LoopState fields, never its route. */
export interface LoopSnapshot {
  prompt: string
  status: string
  mode: string
  interval_seconds: number
  current_delay: number
  times: number
  until: string
  max_ticks: number
  ticks_fired: number
  created_at: number
  last_fired_at: number
  next_due_at: number
  awaiting_response: boolean
  deferred_by_goal: boolean
  paused_reason?: string | null
  last_stop_reason?: string | null
}
export interface HeartbeatSnapshot {
  prompt: string
  status: string
  interval_seconds: number
  created_at: number
  last_fired_at: number
  fire_count: number
}
/** ``action`` is validated by the handler (unknown / gate actions answer ``4004``), so it stays a string on the wire; ``SessionControlAction`` lists the accepted set. */
export interface SessionControlParams {
  profile?: string | null
  session_id: string
  action: string
  args?: SessionControlArgs | null
}
/** ``subgoal.add`` reads ``text``; ``subgoal.remove`` reads the 1-based ``index``. */
export interface SessionControlArgs {
  text?: string | null
  index?: number | null
}
export interface SessionControlResult {
  control: SessionControlSnapshot
  dispatch: SessionControlDispatch
}
/** ``_dispatch_envelope`` — the command result's user-visible envelope, every key always present. */
export interface SessionControlDispatch {
  type: string | null
  output: string | null
  notice: string | null
  message: string | null
  display: string | null
}
export interface VerificationStatusParams {
  profile?: string | null
  session_id?: string | null
  session_key?: string | null
  cwd?: string | null
}
export interface VerificationStatusResult {
  verification: VerificationStatusInfo
}
/** ``verification_status()``: ``disabled`` / ``not_applicable`` / ``unverified`` / ``stale`` or the latest event's own status; ``root`` and friends only once a workspace was identified. */
export interface VerificationStatusInfo {
  status: string
  evidence?: VerificationEvidenceRow | null
  root?: string | null
  session_id?: string | null
  changed_paths?: string[] | null
}
/** One ``verification_events`` row (``agent/verification_evidence.py``). */
export interface VerificationEvidenceRow {
  id?: number | null
  created_at?: string | null
  session_id?: string | null
  cwd?: string | null
  root?: string | null
  command?: string | null
  canonical_command?: string | null
  kind?: string | null
  scope?: string | null
  status?: string | null
  exit_code?: number | null
  output_summary?: string | null
  [key: string]: unknown
}
export interface ConnectionOperationParams {
  profile?: string | null
  owner: SessionOwner | AccountOwner
  op_id: string
}
export interface SessionOwner {
  type: 'session'
  session_id: string
}
export interface AccountOwner {
  type: 'account'
}
/** ``methods_connectors._operation_view``: the operation's full snapshot. */
export interface ConnectionOperationStatus {
  op_id: string
  seq: number
  deadline_at: number
  settled: boolean
  settled_at?: number | null
  settled_by?: ConnectionSettleReason | null
  targets: ConnectionOperationTarget[]
}
/** ``tools/connectors/contract.py::SettleReason``. */
export type ConnectionSettleReason = 'all_resolved' | 'continue' | 'deadline' | 'interrupt'
/** ``Target.snapshot``: the link minted up front rides here, never in the model result. ``extra`` keys a leg records (``tools``, ``hint``) are typed here as they appear. */
export interface ConnectionOperationTarget {
  name: string
  kind: ConnectionTargetKind
  action: ConnectionTargetAction
  state: ConnectionTargetState
  detail?: string | null
  instructions?: string | null
  discovery_error?: string | null
  connect_url?: string | null
  connection_id?: string | null
  attempt?: string | null
  required_env?: ConnectionTargetEnvField[] | null
  tools?: string[] | null
  hint?: string | null
}
export type ConnectionTargetKind = 'connector' | 'mcp'
export type ConnectionTargetAction = 'authorize' | 'connect' | 'enable' | 'install' | 'reconnect'
/** ``tools/connectors/contract.py::TargetState``. */
export type ConnectionTargetState = 'pending' | 'initiated' | 'connected' | 'skipped' | 'failed' | 'expired' | 'not_connected'
/** One credential an MCP install still needs; the card renders a field per entry and sends the values back with the approval. */
export interface ConnectionTargetEnvField {
  name: string
  required: boolean
  secret: boolean
  default: string
  prompt?: string | null
}
export interface ConnectionWakeResult {
  status: 'ok'
}
export interface ConnectionRespondParams {
  profile?: string | null
  owner: SessionOwner | AccountOwner
  op_id: string
  result: ConnectionAnswer
}
/** The card's answer: per-target outcomes and an optional Continue (``settled_by: "continue"``). Settlement is derived from target states afterwards. */
export interface ConnectionAnswer {
  targets?: ConnectionAnswerTarget[]
  settled_by?: ConnectionSettleReason | null
}
/** One row's answer from the card. ``env`` carries the credential values an install asked for through ``required_env``. */
export interface ConnectionAnswerTarget {
  name: string
  status: ConnectionAnswerStatus
  detail?: string | null
  env?: Record<string, string> | null
}
/** What the card says about one row: ``tools/connectors/mcp.py::apply_answer``. */
export type ConnectionAnswerStatus = 'approved' | 'skipped'
export interface ConnectionRespondResult {
  status: 'ok'
  settled: boolean
}
export interface ConnectorsListParams {
  profile?: string | null
  owner: SessionOwner | AccountOwner
}
export interface ConnectorsListResult {
  available: boolean
  connectors: ConnectorRow[]
}
export interface ConnectorRow {
  connector: string
  enabled: boolean
  connected: boolean
  connection_status: 'pending' | 'active' | 'failed' | 'expired' | 'revoked' | 'inactive' | null
  status_reason: string | null
  gateway_disabled_tools: string[]
}
export interface ConnectorsConnectParams {
  profile?: string | null
  owner: SessionOwner | AccountOwner
  connectors: string[]
  reconnect?: boolean
}
/** ``methods_connectors._reissue`` / ``managed._off_desktop_result``: the operation the connect opened; ``status``/``note`` ride along from the tool result. */
export interface ConnectorsConnectResult {
  op_id: string
  seq: number
  deadline_at: number
  settled: boolean
  settled_at?: number | null
  settled_by?: ConnectionSettleReason | null
  targets: ConnectionOperationTarget[]
  status?: 'initiated' | 'settled' | null
  note?: string | null
}
export interface ConnectorToolsParams {
  profile?: string | null
  slug: string
  refresh?: boolean
}
export interface ConnectorToolsResult {
  connector: string
  toolkit_version: string
  etag: string
  fetched_at: number
  source: ConnectorToolsSource
  stale: boolean
  tools: ConnectorToolRow[]
}
export type ConnectorToolsSource = 'cache' | 'network' | 'revalidated'
export interface ConnectorToolRow {
  slug: string
  name: string
  description: string
  facet: ConnectorToolFacet
  hints: string[]
  categories: string[]
  no_auth: boolean
  deprecated: boolean
}
export type ConnectorToolFacet = 'read' | 'write' | 'destructive' | 'unclassified'
export interface ConnectorsCatalogResult {
  connectors: ConnectorCatalogRow[]
}
export interface ConnectorCatalogRow {
  slug: string
  name: string
  description: string
  category: string
  logo_url?: string | null
}
export interface ConnectorAccountsParams {
  profile?: string | null
  connector?: string | null
}
export interface ConnectorAccountsResult {
  accounts: ConnectorAccountRow[]
}
export interface ConnectorAccountRow {
  connection_id: string
  connector: string
  status: ConnectorAccountStatus
  status_reason?: string | null
  label: string
  alias?: string | null
  active: boolean
  created_at: string
  updated_at: string
}
export type ConnectorAccountStatus = 'pending' | 'active' | 'failed' | 'expired' | 'revoked' | 'inactive'
export interface ConnectorAccountsRemoveParams {
  profile?: string | null
  connection_id: string
}
export interface ConnectorAccountsRemoveResult {
  connection_id: string
  connector: string
  status: 'removed'
}
export interface ConnectorPolicyGetResult {
  layers: ConnectorPolicyLayer[]
  effective: ConnectorPolicyEffectiveUnrestricted | ConnectorPolicyEffectiveDenyAll | ConnectorPolicyEffectiveAllow | ConnectorPolicyEffectiveDeny
}
export interface ConnectorPolicyLayer {
  kind: ConnectorPolicyLayerKind
  revision: string
  body: ConnectorPolicyUnrestrictedBody | ConnectorPolicyDenyAllBody | ConnectorPolicyAllowBody | ConnectorPolicyDenyBody
}
export type ConnectorPolicyLayerKind = 'org' | 'role' | 'member'
export interface ConnectorPolicyUnrestrictedBody {
  mode: 'unrestricted'
}
export interface ConnectorPolicyDenyAllBody {
  mode: 'deny-all'
}
export interface ConnectorPolicyAllowBody {
  mode: 'allow'
  connectors: string[]
  tools: Record<string, string[]>
  tags?: ConnectorPolicyTags | null
}
export interface ConnectorPolicyTags {
  enable?: string[] | null
  disable?: string[] | null
}
export interface ConnectorPolicyDenyBody {
  mode: 'deny'
  disabled_connectors: string[]
  tools: Record<string, string[]>
  tags?: ConnectorPolicyTags | null
}
export interface ConnectorPolicyEffectiveUnrestricted {
  version: 1
  revision: string
  issued_at_ms: number
  mode: 'unrestricted'
}
export interface ConnectorPolicyEffectiveDenyAll {
  version: 1
  revision: string
  issued_at_ms: number
  mode: 'deny-all'
}
export interface ConnectorPolicyEffectiveAllow {
  version: 1
  revision: string
  issued_at_ms: number
  mode: 'allow'
  connectors: string[]
  tools: Record<string, string[]>
  tags?: ConnectorPolicyTags | null
}
export interface ConnectorPolicyEffectiveDeny {
  version: 1
  revision: string
  issued_at_ms: number
  mode: 'deny'
  disabled_connectors: string[]
  tools: Record<string, string[]>
  tags?: ConnectorPolicyTags | null
}
export interface ConnectorPolicySetParams {
  profile?: string | null
  change: ToolsChange | ConnectorChange
  expected_revision: string
}
export interface ToolsChange {
  type: 'tools'
  connector: string
  disabled_tools: string[]
}
export interface ConnectorChange {
  type: 'connector'
  connector: string
  enabled: boolean
}
export interface ConnectorPolicySetResult {
  revision: string
  effective: ConnectorPolicyEffectiveUnrestricted | ConnectorPolicyEffectiveDenyAll | ConnectorPolicyEffectiveAllow | ConnectorPolicyEffectiveDeny
}
export interface GroupsCapabilitiesParams {
  profile?: string | null
}
export interface GroupsCapabilitiesResult {
  protocol_version: number
  driver: boolean
  persistent_process: boolean
  authority_gateway_id: string
  room_link: RoomLinkStatus
  features: string[]
  methods: string[]
  max_log_limit: number
}
/** ``enabled`` with ``profile``/``catalog``/``endpoint``, or disabled with a ``reason``. */
export interface RoomLinkStatus {
  enabled: boolean
  profile?: string | null
  catalog?: RoomLinkCatalog | null
  endpoint?: RoomLinkEndpoint | null
  reason?: string | null
}
/** ``gateway/hosted_room_peer.py::GatewayRoomCatalog.as_mapping``. */
export interface RoomLinkCatalog {
  installation_id: string
  protocol_versions: number[]
  link_modes: string[]
  persistent_process: boolean
  text: boolean
  attachments: boolean
  execution_policy: RoomExecutionPolicy
  catalog_digest: string
  endpoint?: RoomLinkEndpoint | null
}
/** ``gateway/hosted_room_execution_policy.py::execution_policy_mapping``. */
export interface RoomExecutionPolicy {
  version: number
  target_profile: string
  enabled_toolsets: string[]
  approval_mode: string
  max_iterations: number
  policy_digest: string
}
/** ``GatewayRoomCatalog.endpoint_mapping``: ``url``/``transport_security`` when available, ``reason`` when not. */
export interface RoomLinkEndpoint {
  available: boolean
  url?: string | null
  transport_security?: string | null
  reason?: string | null
}
export interface GroupsListParams {
  profile?: string | null
  include_disbanded?: boolean | null
  limit?: number | null
  offset?: number | null
}
export interface GroupsListResult {
  rooms: Room[]
  next_offset?: number | null
}
/** ``gateway/hosted_rooms.py::_room_from_row`` plus the branch-only keys ``create`` (legacy adoption), ``state`` (``authority_claim``) and ``rename`` (``event``) add. */
export interface Room {
  room_id: string
  name: string
  members: RoomMember[]
  authority_gateway_id: string
  authority_epoch: number
  revision: number
  created_at: number
  updated_at: number
  idempotent?: boolean
  disbanded_at?: number | null
  latest_seq?: number | null
  adopted?: boolean | null
  claim_event?: RoomEvent | null
  authority_claim?: RoomEvent | null
  event?: RoomEvent | null
}
/** One roster row (``hosted_room_discussion.validate_roster``); legacy rooms may carry pre-normalisation rows, so the set stays open. */
export interface RoomMember {
  member_id?: string | null
  profile?: string | null
  handle?: string | null
  display_name?: string | null
  target?: Record<string, unknown> | null
  [key: string]: unknown
}
/** ``gateway/hosted_rooms.py::_event_from_row``. */
export interface RoomEvent {
  room_id: string
  seq: number
  event_id: string
  kind: string
  actor: RoomActor
  authority_epoch?: number | null
  payload: Record<string, unknown>
  created_at: number
  idempotent?: boolean
}
export interface RoomActor {
  kind: string
  id: string
}
export interface GroupsCreateParams {
  profile?: string | null
  room_id: string
  name: string
  members: RoomMemberInput[]
  authority_gateway_id?: string | null
}
/** A roster row as the client proposes it; ``validate_roster`` owns the exact rules. */
export interface RoomMemberInput {
  member_id?: string | null
  profile?: string | null
  handle?: string | null
  display_name?: string | null
  target?: Record<string, unknown> | null
  [key: string]: unknown
}
export interface GroupsCreateResult {
  room: Room
}
export interface GroupsStateParams {
  profile?: string | null
  room_id: string
  include_disbanded?: boolean | null
}
export interface GroupsStateResult {
  room: Room
  driver_status?: RoomDriverStatus | null
}
/** ``HostedRoomService.status(room_id)``; ``pending_actions`` rows are ``{kind: retry, task_id}`` or the driver's approval action (``kind: approval`` + run/session/approval context). */
export interface RoomDriverStatus {
  running: boolean
  working: boolean
  blocked: boolean
  counts: Record<string, number>
  pending_actions: Record<string, unknown>[]
  peer_routes: PeerRouteStatus[]
}
export interface PeerRouteStatus {
  room_id: string
  member_id: string
  status: string
}
export interface GroupsSendParams {
  profile?: string | null
  room_id: string
  event_id?: string | null
  payload: Record<string, unknown>
}
export interface GroupsSendResult {
  event: RoomEvent
  client_event_id?: string | null
  accepted?: boolean
  driver_started?: boolean
}
export interface GroupsRenameParams {
  profile?: string | null
  room_id: string
  event_id: string
  name: string
}
export interface GroupsRenameResult {
  room: Room
}
export interface GroupsLogParams {
  profile?: string | null
  room_id: string
  since_seq?: number | null
  limit?: number | null
  include_disbanded?: boolean | null
}
/** ``gateway/hosted_rooms.py::read_events`` page — also the ``page`` ``groups.replicate`` ingests. */
export interface GroupsLogResult {
  events: RoomEvent[]
  cursor: number
  latest_seq: number
  has_more: boolean
  authority: RoomAuthority
}
export interface RoomAuthority {
  gateway_id: string
  epoch: number
}
export interface GroupsDisbandParams {
  profile?: string | null
  room_id: string
  cancel_id?: string | null
}
export interface GroupsDisbandResult {
  tombstone: RoomTombstone
}
export interface RoomTombstone {
  room_id: string
  disbanded_at: number
  idempotent: boolean
  history_expired?: boolean | null
  event?: RoomEvent | null
}
export interface GroupsStopParams {
  profile?: string | null
  room_id: string
  cancel_id?: string | null
}
export interface GroupsStopResult {
  cancelled: number
}
export interface GroupsApproveParams {
  profile?: string | null
  room_id: string
  member_id: string
  task_id: string
  execution_generation: number
  choice: ApprovalChoice
  request_id: string
}
export type ApprovalChoice = 'once' | 'session' | 'always' | 'deny'
/** ``result`` is the local ``approval.respond`` answer or the peer's run-action receipt. */
export interface GroupsApproveResult {
  approved?: boolean
  result: Record<string, unknown>
}
export interface GroupsRetryParams {
  profile?: string | null
  room_id: string
  task_id: string
}
export interface GroupsRetryResult {
  retried?: boolean
  task: RoomTaskReceipt
}
export interface RoomTaskReceipt {
  room_id: string
  task_id: string
  thread_id: string
  turn_id: string
  status: string
  execution_generation: number
  cancel_generation: number
}
export interface GroupsReplicateParams {
  profile?: string | null
  room_id: string
  room_name: string
  members: RoomMemberInput[]
  page: Record<string, unknown>
}
export interface GroupsReplicateResult {
  room_id: string
  stored_seq: number
  ingested: number
  authority: RoomAuthority
  caught_up: boolean
}
export interface GroupsReplicaStateParams {
  profile?: string | null
  room_id: string
}
export interface GroupsReplicaStateResult {
  room_id: string
  name: string
  members: RoomMember[]
  authority: RoomAuthority
  last_seq: number
  latest_seq: number
  event_bytes: number
  created_at: number
  updated_at: number
}
export interface GroupsPromoteParams {
  profile?: string | null
  room_id: string
  confirm?: boolean | null
  reason?: string | null
}
export interface GroupsPromoteResult {
  room_id: string
  authority_gateway_id: string
  authority_epoch: number
  previous_gateway_id: string
  previous_epoch: number
  claim_seq: number
  latest_seq: number
}
export interface GroupsDemoteParams {
  profile?: string | null
  room_id: string
  observed_gateway_id: string
  observed_epoch: number
}
export interface GroupsDemoteResult {
  room_id: string
  authority_gateway_id: string
  authority_epoch: number
  idempotent: boolean
}
export interface GroupsPeerInviteParams {
  profile?: string | null
  room_id?: string | null
  home_install_id?: string | null
  authority_gateway_id?: string | null
  authority_epoch?: number | null
  member_id?: string | null
  grant_id?: string | null
  ttl_seconds?: number | null
}
export interface GroupsPeerInviteResult {
  grant: string
  target_profile: string
  catalog: RoomLinkCatalog
  endpoint: RoomLinkEndpoint
}
export interface GroupsPeerRevokeParams {
  profile?: string | null
  grant: string
}
export interface GroupsPeerRevokeResult {
  revoked?: boolean
}
export interface GroupsPeerRegisterParams {
  profile?: string | null
  room_id: string
  member_id: string
  target_url: string
  target_profile: string
  grant: string
  catalog: Record<string, unknown>
  cancellation_scope_id?: string | null
  trace_id?: string | null
}
export interface GroupsPeerRegisterResult {
  registered?: boolean
  mode: string
  transport_security: string
  target_install_id: string
  target_profile: string
}
export interface BotRelayRosterSyncParams {
  profile?: string | null
  agents?: RelayAgentRow[] | null
}
/** A roster row the Desktop pushes (``tools/bot_relay.py::_normalize_roster_row``); invalid rows are dropped server-side, so the shape stays open. */
export interface RelayAgentRow {
  profile?: string | null
  handle?: string | null
  connection_id?: string | null
  connection_label?: string | null
  title?: string | null
  description?: string | null
  online?: boolean | null
  [key: string]: unknown
}
export interface BotRelayRosterSyncResult {
  count: number
}
export interface BotRelayOutboxDrainParams {
  profile?: string | null
}
export interface BotRelayOutboxDrainResult {
  envelopes: RelayEnvelope[]
}
/** ``tools/bot_relay.py::enqueue_envelope``. */
export interface RelayEnvelope {
  id: string
  created_at: number
  from_profile: string
  from_handle: string
  target_connection: string
  target_profile: string
  target_handle: string
  message: string
  [key: string]: unknown
}
/** ``profile`` here is the TARGET profile on this gateway (also what the desktop route wrapper adds). */
export interface BotRelayDeliverParams {
  profile: string
  message: string
  from_profile?: string | null
  from_handle?: string | null
  from_connection?: string | null
}
export interface BotRelayDeliverResult {
  reply: string
}
export interface BotRelayReplyParams {
  profile?: string | null
  id: string
  reply?: string | null
  error?: string | null
  reason?: string | null
}
export interface OkResult {
  ok?: boolean
}
export interface BrowserControllerRegisterParams {
  session_id: string
  controller_id: string
  browser_profile_id: string
  capabilities?: string[] | null
  protocol_version?: unknown | null
  principal_id?: string | null
}
export interface BrowserControllerRegisterResult {
  scope: ControllerScope
}
export interface ControllerScope {
  principal_id: string
  profile_id: string
  session_id: string
  controller_id: string
  browser_profile_id: string
  transport_family: string
  capabilities: string[]
}
export interface BrowserControllerResultParams {
  session_id: string
  command_id: string
  ok?: unknown | null
  result?: unknown | null
  error?: unknown | null
}
export interface BrowserControllerResultResult {
  accepted: boolean
}
/** Every controller call names the session the controller is attached to. */
export interface BrowserControllerParams {
  session_id: string
}
export interface BrowserControllerDetachResult {
  detached?: boolean
}
export type PingParams = Record<string, never>
export interface PingResult {
  pong: boolean
}
export interface GatewayCapabilitiesResult {
  per_session_exclusive_submit: boolean
}
export interface ClientCapabilitiesParams {
  server_requests?: boolean
}
export interface ClientCapabilitiesResult {
  server_requests: string[]
}
/** ``word`` is the token under the cursor (``@`` prefix = context reference); ``cwd`` / ``session_id`` pick the directory the listing resolves against. */
export interface CompletePathParams {
  profile?: string | null
  word?: string | null
  cwd?: string | null
  session_id?: string | null
}
export interface CompletionItemsResult {
  items?: CompletionItem[]
}
/** One popover row; ``kind`` rides only on slash completions (command vs skill). */
export interface CompletionItem {
  text: string
  display?: string
  meta?: string
  kind?: string | null
}
/** ``session_id`` binds skill completions to that session's profile and workspace (project skills). */
export interface CompleteSlashParams {
  text?: string | null
  session_id?: string | null
}
/** ``replace_from`` is the column the accepted item replaces from. */
export interface CompleteSlashResult {
  items?: CompletionItem[]
  replace_from?: number | null
}
export interface PasteCollapseParams {
  text?: string | null
}
export interface PasteCollapseResult {
  placeholder: string
  path: string
  lines: number
}
export interface ModelSaveKeyParams {
  slug: string
  api_key: string
  session_id?: string | null
}
export interface ModelSaveKeyResult {
  provider: ModelOptionProvider
}
export interface ModelDisconnectParams {
  slug: string
  session_id?: string | null
}
export interface ModelDisconnectResult {
  slug: string
  name: string
  disconnected: boolean
}
export interface ProfilesListParams {
  profile?: string | null
  include_sessions?: boolean | string | null
}
/** ``bot_mode_protocol`` tells clients this backend injects the teammate protocol itself. */
export interface ProfilesListResult {
  profiles?: ProfileRow[]
  bot_mode_protocol?: boolean
}
/** One roster row; the session fields are present only with ``include_sessions``. */
export interface ProfileRow {
  name: string
  path: string
  is_default?: boolean
  model?: string | null
  provider?: string | null
  description?: string
  display_name?: string
  skill_count?: number
  previous_names?: string[]
  role?: 'setup' | null
  last_session?: ProfileSessionPreview | null
  worker_session?: ProfileWorkerSession | null
  canonical_session?: ProfileCanonicalSession | null
  ui_meta_revisions?: Record<string, number>
  ui_meta?: Record<string, unknown> | null
  has_avatar?: boolean
}
/** Newest human-facing session of a profile (``_latest_profile_session_rows``). */
export interface ProfileSessionPreview {
  id: string
  title?: string
  preview?: string
  started_at?: number
  last_active?: number
  message_count?: number
}
/** Newest kanban/tool worker row, so rosters can show a profile as working. */
export interface ProfileWorkerSession {
  id: string
  source?: string
  title?: string
  last_active?: number
}
/** The profile's "Bot Chat" registry row; ``resolved_id`` is the live compression tip. */
export interface ProfileCanonicalSession {
  id: string
  resolved_id: string
  root_title?: string
  title?: string
  preview?: string
  started_at?: number
  last_active?: number
  message_count?: number
}
/** ``clone_from`` omitted = fresh profile + bundled skills; ``mirror_credentials`` defaults on so a headless bot has a provider. */
export interface ProfilesCreateParams {
  profile?: string | null
  name: string
  description?: string | null
  clone_from?: string | null
  clone_all?: boolean | string | null
  clone_channels?: boolean | string | null
  no_skills?: boolean | string | null
  no_alias?: boolean | string | null
  soul?: string | null
  model?: string | null
  provider?: string | null
  share_auth?: boolean | string | null
  mirror_credentials?: boolean | string | null
}
export interface ProfilesCreateResult {
  ok?: boolean
  name: string
  path: string
  soul_written?: boolean
  model_set?: boolean
  mirrored: ProfileMirrored
}
/** What was copied from the launch profile; ``auth`` is ``"shared"`` under ``share_auth``. */
export interface ProfileMirrored {
  env?: boolean
  auth?: boolean | 'shared'
  model_inherited?: boolean
  voice?: boolean
}
export interface ProfileNameParams {
  profile?: string | null
  name?: string | null
}
/** Editor snapshot; ``toolsets_pinned`` says whether ``tools.enabled_toolsets`` is explicit. */
export interface ProfilesDescribeResult {
  name: string
  description?: string
  soul?: string
  model: ProfileModelPin
  skills?: CapabilityEntry[]
  toolsets?: ToolsetEntry[]
  toolsets_pinned?: boolean
  mcp_servers?: McpServerEntry[]
}
export interface ProfileModelPin {
  provider?: string
  default?: string
}
export interface CapabilityEntry {
  name: string
  enabled?: boolean
}
export interface ToolsetEntry {
  name: string
  enabled?: boolean
  label?: string
  description?: string
  tool_count?: number
}
export interface McpServerEntry {
  name: string
  enabled?: boolean
  transport?: string
}
/** Sections are independent; ``ui_meta_expected_revisions`` is a per-key compare-and-swap. */
export interface ProfilesConfigureParams {
  profile?: string | null
  name?: string | null
  ui_meta?: Record<string, unknown> | null
  ui_meta_expected_revisions?: Record<string, number> | null
  soul?: string | null
  description?: string | null
  model?: string | null
  provider?: string | null
  confirm_expensive_model?: boolean | string | null
  disabled_skills?: string[] | null
  enabled_toolsets?: string[] | null
  enabled_mcp_servers?: string[] | null
}
/** ``confirm_required`` mirrors ``config.set``: a guarded model pick wrote nothing yet. */
export interface ProfilesConfigureResult {
  ok: boolean
  applied: ProfilesConfigureApplied
  confirm_required?: boolean | null
  confirm_message?: string | null
}
/** Per-section outcome; only the sections the request carried are present. */
export interface ProfilesConfigureApplied {
  ui_meta?: boolean | null
  ui_meta_revisions?: Record<string, number> | null
  ui_meta_conflicts?: Record<string, UiMetaConflict> | null
  soul?: boolean | null
  description?: boolean | null
  model?: boolean | null
  skills?: boolean | null
  toolsets?: boolean | null
  mcp_servers?: boolean | null
}
export interface UiMetaConflict {
  expected?: unknown
  actual?: number
}
/** ``data`` is a data URL or bare base64 (PNG/JPEG/WebP, sniffed); ``clear`` deletes instead. */
export interface ProfilesSetAssetParams {
  profile?: string | null
  name?: string | null
  asset?: string | null
  data?: string | null
  clear?: boolean | string | null
}
export interface ProfilesSetAssetResult {
  ok?: boolean
  asset: string
  size?: number
  removed?: number | null
}
export interface ProfilesGetAssetParams {
  profile?: string | null
  name?: string | null
  asset?: string | null
}
/** Absent is ``found: false``, not an error. */
export interface ProfilesGetAssetResult {
  found: boolean
  mime?: string | null
  size?: number | null
  data?: string | null
}
export interface ProfilesRememberOnboardingParams {
  profile?: string | null
  answers?: OnboardingAnswers | null
}
/** ``tui_gateway/onboarding_personalization.py`` — the facts agreed during onboarding. */
export interface OnboardingAnswers {
  name?: string | null
  context?: string | null
  theme?: string | null
  accent?: string | null
  layout?: string | null
  focus?: string[] | null
  connectors?: string[] | null
  [key: string]: unknown
}
export interface ProfilesRememberOnboardingResult {
  saved?: boolean
  profile?: string
  target?: string
}
/** Client→server method params / server→client request params. Unknown keys are rejected. */
export type Params = Record<string, never>
/** ``created`` is false when an existing setup profile was found (and returned untouched). */
export interface OnboardingEnsureSetupProfileResult {
  name: string
  path: string
  created: boolean
  role?: 'setup'
}
export interface OnboardingResetSetupProfileResult {
  name: string
  path: string
  reset?: boolean
}
export interface VaultListResult {
  items?: VaultItem[]
}
/** Metadata-only view (``VaultItemMeta.to_dict`` + ``backend``); never a secret. */
export interface VaultItem {
  id: string
  kind: string
  label: string
  origin?: string | null
  created_at?: string
  identifier?: string | null
  identifier_type?: string | null
  has_otp?: boolean | null
  backend: string
}
export interface VaultSourcesResult {
  sources?: VaultSource[]
}
export interface VaultSource {
  name: string
  display_name: string
  enabled: boolean
  needs_unlock: boolean
  unlocked: boolean
  installed: boolean
}
export interface VaultSourceSetParams {
  profile?: string | null
  name?: string | null
  enabled?: boolean | null
}
export interface VaultSourceSetResult {
  name: string
  enabled: boolean
}
/** The master password is consumed by the manager CLI and never stored or logged. */
export interface VaultUnlockParams {
  profile?: string | null
  name?: string | null
  password?: string | null
}
export interface VaultUnlockResult {
  name: string
  unlocked?: boolean
}
export interface VaultLockParams {
  profile?: string | null
  name?: string | null
}
export interface VaultLockResult {
  locked?: boolean
}
/** ``secret`` goes straight into the encrypted store; the result carries only the new id. */
export interface VaultAddParams {
  profile?: string | null
  kind?: VaultKind | null
  label?: string | null
  origin?: string | null
  secret?: Record<string, unknown> | null
}
export type VaultKind = 'login' | 'payment' | 'address'
export interface VaultAddResult {
  id: string
}
export interface VaultRemoveParams {
  profile?: string | null
  id?: string | null
}
export interface VaultRemoveResult {
  removed: boolean
}
export interface SessionForeignListParams {
  profile?: string | null
  source?: ForeignSource | null
  offset?: number | null
  limit?: number | null
}
export type ForeignSource = 'claude' | 'codex'
/** ``unreadable`` counts logs on this page that failed to parse. */
export interface SessionForeignListResult {
  sessions?: ForeignSessionRow[]
  next_offset?: number | null
  host: string
  unreadable?: number
}
/** ``hermes_cli/foreign_sessions_browser.py::list_foreign_sessions`` — ``id`` is an opaque handle, never a path. */
export interface ForeignSessionRow {
  id: string
  source: ForeignSource
  label: string
  title?: string
  cwd?: string | null
  mtime: number
  turn_count?: number
  excerpt?: string
}
export interface SessionForeignIdParams {
  profile?: string | null
  id?: string | null
}
/** Bounded to the last 40 turns / 8000 chars each; ``already_imported`` is the local id. */
export interface SessionForeignPreviewResult {
  messages?: ForeignTurn[]
  total?: number
  truncated?: boolean
  already_imported?: string | null
  cwd?: string | null
}
export interface ForeignTurn {
  role: string
  content: string
}
export interface SessionForeignImportResult {
  session_id: string
  already_imported?: boolean
}
/** ``delegations`` is reserved for async delegation records and is currently always empty. */
export interface SubagentListResult {
  subagents?: SubagentSnapshot[]
  delegations?: Record<string, unknown>[]
}
/** ``methods_subagents._SUBAGENT_SNAPSHOT_FIELDS`` projection of one live child record. */
export interface SubagentSnapshot {
  subagent_id: string
  parent_id?: string | null
  depth?: number | null
  goal?: string | null
  delegation_id?: string | null
  model?: string | null
  started_at?: number | null
  status?: SubagentStatus | null
  tool_count?: number | null
  last_tool?: string | null
  accepting_steer?: boolean | null
}
/** Lifecycle of one delegated child (``tools/delegate_tool_child_run.py``); ``failed`` / ``error`` / ``timeout`` / ``interrupted`` / ``completed`` are terminal. */
export type SubagentStatus = 'queued' | 'running' | 'completed' | 'failed' | 'error' | 'timeout' | 'interrupted'
export interface SubagentIdParams {
  session_id: string
  profile?: string | null
  subagent_id: string
}
export interface SubagentInterruptResult {
  found: boolean
  subagent_id: string
}
/** ``available`` is false while the child has no live transcript yet (or it was cleaned up). */
export interface SubagentTailResult {
  subagent_id: string
  available?: boolean
  text?: string
  truncated?: boolean
}
/** ``methods_projects._projects_payload``: every project (archived included) + the active id. */
export interface ProjectsPayload {
  projects: ProjectInfo[]
  active_id?: string | null
}
/** ``hermes_cli/projects_db.py::Project.to_dict`` — one stored project with its folders. */
export interface ProjectInfo {
  id: string
  slug: string
  name: string
  description?: string | null
  icon?: string | null
  color?: string | null
  board_slug?: string | null
  primary_path?: string | null
  archived?: boolean
  created_at: number
  folders?: ProjectFolder[]
}
/** ``hermes_cli/projects_db.py::ProjectFolder.to_dict``. */
export interface ProjectFolder {
  path: string
  label?: string | null
  is_primary?: boolean
  added_at?: number | null
}
/** Any method addressed at one stored project (``5062`` when the id resolves to nothing). */
export interface ProjectIdParams {
  profile?: string | null
  id: string
}
export interface ProjectResult {
  project: ProjectInfo
}
/** ``use`` also activates the new project. */
export interface ProjectsCreateParams {
  profile?: string | null
  name: string
  folders?: string[] | null
  slug?: string | null
  primary_path?: string | null
  description?: string | null
  icon?: string | null
  color?: string | null
  board_slug?: string | null
  use?: boolean
}
export interface OptionalProjectResult {
  project?: ProjectInfo | null
}
/** Absent keys are left untouched; ``''`` clears ``color`` / ``icon``. */
export interface ProjectsUpdateParams {
  profile?: string | null
  id: string
  name?: string | null
  description?: string | null
  icon?: string | null
  color?: string | null
  board_slug?: string | null
}
export interface ProjectsAddFolderParams {
  profile?: string | null
  id: string
  path: string
  label?: string | null
  is_primary?: boolean
}
export interface ProjectFolderParams {
  profile?: string | null
  id: string
  path: string
}
export interface ProjectsArchiveParams {
  profile?: string | null
  id: string
  restore?: boolean
}
/** No ``id`` (or null) clears the active project. */
export interface ProjectsSetActiveParams {
  profile?: string | null
  id?: string | null
}
export interface ActiveIdResult {
  active_id?: string | null
}
/** Absent ``cwd`` resolves the gateway's default completion cwd. */
export interface ProjectsForCwdParams {
  profile?: string | null
  cwd?: string | null
}
export interface ProjectsForCwdResult {
  project?: ProjectInfo | null
  cwd: string
  branch?: string
}
/** ``scan`` asks the host to walk the policy roots itself (remote-gateway desktop). */
export interface ProjectsDiscoverReposParams {
  profile?: string | null
  scan?: boolean
}
export interface ProjectsDiscoverReposResult {
  repos: DiscoveredRepo[]
  discovery_policy?: RepoDiscoveryPolicy | null
}
/** ``methods_projects._discover_repos_payload`` row: a git root with session totals. */
export interface DiscoveredRepo {
  root: string
  label?: string
  sessions?: number
  last_active?: number
}
/** ``methods_projects._repo_discovery_policy`` — the effective ``desktop.repo_scan_*`` config. */
export interface RepoDiscoveryPolicy {
  enabled: boolean
  roots: string[]
  exclude_paths: string[]
}
/** Repos as ``{root, label}`` objects or bare root strings; entries without a root are skipped. */
export interface ProjectsRecordReposParams {
  profile?: string | null
  repos?: (RecordRepoItem | string)[] | null
  discovery_policy?: RepoDiscoveryPolicyParams | null
}
export interface RecordRepoItem {
  root: string
  label?: string | null
}
/** The policy the desktop scanned under (short or ``repo_scan_*`` long keys both accepted). */
export interface RepoDiscoveryPolicyParams {
  enabled?: boolean | null
  roots?: string[] | null
  exclude_paths?: string[] | null
  repo_scan_enabled?: boolean | null
  repo_scan_roots?: string[] | null
  repo_scan_exclude_paths?: string[] | null
}
export interface ProjectsRecordReposResult {
  repos: DiscoveredRepo[]
  discovery_policy?: RepoDiscoveryPolicy | null
  accepted: boolean
}
export interface ProjectsTreeParams {
  profile?: string | null
  preview_limit?: number | null
  session_limit?: number | null
}
export interface ProjectsTreeResult {
  projects: ProjectTreeNode[]
  active_id?: string | null
  scoped_session_ids?: string[]
}
/** ``project_tree._project_node`` — explicit, auto (git root) or the synthetic Home bucket. */
export interface ProjectTreeNode {
  id: string
  label: string
  path?: string | null
  color?: string | null
  icon?: string | null
  isAuto?: boolean
  isNoProject?: boolean
  sessionCount?: number
  lastActive?: number
  totalTokens?: number
  totalCostUsd?: number
  repos?: ProjectTreeRepo[]
  previewSessions?: ProjectTreeSession[]
  sessionIds?: string[]
}
export interface ProjectTreeRepo {
  id: string
  label: string
  path?: string | null
  groups?: ProjectTreeLane[]
  sessionCount?: number
}
/** One branch / worktree / kanban lane inside a repo; ``sessions`` is empty unless hydrated. */
export interface ProjectTreeLane {
  id: string
  label: string
  path?: string | null
  isMain?: boolean
  isKanban?: boolean
  sessions?: ProjectTreeSession[]
}
/** ``methods_projects._project_tree_row`` + ``project_tree.stamp_profile``: the minimal row the sidebar renders, stamped with the profile it belongs to. */
export interface ProjectTreeSession {
  id: string
  title?: string | null
  preview?: string | null
  source?: string | null
  model?: string | null
  started_at?: number | null
  ended_at?: number | null
  last_active?: number | null
  message_count?: number
  tool_call_count?: number
  input_tokens?: number
  output_tokens?: number
  is_active?: boolean
  cwd?: string | null
  git_branch?: string | null
  git_repo_root?: string | null
  parent_session_id?: string | null
  pinned?: boolean | null
  unread?: boolean | null
  archived?: boolean | null
  actual_cost_usd?: number | null
  estimated_cost_usd?: number | null
  handoff_platform?: string | null
  handoff_state?: string | null
  _lineage_root_id?: string | null
  _lineage_ids?: string[] | null
  profile?: string | null
  [key: string]: unknown
}
export interface ProjectsProjectSessionsParams {
  profile?: string | null
  project_id: string
  session_limit?: number | null
}
export interface ProjectsProjectSessionsResult {
  project?: ProjectTreeNode | null
}
/** ``knownRevision``: the spritesheet revision the caller already holds (send-once bytes). */
export interface PetInfoParams {
  profile?: string | null
  knownRevision?: string | null
}
/** ``server._pet_sprite_payload`` behind ``enabled``; every sprite field is absent when the pet display is off, ``spritesheetBase64`` is elided when ``spritesheetUnchanged``. */
export interface PetInfoResult {
  enabled: boolean
  slug?: string | null
  displayName?: string | null
  mime?: string | null
  spritesheetBase64?: string | null
  spritesheetRevision?: string | null
  spritesheetUnchanged?: boolean | null
  frameW?: number | null
  frameH?: number | null
  framesPerState?: number | null
  framesByState?: Record<string, number> | null
  framesByRow?: Record<string, number> | null
  loopMs?: number | null
  scale?: number | null
  stateRows?: string[] | null
  [key: string]: unknown
}
export interface PetInfoMetaResult {
  enabled: boolean
  slug?: string | null
  displayName?: string | null
  scale?: number | null
  spritesheetRevision?: string | null
}
/** ``graphics`` opts into the kitty payload when the TTY speaks it; ``cols`` overrides the width. */
export interface PetCellsParams {
  profile?: string | null
  state?: string | null
  cols?: number | null
  graphics?: boolean
}
/** Unicode: ``frames`` is frame → row → cell ``[tr,tg,tb,ta, br,bg,bb,ba]``; kitty (``graphics`` set): ``frames`` are transmit escapes and ``placeholder`` the text grid. */
export interface PetCellsResult {
  enabled: boolean
  slug?: string | null
  displayName?: string | null
  state?: string | null
  cols?: number | null
  frameMs?: number | null
  frames?: number[][][][] | string[] | null
  scale?: number | null
  graphics?: string | null
  imageId?: number | null
  color?: string | null
  rows?: number | null
  placeholder?: string[] | null
}
export interface PetGalleryParams {
  profile?: string | null
  localOnly?: boolean
}
export interface PetGalleryResult {
  enabled: boolean
  active?: string
  pets?: PetGalleryEntry[]
}
export interface PetGalleryEntry {
  slug: string
  displayName: string
  installed: boolean
  spritesheetUrl?: string
  curated?: boolean | null
  generated?: boolean
}
export interface PetSlugParams {
  profile?: string | null
  slug: string
}
export interface PetSlugResult {
  ok: boolean
  slug: string
  displayName?: string | null
}
export interface PetRenameParams {
  profile?: string | null
  slug: string
  name: string
}
export interface PetExportResult {
  ok: boolean
  filename: string
  zipBase64: string
}
/** ``url``: spritesheet source for a not-yet-installed pet. */
export interface PetThumbParams {
  profile?: string | null
  slug: string
  url?: string | null
}
export interface PetThumbResult {
  ok: boolean
  slug: string
  dataUri?: string | null
}
export interface PetScaleParams {
  profile?: string | null
  scale?: unknown
}
export interface PetScaleResult {
  ok: boolean
  scale: number
}
/** ``text`` is normally a string; the relay / hosted paths may hand a structured (parts list) payload, and the busy path renders it. Truncation (rewind / edit / regenerate) needs explicit consent: ``confirm_truncate`` plus one durable target (``truncate_before_row_id`` preferred, ``truncate_before_message_id``, or the legacy ``truncate_before_user_ordinal``). */
export interface PromptSubmitParams {
  session_id: string
  profile?: string | null
  text?: unknown
  display_kind?: string | null
  interrupted?: boolean | null
  queued?: boolean | null
  surface?: string | null
  voice_context?: string | null
  title_preview?: string | null
  truncate_before_user_ordinal?: number | null
  truncate_before_row_id?: number | null
  truncate_before_message_id?: string | null
  confirm_truncate?: boolean | null
  confirm_empty_truncate?: boolean | null
  rebind_survivor_row_ids?: number[] | null
}
/** ``status`` is absent only on the typed-stop-phrase reply (``voice_stopped``). After a truncation the survivor row ids let the client rebind its cached ``rowId``s (``None`` map entries: drop the cached id). ``turn_isolation`` marks a compute-host dispatch. */
export interface PromptSubmitResult {
  status?: PromptSubmitStatus | null
  voice_stopped?: boolean | null
  survivor_user_row_ids?: (number | null)[] | null
  survivor_row_id_map?: Record<string, number | null> | null
  turn_isolation?: boolean | null
}
export type PromptSubmitStatus = 'streaming' | 'queued' | 'steered' | 'redirected'
export interface ClipboardPasteParams {
  session_id: string
  profile?: string | null
}
/** ``methods_prompt.py::_attached_image_result``: the image is queued for the next turn. */
export interface AttachedImageResult {
  name?: string | null
  width?: number | null
  height?: number | null
  token_estimate?: number | null
  attached: boolean
  path?: string | null
  count?: number | null
  remainder?: string | null
  text?: string | null
  bytes?: number | null
  message?: string | null
}
export interface ImageAttachParams {
  session_id: string
  profile?: string | null
  path: string
}
/** ``content_base64`` (or the ``data`` alias) carries the bytes; ``filename`` / ``ext`` only hint the extension — magic bytes decide. */
export interface ImageAttachBytesParams {
  session_id: string
  profile?: string | null
  content_base64?: string | null
  data?: string | null
  filename?: string | null
  ext?: string | null
}
/** Host ``path`` or base64 ``content_base64`` / ``data``; ``first_page`` / ``last_page`` bound the render (per-call page cap enforced server-side). */
export interface PdfAttachParams {
  session_id: string
  profile?: string | null
  path?: string | null
  content_base64?: string | null
  data?: string | null
  filename?: string | null
  first_page?: number | null
  last_page?: number | null
}
export interface PdfAttachResult {
  attached: boolean
  filename: string
  pages_attached: number
  pages: PdfPage[]
  count: number
  text: string
}
export interface PdfPage {
  name?: string | null
  width?: number | null
  height?: number | null
  token_estimate?: number | null
  path: string
  page: number
}
/** ``path`` when the file is gateway-visible, else ``data_url`` carries the bytes; ``name`` labels an uploaded file. */
export interface FileAttachParams {
  session_id: string
  profile?: string | null
  path?: string | null
  data_url?: string | null
  name?: string | null
}
export interface FileAttachResult {
  attached: boolean
  name: string
  path: string
  ref_path: string
  ref_text: string
  uploaded: boolean
}
export interface ImageDetachParams {
  session_id: string
  profile?: string | null
  path: string
}
export interface ImageDetachResult {
  detached: boolean
  count: number
}
export interface InputDetectDropParams {
  session_id: string
  profile?: string | null
  text?: string | null
}
/** ``matched: false`` alone when the text is not a drop; an image drop is queued immediately (``is_image`` + ``count``), a file drop only yields the ``text`` to insert. */
export interface InputDetectDropResult {
  name?: string | null
  width?: number | null
  height?: number | null
  token_estimate?: number | null
  matched: boolean
  is_image?: boolean | null
  path?: string | null
  count?: number | null
  text?: string | null
}
export interface SideAgentParams {
  session_id: string
  profile?: string | null
  text: string
}
/** The side agent runs detached; its answer lands on the parent session as an event carrying this ``task_id``. */
export interface TaskIdResult {
  task_id: string
}
export interface PreviewRestartParams {
  session_id: string
  profile?: string | null
  url: string
  cwd?: string | null
  context?: string | null
}
export interface ClarifyLockParams {
  request_id: string
  question_id: string
  answer?: unknown
  profile?: string | null
}
/** ``remaining`` lists the qids still unanswered; the lock that empties it resolves the request. ``expired``: the wait already ended (timeout / cancel) — not an error. */
export interface ClarifyLockResult {
  status: ClarifyLockStatus
  remaining?: string[] | null
}
export type ClarifyLockStatus = 'ok' | 'expired'
export interface RequestAnswerParams {
  id: string
  result: Record<string, unknown>
  profile?: string | null
}
export interface RequestAnswerResult {
  status: ClarifyLockStatus
}
export interface ApprovalPendingParams {
  session_id: string
  profile?: string | null
}
export interface ApprovalPendingResult {
  approvals: PendingApproval[]
}
/** One unresolved ``tools/approval.py`` gateway queue entry as ``server._approval_request_payload`` renders it (command redacted; ``choices`` precomputed). The key set is owned by the approval tool. */
export interface PendingApproval {
  request_id?: string | null
  command?: string | null
  description?: string | null
  pattern_key?: string | null
  pattern_keys?: string[] | null
  allow_permanent?: boolean | null
  allow_session?: boolean | null
  smart_denied?: boolean | null
  choices?: string[] | null
  tool_name?: string | null
  [key: string]: unknown
}
export interface ApprovalReceivedParams {
  session_id: string
  profile?: string | null
  request_id: string
}
export interface ApprovalReceivedResult {
  acknowledged: boolean
}
/** ``choice`` is one of the offered ``approval`` choices (once / session / always / deny); ``all`` resolves every pending approval, ``request_id`` a specific one, neither the oldest. */
export interface ApprovalRespondParams {
  session_id: string
  profile?: string | null
  choice?: string | null
  all?: boolean | null
  request_id?: string | null
}
export interface ApprovalRespondResult {
  resolved: number
}
export interface VoiceToggleParams {
  action?: VoiceToggleAction
  profile?: string | null
}
export type VoiceToggleAction = 'status' | 'on' | 'off' | 'tts'
/** ``methods_voice.py::_voice_status_payload`` (+ the requirements probe on ``status``, the spoken stop hint on ``on``). */
export interface VoiceToggleResult {
  enabled: boolean
  record_key: string
  tts: boolean
  stop_hint?: string | null
  available?: boolean | null
  audio_available?: boolean | null
  stt_available?: boolean | null
  details?: string | null
}
export interface VoiceRecordParams {
  action?: VoiceRecordAction
  session_id?: string | null
  profile?: string | null
}
export type VoiceRecordAction = 'start' | 'stop'
export interface VoiceRecordResult {
  status: VoiceRecordStatus
  reason?: string | null
}
export type VoiceRecordStatus = 'recording' | 'stopped' | 'busy'
export interface VoiceTtsParams {
  text: string
  profile?: string | null
}
export interface VoiceTtsResult {
  status: string
}
/** ``surface`` names the caller ("tui" | "gui"); ``persist`` is the explicit gesture that also flips ``wake_word.enabled`` on; ``client_capture`` asks for PCM streamed via wake.feed. */
export interface WakeStartParams {
  surface?: string | null
  persist?: boolean | null
  client_capture?: boolean | null
  session_id?: string | null
  profile?: string | null
}
/** ``started: false`` carries ``reason`` (unavailable / disabled / disabled_for_surface / owned); ``sample_rate`` / ``frame_length`` describe the PCM frames the armed detector expects. */
export interface WakeStartResult {
  started: boolean
  reason?: string | null
  hint?: string | null
  phrase?: string | null
  provider?: string | null
  owner_surface?: string | null
  enabled_persisted?: boolean | null
  capture?: string | null
  sample_rate?: number | null
  frame_length?: number | null
}
export interface WakeStopParams {
  persist?: boolean | null
  profile?: string | null
}
export interface WakeStopResult {
  reason?: string | null
  stopped: boolean
  disabled_persisted: boolean
}
export interface WakeControlParams {
  profile?: string | null
}
export interface WakePauseResult {
  reason?: string | null
  paused: boolean
}
export interface WakeResumeResult {
  reason?: string | null
  resumed: boolean
}
export interface WakeStatusParams {
  surface?: string | null
  client_capture?: boolean | null
  profile?: string | null
}
/** ``enabled`` is config truth; ``listening`` is this caller's armed detector; ``audio_silent`` means armed but deaf (see ``hint``). */
export interface WakeStatusResult {
  listening: boolean
  owned_by_caller: boolean
  owner_surface?: string | null
  phrase: string
  provider: string
  configured_surface: string
  input_device: WakeInputDevice
  available: boolean
  hint: string
  enabled: boolean
  audio_silent: boolean
  capture: string
  local_input_available: boolean
  sample_rate: number
  frame_length: number
}
/** ``tools/wake_word.py::_describe_input_device`` — PortAudio diagnostics for the configured mic. */
export interface WakeInputDevice {
  selector?: number | string | null
  name?: string | null
  error?: string | null
  max_input_channels?: number | null
  default_samplerate?: number | null
  hostapi_index?: number | null
  hostapi?: string | null
  [key: string]: unknown
}
/** ``pcm`` (or the ``pcm_b64`` alias): base64 int16 mono little-endian, 16 kHz only. */
export interface WakeFeedParams {
  pcm?: string | null
  pcm_b64?: string | null
  sample_rate?: number | null
  profile?: string | null
}
export interface WakeFeedResult {
  reason?: string | null
  fed: boolean
}
export interface SessionCreateParams {
  profile?: string | null
  cols?: number | null
  source?: string | null
  cwd?: string | null
  messages?: SeedMessage[] | null
  parent_session_id?: string | null
  title?: string | null
  model?: string | null
  provider?: string | null
  reasoning_effort?: string | null
  fast?: boolean | null
  close_on_disconnect?: boolean
  hidden?: boolean
  room_plumbing?: boolean
  follow_profile_config?: boolean
}
/** One create-time transcript row (``session_history._coerce_seed_history``); ``text`` is the legacy alias of ``content``; only ``display_kind: "hidden"`` is accepted from the wire. Clients forward stored rows verbatim (``_row_id``, ``timestamp``, …) and the coercer drops what it does not use, so the row stays open. */
export interface SeedMessage {
  role: string
  content?: string | null
  text?: string | null
  display_kind?: string | null
  [key: string]: unknown
}
export interface SessionCreateResult {
  session_id: string
  stored_session_id: string
  message_count: number
  messages: TranscriptMessage[]
  info: SessionLiveInfo
}
/** One transcript row as the gateway PROJECTS it for renderers (``session_history._project_history``): ``text`` (never ``content``), display-only ``timestamp`` / ``display_kind`` / ``display_metadata``, the durable ``row_id`` rewind targets, and for tool rows ``name`` + ``context`` preview + full ``args``. Assistant detail sidecars (``reasoning``, …) ride as extra keys. */
export interface TranscriptMessage {
  role: string
  text?: string | null
  timestamp?: number | null
  row_id?: number | null
  display_kind?: string | null
  display_metadata?: unknown | null
  name?: string | null
  context?: string | null
  args?: Record<string, unknown> | null
  labels?: ToolLabel[] | null
  reasoning?: string | null
  [key: string]: unknown
}
/** ``tools.tool_labels.ToolLabel`` — what one call executed through the tool_search bridge is, in words. Clients render ``text`` (or ``app``/``action`` in their own columns) and never parse the tool name themselves. */
export interface ToolLabel {
  kind: ToolLabelKind
  app: string
  action: string
  emoji: string
  text: string
  name: string
  preview?: string
}
/** Which surface one inner call of a bridged ``tool_call`` runs on. */
export type ToolLabelKind = 'connector' | 'mcp' | 'tool'
/** ``session_id`` is the STORED id (or an exact title); the reply's ``session_id`` is the runtime id. */
export interface SessionResumeParams {
  session_id: string
  profile?: string | null
  cols?: number | null
  source?: string | null
  lazy?: boolean
  defer_history?: boolean
  omit_messages?: boolean
  eager_build?: boolean
  close_on_disconnect?: boolean
}
export interface SessionResumeResult {
  session_id: string
  message_count: number
  messages: TranscriptMessage[]
  info: SessionLiveInfo
  stored_session_id?: string | null
  resumed?: string | null
  session_key?: string | null
  messages_omitted?: boolean | null
  hydrating?: boolean | null
  running?: boolean | null
  turn_started_at?: number | null
  started_at?: number | null
  status?: string | null
  inflight?: InflightTurn | null
  queued?: QueuedPrompt | null
  pending_approval?: PendingApproval | null
  open_requests?: OpenRequestEntry[] | null
  pending_connection?: ConnectionRequestPayload | null
  todo_state?: TodoState | null
  auto_continue?: AutoContinue | null
}
/** ``session_auto_continue._inflight_snapshot``: the live (or retained failed) turn a reconnecting client rebuilds its bubbles from. */
export interface InflightTurn {
  assistant?: string
  streaming?: boolean
  user?: string
  display_kind?: string | null
  display_metadata?: Record<string, unknown> | null
  corrections?: string[] | null
  correction_offsets?: number[] | null
  error?: string | null
  status?: string | null
  recoverable?: boolean | null
  error_surface?: Record<string, unknown> | null
}
export interface QueuedPrompt {
  user: string
}
/** One unanswered server→client request (``server_requests.Request.snapshot``); the reconnecting client re-delivers it to its request handlers. */
export interface OpenRequestEntry {
  id: string
  method: string
  params: Record<string, unknown>
}
/** ``ConnectionOperation.request_payload``: opens the card; also the ``pending_connection`` resume snapshot so a client that missed the event restores the card with the server's deadline. */
export interface ConnectionRequestPayload {
  op_id: string
  seq: number
  deadline_at: number
  timeout_seconds: number
  targets: ConnectionOperationTarget[]
  tool_call_id?: string | null
}
/** ``tool_progress._normalize_todo_state``: the authoritative todo snapshot. */
export interface TodoState {
  todos: Record<string, unknown>[]
  revision: number
}
/** A crash-interrupted turn was scheduled to continue right after this resume. */
export interface AutoContinue {
  attempt: number
  interrupted_at: number
}
export interface SessionActivateParams {
  session_id: string
  profile?: string | null
  cols?: number | null
  omit_messages?: boolean
}
export interface SessionActivateResult {
  session_id: string
  message_count: number
  messages: TranscriptMessage[]
  info: SessionLiveInfo
  stored_session_id?: string | null
  resumed?: string | null
  session_key?: string | null
  messages_omitted?: boolean | null
  hydrating?: boolean | null
  running?: boolean | null
  turn_started_at?: number | null
  started_at?: number | null
  status?: string | null
  inflight?: InflightTurn | null
  queued?: QueuedPrompt | null
  pending_approval?: PendingApproval | null
  open_requests?: OpenRequestEntry[] | null
  pending_connection?: ConnectionRequestPayload | null
  todo_state?: TodoState | null
  auto_continue?: AutoContinue | null
}
export interface SessionListParams {
  profile?: string | null
  title?: string | null
  limit?: number | null
  include_hidden?: boolean
}
export interface SessionListResult {
  sessions: SessionListRow[]
}
/** ``methods_session._session_row_summary``; ``resolved_id`` only on a title lookup that followed a compression lineage to its tip. */
export interface SessionListRow {
  id: string
  resolved_id?: string | null
  title?: string
  preview?: string
  started_at?: number
  message_count?: number
  source?: string
}
export interface SessionMostRecentParams {
  profile?: string | null
}
export interface SessionMostRecentResult {
  session_id: string | null
  title?: string | null
  started_at?: number | null
  source?: string | null
}
export interface SessionActiveListParams {
  profile?: string | null
  current_session_id?: string | null
}
export interface SessionActiveListResult {
  sessions: SessionActiveItem[]
}
/** ``server._session_live_item``. */
export interface SessionActiveItem {
  current: boolean
  id: string
  last_active: number
  message_count: number
  model: string
  preview: string
  session_key: string
  started_at: number
  status: LiveSessionStatus
  title: string
}
export type LiveSessionStatus = 'idle' | 'starting' | 'waiting' | 'working' | 'streaming' | 'resuming'
/** ``session_id`` is the STORED id. */
export interface SessionDeleteParams {
  session_id: string
  profile?: string | null
}
export interface SessionDeleteResult {
  deleted: string
}
export interface SessionTitleParams {
  session_id: string
  profile?: string | null
  title?: string | null
}
export interface SessionTitleResult {
  title: string
  session_key?: string | null
  pending?: boolean | null
}
/** ``session_id`` is a live runtime id first, else a stored id / key / title. */
export interface SessionSetHiddenParams {
  session_id: string
  hidden?: boolean
  profile?: string | null
}
export interface SessionSetHiddenResult {
  hidden: boolean
  session_key: string
}
export interface SessionWorkspaceMoveParams {
  profile?: string | null
  session_key: string
  cwd: string
}
export interface SessionWorkspaceMoveResult {
  cwd: string
  branch?: string | null
  git_repo_root?: string | null
}
export interface SessionCwdSetParams {
  session_id: string
  profile?: string | null
  cwd: string
}
/** The refreshed ``session.info`` view (full agent view, or the lazy shape). */
export interface SessionCwdSetResult {
  model?: string
  provider?: string
  reasoning_effort?: string
  reasoning_effort_wire?: string
  service_tier?: string
  fast?: boolean
  yolo?: boolean
  approval_mode?: string
  tools?: Record<string, string[]>
  skills?: Record<string, string[]>
  cwd?: string
  branch?: string | null
  project?: ProjectRef | null
  terminal_backend?: string
  personality?: string
  running?: boolean
  turn_started_at?: number | null
  title?: string
  stored_session_id?: string
  desktop_contract?: number | string | null
  version?: string
  release_date?: string
  update_behind?: unknown | null
  update_command?: string
  usage?: Usage | null
  profile_name?: string | null
  mcp_servers?: McpServerStatus[]
  system_prompt?: string | null
  credential_warning?: string | null
  lazy?: boolean | null
  [key: string]: unknown
}
export interface SessionCloseParams {
  session_id: string
  profile?: string | null
}
export interface SessionCloseResult {
  closed: boolean
}
export interface SessionBranchParams {
  session_id: string
  profile?: string | null
  name?: string | null
  count?: number | null
}
export interface SessionBranchResult {
  session_id: string
  stored_session_id: string
  title: string
  parent: string
  message_count: number
  messages: TranscriptMessage[]
  info: SessionLiveInfo
}
export interface SessionUndoParams {
  session_id: string
  profile?: string | null
}
export interface SessionUndoResult {
  removed: number
}
export interface SessionSaveParams {
  session_id: string
  profile?: string | null
}
/** Under turn isolation the compute host's result passes through verbatim. */
export interface SessionSaveResult {
  file?: string | null
  [key: string]: unknown
}
export interface SessionStatusParams {
  session_id: string
  profile?: string | null
}
export interface SessionStatusResult {
  output: string
}
export interface SessionHistoryParams {
  session_id: string
  profile?: string | null
}
export interface SessionHistoryResult {
  count: number
  messages: TranscriptMessage[]
}
export interface SessionUsageParams {
  session_id: string
  profile?: string | null
}
export interface SessionUsageResult {
  model?: string
  input?: number
  output?: number
  reasoning?: number
  prompt?: number
  completion?: number
  total?: number
  calls?: number
  compressions?: number | null
  context_used?: number | null
  context_max?: number | null
  context_percent?: number | null
  context_source?: string | null
  context_estimated?: boolean | null
  cache_hit_pct?: number | null
  cache_read?: number | null
  cache_write?: number | null
  avg_latency_s?: number | null
  avg_tps?: number | null
  active_subagents?: number | null
  dev_credits_spent_micros?: number | null
  cost_usd?: number | null
  cost_status?: string | null
  credits_lines?: string[] | null
  [key: string]: unknown
}
export interface SessionContextBreakdownParams {
  session_id: string
  profile?: string | null
}
/** ``agent.context_breakdown.compute_session_context_breakdown`` (empty categories before the agent builds) plus the per-file context manifest (empty until the agent exists). */
export interface SessionContextBreakdownResult {
  categories: ContextCategory[]
  context_max: number
  context_percent: number
  context_used: number
  estimated_total: number
  context_estimated: boolean
  context_source: string
  model: string
  context_files?: ContextFileSource[]
}
export interface ContextCategory {
  color: string
  id: string
  label: string
  tokens: number
}
/** One row of ``agent.context_file_sources.list_context_file_sources``. */
export interface ContextFileSource {
  label: string
  path: string
  chars: number
  est_tokens: number
  loaded: boolean
  status: string
}
export interface SessionCompressParams {
  session_id: string
  profile?: string | null
  focus_topic?: string | null
}
/** In-process: the before/after summary + replacement transcript. Compute host: its result passes through (hence open) with ``turn_isolation``; a lock held elsewhere answers ``compressed: false``. */
export interface SessionCompressResult {
  status?: string | null
  removed?: number | null
  before_messages?: number | null
  after_messages?: number | null
  before_tokens?: number | null
  after_tokens?: number | null
  summary?: CompressionSummary | null
  usage?: Usage | null
  info?: SessionLiveInfo | null
  messages?: TranscriptMessage[] | null
  compressed?: boolean | null
  lock_held?: boolean | null
  message?: string | null
  turn_isolation?: boolean | null
  host_ack?: Record<string, unknown> | null
  [key: string]: unknown
}
/** ``agent.manual_compression_feedback.summarize_manual_compression``. */
export interface CompressionSummary {
  noop?: boolean
  aborted?: boolean
  refused_would_grow?: boolean | null
  fallback_used?: boolean | null
  headline?: string
  token_line?: string
  note?: string | null
  [key: string]: unknown
}
export interface SessionInterruptParams {
  session_id: string
  profile?: string | null
  expected_hosted_task_id?: string | null
}
export interface SessionInterruptResult {
  status: InterruptStatus
  interrupted?: boolean | null
  turn_isolation?: boolean | null
}
export type InterruptStatus = 'interrupted' | 'not_interrupted'
export interface SessionCorrectionParams {
  session_id: string
  profile?: string | null
  text: string
}
export interface SessionCorrectionResult {
  status: CorrectionStatus
  text: string
}
export type CorrectionStatus = 'queued' | 'redirected' | 'rejected'
export interface SpawnTreeSaveParams {
  profile?: string | null
  subagents: Record<string, unknown>[]
  session_id?: string | null
  started_at?: number | null
  finished_at?: number | null
  label?: string | null
}
export interface SpawnTreeSaveResult {
  path: string
  session_id: string
}
export interface SpawnTreeListParams {
  profile?: string | null
  session_id?: string | null
  cross_session?: boolean
  limit?: number | null
}
export interface SpawnTreeListResult {
  entries: SpawnTreeEntry[]
}
/** Index row (``server._append_spawn_tree_index``) or a legacy file scan. */
export interface SpawnTreeEntry {
  path: string
  session_id?: string | null
  started_at?: number | null
  finished_at?: number | null
  label?: string
  count?: number
  [key: string]: unknown
}
export interface SpawnTreeLoadParams {
  profile?: string | null
  path: string
}
/** The snapshot file as written by ``spawn_tree.save`` (open: the file is the contract). */
export interface SpawnTreeLoadResult {
  session_id?: string | null
  started_at?: number | null
  finished_at?: number | null
  label?: string | null
  subagents?: Record<string, unknown>[]
  [key: string]: unknown
}
export interface TerminalResizeParams {
  session_id: string
  profile?: string | null
  cols?: number | null
}
export interface TerminalResizeResult {
  cols: number
}
export interface SessionEventsSinceParams {
  session_id: string
  profile?: string | null
  last_seen?: number | null
}
export interface SessionEventsSinceResult {
  events: Record<string, unknown>[]
  latest_seq: number
  truncated: boolean
  count: number
  epoch: string
  open_requests: OpenRequestEntry[]
}
export interface SessionEventsStatsParams {
  profile?: string | null
}
/** ``event_replay.replay_stats``. */
export interface SessionEventsStatsResult {
  sessions: number
  events: number
  bytes: number
  max_per_session: number
  max_bytes_per_session: number
  max_bytes_process: number
}
/** Needs a ``template`` or ``instructions`` / ``input``; a live ``session_id`` lends its model. */
export interface LlmOneshotParams {
  profile?: string | null
  template?: string | null
  instructions?: string | null
  input?: string | null
  variables?: Record<string, unknown> | null
  task?: string | null
  temperature?: number | null
  max_tokens?: number | null
  session_id?: string | null
}
export interface LlmOneshotResult {
  text: string
}
export interface SystemBatteryParams {
  profile?: string | null
}
export interface SystemBatteryResult {
  available: boolean
  percent?: number | null
  plugged?: boolean | null
  category?: BatteryCategory
}
/** ``agent/battery.py::battery_category`` colour bucket. */
export type BatteryCategory = 'good' | 'warn' | 'bad' | 'critical' | 'dim'
export interface ProcessStopParams {
  session_id?: string | null
  profile?: string | null
}
export interface ProcessStopResult {
  killed: number
}
export interface AgentsListParams {
  profile?: string | null
}
export interface AgentsListResult {
  processes?: AgentProcessRow[]
}
export interface AgentProcessRow {
  session_id: string
  command: string
  status: string
  uptime: number
}
export interface ProcessListParams {
  session_id: string
  profile?: string | null
}
export interface ProcessListResult {
  processes?: ProcessEntry[]
}
/** ``tools/process_registry.py::list_sessions`` row plus the gateway's ``output_tail``. */
export interface ProcessEntry {
  session_id: string
  command?: string
  cwd?: string | null
  pid?: number | null
  owner_task_id?: string | null
  started_at?: string | null
  uptime_seconds?: number | null
  status?: string
  output_preview?: string
  output_tail?: string | null
  session_scoped?: boolean | null
  watch_patterns?: string[] | null
  watch_hit?: boolean | null
  notify_on_complete?: boolean | null
  exit_code?: number | null
  exited_at?: number | null
  completion_reason?: string | null
  detached?: boolean | null
  [key: string]: unknown
}
export interface ProcessKillParams {
  session_id: string
  process_id: string
  profile?: string | null
}
/** ``tools/process_registry.py::kill_process`` snapshot; ``error`` rides on the failure statuses. */
export interface ProcessKillResult {
  status: ProcessKillStatus
  session_id?: string | null
  command?: string | null
  exit_code?: number | null
  completion_reason?: string | null
  termination_source?: string | null
  output?: string | null
  error?: string | null
  [key: string]: unknown
}
export type ProcessKillStatus = 'killed' | 'already_exited' | 'not_found' | 'error'
export interface ShellExecParams {
  command: string
  profile?: string | null
}
export interface ShellExecResult {
  stdout: string
  stderr: string
  code: number
}
export interface CliExecParams {
  argv: string[]
  timeout?: number | null
  profile?: string | null
}
export interface CliExecResult {
  blocked: boolean
  code: number
  output: string
  hint?: string | null
}
export interface CommandsCatalogParams {
  session_id?: string | null
  profile?: string | null
}
export interface CommandsCatalogResult {
  pairs?: string[][]
  sub?: Record<string, string[]>
  canon?: Record<string, string>
  commands?: Record<string, CommandCatalogMeta>
  categories?: CommandCategory[]
  skills?: Record<string, SkillCatalogEntry>
  skill_count?: number
  warning?: string
}
export interface CommandCatalogMeta {
  argument_mode?: ArgumentMode | null
  desktop?: string | null
}
export type ArgumentMode = 'options' | 'text' | 'mixed'
export interface CommandCategory {
  name: string
  pairs?: string[][]
}
export interface SkillCatalogEntry {
  usage?: number
  origin?: string
}
export interface CommandResolveParams {
  name?: string | null
  profile?: string | null
}
export interface CommandResolveResult {
  canonical: string
  description: string
  category: string
}
export interface CommandDispatchParams {
  name: string
  arg?: string | null
  session_id?: string | null
  profile?: string | null
}
/** One structured directive: ``exec``/``plugin`` carry ``output``; ``alias`` a ``target``; ``send``/``prefill``/``skill`` a ``message`` (UIs render ``display``, never ``message``). */
export interface CommandDispatchResult {
  type: DispatchType
  output?: string | null
  target?: string | null
  message?: string | null
  notice?: string | null
  display?: string | null
  name?: string | null
  status?: string | null
}
/** ``apps/shared/src/slash.ts::parseCommandDispatch`` branches on this. */
export type DispatchType = 'exec' | 'alias' | 'plugin' | 'send' | 'skill' | 'prefill'
export interface SlashExecParams {
  session_id: string
  command: string
  profile?: string | null
}
/** Plain worker/plugin text in ``output`` (+ ``warning``), or — when the command was rerouted to ``command.dispatch`` — that method's directive fields with ``type`` set. */
export interface SlashExecResult {
  output?: string | null
  warning?: string | null
  type?: DispatchType | null
  target?: string | null
  message?: string | null
  notice?: string | null
  display?: string | null
  name?: string | null
  status?: string | null
}
export interface InsightsGetParams {
  days?: number | null
  profile?: string | null
}
export interface InsightsGetResult {
  days: number
  sessions: number
  messages: number
}
export interface ConfigShowParams {
  profile?: string | null
}
export interface ConfigShowResult {
  sections?: ConfigSection[]
  [key: string]: unknown
}
export interface ConfigSection {
  title: string
  rows?: string[][]
}
export interface RollbackListParams {
  session_id: string
  profile?: string | null
}
export interface RollbackListResult {
  enabled: boolean
  checkpoints?: RollbackCheckpoint[]
}
export interface RollbackCheckpoint {
  hash?: string
  timestamp?: string
  message?: string
}
export interface RollbackRestoreParams {
  session_id: string
  hash: string
  file_path?: string | null
  profile?: string | null
}
/** ``tools/checkpoint_manager.py::restore`` outcome; ``history_removed`` is added for a full (non-file) restore that also rewound the live transcript. */
export interface RollbackRestoreResult {
  success: boolean
  restored_to?: string | null
  reason?: string | null
  directory?: string | null
  file?: string | null
  restored_files?: string[] | null
  skipped_user_edits?: string[] | null
  skipped_oversize?: string[] | null
  failed_deletes?: string[] | null
  history_removed?: number | null
  error?: string | null
  debug?: unknown | null
  [key: string]: unknown
}
export interface RollbackDiffParams {
  session_id: string
  hash: string
  profile?: string | null
}
export interface RollbackDiffResult {
  stat?: string
  diff?: string
  rendered?: string | null
}
export interface CronManageParams {
  action?: CronAction
  name?: string | null
  include_disabled?: boolean | string | null
  schedule?: string | null
  prompt?: string | null
  repeat?: number | string | null
  continuity?: boolean | string | null
  deliver?: string | null
  profile?: string | null
}
export type CronAction = 'list' | 'add' | 'remove' | 'pause' | 'resume'
/** Pass-through of ``tools/cronjob_tools.py::cronjob`` JSON: ``list`` → ``jobs``/``count`` (+ ``scoped`` when profile-scoped); ``add`` → the created job's summary + ``job``; ``remove`` → ``removed_job``; ``pause``/``resume`` → ``job``. A tool-level failure lands in ``error``. */
export interface CronManageResult {
  success?: boolean | null
  error?: string | null
  count?: number | null
  jobs?: CronJobRow[] | null
  scoped?: string | null
  gateway_running?: boolean | null
  warning?: string | null
  job_id?: string | null
  name?: string | null
  skill?: string | null
  skills?: string[] | null
  schedule?: string | null
  repeat?: number | string | null
  deliver?: string | null
  next_run_at?: string | null
  job?: CronJobRow | null
  message?: string | null
  guidance?: unknown | null
  removed_job?: CronRemovedJob | null
  [key: string]: unknown
}
/** ``tools/cronjob_job_args.py::_format_job``. */
export interface CronJobRow {
  job_id: string
  name?: string
  skill?: string | null
  skills?: string[]
  prompt_preview?: string
  model?: string | null
  provider?: string | null
  base_url?: string | null
  schedule?: string
  repeat?: number | string | null
  deliver?: string | null
  next_run_at?: string | null
  last_run_at?: string | null
  last_status?: string | null
  last_delivery_error?: string | null
  last_delivery_unverified?: boolean | null
  last_fire_error?: string | null
  last_error?: string | null
  enabled?: boolean
  state?: string | null
  paused_at?: string | null
  paused_reason?: string | null
  workdir?: string | null
  script?: string | null
  reasoning_effort?: string | null
  monitor_script?: string | null
  monitor_url?: string | null
  monitor_state?: unknown | null
  no_agent?: boolean | null
  enabled_toolsets?: string[] | null
  continuity?: boolean | null
  context_from?: string[] | null
  attach_to_session?: boolean | null
  [key: string]: unknown
}
export interface CronRemovedJob {
  id: string
  name?: string
  schedule?: string | null
}
export interface BrowserManageParams {
  action?: BrowserAction
  url?: string | null
  session_id?: string | null
  profile?: string | null
}
export type BrowserAction = 'status' | 'connect' | 'disconnect'
export interface BrowserManageResult {
  connected: boolean
  url?: string | null
  messages?: string[] | null
}
/** Handlers that look a live session up with ``_sessions.get(params.get("session_id"))``: an absent / unknown id falls back to the launch profile's config, so it is never required. */
export interface _SessionScoped {
  session_id?: string | null
}
export interface ToolsetsListResult {
  toolsets: ToolsetRow[]
}
/** One row of ``methods_tools._toolset_rows``; ``tools`` only when the caller asked for them (``tools.list``). */
export interface ToolsetRow {
  name: string
  description: string
  tool_count: number
  enabled: boolean
  tools?: string[] | null
}
export interface ToolsShowResult {
  sections: ToolShowSection[]
  total: number
}
export interface ToolShowSection {
  name: string
  tools: ToolShowRow[]
}
export interface ToolShowRow {
  name: string
  description: string
}
/** ``names`` are toolset keys or ``server:tool`` MCP targets; with ``session_id`` the live session's profile is authoritative and its agent is rebuilt. */
export interface ToolsConfigureParams {
  action: ToolsAction
  names: string[]
  session_id?: string | null
  profile?: string | null
}
export type ToolsAction = 'enable' | 'disable'
export interface ToolsConfigureResult {
  changed: string[]
  enabled_toolsets: string[]
  info?: SessionLiveInfo | null
  missing_servers: string[]
  reset: boolean
  unknown: string[]
}
export type ReloadEnvParams = Record<string, never>
export interface ReloadEnvResult {
  updated: number
}
/** Without ``confirm`` the handler may answer ``confirm_required`` (per ``approvals.mcp_reload_confirm``); ``always`` persists the opt-out; ``rev`` is the config revision the caller wants loaded (coalescing). */
export interface ReloadMcpParams {
  session_id?: string | null
  confirm?: boolean
  always?: boolean
  rev?: string | null
}
export interface ReloadMcpResult {
  status: ReloadMcpStatus
  message?: string | null
  loaded_rev?: string | null
  coalesced?: boolean | null
  turn_isolation?: boolean | null
  host_ack?: unknown | null
}
export type ReloadMcpStatus = 'confirm_required' | 'reloaded'
/** ``query`` is the search text / hub identifier / browse page (digits); ``page`` / ``page_size`` apply to ``browse``. */
export interface SkillsManageParams {
  profile?: string | null
  action?: SkillsAction
  query?: string | null
  page?: number | null
  page_size?: number | null
}
export type SkillsAction = 'list' | 'search' | 'install' | 'browse' | 'inspect'
/** Shape follows the action: ``list`` → ``skills`` (category → names); ``search`` → ``results``; ``install`` → ``installed`` + ``name``; ``browse`` → ``items`` + paging; ``inspect`` → ``info``. */
export interface SkillsManageResult {
  skills?: Record<string, string[]> | null
  results?: SkillHubHit[] | null
  installed?: boolean | null
  name?: string | null
  items?: SkillBrowseItem[] | null
  page?: number | null
  total_pages?: number | null
  total?: number | null
  info?: SkillInspectInfo | null
}
export interface SkillHubHit {
  name: string
  description: string
}
/** ``hermes_cli.skills_hub.browse_skills`` row. */
export interface SkillBrowseItem {
  name?: string
  description?: string
  source?: string
  trust?: string | null
  identifier?: string | null
  [key: string]: unknown
}
/** ``hermes_cli.skills_hub.inspect_skill``; ``{}`` when the identifier resolves nowhere. */
export interface SkillInspectInfo {
  name?: string | null
  description?: string | null
  source?: string | null
  identifier?: string | null
  tags?: string[] | null
  skill_md_preview?: string | null
  [key: string]: unknown
}
/** ``session_id`` binds the rescan to that session's profile and workspace (project skills). */
export interface SkillsReloadParams {
  session_id?: string | null
}
export interface SkillsReloadResult {
  output: string
  result: SkillsReloadDiff
}
/** ``agent.skill_commands.reload_skills``. */
export interface SkillsReloadDiff {
  added?: SkillCommandRef[]
  removed?: SkillCommandRef[]
  unchanged?: string[]
  total?: number
  commands?: number
  [key: string]: unknown
}
export interface SkillCommandRef {
  name: string
  description?: string
}
export interface LearningFramesParams {
  cols?: number | null
  rows?: number | null
  frames?: number | null
}
export interface LearningFramesResult {
  frames: LearningFrame[]
  legend: LearningLegendItem[]
  categories: LearningLegendItem[]
  buckets: LearningBucketRow[]
  summary: string[]
  axis: LearningAxis
  count: number
  cols: number
  rows: number
}
/** ``agent.learning_graph_render.render_graph`` projection; ``grid`` rows are lists of ``[text, styleKey, alpha?, hexOverride?]`` runs. */
export interface LearningFrame {
  reveal: number
  date: string
  visible: number
  grid: unknown[][]
  labels?: Record<string, unknown>[]
}
export interface LearningLegendItem {
  glyph: string
  label: string
  style?: string | null
  color?: string | null
}
export interface LearningBucketRow {
  index: number
  label: string
  date: string
  skills: number
  memories: number
  total: number
  category?: string | null
  color?: string | null
  nodes: LearningNodeRow[]
}
export interface LearningNodeRow {
  id: string
  glyph: string
  label: string
  fullLabel: string
  meta: string
  body: string
  style: string
}
export interface LearningAxis {
  start: string
  end: string
}
export interface LearningNodeParams {
  id?: string | null
}
export interface LearningDetailResult {
  ok: boolean
  message?: string | null
  kind?: string | null
  id?: string | null
  label?: string | null
  content?: string | null
}
/** ``agent.learning_mutations`` — ``ok: false`` carries the reason in ``message``. */
export interface LearningMutationResult {
  ok: boolean
  message?: string | null
}
export interface LearningEditParams {
  id?: string | null
  content?: string | null
}
export interface McpCatalogResult {
  servers: McpCatalogEntry[]
}
export interface McpCatalogEntry {
  name: string
  description: string
  connector_slug?: string | null
  installed: boolean
  enabled: boolean
  requires: string[]
  transport: string
}
export interface McpServersListResult {
  servers: McpServerSummary[]
}
/** ``tui_gateway/mcp_rpc_helpers.summarize_server`` — a server's config without secret values. */
export interface McpServerSummary {
  name: string
  transport: string
  url?: string | null
  command?: string | null
  args: string[]
  env: string[]
  auth?: string | null
  oauth_tokens_present?: boolean | null
  enabled: boolean
  tools?: unknown | null
  source: McpServerSource
  plugin?: string | null
}
export type McpServerSource = 'config' | 'plugin'
export interface McpServersStatusResult {
  servers: McpServerRuntimeRow[]
  checked_at: number
}
/** Safe projection of ``tools.mcp_tool_discovery.get_mcp_status`` rows. */
export interface McpServerRuntimeRow {
  name: string
  transport: string
  tools: number
  connected: boolean
  disabled: boolean
  status: McpRuntimeStatus
  source: McpServerSource
  plugin?: string | null
}
export type McpRuntimeStatus = 'connected' | 'disabled' | 'connecting' | 'failed' | 'lazy' | 'configured'
/** ``preset`` (catalog id) and/or ``config`` (url/command/args/env/headers/auth/tools); a ``bearer_token`` is written to the profile's .env, only the header template persists. */
export interface McpServersAddParams {
  profile?: string | null
  name: string
  preset?: string | null
  config?: Record<string, unknown> | null
  bearer_token?: string | null
}
export interface McpServersAddResult {
  ok: boolean
  name: string
  server: McpServerSummary
}
export interface McpServersSetApiKeyParams {
  profile?: string | null
  name: string
  value: string
  env_var?: string | null
}
export interface McpServersSetApiKeyResult {
  ok: boolean
  name: string
  env_var: string
  server: McpServerSummary
}
export interface McpServerNameParams {
  profile?: string | null
  name: string
}
/** ``ok: false`` carries ``error``; ``prompts`` / ``resources`` are only counted on success. */
export interface McpServersTestResult {
  ok: boolean
  tools: McpProbeTool[]
  error?: string | null
  prompts?: number | null
  resources?: number | null
  oauth_needed: boolean
  oauth_tokens_present?: boolean | null
}
export interface McpProbeTool {
  name: string
  description: string
}
export interface McpServersRemoveResult {
  ok: boolean
  removed: boolean
}
/** With ``client_redirect_uri`` the CLIENT hosts the loopback and relays the code via ``mcp.servers.oauth.callback``. */
export interface McpOauthStartParams {
  profile?: string | null
  name: string
  client_redirect_uri?: string | null
}
export interface McpOauthStartResult {
  ok: boolean
  session_id: string
  auth_url: string
  flow: string
}
/** ``session_id`` is the OAuth flow id returned by ``oauth.start`` (not a gateway session). */
export interface McpOauthFlowParams {
  profile?: string | null
  name: string
  session_id: string
}
export interface McpOauthPollResult {
  ok: boolean
  status: McpOauthPollStatus
  session_id?: string | null
  error_message?: string | null
  auth_url?: string | null
  tools?: McpProbeTool[] | null
}
export type McpOauthPollStatus = 'pending' | 'approved' | 'error'
export interface McpOauthCancelResult {
  ok: boolean
  status?: string | null
  error_message?: string | null
}
export interface McpOauthCallbackParams {
  profile?: string | null
  name: string
  session_id: string
  code?: string | null
  state?: string | null
  error?: string | null
  iss?: string | null
}
export interface McpOauthCallbackResult {
  ok: boolean
  session_id?: string | null
  error_message?: string | null
}
export type PluginsListParams = Record<string, never>
export interface PluginsListResult {
  plugins: LegacyPluginRow[]
}
export interface LegacyPluginRow {
  name: string
  version: string
  enabled: boolean
}
/** ``toggle``: ``key``/``name`` + ``enable``; ``install``: ``identifier``/``repo`` or ``catalog_name`` (+ ``force``, ``enable``, ``ref``); ``update``: ``name`` (+ ``accept_capabilities`` to apply a re-pin that widened the plugin after the user confirmed the ``delta``); ``remove``: ``name`` (user installs only); ``settings``: ``key`` + ``values`` (``{setting_key: value}``, non-secret schema keys only). */
export interface PluginsManageParams {
  profile?: string | null
  action?: PluginsAction
  key?: string | null
  name?: string | null
  enable?: boolean | null
  identifier?: string | null
  repo?: string | null
  catalog_name?: string | null
  force?: boolean | null
  ref?: string | null
  accept_capabilities?: boolean | null
  values?: Record<string, unknown> | null
}
export type PluginsAction = 'list' | 'toggle' | 'install' | 'update' | 'remove' | 'settings'
/** ``list`` → ``plugins`` + counts; ``toggle`` → ``ok``/``unchanged``/``restart_required``/``name`` (the canonical key written)/``plugin``; ``install`` → ``hermes_cli.plugins_cmd.dashboard_install_plugin``'s ok payload; ``toggle``/``install``/``update`` that loaded a plugin also carry ``gateway_reloaded`` (the running gateway picked it up and re-wired its handlers) and ``activation`` — the honest split of what is live now vs deferred, so ``restart_required`` is True only when no gateway answered; ``update`` → ``ok``/``unchanged``/``sha``, or ``ok=false`` + ``consent_required`` with the ``delta`` (``{surface: [added...]}``) / ``delta_lines`` a widened pin adds — nothing changed until the client retries with ``accept_capabilities``; ``remove`` → ``ok``/``name`` plus ``cleared_memory_provider`` when the removed plugin was the live ``memory.provider``. */
export interface PluginsManageResult {
  plugins?: AgentPluginRow[] | null
  user_count?: number | null
  bundled_count?: number | null
  ok?: boolean | null
  unchanged?: boolean | null
  restart_required?: boolean | null
  gateway_reloaded?: boolean | null
  activation?: PluginActivation | null
  cleared_memory_provider?: boolean | null
  name?: string | null
  plugin?: AgentPluginRow | null
  plugin_name?: string | null
  warnings?: string[] | null
  missing_env?: string[] | null
  python_dependencies?: string[] | null
  after_install_path?: string | null
  enabled?: boolean | null
  sha?: string | null
  consent_required?: boolean | null
  delta?: Record<string, string[]> | null
  delta_lines?: string[] | null
  error?: string | null
  written?: string[] | null
}
/** ``methods_tools._plugin_rows`` + ``plugins_cmd_catalog.catalog_row_fields`` provenance. */
export interface AgentPluginRow {
  name: string
  key: string
  version: string
  description: string
  source: string
  status: string
  portable: boolean
  install_dir: string
  has_desktop_half: boolean
  servers: PluginServerRow[]
  catalog_name?: string | null
  catalog_tier?: string | null
  installed_sha?: string | null
  catalog_sha?: string | null
  catalog_version?: string | null
  update_available?: boolean | null
  pinned_sha?: string | null
  settings_schema?: PluginSettingField[] | null
}
export interface PluginServerRow {
  name: string
  state: PluginServerState
  sentence: string
}
export type PluginServerState = 'connected' | 'app_not_running' | 'endpoint_unavailable' | 'no_interactive_session' | 'version_too_old' | 'missing_app' | 'unknown'
/** One ``config_schema`` key of a plugin manifest, rendered by the Plugins hub (``hermes_cli.plugins_settings.plugin_settings_fields``). ``secret`` fields carry no value: ``env`` names the ``.env`` variable and ``has_value`` whether it is set. */
export interface PluginSettingField {
  key: string
  type: PluginSettingFieldType
  label: string
  description: string
  required: boolean
  value?: unknown | null
  default?: unknown | null
  choices?: string[] | null
  env?: string | null
  has_value?: boolean | null
}
export type PluginSettingFieldType = 'string' | 'number' | 'boolean' | 'enum' | 'secret' | 'json'
/** What a plugin loaded mid-run does NOW vs later (``hermes_cli.plugins_activation``), ``{kind: [names]}`` with only non-empty kinds present. ``activated_now`` kinds: ``gateway_commands`` (slash names), ``gateway_transforms`` / ``hooks`` (hook names), ``callbacks`` (platforms / ``slack:<action_id>``) — live in the running gateway once it reloaded (``gateway_reloaded``). ``deferred`` kinds: ``tools`` (tool names) and ``prompt`` (section ids) apply from the next session; ``mcp_servers`` lists the plugin's mcp.json server names (exactly as ``mcp.servers.*`` know them) — not connected until ``mcp.reload``. The Desktop "Installed. Connect its servers now" card reads exactly ``deferred.mcp_servers``. */
export interface PluginActivation {
  name: string
  key: string
  activated_now?: Record<string, string[]>
  deferred?: Record<string, string[]>
}
/** Single question: ``question`` / ``choices`` (/ ``multi_select``); batch: ``questions``. ``answers`` rides only on a reconnect replay (locks the server already accepted). */
export interface ClarifyRequestParams {
  session_id: string
  question?: string | null
  choices?: string[] | null
  multi_select?: boolean | null
  questions?: ClarifyQuestion[] | null
  answers?: Record<string, string> | null
}
export interface ClarifyQuestion {
  qid: string
  question: string
  choices?: string[] | null
  multi_select?: boolean
}
/** Single: ``{answer}`` ('' = skip). Batch: ``{answers}`` for the whole set (early locks go through the ``clarify.lock`` RPC); a response with neither is cancel-all. */
export interface ClarifyResult {
  answer?: string | null
  answers?: Record<string, string> | null
}
/** ``tui_gateway/server.py::_approval_request_payload`` — the command is redacted server-side. */
export interface ApprovalRequestParams {
  session_id: string
  request_id: string
  command?: string
  description?: string
  choices?: ApprovalChoice[]
  allow_permanent?: boolean | null
  allow_session?: boolean | null
  smart_denied?: boolean | null
  tool_name?: string | null
  gateway_session_id?: string | null
  [key: string]: unknown
}
export interface ApprovalResult {
  choice: ApprovalChoice
  all?: boolean | null
}
/** Original command, redacted server-side before any password-injection rewrite. */
export interface SudoRequestParams {
  session_id: string
  command?: string
}
/** The answer to any one-string prompt (sudo, secret, vault prompts, desktop bridges): ``''`` means skipped / declined. */
export interface ValueResult {
  value: string
}
export interface SecretRequestParams {
  session_id: string
  env_var: string
  prompt: string
  metadata?: Record<string, unknown> | null
}
export interface VaultUnlockRequestParams {
  session_id: string
  backend: string
  display_name: string
}
export interface VaultSaveLoginRequestParams {
  session_id: string
  origin: string
  site: string
}
export interface VaultCodeRequestParams {
  session_id: string
  site?: string | null
  hint?: string | null
}
export interface ReadRangeRequestParams {
  session_id: string
  start?: number | null
  count?: number | null
}
export interface EmptyRequestParams {
  session_id: string
}
/** ``tools/drive_preview_tool.py`` and ``tools/annotate_preview_tool.py`` field sets. */
export interface PreviewActRequestParams {
  session_id: string
  action: string
  ref?: string | null
  selector?: string | null
  text?: string | null
  key?: string | null
  submit?: boolean | null
  full?: boolean | null
  to?: string | null
  amount?: number | null
  max?: number | null
}
/** ``tools/tour_tool.py`` field set. */
export interface TourRequestParams {
  session_id: string
  action: string
  surface?: string | null
  selector?: string | null
  title?: string | null
  text?: string | null
  side?: string | null
  steps?: TourStep[] | null
  step_index?: number | null
}
export interface TourStep {
  selector?: string | null
  title?: string | null
  text?: string | null
  side?: string | null
  [key: string]: unknown
}
/** ``methods_connectors._connection_update``: one target transition (``target``/``from``/``to``/ ``actor``) or the settlement (none of those), with the full snapshot. */
export interface ConnectionUpdatePayload {
  op_id: string
  seq: number
  deadline_at: number
  settled: boolean
  settled_at?: number | null
  settled_by?: ConnectionSettleReason | null
  targets: ConnectionOperationTarget[]
  owner: SessionOwner | AccountOwner
  target?: string | null
  from?: ConnectionTargetState | null
  to?: ConnectionTargetState | null
  actor?: ConnectionActor | null
  detail?: string | null
}
/** ``tools/connectors/contract.py::Actor``. */
export type ConnectionActor = 'user' | 'backend_watcher' | 'clock'
/** ``tui_gateway/entry.py`` (stdio) / ``tui_gateway/ws.py`` (WebSocket) first frame. */
export interface GatewayReadyPayload {
  skin: SkinPayload
  change_events: boolean
  replay_epoch: string
  heartbeat?: boolean | null
}
/** ``tui_gateway/change_watcher.py::resolve_skin`` — the resolved active skin (``HermesSkin``). ``{}`` when the skin engine failed to load. Colour maps are token → colour string. */
export interface SkinPayload {
  name?: string
  description?: string
  colors?: Record<string, string>
  light_colors?: Record<string, string>
  dark_colors?: Record<string, string>
  branding?: Record<string, string>
  banner_logo?: string
  banner_hero?: string
  tool_prefix?: string
  help_header?: string
  [key: string]: unknown
}
/** ``hermes_cli/free_tier_bootstrap.py::SetupRecord.as_payload``. */
export interface SetupReadyPayload {
  provider_configured: boolean
  inference_provider: string
  free_tier: boolean
  has_identity: boolean
  other_providers: boolean
  error?: string
  error_code?: string | null
  retryable?: boolean | null
  retry_after?: number | null
  finished_at: number
  [key: string]: unknown
}
/** Every ``_emit("error", …)`` site sets exactly ``message``. */
export interface ErrorPayload {
  message: string
}
/** ``tui_gateway/model_switch.py`` capability-refresh notice. */
export interface NoticePayload {
  message: string
}
/** ``prompt_turn._invoke_agent._stream`` (message.delta: ``text`` + optional ``rendered``), ``agent_callbacks._agent_cbs`` (reasoning.delta / thinking.delta), ``tool_progress._progress_reasoning`` (reasoning.available). ``verbose`` rides only when the session's verbose reasoning mode is on. */
export interface StreamDeltaPayload {
  text: string
  rendered?: string | null
  verbose?: boolean | null
}
/** ``prompt_turn._interim_assistant_cb`` / ``agent_callbacks`` interim_assistant_callback. */
export interface MessageInterimPayload {
  text: string
  already_streamed: boolean
}
/** ``prompt_turn._complete_turn_payload`` / ``session_auto_continue._emit_terminal_turn_error`` / ``agent_callbacks._mirror_subagent_to_child`` (child watch mirror: ``text`` only) / ``compute_host_bridge`` (``text`` + ``status``). */
export interface MessageCompletePayload {
  text?: string | unknown
  usage?: Usage | null
  status?: TurnStatus | null
  reasoning?: string | null
  warning?: string | null
  response_previewed?: boolean | null
  billing?: BillingBlock | null
  failure_reason?: string | null
  rendered?: string | null
  error?: string | null
  recoverable?: boolean | null
  error_surface?: ErrorSurface | null
  partial?: boolean | null
}
/** ``prompt_turn._result_status``. */
export type TurnStatus = 'complete' | 'error' | 'interrupted'
/** ``agent/billing_links.py::BillingBlock.to_dict`` (+ ``unverified`` from conversation_loop). */
export interface BillingBlock {
  provider: string
  provider_label: string
  model: string
  billing_url: string | null
  is_nous: boolean
  message: string
  unverified?: boolean | null
}
/** ``agent/error_surface.py::_surface`` — advisory {layer, code, retryable} (+ identity, + auth hint, + ``resets_at`` epoch seconds when the provider named when its limit lifts). */
export interface ErrorSurface {
  layer: string
  code: string
  retryable: boolean
  provider?: string | null
  model?: string | null
  resets_at?: number | null
  [key: string]: unknown
}
/** ``server._status_update`` and the direct emitters (goal / loop / heartbeat / process). */
export interface StatusUpdatePayload {
  kind: string
  text: string
}
/** ``server._start_usage_ticker``. */
export interface SessionUsagePayload {
  usage: Usage
}
/** ``prompt_turn._invoke_agent`` ``_on_session_title`` hook. */
export interface SessionTitlePayload {
  session_id: string
  title: string
}
/** ``agent_callbacks`` reaction_callback. */
export interface ReactionPayload {
  kind: string
}
/** ``server`` background_review_callback. */
export interface ReviewSummaryPayload {
  text: string
}
/** ``tool_progress._on_tool_start`` (+ ``agent_callbacks._mirror_subagent_to_child`` rows with ``preview`` and empty ``args``). ``todos``/``revision`` are NOT set by the emitter; kept optional because tool.start rows may pass through connector redaction unchanged. */
export interface ToolStartPayload {
  tool_id: string
  name: string
  context?: string | null
  args?: Record<string, unknown> | null
  args_text?: string | null
  preview?: string | null
  labels?: ToolLabel[] | null
}
/** ``tool_progress._on_tool_complete``; ``todos``/``revision`` merged in for the todo tools. */
export interface ToolCompletePayload {
  tool_id: string
  name: string
  args?: Record<string, unknown> | null
  duration_s?: number | null
  result?: unknown
  summary?: string | null
  result_text?: string | null
  inline_diff?: string | null
  todos?: unknown[] | null
  revision?: number | null
  labels?: ToolLabel[] | null
}
/** ``agent_callbacks`` tool_gen_callback. */
export interface ToolGeneratingPayload {
  name: string
}
/** ``tool_progress._progress_output_risk``. */
export interface ToolOutputRiskPayload {
  tool_id: string
  name: string
  risk: string
  findings: string[]
  redacted: boolean
}
/** ``tool_progress._normalize_todo_state`` — full task snapshot. */
export interface TodoUpdatedPayload {
  todos: unknown[]
  revision: number
}
/** ``agent/credits_tracker.py::AgentNotice`` via notice_callback, and ``server._await_agent_ready``'s slow-build notice. ``level``: info | warn | error | success; ``kind``: sticky | ttl | agent. */
export interface NotificationShowPayload {
  text: string
  level: string
  kind: string
  ttl_ms?: number | null
  key?: string | null
  id?: string | null
}
export interface NotificationClearPayload {
  key: string
}
/** ``tools/tip_tool.py``. */
export interface TipShowPayload {
  selector: string
  text: string
  title?: string | null
  side?: string | null
}
/** ``server._hydrate_resume_history``. */
export interface SessionResumeProgressPayload {
  phase: string
  status: ResumePhaseStatus
  message_count?: number | null
  message?: string | null
}
export type ResumePhaseStatus = 'loading' | 'complete' | 'failed'
/** ``session_lifecycle._announce_session_reclaimed`` (broadcast). */
export interface SessionReclaimedPayload {
  session_id: string
  stored_session_id: string
  reason: string
}
export interface SessionControlUpdatePayload {
  control: SessionControlSnapshot
}
/** ``methods_session`` billing.step_up on_verification. */
export interface BillingStepUpVerificationPayload {
  verification_url: string
  user_code: string
}
/** ``methods_prompt._spawn_side_agent``: ``{task_id, **extra, text}``; btw adds ``question``. */
export interface SideAgentCompletePayload {
  task_id: string
  text: string
  question?: string | null
}
/** ``methods_prompt`` restart body + ``agent_callbacks._preview_restart_callbacks``. */
export interface PreviewRestartProgressPayload {
  task_id: string
  text: string
  level?: string | null
}
/** ``tool_progress._progress_subagent`` — every ``subagent.*`` frame; identity fields are optional because older emitters omit them and the TUI spawn tree falls back to flat rendering. */
export interface SubagentEventPayload {
  goal: string
  task_count: number
  task_index: number
  subagent_id?: string | null
  parent_id?: string | null
  child_session_id?: string | null
  delegation_id?: string | null
  depth?: number | null
  model?: string | null
  tool_count?: number | null
  toolsets?: string[] | null
  input_tokens?: number | null
  output_tokens?: number | null
  reasoning_tokens?: number | null
  api_calls?: number | null
  files_read?: string[] | null
  files_written?: string[] | null
  output_tail?: SubagentOutputTailEntry[] | null
  tool_name?: string | null
  text?: string | null
  status?: SubagentStatus | null
  summary?: string | null
  duration_seconds?: number | null
  tool_preview?: string | null
}
/** ``tools/delegate_tool_results.py::_extract_output_tail`` row. */
export interface SubagentOutputTailEntry {
  tool: string
  preview: string
  is_error: boolean
}
/** ``tool_progress._progress_moa_reference``. */
export interface MoaReferencePayload {
  label: string
  text: string
  index?: number | null
  count?: number | null
}
export interface MoaAggregatingPayload {
  aggregator: string
}
export interface MoaProgressPayload {
  label: string
  refs_done: number
  refs_total: number
}
export interface MoaPhasePayload {
  phase: string
  refs_done?: number | null
  refs_total?: number | null
  aggregator?: string | null
}
/** ``tools/open_preview_tool.py``. */
export interface PreviewOpenPayload {
  url: string
  label?: string
}
/** ``tools/preview_tool.py`` / ``tools/close_preview_tool.py``; ``url`` '' closes every tab. */
export interface PreviewClosePayload {
  url?: string
}
/** ``tools/apply_layout_tool.py``. */
export interface LayoutApplyPayload {
  preset: string
  [key: string]: unknown
}
/** ``tools/focus_pane_tool.py``. */
export interface PaneRevealPayload {
  pane: string
  [key: string]: unknown
}
/** ``tools/react_to_message_tool.py``. */
export interface MessageReactionPayload {
  row_id: number
  reactions: MessageReaction[]
  role: string
}
/** ``session_notifications`` process_registry.on_output. */
export interface TerminalOutputPayload {
  process_id: string
  chunk: string
}
export interface TerminalClosePayload {
  process_id: string
}
/** ``methods_browser`` announce(); ``level``: info | warn | error. */
export interface BrowserProgressPayload {
  message: string
  level: string
}
/** ``gateway/browser_control_broker.py`` FRAME_COMMAND params. */
export interface BrowserControllerCommandPayload {
  command_id: string
  action: string
  arguments: Record<string, unknown>
  controller_id?: string | null
  browser_profile_id?: string | null
  tool_call_id?: string | null
}
/** ``gateway/browser_control_broker.py::_cancel_frame``. */
export interface BrowserControllerCancelPayload {
  command_id: string
  tool_call_id?: string | null
}
/** ``methods_voice._vr_on_status``; states come from the recorder (idle / listening / transcribing …). */
export interface VoiceStatusPayload {
  state: string
}
/** ``methods_voice._vr_transcript`` / ``_deliver_fd_transcript`` / typed stop phrase in methods_prompt. */
export interface VoiceTranscriptPayload {
  text?: string | null
  stop_phrase?: boolean | null
  typed?: boolean | null
  no_speech_limit?: boolean | null
}
/** ``methods_voice`` wake detector ``_on_detect``. */
export interface WakeDetectedPayload {
  phrase: string
  profile?: string | null
  start_new_session: boolean
}
/** ``change_watcher._pet_changed_payload`` — ``pet.info.meta``-shaped; ``{enabled: false}`` when off. */
export interface PetChangedPayload {
  enabled: boolean
  slug?: string | null
  displayName?: string | null
  scale?: number | null
  spritesheetRevision?: string | null
  [key: string]: unknown
}
/** ``methods_session`` pet.generate: token-only init frame, then one per draft. */
export interface PetGenerateProgressPayload {
  token: string
  count: number
  index?: number | null
  dataUri?: string | null
  [key: string]: unknown
}
/** ``methods_session`` pet.hatch ``_on_progress``: ``{event, detail}`` or the parsed row form. */
export interface PetHatchProgressPayload {
  event: string
  detail?: string | null
  state?: string | null
  done?: string | null
  total?: string | null
  [key: string]: unknown
}
/** ``change_watcher._CHANGE_WATCHES`` payload fn — ``{}`` for every watch except pet.changed. */
export type ChangeSignalPayload = Record<string, unknown>
export interface RequestCancelPayload {
  id: string
  method: string
  reason: string
}
export type ConnectorErrorReason = 'INVALID_PARAMS' | 'NOT_OWNER' | 'UNSUPPORTED_RUNTIME' | 'CONNECTOR_REQUEST_FAILED' | 'INVALID_CONNECTOR_RESPONSE' | 'UNKNOWN_TARGET' | 'LINK_STILL_VALID' | 'REISSUE_REFUSED' | 'UNKNOWN_OPERATION' | 'INVALID_ANSWER' | 'NEEDS_NOUS_AUTH' | 'CONNECTOR_NOT_FOUND' | 'TOOLS_UNAVAILABLE' | 'CONNECTORS_UNAVAILABLE' | 'CATALOG_UNAVAILABLE' | 'ACCOUNTS_UNAVAILABLE' | 'CONNECTION_NOT_FOUND' | 'POLICY_UNAVAILABLE' | 'POLICY_CONFLICT' | 'FORBIDDEN_SCOPE' | 'ORG_REQUIRED' | 'ORG_ACCESS_DENIED' | 'INVALID_POLICY'

// ── Client→server methods ──
export interface RpcMethods {
  /** Registry-wide background process summary for ``/agents``. */
  'agents.list': { params: AgentsListParams; result: AgentsListResult }
  /** Replay the approvals still waiting on this session (reconnect / polling). */
  'approval.pending': { params: ApprovalPendingParams; result: ApprovalPendingResult }
  /** Tell the backend the card is on screen, so its timeout clock starts. */
  'approval.received': { params: ApprovalReceivedParams; result: ApprovalReceivedResult }
  /** Deliver the user's decision on a dangerous command (falls back to durable identity on a stale sid). */
  'approval.respond': { params: ApprovalRespondParams; result: ApprovalRespondResult }
  /** Enable/disable auto top-up with its threshold and reload amount (billing:manage). */
  'billing.auto_reload': { params: BillingAutoReloadParams; result: BillingMutationResult }
  /** Start a one-off top-up charge (billing:manage, idempotent). */
  'billing.charge': { params: BillingChargeParams; result: BillingChargeResult }
  /** Poll one charge by id. */
  'billing.charge_status': { params: BillingChargeStatusParams; result: BillingChargeStatusResult }
  /** Read-only billing view (no scope); the Nous free tier is answered locally without a portal call. */
  'billing.state': { params: ProfileParams; result: BillingStateResult }
  /** Run the billing:manage device flow; the URL/code arrive via billing.step_up.verification. */
  'billing.step_up': { params: BillingStepUpParams; result: BillingStepUpResult }
  /** Deliver a relayed DM into a Bot Chat on this gateway and return the one-turn reply (blocking). */
  'bot_relay.deliver': { params: BotRelayDeliverParams; result: BotRelayDeliverResult }
  /** Atomically claim every pending cross-connection envelope queued on this gateway. */
  'bot_relay.outbox.drain': { params: BotRelayOutboxDrainParams; result: BotRelayOutboxDrainResult }
  /** Write a relayed reply and/or typed error for an envelope so the sender-side waiter resolves. */
  'bot_relay.reply': { params: BotRelayReplyParams; result: OkResult }
  /** Replace this gateway's view of agents on other connections; answers the accepted row count. */
  'bot_relay.roster.sync': { params: BotRelayRosterSyncParams; result: BotRelayRosterSyncResult }
  /** Hard-detach only the controller owned by this authenticated transport. */
  'browser.controller.detach': { params: BrowserControllerParams; result: BrowserControllerDetachResult }
  /** Acknowledge a heartbeat only for this transport's own attached controller. */
  'browser.controller.heartbeat': { params: BrowserControllerParams; result: OkResult }
  /** Attach this connection as the browser controller for one session; fails closed (4403). */
  'browser.controller.register': { params: BrowserControllerRegisterParams; result: BrowserControllerRegisterResult }
  /** Deliver one command result to the broker; accepted is false for unknown or settled command ids. */
  'browser.controller.result': { params: BrowserControllerResultParams; result: BrowserControllerResultResult }
  /** Inspect, attach to, or drop the CDP browser the tools use; ``messages`` narrate a connect. */
  'browser.manage': { params: BrowserManageParams; result: BrowserManageResult }
  /** Lock one answer of a batch clarify request (editable until every question is locked). */
  'clarify.lock': { params: ClarifyLockParams; result: ClarifyLockResult }
  /** Run ``hermes <argv>`` non-interactively and capture its output; ``blocked`` explains a refusal. */
  'cli.exec': { params: CliExecParams; result: CliExecResult }
  /** What the calling client handles, sent once per connection (after gateway.ready); returns the server→client request methods this backend may send. */
  'client.capabilities': { params: ClientCapabilitiesParams; result: ClientCapabilitiesResult }
  /** Save the host clipboard image into the session and queue it for the next turn. */
  'clipboard.paste': { params: ClipboardPasteParams; result: AttachedImageResult }
  /** Run a quick/plugin/bundle/skill/built-in slash command and answer a structured directive. */
  'command.dispatch': { params: CommandDispatchParams; result: CommandDispatchResult }
  /** Canonical registry command for a name or alias. */
  'command.resolve': { params: CommandResolveParams; result: CommandResolveResult }
  /** Categorized slash metadata (registry, quick, plugin, skill) for completion menus. */
  'commands.catalog': { params: CommandsCatalogParams; result: CommandsCatalogResult }
  /** Path / @-reference completions for the composer (files, folders, profiles, plugin providers). */
  'complete.path': { params: CompletePathParams; result: CompletionItemsResult }
  /** Ranked slash-command / skill completions for a ``/`` token. */
  'complete.slash': { params: CompleteSlashParams; result: CompleteSlashResult }
  /** Read one normalised config value (or the whole effective config) the way the UIs render it. */
  'config.get': { params: ConfigGetParams; result: ConfigGetResult }
  /** Change one config key (persisted or session-scoped) and read back the normalised value. */
  'config.set': { params: ConfigSetParams; result: ConfigSetResult }
  /** Masked, display-ready config summary (model / agent / environment rows). */
  'config.show': { params: ConfigShowParams; result: ConfigShowResult }
  /** Per-target outcomes from the card, and an optional Continue. */
  'connection.respond': { params: ConnectionRespondParams; result: ConnectionRespondResult }
  /** The scoped member's hosted connector accounts, optionally filtered by connector slug. */
  'connectors.accounts': { params: ConnectorAccountsParams; result: ConnectorAccountsResult }
  /** Remove one hosted connector account owned by the scoped member. */
  'connectors.accounts.remove': { params: ConnectorAccountsRemoveParams; result: ConnectorAccountsRemoveResult }
  /** The hosted connector catalog available to the scoped member. */
  'connectors.catalog': { params: ProfileParams; result: ConnectorsCatalogResult }
  /** Start or re-initiate authorization for named connectors on a session or account operation. */
  'connectors.connect': { params: ConnectorsConnectParams; result: ConnectorsConnectResult }
  /** Connector catalog + connection state for one session or profile account owner. */
  'connectors.list': { params: ConnectorsListParams; result: ConnectorsListResult }
  /** The current snapshot of one open session or account operation. */
  'connectors.operation.status': { params: ConnectionOperationParams; result: ConnectionOperationStatus }
  /** The browser leg came back (hermes://connections/done): read the accounts now, not at the next tick. */
  'connectors.operation.wake': { params: ConnectionOperationParams; result: ConnectionWakeResult }
  /** Policy layers for the scoped member, from organization to member scope. */
  'connectors.policy.get': { params: ProfileParams; result: ConnectorPolicyGetResult }
  /** Apply one scoped member connector or tool-list policy change. */
  'connectors.policy.set': { params: ConnectorPolicySetParams; result: ConnectorPolicySetResult }
  /** The scoped profile's cached or current tool list for one connector. */
  'connectors.tools': { params: ConnectorToolsParams; result: ConnectorToolsResult }
  /** List/add/remove/pause/resume cron jobs in the (optionally profile-scoped) cron store. */
  'cron.manage': { params: CronManageParams; result: CronManageResult }
  /** Block/unblock NEW spawns globally (active children keep running); returns the new state. */
  'delegation.pause': { params: DelegationPauseParams; result: DelegationPauseResult }
  /** Running subagent tree plus the spawn pause flag and limits. */
  'delegation.status': { params: ProfileParams; result: DelegationStatusResult }
  /** Upload a force-redacted debug bundle to Nous-internal diagnostics storage. */
  'diagnostics.share_nous': { params: DiagnosticsShareNousParams; result: DiagnosticsShareNousResult }
  /** Stage a non-image file into the session workspace and hand back its @file: ref. */
  'file.attach': { params: FileAttachParams; result: FileAttachResult }
  /** Mark the one-time availability notice as shown on the free-tier identity. */
  'free_tier.ack_notice': { params: ProfileParams; result: FreeTierAckNoticeResult }
  /** Explicit retry of the free-tier identity mint when the boot bootstrap could not create it. */
  'free_tier.provision': { params: ProfileParams; result: FreeTierProvisionResult }
  /** Pure read of the focused profile's free-tier identity state (no network, no side effects). */
  'free_tier.status': { params: ProfileParams; result: FreeTierStatusResult }
  /** What THIS build enforces (a client withholds a feature unless advertised). */
  'gateway.capabilities': { params: PingParams; result: GatewayCapabilitiesResult }
  /** Resolve one exact pending approval raised by a local or peer room member. */
  'groups.approve': { params: GroupsApproveParams; result: GroupsApproveResult }
  /** Describe the hosted-room protocol implemented by this gateway. */
  'groups.capabilities': { params: GroupsCapabilitiesParams; result: GroupsCapabilitiesResult }
  /** Create a hosted room idempotently; authority is this gateway's stable install identity. */
  'groups.create': { params: GroupsCreateParams; result: GroupsCreateResult }
  /** Fence this gateway's stale room authority against a proven newer epoch. */
  'groups.demote': { params: GroupsDemoteParams; result: GroupsDemoteResult }
  /** Permanently tombstone a hosted room id after stopping its work and revoking peer routes. */
  'groups.disband': { params: GroupsDisbandParams; result: GroupsDisbandResult }
  /** List rooms hosted by this gateway, most recently changed first. */
  'groups.list': { params: GroupsListParams; result: GroupsListResult }
  /** A monotonic room-log delta after since_seq, bounded by count and page bytes. */
  'groups.log': { params: GroupsLogParams; result: GroupsLogResult }
  /** Mint one target-issued room/profile grant for a prospective room home. */
  'groups.peer.invite': { params: GroupsPeerInviteParams; result: GroupsPeerInviteResult }
  /** Register and probe one scoped peer route on the room home. */
  'groups.peer.register': { params: GroupsPeerRegisterParams; result: GroupsPeerRegisterResult }
  /** Revoke one target-issued grant using its exact profile scope. */
  'groups.peer.revoke': { params: GroupsPeerRevokeParams; result: GroupsPeerRevokeResult }
  /** Continue a replicated room on this gateway at epoch + 1; requires confirm=true. */
  'groups.promote': { params: GroupsPromoteParams; result: GroupsPromoteResult }
  /** Rename one hosted room atomically with its replay event. */
  'groups.rename': { params: GroupsRenameParams; result: GroupsRenameResult }
  /** The local replica's coverage and authority lineage for one room. */
  'groups.replica_state': { params: GroupsReplicaStateParams; result: GroupsReplicaStateResult }
  /** Persist one authority-stamped replay page into the local replica store; idempotent. */
  'groups.replicate': { params: GroupsReplicateParams; result: GroupsReplicateResult }
  /** Retry one indeterminate room task after explicit user confirmation. */
  'groups.retry': { params: GroupsRetryParams; result: GroupsRetryResult }
  /** Append one inert message.user event idempotently; the actor is server-owned. */
  'groups.send': { params: GroupsSendParams; result: GroupsSendResult }
  /** One hosted room's replay cursor and fenced authority state, plus live driver status. */
  'groups.state': { params: GroupsStateParams; result: GroupsStateResult }
  /** Durably cancel queued or running work for one hosted room. */
  'groups.stop': { params: GroupsStopParams; result: GroupsStopResult }
  /** Fail a not-yet-claimed handoff (client poll timeout); CAS against the watcher. */
  'handoff.fail': { params: HandoffFailParams; result: HandoffFailResult }
  /** Queue a handoff to a messaging platform's home channel; the gateway watcher claims it. */
  'handoff.request': { params: HandoffRequestParams; result: HandoffRequestResult }
  /** Poll the handoff row for this session. */
  'handoff.state': { params: SessionParams; result: HandoffStateResult }
  /** Queue a gateway-visible image file for the next turn. */
  'image.attach': { params: ImageAttachParams; result: AttachedImageResult }
  /** Queue an image uploaded as base64 (remote client); reply mirrors image.attach. */
  'image.attach_bytes': { params: ImageAttachBytesParams; result: AttachedImageResult }
  /** Drop a queued image before the turn is sent. */
  'image.detach': { params: ImageDetachParams; result: ImageDetachResult }
  /** Generate an image through the tool's provider dispatcher and hand the renderer a data URL. */
  'image.generate': { params: ImageGenerateParams; result: ImageGenerateResult }
  /** Recognise a terminal file drop pasted into the composer and turn it into an attachment. */
  'input.detect_drop': { params: InputDetectDropParams; result: InputDetectDropResult }
  /** Session/message counts over the last ``days`` for the (optionally scoped) profile store. */
  'insights.get': { params: InsightsGetParams; result: InsightsGetResult }
  /** Archive a skill (restorable via curator) or remove a memory chunk. */
  'learning.delete': { params: LearningNodeParams; result: LearningMutationResult }
  /** Node content (SKILL.md or memory chunk) for an edit prefill. */
  'learning.detail': { params: LearningNodeParams; result: LearningDetailResult }
  /** Rewrite a node's content (SKILL.md or memory chunk). */
  'learning.edit': { params: LearningEditParams; result: LearningMutationResult }
  /** Pre-render the /journey timeline (frames + legend/summary) so the TUI walks it locally. */
  'learning.frames': { params: LearningFramesParams; result: LearningFramesResult }
  /** Stateless one-shot LLM completion (titles, ideas) on the session's or the task backend. */
  'llm.oneshot': { params: LlmOneshotParams; result: LlmOneshotResult }
  /** Curated MCP presets with per-profile installed/enabled state and the env keys each needs. */
  'mcp.catalog': { params: ProfileParams; result: McpCatalogResult }
  /** Add a server to the profile's config from a catalog preset and/or an explicit config. */
  'mcp.servers.add': { params: McpServersAddParams; result: McpServersAddResult }
  /** Configured MCP servers for the (scoped) profile, secrets redacted to env-key names. */
  'mcp.servers.list': { params: ProfileParams; result: McpServersListResult }
  /** Relay a client-captured redirect into a client_redirect_uri flow. */
  'mcp.servers.oauth.callback': { params: McpOauthCallbackParams; result: McpOauthCallbackResult }
  /** Cancel a flow owned by the resolved profile, waking its callback worker. */
  'mcp.servers.oauth.cancel': { params: McpOauthFlowParams; result: McpOauthCancelResult }
  /** Poll a flow; approved persists tokens for the profile and returns the probed tools. */
  'mcp.servers.oauth.poll': { params: McpOauthFlowParams; result: McpOauthPollResult }
  /** Begin a PKCE OAuth flow; the client opens auth_url and polls mcp.servers.oauth.poll. */
  'mcp.servers.oauth.start': { params: McpOauthStartParams; result: McpOauthStartResult }
  /** Drop a server from the profile's config.yaml. */
  'mcp.servers.remove': { params: McpServerNameParams; result: McpServersRemoveResult }
  /** Store a credential in the profile's .env and reference it from the server config (header or env). */
  'mcp.servers.set_api_key': { params: McpServersSetApiKeyParams; result: McpServersSetApiKeyResult }
  /** Cached runtime state per configured server; never connects, probes, or starts auth. */
  'mcp.servers.status': { params: ProfileParams; result: McpServersStatusResult }
  /** Connect, list tools, disconnect — an OAuth server with no token on disk is reported as not ok. */
  'mcp.servers.test': { params: McpServerNameParams; result: McpServersTestResult }
  /** Set/clear one author's emoji reaction on a message; returns the row's full reaction list. */
  'message.react': { params: MessageReactParams; result: MessageReactResult }
  /** Remove every credential (env keys and OAuth state) for a provider. */
  'model.disconnect': { params: ModelDisconnectParams; result: ModelDisconnectResult }
  /** Provider/model inventory for the picker, layered over the session's live provider when given. */
  'model.options': { params: ModelOptionsParams; result: ModelOptionsResult }
  /** Save an API key for a provider and return its refreshed inventory row. */
  'model.save_key': { params: ModelSaveKeyParams; result: ModelSaveKeyResult }
  /** Create-or-read the backend-owned setup profile; the backend picks the name and finds it by role. */
  'onboarding.ensure_setup_profile': { params: Params; result: OnboardingEnsureSetupProfileResult }
  /** Restore the setup profile to its created state in place (soul, memories, skills, sessions). */
  'onboarding.reset_setup_profile': { params: Params; result: OnboardingResetSetupProfileResult }
  /** Spill a large paste to a file and hand back the inline placeholder. */
  'paste.collapse': { params: PasteCollapseParams; result: PasteCollapseResult }
  /** Render a PDF's pages to PNG and queue them as images for the next turn. */
  'pdf.attach': { params: PdfAttachParams; result: PdfAttachResult }
  /** Stop an in-flight pet generate/hatch by token (idempotent). */
  'pet.cancel': { params: PetCancelParams; result: PetCancelResult }
  /** Half-block cell frames (or a kitty placement) for one pet state. */
  'pet.cells': { params: PetCellsParams; result: PetCellsResult }
  /** Turn the pet display off from the desktop picker. */
  'pet.disable': { params: ProfileParams; result: OkResult }
  /** Export an installed pet as a re-importable .zip. */
  'pet.export': { params: PetSlugParams; result: PetExportResult }
  /** Petdex gallery + local install state (installed-only offline); localOnly skips the remote manifest. */
  'pet.gallery': { params: PetGalleryParams; result: PetGalleryResult }
  /** Candidate base looks for a new pet (draft step); drafts also stream via pet.generate.progress. */
  'pet.generate': { params: PetGenerateParams; result: PetGenerateResult }
  /** Whether pet generation is possible (a reference-capable image backend) and which providers. */
  'pet.generate.status': { params: ProfileParams; result: PetGenerateStatusResult }
  /** Turn a base draft into a full spritesheet pet; progress streams via pet.hatch.progress. */
  'pet.hatch': { params: PetHatchParams; result: PetHatchResult }
  /** Active pet for sprite renderers: spritesheet (base64) + frame geometry + state-row taxonomy. */
  'pet.info': { params: PetInfoParams; result: PetInfoResult }
  /** Cheap active-pet metadata used to avoid full payload refreshes. */
  'pet.info.meta': { params: ProfileParams; result: PetInfoMetaResult }
  /** Uninstall a pet (delete its directory); if it was active, turn the display off. */
  'pet.remove': { params: PetSlugParams; result: PetSlugResult }
  /** Rename a pet's display name + realign its slug/dir; follows the active slug in config. */
  'pet.rename': { params: PetRenameParams; result: PetSlugResult }
  /** Persist display.pet.scale (clamped to engine bounds) from the desktop slider. */
  'pet.scale': { params: PetScaleParams; result: PetScaleResult }
  /** Adopt a pet: install (if needed) + activate; writes display.pet.* to config. */
  'pet.select': { params: PetSlugParams; result: PetSlugResult }
  /** Idle-frame PNG data URI for the picker (desktop CSP breaks CDN <img>). */
  'pet.thumb': { params: PetThumbParams; result: PetThumbResult }
  /** Cheapest liveness probe; answered on the WS reader thread even while every agent is mid-turn. */
  ping: { params: PingParams; result: PingResult }
  /** Loaded plugin manager entries (legacy flat view); the Plugins Hub uses plugins.manage list. */
  'plugins.list': { params: PluginsListParams; result: PluginsListResult }
  /** Plugins Hub backend: list installed plugins, toggle, git-install, re-pin a catalog install, or remove a user install. */
  'plugins.manage': { params: PluginsManageParams; result: PluginsManageResult }
  /** Spawn a hidden agent that brings the desktop preview's dev server back up. */
  'preview.restart': { params: PreviewRestartParams; result: TaskIdResult }
  /** Kill one background process the caller's session owns and return its output snapshot. */
  'process.kill': { params: ProcessKillParams; result: ProcessKillResult }
  /** Background processes owned by the caller's session (desktop status stack poll). */
  'process.list': { params: ProcessListParams; result: ProcessListResult }
  /** Kill every background process in the registry (``/stop``), answering the count killed. */
  'process.stop': { params: ProcessStopParams; result: ProcessStopResult }
  /** Editor Save: apply any subset of a profile's sections and report each one. */
  'profiles.configure': { params: ProfilesConfigureParams; result: ProfilesConfigureResult }
  /** Create a profile (ws twin of POST /api/profiles), mirroring launch credentials by default. */
  'profiles.create': { params: ProfilesCreateParams; result: ProfilesCreateResult }
  /** Everything the profile editor shows: soul, model pin, skills, toolsets, MCP servers. */
  'profiles.describe': { params: ProfileNameParams; result: ProfilesDescribeResult }
  /** A profile asset as a data URL. */
  'profiles.get_asset': { params: ProfilesGetAssetParams; result: ProfilesGetAssetResult }
  /** Roster of profiles with previews so a client paints without N follow-up calls. */
  'profiles.list': { params: ProfilesListParams; result: ProfilesListResult }
  /** Write the onboarding facts into the default profile's user memory and confirm they landed. */
  'profiles.remember_onboarding': { params: ProfilesRememberOnboardingParams; result: ProfilesRememberOnboardingResult }
  /** Store or clear a profile asset (avatar) atomically. */
  'profiles.set_asset': { params: ProfilesSetAssetParams; result: ProfilesSetAssetResult }
  /** Structured project facts for a cwd so UIs don't re-sniff the workspace. */
  'project.facts': { params: ProjectFactsParams; result: ProjectFactsResult }
  /** Attach a folder to a project (optionally as its primary path). */
  'projects.add_folder': { params: ProjectsAddFolderParams; result: ProjectResult }
  /** Archive (or with ``restore`` un-archive) a project; answers the full listing. */
  'projects.archive': { params: ProjectsArchiveParams; result: ProjectsPayload }
  /** Create a project from a name + folders; duplicate primary paths are refused (5063). */
  'projects.create': { params: ProjectsCreateParams; result: OptionalProjectResult }
  /** Delete a project and its folders; answers the full listing. */
  'projects.delete': { params: ProjectIdParams; result: ProjectsPayload }
  /** Repos for the desktop overview: scanned-from-disk (cached) ∪ session-derived. */
  'projects.discover_repos': { params: ProjectsDiscoverReposParams; result: ProjectsDiscoverReposResult }
  /** Which project (if any) owns a directory, plus the resolved cwd and its git branch. */
  'projects.for_cwd': { params: ProjectsForCwdParams; result: ProjectsForCwdResult }
  /** One stored project with its folders. */
  'projects.get': { params: ProjectIdParams; result: ProjectResult }
  /** Every project of the profile (archived included) plus which one is active. */
  'projects.list': { params: ProfileParams; result: ProjectsPayload }
  /** Fully hydrated lanes for one project, from the same grouping as projects.tree. */
  'projects.project_sessions': { params: ProjectsProjectSessionsParams; result: ProjectsProjectSessionsResult }
  /** Persist repo roots found by the client's (desktop-side) scan; return the merged list. */
  'projects.record_repos': { params: ProjectsRecordReposParams; result: ProjectsRecordReposResult }
  /** Detach a folder from a project. */
  'projects.remove_folder': { params: ProjectFolderParams; result: ProjectResult }
  /** Switch (or clear) the active project for the profile. */
  'projects.set_active': { params: ProjectsSetActiveParams; result: ActiveIdResult }
  /** Make one attached folder the project's primary path. */
  'projects.set_primary': { params: ProjectFolderParams; result: ProjectResult }
  /** Project → repo → lane overview with counts and a few preview sessions per project. */
  'projects.tree': { params: ProjectsTreeParams; result: ProjectsTreeResult }
  /** Patch a project's display fields; answers the refreshed project. */
  'projects.update': { params: ProjectsUpdateParams; result: ProjectResult }
  /** Run a task on a fresh agent in the background; the answer arrives as background.complete. */
  'prompt.background': { params: SideAgentParams; result: TaskIdResult }
  /** Side question over a snapshot of the live conversation; the answer arrives as btw.complete. */
  'prompt.btw': { params: SideAgentParams; result: TaskIdResult }
  /** Send a user turn to a live session; busy sessions queue / steer / redirect instead of refusing. */
  'prompt.submit': { params: PromptSubmitParams; result: PromptSubmitResult }
  /** Re-read ~/.hermes/.env (CLI /reload parity); built agents keep their pool until /new. */
  'reload.env': { params: ReloadEnvParams; result: ReloadEnvResult }
  /** Tear down and rediscover MCP servers for every live session (prompt cache is invalidated). */
  'reload.mcp': { params: ReloadMcpParams; result: ReloadMcpResult }
  /** Answer an open server→client request from a client that never received the frame. */
  'request.answer': { params: RequestAnswerParams; result: RequestAnswerResult }
  /** Diff between a checkpoint and the working tree, with an ANSI rendering sized to the TUI. */
  'rollback.diff': { params: RollbackDiffParams; result: RollbackDiffResult }
  /** Checkpoints for the session's cwd; ``enabled: false`` when checkpointing is off. */
  'rollback.list': { params: RollbackListParams; result: RollbackListResult }
  /** Restore the working tree (or one file) to a checkpoint by hash or 1-based index. */
  'rollback.restore': { params: RollbackRestoreParams; result: RollbackRestoreResult }
  /** Attach the frontend to a live session without closing the previously focused one. */
  'session.activate': { params: SessionActivateParams; result: SessionActivateResult }
  /** Live sessions in this process, insertion order (not a DB browser). */
  'session.active_list': { params: SessionActiveListParams; result: SessionActiveListResult }
  /** Fork a live session into a new stored child that shares the parent's history so far. */
  'session.branch': { params: SessionBranchParams; result: SessionBranchResult }
  /** Tear down a live session (its stored row stays resumable). */
  'session.close': { params: SessionCloseParams; result: SessionCloseResult }
  /** Manual /compress of an idle session, optionally focused on a topic. */
  'session.compress': { params: SessionCompressParams; result: SessionCompressResult }
  /** Cursor-style split of the context window by category. */
  'session.context_breakdown': { params: SessionContextBreakdownParams; result: SessionContextBreakdownResult }
  /** Run one allowlisted goal / loop / subgoal / heartbeat action and return the exact resulting snapshot. */
  'session.control': { params: SessionControlParams; result: SessionControlResult }
  /** Stable, allowlisted snapshot of one live session's goal / loop / heartbeat state. */
  'session.control.read': { params: SessionControlReadParams; result: SessionControlReadResult }
  /** Mint a live session (agent builds after the reply); a DB row appears on the first prompt unless seeded. */
  'session.create': { params: SessionCreateParams; result: SessionCreateResult }
  /** Change a live, idle session's working directory. */
  'session.cwd.set': { params: SessionCwdSetParams; result: SessionCwdSetResult }
  /** Delete a stored session + transcripts; refused while it is live here. */
  'session.delete': { params: SessionDeleteParams; result: SessionDeleteResult }
  /** Replay events after a seq watermark on WS reconnect; truncated means refetch state. */
  'session.events.since': { params: SessionEventsSinceParams; result: SessionEventsSinceResult }
  /** Replay-buffer occupancy telemetry (ops/debug). */
  'session.events.stats': { params: SessionEventsStatsParams; result: SessionEventsStatsResult }
  /** Import a foreign session into this profile's history (idempotent per origin). */
  'session.foreign.import': { params: SessionForeignIdParams; result: SessionForeignImportResult }
  /** One page of Claude Code / Codex sessions found on the serving backend. */
  'session.foreign.list': { params: SessionForeignListParams; result: SessionForeignListResult }
  /** Preview a foreign session's tail before importing it. */
  'session.foreign.preview': { params: SessionForeignIdParams; result: SessionForeignPreviewResult }
  /** The durable display transcript (ancestors included, row ids attached). */
  'session.history': { params: SessionHistoryParams; result: SessionHistoryResult }
  /** Stop the running turn (and streaming TTS); retires the crash-recovery marker. */
  'session.interrupt': { params: SessionInterruptParams; result: SessionInterruptResult }
  /** Human-facing stored sessions, most recent first (sub-agent / kanban sources denied). */
  'session.list': { params: SessionListParams; result: SessionListResult }
  /** Most recent human-facing session; errors fold into a null session_id. */
  'session.most_recent': { params: SessionMostRecentParams; result: SessionMostRecentResult }
  /** Redirect the active turn (queued for the next turn while the agent is still building). */
  'session.redirect': { params: SessionCorrectionParams; result: SessionCorrectionResult }
  /** Attach to a stored session: reuse it if live here, else lazy / deferred / cold / eager rebuild. */
  'session.resume': { params: SessionResumeParams; result: SessionResumeResult }
  /** Export the transcript to ~/.hermes/sessions/saved (classic /save). */
  'session.save': { params: SessionSaveParams; result: SessionSaveResult }
  /** Set/clear hidden (out of the default list, still resumable by its owner) on a session + lineage. */
  'session.set_hidden': { params: SessionSetHiddenParams; result: SessionSetHiddenResult }
  /** Rendered /status text for the session. */
  'session.status': { params: SessionStatusParams; result: SessionStatusResult }
  /** Inject text into the next tool result without interrupting the turn. */
  'session.steer': { params: SessionCorrectionParams; result: SessionCorrectionResult }
  /** Read or set a live session's title; a title set before the row exists is queued. */
  'session.title': { params: SessionTitleParams; result: SessionTitleResult }
  /** Drop the last user turn (and everything after it) from an idle session. */
  'session.undo': { params: SessionUndoParams; result: SessionUndoResult }
  /** Token / context / cost counters for the session (+ Nous credit lines when available). */
  'session.usage': { params: SessionUsageParams; result: SessionUsageResult }
  /** Re-home a stored session's workspace; git identity is replaced and a live agent follows. */
  'session.workspace.move': { params: SessionWorkspaceMoveParams; result: SessionWorkspaceMoveResult }
  /** Strict provider check through the same runtime resolution the agent uses on session creation. */
  'setup.runtime_check': { params: SetupRuntimeCheckParams; result: SetupRuntimeCheckResult }
  /** Loose provider check: is ANY provider auth state discoverable for the (launch or named) profile. */
  'setup.status': { params: ProfileParams; result: SetupStatusResult }
  /** Run a safe (non-dangerous) shell command captured for ``!cmd`` / inline substitution. */
  'shell.exec': { params: ShellExecParams; result: ShellExecResult }
  /** Skills hub backend: list the profile's skills or search / browse / inspect / install from the hub. */
  'skills.manage': { params: SkillsManageParams; result: SkillsManageResult }
  /** Re-scan skill dirs; the pre-rendered ``output`` is what /reload-skills prints. */
  'skills.reload': { params: SkillsReloadParams; result: SkillsReloadResult }
  /** Execute a slash command against the session's slash worker (or a live/plugin shortcut). */
  'slash.exec': { params: SlashExecParams; result: SlashExecResult }
  /** Saved spawn-tree snapshots, newest first. */
  'spawn_tree.list': { params: SpawnTreeListParams; result: SpawnTreeListResult }
  /** Read one saved spawn-tree snapshot (path must be under the spawn-trees root). */
  'spawn_tree.load': { params: SpawnTreeLoadParams; result: SpawnTreeLoadResult }
  /** Persist a finished delegation tree snapshot under the session's spawn-trees dir. */
  'spawn_tree.save': { params: SpawnTreeSaveParams; result: SpawnTreeSaveResult }
  /** Hard-interrupt one owned child; ``found`` is false when it already finished. */
  'subagent.interrupt': { params: SubagentIdParams; result: SubagentInterruptResult }
  /** Live children owned by this session (other sessions' children never leak). */
  'subagent.list': { params: SessionParams; result: SubagentListResult }
  /** Queue steering text into a live delegated child owned by this session. */
  'subagent.steer': { params: SubagentSteerParams; result: SubagentSteerResult }
  /** Last 16KB of an owned child's live transcript. */
  'subagent.tail': { params: SubagentIdParams; result: SubagentTailResult }
  /** Schedule a downgrade / same-price change or a period-end cancellation. */
  'subscription.change': { params: SubscriptionChangeParams; result: BillingPendingChangeResult }
  /** Chargeless quote of what a plan change would do (billing:manage). */
  'subscription.preview': { params: SubscriptionPreviewParams; result: SubscriptionPreviewResult }
  /** Clear a scheduled downgrade / cancellation (re-enables recurring spend). */
  'subscription.resume': { params: ProfileParams; result: BillingPendingChangeResult }
  /** Current plan, tier catalog and usage for the picker; fail-open when logged out. */
  'subscription.state': { params: ProfileParams; result: SubscriptionStateResult }
  /** Prorate, charge and flip the plan (billing:manage, idempotent). */
  'subscription.upgrade': { params: SubscriptionUpgradeParams; result: SubscriptionUpgradeResult }
  /** Host battery for the status bar; always resolves, ``available: false`` when unreadable. */
  'system.battery': { params: SystemBatteryParams; result: SystemBatteryResult }
  /** Record the client's column width for server-side rendering. */
  'terminal.resize': { params: TerminalResizeParams; result: TerminalResizeResult }
  /** Persist a toolset / MCP enable-disable change and rebuild the session agent so it takes effect now. */
  'tools.configure': { params: ToolsConfigureParams; result: ToolsConfigureResult }
  /** Every toolset with its resolved tool names, flagged against the session's (or config's) enabled set. */
  'tools.list': { params: _SessionScoped; result: ToolsetsListResult }
  /** The /tools listing grouped by toolset, including tools deferred behind the tool_search bridge. */
  'tools.show': { params: _SessionScoped; result: ToolsShowResult }
  /** Toolset summaries (no tool names) for the desktop Toolsets tab. */
  'toolsets.list': { params: _SessionScoped; result: ToolsetsListResult }
  /** Two-bar dollar usage view shared by /usage, /topup and /subscription; fail-open to unavailable. */
  'usage.bars': { params: ProfileParams; result: UsageModel }
  /** Add a login / payment / address item to the local vault. */
  'vault.add': { params: VaultAddParams; result: VaultAddResult }
  /** Metadata-only listing across the local vault and every unlocked password manager. */
  'vault.list': { params: ProfileParams; result: VaultListResult }
  /** Forget a manager's session token (every manager when no name is given). */
  'vault.lock': { params: VaultLockParams; result: VaultLockResult }
  /** Remove a local vault item by id. */
  'vault.remove': { params: VaultRemoveParams; result: VaultRemoveResult }
  /** Enable or disable an external password manager (disabling also locks it). */
  'vault.source.set': { params: VaultSourceSetParams; result: VaultSourceSetResult }
  /** Status of every login source (local vault + detected password managers). */
  'vault.sources': { params: ProfileParams; result: VaultSourcesResult }
  /** Unlock a password manager for this session with its master password. */
  'vault.unlock': { params: VaultUnlockParams; result: VaultUnlockResult }
  /** Best known verification evidence for a cwd/session; read-only, never runs checks. */
  'verification.status': { params: VerificationStatusParams; result: VerificationStatusResult }
  /** VAD-bounded push-to-talk; the transcript arrives as a voice.transcript event. */
  'voice.record': { params: VoiceRecordParams; result: VoiceRecordResult }
  /** /voice parity: report, flip voice mode on/off, or toggle speech output. */
  'voice.toggle': { params: VoiceToggleParams; result: VoiceToggleResult }
  /** Speak text through the backend TTS engine (barge-in aware). */
  'voice.tts': { params: VoiceTtsParams; result: VoiceTtsResult }
  /** Push client-captured PCM into the armed detector (mic-less remote backends). */
  'wake.feed': { params: WakeFeedParams; result: WakeFeedResult }
  /** Release the mic (e.g. while the desktop's browser captures audio). */
  'wake.pause': { params: WakeControlParams; result: WakePauseResult }
  /** Reclaim the mic after a pause; no-op if the listener isn't armed. */
  'wake.resume': { params: WakeControlParams; result: WakeResumeResult }
  /** Arm the wake-word listener for the calling surface; refusals explain why. */
  'wake.start': { params: WakeStartParams; result: WakeStartResult }
  /** Everything a client needs to draw the wake-word state and decide whether to (re)arm. */
  'wake.status': { params: WakeStatusParams; result: WakeStatusResult }
  /** Stop this surface's listener; persist also writes wake_word.enabled: false. */
  'wake.stop': { params: WakeStopParams; result: WakeStopResult }
}
export type RpcMethod = keyof RpcMethods
export const RPC_METHODS = [
  'agents.list',
  'approval.pending',
  'approval.received',
  'approval.respond',
  'billing.auto_reload',
  'billing.charge',
  'billing.charge_status',
  'billing.state',
  'billing.step_up',
  'bot_relay.deliver',
  'bot_relay.outbox.drain',
  'bot_relay.reply',
  'bot_relay.roster.sync',
  'browser.controller.detach',
  'browser.controller.heartbeat',
  'browser.controller.register',
  'browser.controller.result',
  'browser.manage',
  'clarify.lock',
  'cli.exec',
  'client.capabilities',
  'clipboard.paste',
  'command.dispatch',
  'command.resolve',
  'commands.catalog',
  'complete.path',
  'complete.slash',
  'config.get',
  'config.set',
  'config.show',
  'connection.respond',
  'connectors.accounts',
  'connectors.accounts.remove',
  'connectors.catalog',
  'connectors.connect',
  'connectors.list',
  'connectors.operation.status',
  'connectors.operation.wake',
  'connectors.policy.get',
  'connectors.policy.set',
  'connectors.tools',
  'cron.manage',
  'delegation.pause',
  'delegation.status',
  'diagnostics.share_nous',
  'file.attach',
  'free_tier.ack_notice',
  'free_tier.provision',
  'free_tier.status',
  'gateway.capabilities',
  'groups.approve',
  'groups.capabilities',
  'groups.create',
  'groups.demote',
  'groups.disband',
  'groups.list',
  'groups.log',
  'groups.peer.invite',
  'groups.peer.register',
  'groups.peer.revoke',
  'groups.promote',
  'groups.rename',
  'groups.replica_state',
  'groups.replicate',
  'groups.retry',
  'groups.send',
  'groups.state',
  'groups.stop',
  'handoff.fail',
  'handoff.request',
  'handoff.state',
  'image.attach',
  'image.attach_bytes',
  'image.detach',
  'image.generate',
  'input.detect_drop',
  'insights.get',
  'learning.delete',
  'learning.detail',
  'learning.edit',
  'learning.frames',
  'llm.oneshot',
  'mcp.catalog',
  'mcp.servers.add',
  'mcp.servers.list',
  'mcp.servers.oauth.callback',
  'mcp.servers.oauth.cancel',
  'mcp.servers.oauth.poll',
  'mcp.servers.oauth.start',
  'mcp.servers.remove',
  'mcp.servers.set_api_key',
  'mcp.servers.status',
  'mcp.servers.test',
  'message.react',
  'model.disconnect',
  'model.options',
  'model.save_key',
  'onboarding.ensure_setup_profile',
  'onboarding.reset_setup_profile',
  'paste.collapse',
  'pdf.attach',
  'pet.cancel',
  'pet.cells',
  'pet.disable',
  'pet.export',
  'pet.gallery',
  'pet.generate',
  'pet.generate.status',
  'pet.hatch',
  'pet.info',
  'pet.info.meta',
  'pet.remove',
  'pet.rename',
  'pet.scale',
  'pet.select',
  'pet.thumb',
  'ping',
  'plugins.list',
  'plugins.manage',
  'preview.restart',
  'process.kill',
  'process.list',
  'process.stop',
  'profiles.configure',
  'profiles.create',
  'profiles.describe',
  'profiles.get_asset',
  'profiles.list',
  'profiles.remember_onboarding',
  'profiles.set_asset',
  'project.facts',
  'projects.add_folder',
  'projects.archive',
  'projects.create',
  'projects.delete',
  'projects.discover_repos',
  'projects.for_cwd',
  'projects.get',
  'projects.list',
  'projects.project_sessions',
  'projects.record_repos',
  'projects.remove_folder',
  'projects.set_active',
  'projects.set_primary',
  'projects.tree',
  'projects.update',
  'prompt.background',
  'prompt.btw',
  'prompt.submit',
  'reload.env',
  'reload.mcp',
  'request.answer',
  'rollback.diff',
  'rollback.list',
  'rollback.restore',
  'session.activate',
  'session.active_list',
  'session.branch',
  'session.close',
  'session.compress',
  'session.context_breakdown',
  'session.control',
  'session.control.read',
  'session.create',
  'session.cwd.set',
  'session.delete',
  'session.events.since',
  'session.events.stats',
  'session.foreign.import',
  'session.foreign.list',
  'session.foreign.preview',
  'session.history',
  'session.interrupt',
  'session.list',
  'session.most_recent',
  'session.redirect',
  'session.resume',
  'session.save',
  'session.set_hidden',
  'session.status',
  'session.steer',
  'session.title',
  'session.undo',
  'session.usage',
  'session.workspace.move',
  'setup.runtime_check',
  'setup.status',
  'shell.exec',
  'skills.manage',
  'skills.reload',
  'slash.exec',
  'spawn_tree.list',
  'spawn_tree.load',
  'spawn_tree.save',
  'subagent.interrupt',
  'subagent.list',
  'subagent.steer',
  'subagent.tail',
  'subscription.change',
  'subscription.preview',
  'subscription.resume',
  'subscription.state',
  'subscription.upgrade',
  'system.battery',
  'terminal.resize',
  'tools.configure',
  'tools.list',
  'tools.show',
  'toolsets.list',
  'usage.bars',
  'vault.add',
  'vault.list',
  'vault.lock',
  'vault.remove',
  'vault.source.set',
  'vault.sources',
  'vault.unlock',
  'verification.status',
  'voice.record',
  'voice.toggle',
  'voice.tts',
  'wake.feed',
  'wake.pause',
  'wake.resume',
  'wake.start',
  'wake.status',
  'wake.stop'
] as const satisfies readonly RpcMethod[]

// ── Server→client requests ──
export interface ServerRequestMap {
  /** A dangerous command awaits the user's decision. */
  approval: { params: ApprovalRequestParams; result: ApprovalResult }
  /** The clarify tool: ask the user one question or a batch. */
  clarify: { params: ClarifyRequestParams; result: ClarifyResult }
  /** Click / type / scroll / annotate inside the in-app browser preview. */
  'preview.act': { params: PreviewActRequestParams; result: ValueResult }
  /** Read the in-app browser preview's text (JSON text answer). */
  'preview.read': { params: ReadRangeRequestParams; result: ValueResult }
  /** Masked value for a named env var (skills / setup flows). */
  secret: { params: SecretRequestParams; result: ValueResult }
  /** Masked sudo password for the terminal tool. */
  sudo: { params: SudoRequestParams; result: ValueResult }
  /** Read the visible in-app terminal buffer (JSON text answer). */
  'terminal.read': { params: ReadRangeRequestParams; result: ValueResult }
  /** Drive a guided tour highlight in the desktop renderer. */
  tour: { params: TourRequestParams; result: ValueResult }
  /** A one-time / 2FA code the user reads from their device. */
  'vault.code': { params: VaultCodeRequestParams; result: ValueResult }
  /** Save a login for a site the agent is about to fill; the answer is JSON {identifier, password}. */
  'vault.save_login': { params: VaultSaveLoginRequestParams; result: ValueResult }
  /** Master password to unlock an external password manager for this session. */
  'vault.unlock_prompt': { params: VaultUnlockRequestParams; result: ValueResult }
  /** Enumerate the native window below the app (JSON text answer). */
  'window.read': { params: EmptyRequestParams; result: ValueResult }
}
export type ServerRequestMethod = keyof ServerRequestMap
export const SERVER_REQUEST_METHODS = [
  'approval',
  'clarify',
  'preview.act',
  'preview.read',
  'secret',
  'sudo',
  'terminal.read',
  'tour',
  'vault.code',
  'vault.save_login',
  'vault.unlock_prompt',
  'window.read'
] as const satisfies readonly ServerRequestMethod[]

// ── Notifications (`event` frames) ──
export interface BackendGatewayEventMap {
  /** Output chunk from an agent-owned background process. */
  'agent.terminal.output': TerminalOutputPayload
  /** A /background side agent finished. */
  'background.complete': SideAgentCompletePayload
  /** Device-flow URL + code for the billing scope step-up; the client opens the browser. */
  'billing.step_up.verification': BillingStepUpVerificationPayload
  /** A bot-relay outbox envelope is queued; drain it. */
  'bot_relay.outbox.pending': ChangeSignalPayload
  /** Withdraw a pending controller command. */
  'browser.controller.cancel': BrowserControllerCancelPayload
  /** Dispatch one browser action to the attached controller. */
  'browser.controller.command': BrowserControllerCommandPayload
  /** Browser (CDP) connect / install progress line. */
  'browser.progress': BrowserProgressPayload
  /** A /btw side question was answered. */
  'btw.complete': SideAgentCompletePayload
  /** A connection operation opened on this session; the desktop renders its card. */
  'connection.request': ConnectionRequestPayload
  /** One transition or the settlement of an open connection operation. */
  'connection.update': ConnectionUpdatePayload
  /** cron/jobs.json moved; refetch the cron list. */
  'cron.changed': ChangeSignalPayload
  /** A session-level failure outside a turn (agent init, model switch, compression, resume). */
  error: ErrorPayload
  /** First frame of a connection: the resolved skin, the change-event capability and the replay epoch. */
  'gateway.ready': GatewayReadyPayload
  /** Apply a named desktop layout preset. */
  'layout.apply': LayoutApplyPayload
  /** The turn ended: final text, usage and outcome. */
  'message.complete': MessageCompletePayload
  /** One streamed chunk of the assistant reply. */
  'message.delta': StreamDeltaPayload
  /** Interim assistant commentary (text beside tool calls) sealed as its own segment. */
  'message.interim': MessageInterimPayload
  /** The agent reacted to a message; paint it live. */
  'message.reaction': MessageReactionPayload
  /** A turn began streaming; no payload. */
  'message.start': Record<string, never>
  /** The MoA aggregator started. */
  'moa.aggregating': MoaAggregatingPayload
  /** MoA phase transition (currently only ``aggregator``). */
  'moa.phase': MoaPhasePayload
  /** MoA reference fan-out progress (n/total). */
  'moa.progress': MoaProgressPayload
  /** One MoA reference model's output. */
  'moa.reference': MoaReferencePayload
  /** Informational one-liner for the session (capabilities refreshed). */
  notice: NoticePayload
  /** Withdraw the notice with this key. */
  'notification.clear': NotificationClearPayload
  /** Show / replace a keyed out-of-band notice (toast or status bar). */
  'notification.show': NotificationShowPayload
  /** Pairing state moved; refetch pairing. */
  'pairing.changed': ChangeSignalPayload
  /** Focus / reveal a named desktop pane. */
  'pane.reveal': PaneRevealPayload
  /** The active pet / its spritesheet changed (watcher). */
  'pet.changed': PetChangedPayload
  /** Pet base-draft generation progress. */
  'pet.generate.progress': PetGenerateProgressPayload
  /** Pet hatch (row drawing) progress. */
  'pet.hatch.progress': PetHatchProgressPayload
  /** gateway_state.json moved; refetch platform status. */
  'platforms.changed': ChangeSignalPayload
  /** Close the preview pane or one tab. */
  'preview.close': PreviewClosePayload
  /** Open a URL / file in the desktop preview pane. */
  'preview.open': PreviewOpenPayload
  /** The hidden preview-restart agent finished. */
  'preview.restart.complete': SideAgentCompletePayload
  /** Progress line from the preview-restart agent. */
  'preview.restart.progress': PreviewRestartProgressPayload
  /** Affection reaction detected in the user's message (hearts etc.). */
  reaction: ReactionPayload
  /** A completed reasoning block (non-streaming providers). */
  'reasoning.available': StreamDeltaPayload
  /** One streamed chunk of the model's reasoning. */
  'reasoning.delta': StreamDeltaPayload
  /** The backend withdrew an open server→client request; clear the matching card only. */
  'request.cancel': RequestCancelPayload
  /** Background review of the last turn finished. */
  'review.summary': ReviewSummaryPayload
  /** Persisted goal / loop / heartbeat state changed. */
  'session.control.update': SessionControlUpdatePayload
  /** Live session settings snapshot (``server._session_info``); also the ``info`` of create/resume/activate. */
  'session.info': SessionLiveInfo
  /** The backend reclaimed a live session out from under its clients. */
  'session.reclaimed': SessionReclaimedPayload
  /** Deferred resume hydration progress. */
  'session.resume_progress': SessionResumeProgressPayload
  /** Auto-titling renamed the session (``session_id`` is the stored key). */
  'session.title': SessionTitlePayload
  /** Mid-turn usage tick; message.complete carries the authoritative final usage. */
  'session.usage': SessionUsagePayload
  /** state.db moved; refetch the session list. */
  'sessions.changed': ChangeSignalPayload
  /** The free-tier bootstrap finished (broadcast); the desktop's setup gate reads the record. */
  'setup.ready': SetupReadyPayload
  /** The active skin moved (name switch or live colour edit); repaint from this palette. */
  'skin.changed': SkinPayload
  /** Transient status line (kind: status, lifecycle, compacting, goal, loop, heartbeat, process, …). */
  'status.update': StatusUpdatePayload
  /** A child finished (status + observability rollup). */
  'subagent.complete': SubagentEventPayload
  /** Batched tool-name progress from a child. */
  'subagent.progress': SubagentEventPayload
  /** delegate_task accepted a child goal (before the child starts). */
  'subagent.spawn_requested': SubagentEventPayload
  /** A delegated child started running. */
  'subagent.start': SubagentEventPayload
  /** A child's reasoning chunk. */
  'subagent.thinking': SubagentEventPayload
  /** A child called a tool. */
  'subagent.tool': SubagentEventPayload
  /** An agent-owned background process closed. */
  'terminal.close': TerminalClosePayload
  /** Legacy thinking-text chunk (thinking_callback). */
  'thinking.delta': StreamDeltaPayload
  /** Point at a desktop element with a one-line tip bubble. */
  'tip.show': TipShowPayload
  /** Full todo snapshot after a todo tool ran. */
  'todo.updated': TodoUpdatedPayload
  /** A tool call finished: parsed result, summary, optional diff / todo snapshot. */
  'tool.complete': ToolCompletePayload
  /** The model is emitting a tool call's arguments. */
  'tool.generating': ToolGeneratingPayload
  /** Tool output was classified as risky (prompt-injection / secret findings). */
  'tool.output_risk': ToolOutputRiskPayload
  /** A tool call began (stable id + full args). */
  'tool.start': ToolStartPayload
  /** Barge-in: the spoken interjection interrupted the turn; no payload. */
  'voice.interrupted': Record<string, never>
  /** Voice recorder state changed. */
  'voice.status': VoiceStatusPayload
  /** A voice capture produced text (or a stop phrase / silence limit). */
  'voice.transcript': VoiceTranscriptPayload
  /** A wake phrase fired. */
  'wake.detected': WakeDetectedPayload
}
export type BackendGatewayEventName = keyof BackendGatewayEventMap
export const GATEWAY_EVENT_TYPES = [
  'agent.terminal.output',
  'background.complete',
  'billing.step_up.verification',
  'bot_relay.outbox.pending',
  'browser.controller.cancel',
  'browser.controller.command',
  'browser.progress',
  'btw.complete',
  'connection.request',
  'connection.update',
  'cron.changed',
  'error',
  'gateway.ready',
  'layout.apply',
  'message.complete',
  'message.delta',
  'message.interim',
  'message.reaction',
  'message.start',
  'moa.aggregating',
  'moa.phase',
  'moa.progress',
  'moa.reference',
  'notice',
  'notification.clear',
  'notification.show',
  'pairing.changed',
  'pane.reveal',
  'pet.changed',
  'pet.generate.progress',
  'pet.hatch.progress',
  'platforms.changed',
  'preview.close',
  'preview.open',
  'preview.restart.complete',
  'preview.restart.progress',
  'reaction',
  'reasoning.available',
  'reasoning.delta',
  'request.cancel',
  'review.summary',
  'session.control.update',
  'session.info',
  'session.reclaimed',
  'session.resume_progress',
  'session.title',
  'session.usage',
  'sessions.changed',
  'setup.ready',
  'skin.changed',
  'status.update',
  'subagent.complete',
  'subagent.progress',
  'subagent.spawn_requested',
  'subagent.start',
  'subagent.thinking',
  'subagent.tool',
  'terminal.close',
  'thinking.delta',
  'tip.show',
  'todo.updated',
  'tool.complete',
  'tool.generating',
  'tool.output_risk',
  'tool.start',
  'voice.interrupted',
  'voice.status',
  'voice.transcript',
  'wake.detected'
] as const satisfies readonly BackendGatewayEventName[]
