hermes-agent / apps /shared /src /gateway-contract.generated.ts
SaylorTwift's picture
SaylorTwift HF Staff
Add files using upload-large-folder tool
f76c374 verified
Raw History Blame Contribute Delete
176 kB
// 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[]
}
export interface ConnectionOperationParams {
profile?: string | null
session_id: string
op_id: string
}
/** ``methods_connectors._operation_view``: the operation's full snapshot. */
export interface ConnectionOperationStatus {
op_id: string
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' | 'unavailable'
/** ``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
connect_url?: string | null
attempt?: string | 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' | 'unavailable' | 'not_connected'
export interface ConnectionRespondParams {
profile?: string | null
session_id: string
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. ``status`` is what the card observed for that row (``tools/connectors/mcp.py::_OUTCOME_STATES`` maps it onto a target state); ``state`` is the older spelling of the same field and one of the two is present. */
export interface ConnectionAnswerTarget {
name: string
status?: string | null
state?: string | null
detail?: string | null
tools?: string[] | null
[key: string]: unknown
}
export interface ConnectionRespondResult {
status: string
settled: boolean
}
/** ``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
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 ConnectorsListParams {
profile?: string | null
session_id: string
}
export interface ConnectorsListResult {
available: boolean
connectors: ConnectorRow[]
}
/** One ``manage_connections`` status entry after ``connector_ui_payload`` redaction; the connector service owns the closed key set, so unknown metadata passes through. */
export interface ConnectorRow {
connector?: string
connected?: boolean | null
enabled?: boolean | null
connectionStatus?: string | null
name?: string | null
description?: string | null
[key: string]: unknown
}
export interface ConnectorsConnectParams {
profile?: string | null
session_id: string
connectors: string[]
reconnect?: boolean
}
/** The operation the connect opened (or re-minted on): ``tools/connectors/managed.py`` ``_off_desktop_result`` / ``methods_connectors._reissue``. ``status``/``note`` ride along from the tool result when the call ran through ``manage_connections``. */
export interface ConnectorsConnectResult {
op_id: string
deadline_at: number
settled: boolean
settled_at?: number | null
settled_by?: ConnectionSettleReason | null
targets: ConnectionOperationTarget[]
status?: string | null
note?: 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 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
}
/** ``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
}
export interface CompleteSlashParams {
text?: 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
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
}
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[]
}
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
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
reasoning?: string | null
[key: string]: unknown
}
/** ``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
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
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
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). */
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
}
export interface ContextCategory {
color: string
id: string
label: string
tokens: number
}
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
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
}
export type SkillsReloadParams = Record<string, never>
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
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
}
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
}
export type McpRuntimeStatus = 'connected' | 'disabled' | 'connecting' | 'failed' | '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``. */
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
}
export type PluginsAction = 'list' | 'toggle' | 'install' | 'update'
/** ``list`` → ``plugins`` + counts; ``toggle`` → ``ok``/``unchanged``/``name``/``plugin``; ``install`` → ``hermes_cli.plugins_cmd.dashboard_install_plugin``'s ok payload; ``update`` → ``ok``/``unchanged``/``sha``. */
export interface PluginsManageResult {
plugins?: AgentPluginRow[] | null
user_count?: number | null
bundled_count?: number | null
ok?: boolean | null
unchanged?: boolean | null
name?: string | null
plugin?: AgentPluginRow | null
plugin_name?: string | null
warnings?: string[] | null
missing_env?: string[] | null
after_install_path?: string | null
enabled?: boolean | null
sha?: 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
catalog_name?: string | null
catalog_tier?: string | null
installed_sha?: string | null
catalog_sha?: string | null
update_available?: boolean | null
pinned_sha?: string | null
}
/** 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
deadline_at: number
settled: boolean
settled_at?: number | null
settled_by?: ConnectionSettleReason | null
targets: ConnectionOperationTarget[]
target?: string | null
from?: ConnectionTargetState | null
to?: ConnectionTargetState | null
actor?: ConnectionActor | null
detail?: string | null
}
/** ``tools/connectors/contract.py::Actor``. */
export type ConnectionActor = 'user' | 'renderer_flow' | '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
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). */
export interface ErrorSurface {
layer: string
code: string
retryable: boolean
provider?: string | null
model?: string | 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
}
/** ``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
}
/** ``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
}
// ── 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 }
/** 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 }
/** Start (or re-initiate) authorization for named connectors on the session's connection operation. */
'connectors.connect': { params: ConnectorsConnectParams; result: ConnectorsConnectResult }
/** Connector catalog + connection state for one owned session (``available=False`` when the toolset is off). */
'connectors.list': { params: ConnectorsListParams; result: ConnectorsListResult }
/** The current snapshot of one open operation on an owned session. */
'connectors.operation.status': { params: ConnectionOperationParams; result: ConnectionOperationStatus }
/** 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 }
/** 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 or re-pin a catalog 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',
'clipboard.paste',
'command.dispatch',
'command.resolve',
'commands.catalog',
'complete.path',
'complete.slash',
'config.get',
'config.set',
'config.show',
'connection.respond',
'connectors.connect',
'connectors.list',
'connectors.operation.status',
'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',
'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[]