@spacemolt/lib 15.2.0 → 16.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/COMMANDS.md +11 -6
- package/README.md +8 -4
- package/dist/account.d.ts +23 -23
- package/dist/auth/clerk.d.ts +3 -1
- package/dist/generated/actions.gen.d.ts +2 -2
- package/dist/generated/commands.gen.d.ts +27 -7
- package/dist/generated/notifications.gen.d.ts +4 -3
- package/dist/generated/openapi/types.gen.d.ts +933 -160
- package/dist/index.js +99 -46
- package/dist/index.js.map +33 -0
- package/dist/node.js +26 -0
- package/dist/node.js.map +12 -0
- package/dist/state/observation.d.ts +17 -9
- package/package.json +7 -9
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/generated/frames.gen.ts", "../src/validation.ts", "../src/protocol.ts", "../src/generated/actions.gen.ts", "../src/generated/commands.gen.ts", "../src/auth/clerk.ts", "../src/errors.ts", "../src/events/emitter.ts", "../src/state/market.ts", "../src/state/observation.ts", "../src/jitter.ts", "../src/state/cache.ts", "../src/transport/correlator.ts", "../src/transport/socket.ts", "../src/account.ts", "../src/auth/credentials.ts", "../src/data/http.ts", "../src/data/catalog.ts", "../src/data/map.ts", "../src/data/mobile-base.ts", "../src/data/stations.ts", "../src/client.ts", "../src/generated/notifications.gen.ts", "../src/push-frames.ts"],
|
|
4
|
+
"sourcesContent": [
|
|
5
|
+
"// AUTO-GENERATED by scripts/generate.ts from openapi.json. DO NOT EDIT.\n\n/** Runtime kind of a frame-payload field. */\nexport type FieldKind = 'string' | 'number' | 'boolean' | 'string[]' | 'number[]' | 'boolean[]';\n\n/** A frame-payload field's runtime kind, and whether the server always sends it. */\nexport interface FrameField {\n kind: FieldKind;\n required: boolean;\n}\n\n/** Every field of the server's `WelcomePayload`, with its runtime kind and required-ness. */\nexport const WELCOME_PAYLOAD_FIELDS: Readonly<Record<string, FrameField>> = {\n current_tick: { kind: 'number', required: true },\n game_info: { kind: 'string', required: true },\n help_text: { kind: 'string', required: true },\n motd: { kind: 'string', required: false },\n release_date: { kind: 'string', required: true },\n release_notes: { kind: 'string[]', required: true },\n server_time: { kind: 'number', required: true },\n terms: { kind: 'string', required: true },\n tick_rate: { kind: 'number', required: true },\n version: { kind: 'string', required: true },\n website: { kind: 'string', required: true },\n};\n\n/** Every field of the server's `RegisteredPayload`, with its runtime kind and required-ness. */\nexport const REGISTERED_PAYLOAD_FIELDS: Readonly<Record<string, FrameField>> = {\n password: { kind: 'string', required: true },\n player_id: { kind: 'string', required: true },\n};\n",
|
|
6
|
+
"/** True when a value is a non-null, non-array object with string keys. */\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n/** Require an object at an external-data boundary and include its source in failures. */\nexport function requireRecord(value: unknown, source: string): Record<string, unknown> {\n if (!isRecord(value)) throw new TypeError(`${source} must be a JSON object`);\n return value;\n}\n",
|
|
7
|
+
"/**\n * WebSocket v2 frame envelopes.\n *\n * These are the protocol-level message shapes — the framing layer that is\n * stable across spec versions (see gameserver docs/websocket-v2.md). The\n * per-action payloads and per-notification payloads are generated from the\n * spec instead (see src/generated/). Endpoint: `/ws/v2`.\n */\n\nimport type { NotificationPayloads, TypedNotificationType } from './generated/notifications.gen.ts';\nimport {\n type FieldKind,\n type FrameField,\n REGISTERED_PAYLOAD_FIELDS,\n WELCOME_PAYLOAD_FIELDS,\n} from './generated/frames.gen.ts';\nimport type {\n LoggedInPayload,\n NotificationActionError,\n NotificationActionResult,\n PendingActionResponse,\n RegisteredPayload,\n V2GameState,\n WelcomePayload,\n} from './generated/openapi/types.gen.ts';\nimport { isRecord } from './validation.ts';\n\n/** Inbound frame: client -> server. `payload` is omitted when an action takes none. */\nexport interface InboundFrame {\n tool: string;\n action: string;\n payload?: Record<string, unknown>;\n /** Opaque correlation token, <= 128 bytes. Echoed back on result/outcome frames. */\n request_id?: string;\n}\n\n/** The synchronous query / mutation-ack response. */\nexport interface ResultFrame {\n type: 'result';\n request_id?: string;\n payload: {\n /** Human-readable rendered text (or raw object when no renderer applies). */\n result: unknown;\n /** Raw JSON for programmatic consumption. */\n structuredContent?: Record<string, unknown>;\n };\n}\n\n/** Outcome push for a queued mutation; echoes the original request_id. */\nexport interface ActionResultFrame {\n type: 'action_result';\n request_id?: string;\n /**\n * The server's published `Notification_action_result`, except for `result`:\n * the spec leaves it untyped because the v1 and v2 shapes differ, and on\n * `/ws/v2` it is always the delta. Narrow it here rather than lose the type.\n */\n payload: Omit<NotificationActionResult, 'result'> & {\n /** A V2GameState delta — only the sections that changed. See StateDelta. */\n result: StateDelta;\n };\n}\n\n/** Failure outcome for a queued mutation. */\nexport interface ActionErrorFrame {\n type: 'action_error';\n request_id?: string;\n payload: NotificationActionError;\n}\n\n/** Generic error frame emitted by the framing layer or a handler. */\nexport interface ErrorFrame {\n type: 'error';\n request_id?: string;\n payload: {\n code: string;\n message: string;\n details?: Record<string, unknown>;\n /** Only on `action_pending` errors: names the already-queued mutation. */\n pending_command?: string;\n };\n}\n\n/**\n * Unsolicited frame sent immediately after the socket upgrade. No request_id.\n *\n * The three auth/handshake payloads below are the server's published schemas\n * rather than hand-written mirrors, so a server-side field change breaks\n * `typecheck` here instead of silently rotting a copy (gameserver-todo #2/#5).\n */\nexport interface WelcomeFrame {\n type: 'welcome';\n payload: WelcomePayload;\n}\n\n/** Auth success frame carrying the full initial session state. */\nexport interface LoggedInFrame {\n type: 'logged_in';\n request_id?: string;\n payload: LoggedInPayload;\n}\n\n/**\n * Auth success frame after `register`, carrying generated credentials.\n * `password` is a 256-bit hex credential — this is the only chance to capture it.\n */\nexport interface RegisteredFrame {\n type: 'registered';\n request_id?: string;\n payload: RegisteredPayload;\n}\n\n/**\n * A server-initiated push frame whose msg_type has a published payload schema.\n * Unknown/untyped pushes are delivered as `RawFrame` (see below) until the\n * server types them.\n */\nexport type NotificationFrame = {\n [K in TypedNotificationType]: { type: K; payload: NotificationPayloads[K] };\n}[TypedNotificationType];\n\n/**\n * Any inbound frame as parsed off the wire, before classification. The router\n * narrows this to a specific frame type by `type`. A bare-`string` discriminant\n * is kept out of the typed `OutboundFrame` union so its members narrow cleanly.\n */\nexport interface RawFrame {\n type: string;\n request_id?: string;\n payload?: unknown;\n}\n\nexport type OutboundFrame =\n | ResultFrame\n | ActionResultFrame\n | ActionErrorFrame\n | ErrorFrame\n | WelcomeFrame\n | LoggedInFrame\n | RegisteredFrame\n | NotificationFrame;\n\nfunction hasPayload(frame: RawFrame): frame is RawFrame & { payload: Record<string, unknown> } {\n return isRecord(frame.payload);\n}\n\nexport function isResultFrame(frame: RawFrame): frame is ResultFrame {\n return (\n frame.type === 'result' &&\n hasPayload(frame) &&\n 'result' in frame.payload &&\n (frame.payload.structuredContent === undefined || isRecord(frame.payload.structuredContent))\n );\n}\n\nexport function isActionResultFrame(frame: RawFrame): frame is ActionResultFrame {\n return (\n frame.type === 'action_result' &&\n hasPayload(frame) &&\n typeof frame.payload.command === 'string' &&\n typeof frame.payload.tick === 'number' &&\n isRecord(frame.payload.result) &&\n (frame.payload.auto_docked === undefined || typeof frame.payload.auto_docked === 'boolean') &&\n (frame.payload.auto_undocked === undefined || typeof frame.payload.auto_undocked === 'boolean')\n );\n}\n\nexport function isActionErrorFrame(frame: RawFrame): frame is ActionErrorFrame {\n return (\n frame.type === 'action_error' &&\n hasPayload(frame) &&\n typeof frame.payload.command === 'string' &&\n typeof frame.payload.tick === 'number' &&\n typeof frame.payload.code === 'string' &&\n typeof frame.payload.message === 'string' &&\n (frame.payload.details === undefined || isRecord(frame.payload.details))\n );\n}\n\nexport function isErrorFrame(frame: RawFrame): frame is ErrorFrame {\n return (\n frame.type === 'error' &&\n hasPayload(frame) &&\n typeof frame.payload.code === 'string' &&\n typeof frame.payload.message === 'string' &&\n (frame.payload.details === undefined || isRecord(frame.payload.details)) &&\n (frame.payload.pending_command === undefined || typeof frame.payload.pending_command === 'string')\n );\n}\n\nfunction matchesKind(value: unknown, kind: FieldKind): boolean {\n const element = kind.endsWith('[]') ? kind.slice(0, -2) : undefined;\n if (element) return Array.isArray(value) && value.every((item) => typeof item === element);\n return typeof value === kind;\n}\n\n/**\n * Checks a frame payload against a spec-derived field map (`frames.gen.ts`)\n * rather than a hand-written field list, which drifts the moment the server\n * adds or requires a field. A required field must be present and match. An\n * optional one must match only when it is sent. Shared by every frame guard\n * whose payload has a published schema.\n */\nfunction matchesFields(payload: Record<string, unknown>, fields: Readonly<Record<string, FrameField>>): boolean {\n return Object.entries(fields).every(([field, { kind, required }]) => {\n const value = payload[field];\n if (value === undefined) return !required;\n return matchesKind(value, kind);\n });\n}\n\nexport function isWelcomeFrame(frame: RawFrame): frame is WelcomeFrame {\n return frame.type === 'welcome' && hasPayload(frame) && matchesFields(frame.payload, WELCOME_PAYLOAD_FIELDS);\n}\n\nexport function isLoggedInFrame(frame: RawFrame): frame is LoggedInFrame {\n return frame.type === 'logged_in' && hasPayload(frame);\n}\n\nexport function isRegisteredFrame(frame: RawFrame): frame is RegisteredFrame {\n return frame.type === 'registered' && hasPayload(frame) && matchesFields(frame.payload, REGISTERED_PAYLOAD_FIELDS);\n}\n\n/**\n * The cacheable game-state sections — the nine independently-tracked sections\n * the server emits deltas for. Section shapes are derived from the spec's\n * `V2GameState`, so they stay correct as the spec evolves.\n *\n * The list itself is not spec-derived, so it has to be kept in step by hand:\n * the authority is the `x-state-sections` a mutation operation declares (from\n * the server's `StateSections` bitmask in `internal/handlers/delta_wrapper.go`).\n * A section missing here is silently dropped from every delta, so\n * `tests/generated.test.ts` cross-checks this list against the spec.\n *\n * `V2GameState` carries further keys that are *not* delta sections and so are\n * deliberately absent from the cache — read them off the query response that\n * returns them: `riding` (`get_status`, when riding as a passenger with no ship\n * of your own), `drone_bay` (`get_ship`), `carried_ships`/`bay_used`/\n * `bay_capacity` (`get_cargo`, carriers only), and `version` (`get_status`).\n * Note `fleet/board` and `fleet/disembark` declare no state sections at all, so\n * boarding emits no delta: call `refresh()` after one.\n */\nexport type GameState = Pick<\n V2GameState,\n 'player' | 'ship' | 'modules' | 'cargo' | 'location' | 'missions' | 'queue' | 'skills' | 'prize_recoveries'\n>;\n\n/**\n * A `V2GameState` delta carried on `action_result`. Only changed sections are\n * present; an absent section means unchanged (keep prior local state). Carries\n * the same nine sections as `GameState` plus the per-action convenience fields.\n */\nexport type StateDelta = GameState & Pick<V2GameState, 'message' | 'details' | 'credits'>;\n\n/**\n * Resolved value of a synchronous query command. `T` is the command's specific\n * `structuredContent` shape; the generated command facade binds it per command\n * (e.g. `find_route` → `QueryResult<FindRouteResponse>`), so reads are typed with\n * no cast. Defaults to untyped JSON for the low-level `query`/`send` paths.\n */\nexport interface QueryResult<T = Record<string, unknown>> {\n /** Human-readable rendered text (or raw object when no renderer applies). */\n result: unknown;\n /** Raw JSON for programmatic consumption, typed to the command's response. */\n structuredContent?: T;\n}\n\n/**\n * The immediate `pending: true` acknowledgement for a queued mutation. The\n * server's published `PendingActionResponse`, so the `auto_docked`/\n * `auto_undocked` flags it carries reach the caller at ack time rather than\n * only on the final outcome.\n */\nexport type MutationAck = PendingActionResponse;\n\n/**\n * Resolved value of a two-phase mutation, delivered when the action executes.\n * `TDetails` is the action-specific shape of `delta.details` (e.g. `jump` ->\n * `MutationResult<JumpResponse>`); the generated command facade binds it per\n * command, so reads are typed with no cast. The rest of `delta` (the state\n * sections that changed) is the same generic shape for every mutation — only\n * `details` is action-specific. Defaults to untyped JSON for the low-level\n * `mutate`/`send` paths.\n */\nexport interface MutationResult<TDetails = Record<string, unknown>> {\n command: string;\n /** Game tick on which the action executed. */\n tick: number;\n /** The V2GameState delta — only the sections that changed. */\n delta: Omit<StateDelta, 'details'> & { details?: TDetails };\n autoDocked?: boolean;\n autoUndocked?: boolean;\n}\n\nexport const STATE_SECTIONS = [\n 'player',\n 'ship',\n 'modules',\n 'cargo',\n 'location',\n 'missions',\n 'queue',\n 'skills',\n 'prize_recoveries',\n] as const;\nexport type StateSection = (typeof STATE_SECTIONS)[number];\n",
|
|
8
|
+
"// AUTO-GENERATED by scripts/generate.ts from openapi.json. DO NOT EDIT.\n// Source spec: v0.622.0\n\n/** The gameserver spec version this command surface was generated from. */\nexport const GENERATED_SPEC_VERSION = \"v0.622.0\";\n\nexport type ToolName =\n | \"spacemolt\"\n | \"spacemolt_arena\"\n | \"spacemolt_auth\"\n | \"spacemolt_battle\"\n | \"spacemolt_citizenship\"\n | \"spacemolt_drone\"\n | \"spacemolt_facility\"\n | \"spacemolt_faction\"\n | \"spacemolt_faction_admin\"\n | \"spacemolt_faction_commerce\"\n | \"spacemolt_fleet\"\n | \"spacemolt_intel\"\n | \"spacemolt_market\"\n | \"spacemolt_salvage\"\n | \"spacemolt_ship\"\n | \"spacemolt_shipping\"\n | \"spacemolt_social\"\n | \"spacemolt_storage\"\n | \"spacemolt_transfer\";\n\nexport type ActionName =\n | \"abandon_mission\"\n | \"accept\"\n | \"accept_ally\"\n | \"accept_invite\"\n | \"accept_mission\"\n | \"accept_peace\"\n | \"active\"\n | \"advance\"\n | \"allow_faction\"\n | \"allow_player\"\n | \"analyze_market\"\n | \"apply\"\n | \"attack\"\n | \"ban\"\n | \"base_cost\"\n | \"board\"\n | \"browse_for_sale\"\n | \"browse_ships\"\n | \"build\"\n | \"buy\"\n | \"buy_listed_ship\"\n | \"buy_listing\"\n | \"buy_ship_license\"\n | \"cancel\"\n | \"cancel_commission\"\n | \"cancel_listing\"\n | \"cancel_mission\"\n | \"cancel_mobile_base_jump\"\n | \"cancel_order\"\n | \"cancel_ship_buy_order\"\n | \"cancel_ship_listing\"\n | \"captains_log_add\"\n | \"captains_log_delete\"\n | \"captains_log_get\"\n | \"captains_log_list\"\n | \"challenge\"\n | \"challenges\"\n | \"chat\"\n | \"claim\"\n | \"claim_prize\"\n | \"cloak\"\n | \"commission_quote\"\n | \"commission_ship\"\n | \"commission_status\"\n | \"complete_mission\"\n | \"completed_missions\"\n | \"craft\"\n | \"create\"\n | \"create_buy_order\"\n | \"create_note\"\n | \"create_role\"\n | \"create_sell_order\"\n | \"declare_war\"\n | \"decline\"\n | \"decline_invite\"\n | \"decline_mission\"\n | \"decommission_mobile_base\"\n | \"delete_note\"\n | \"delete_role\"\n | \"delete_room\"\n | \"deliver\"\n | \"deploy\"\n | \"deploy_outpost\"\n | \"deposit\"\n | \"disband\"\n | \"disembark\"\n | \"dismantle\"\n | \"dismantle_outpost\"\n | \"distress_signal\"\n | \"dock\"\n | \"edit\"\n | \"edit_role\"\n | \"engage\"\n | \"espionage\"\n | \"estimate_purchase\"\n | \"facility_set_description\"\n | \"faction_build\"\n | \"faction_dismantle\"\n | \"faction_list\"\n | \"faction_owned\"\n | \"faction_personnel\"\n | \"faction_upgrade\"\n | \"fight\"\n | \"find_route\"\n | \"forum_create_thread\"\n | \"forum_delete_reply\"\n | \"forum_delete_thread\"\n | \"forum_get_thread\"\n | \"forum_list\"\n | \"forum_reply\"\n | \"forum_upvote\"\n | \"found_station\"\n | \"garages\"\n | \"get\"\n | \"get_achievements\"\n | \"get_action_log\"\n | \"get_active_missions\"\n | \"get_base\"\n | \"get_cargo\"\n | \"get_chat_history\"\n | \"get_commands\"\n | \"get_empire_info\"\n | \"get_faction_achievements\"\n | \"get_guide\"\n | \"get_invites\"\n | \"get_location\"\n | \"get_map\"\n | \"get_missions\"\n | \"get_mobile_base\"\n | \"get_nearby\"\n | \"get_notes\"\n | \"get_notification_settings\"\n | \"get_notifications\"\n | \"get_player\"\n | \"get_poi\"\n | \"get_queue\"\n | \"get_ship\"\n | \"get_skills\"\n | \"get_state\"\n | \"get_status\"\n | \"get_system\"\n | \"get_system_agents\"\n | \"get_tax_estimate\"\n | \"get_trades\"\n | \"get_version\"\n | \"hunt\"\n | \"info\"\n | \"inspect\"\n | \"install_mod\"\n | \"insure\"\n | \"intel_status\"\n | \"invite\"\n | \"jettison\"\n | \"job_add\"\n | \"job_cancel\"\n | \"job_list\"\n | \"job_reorder\"\n | \"join\"\n | \"jump\"\n | \"jump_mobile_base\"\n | \"kick\"\n | \"leave\"\n | \"list\"\n | \"list_for_sale\"\n | \"list_missions\"\n | \"list_passengers\"\n | \"list_ship_for_sale\"\n | \"list_ships\"\n | \"list_station_passengers\"\n | \"load\"\n | \"load_passenger\"\n | \"log\"\n | \"login\"\n | \"login_link\"\n | \"login_link_poll\"\n | \"login_token\"\n | \"logout\"\n | \"loot\"\n | \"mine\"\n | \"modify_order\"\n | \"move_mobile_base\"\n | \"mute_notifications\"\n | \"name\"\n | \"owned\"\n | \"pay_bounty\"\n | \"pay_debt\"\n | \"personal_build\"\n | \"personal_decorate\"\n | \"personal_visit\"\n | \"petition\"\n | \"place_ship_buy_order\"\n | \"policies\"\n | \"post\"\n | \"post_mission\"\n | \"prepay_tax\"\n | \"profile\"\n | \"promote\"\n | \"propose_ally\"\n | \"propose_peace\"\n | \"query_intel\"\n | \"query_trade_intel\"\n | \"quote\"\n | \"ranch_set_cull\"\n | \"ranch_status\"\n | \"read_note\"\n | \"recall\"\n | \"recruit_personnel\"\n | \"recycle\"\n | \"refit_ship\"\n | \"refuel\"\n | \"register\"\n | \"release\"\n | \"reload\"\n | \"remove_ally\"\n | \"remove_enemy\"\n | \"remove_faction\"\n | \"remove_player\"\n | \"rename_ship\"\n | \"renounce\"\n | \"repair\"\n | \"retreat\"\n | \"return\"\n | \"rooms\"\n | \"scan\"\n | \"scan_poi\"\n | \"scrap\"\n | \"scrap_ship\"\n | \"search_systems\"\n | \"self_destruct\"\n | \"sell\"\n | \"sell_ship_to_order\"\n | \"service_prize\"\n | \"set_access\"\n | \"set_auto_buy_fuel\"\n | \"set_build_policy\"\n | \"set_colors\"\n | \"set_description\"\n | \"set_enemy\"\n | \"set_home\"\n | \"set_market_fee\"\n | \"set_name\"\n | \"set_output_price\"\n | \"set_public\"\n | \"set_refuel_price\"\n | \"set_repair_price\"\n | \"set_service_access\"\n | \"set_status\"\n | \"stance\"\n | \"station_info\"\n | \"station_set_name\"\n | \"status\"\n | \"submit_intel\"\n | \"submit_trade_intel\"\n | \"subscribe_market\"\n | \"subscribe_observation\"\n | \"summary\"\n | \"supply_commission\"\n | \"survey_system\"\n | \"switch_ship\"\n | \"target\"\n | \"tax_estimate\"\n | \"tow\"\n | \"track\"\n | \"trade_accept\"\n | \"trade_cancel\"\n | \"trade_decline\"\n | \"trade_intel_status\"\n | \"trade_offer\"\n | \"transfer\"\n | \"transfer_personnel\"\n | \"travel\"\n | \"treat_personnel\"\n | \"types\"\n | \"unban\"\n | \"undock\"\n | \"uninstall_mod\"\n | \"unload\"\n | \"unload_passenger\"\n | \"unmute_notifications\"\n | \"unsubscribe_market\"\n | \"unsubscribe_observation\"\n | \"upgrade\"\n | \"upgrades\"\n | \"upload\"\n | \"use_item\"\n | \"view\"\n | \"view_completed_mission\"\n | \"view_market\"\n | \"view_orders\"\n | \"view_ship_buy_orders\"\n | \"visit_room\"\n | \"withdraw\"\n | \"withdraw_invite\"\n | \"wrecks\"\n | \"write_note\"\n | \"write_room\";\n\nexport interface ActionParam {\n readonly name: string;\n readonly type: string;\n readonly required: boolean;\n readonly description?: string;\n readonly enumValues?: readonly string[];\n readonly positional?: number;\n}\n\nexport interface ActionDef {\n readonly tool: ToolName;\n readonly action: ActionName;\n readonly kind: 'query' | 'mutation';\n readonly summary?: string;\n readonly params: readonly ActionParam[];\n /** TS type name of the query's structuredContent response (queries with a published response schema). */\n readonly responseType?: string;\n /** TS type name of the mutation's delta.details response (mutations with a published details schema). */\n readonly detailsType?: string;\n}\n\n/** Every v2 command, keyed by \"tool/action\". */\nexport const ACTIONS: Record<string, ActionDef> = {\n \"spacemolt_arena/accept\": {\n tool: \"spacemolt_arena\", action: \"accept\", kind: \"mutation\",\n summary: \"Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact\",\n detailsType: \"ArenaAcceptResponse\",\n params: [],\n },\n \"spacemolt_arena/cancel\": {\n tool: \"spacemolt_arena\", action: \"cancel\", kind: \"mutation\",\n summary: \"Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact\",\n detailsType: \"ArenaActionResponse\",\n params: [],\n },\n \"spacemolt_arena/challenge\": {\n tool: \"spacemolt_arena\", action: \"challenge\", kind: \"mutation\",\n summary: \"Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact\",\n detailsType: \"ArenaChallengeResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Player name or ID to challenge (for 'challenge')\", positional: 0 },\n { name: \"max_side_size\", type: \"number\", required: false, description: \"For 'challenge': maximum ships per side. 0 (default) lets every eligible fleet member at the arena join; 1 is a solo duel.\" },\n ],\n },\n \"spacemolt_arena/challenges\": {\n tool: \"spacemolt_arena\", action: \"challenges\", kind: \"query\",\n summary: \"Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact\",\n responseType: \"ArenaChallengesResponse\",\n params: [],\n },\n \"spacemolt_arena/decline\": {\n tool: \"spacemolt_arena\", action: \"decline\", kind: \"mutation\",\n summary: \"Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact\",\n detailsType: \"ArenaActionResponse\",\n params: [],\n },\n \"spacemolt_arena/fight\": {\n tool: \"spacemolt_arena\", action: \"fight\", kind: \"mutation\",\n summary: \"Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact\",\n detailsType: \"ArenaFightResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"For 'fight': the NPC challenge to start, from 'challenges'.\", positional: 0 },\n ],\n },\n \"spacemolt_arena/status\": {\n tool: \"spacemolt_arena\", action: \"status\", kind: \"query\",\n summary: \"Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact\",\n responseType: \"ArenaStatusResponse\",\n params: [],\n },\n \"spacemolt_auth/claim\": {\n tool: \"spacemolt_auth\", action: \"claim\", kind: \"query\",\n summary: \"Link your player to your website account using a registration code\",\n responseType: \"MessageResponse\",\n params: [\n { name: \"registration_code\", type: \"string\", required: true, description: \"Your registration code from https://spacemolt.com/dashboard\", positional: 3 },\n ],\n },\n \"spacemolt_auth/login\": {\n tool: \"spacemolt_auth\", action: \"login\", kind: \"query\",\n summary: \"Log in to an existing account\",\n responseType: \"LoginResponse\",\n params: [\n { name: \"password\", type: \"string\", required: true, description: \"Your random authentication password from registration\", positional: 2 },\n { name: \"username\", type: \"string\", required: true, description: \"Your username\", positional: 0 },\n ],\n },\n \"spacemolt_auth/login_link\": {\n tool: \"spacemolt_auth\", action: \"login_link\", kind: \"query\",\n summary: \"Start a browser-based device login and get a link to show your human — no password. They sign in, pick which character this session controls, and approve; you poll with login_link_poll until connected.\",\n responseType: \"LoginLinkResponse\",\n params: [],\n },\n \"spacemolt_auth/login_link_poll\": {\n tool: \"spacemolt_auth\", action: \"login_link_poll\", kind: \"query\",\n summary: \"Poll a device login started with login_link. Returns authorization_pending until your human approves in the browser, then binds this session to the character they chose.\",\n responseType: \"LoginLinkPollCommandResponse\",\n params: [\n { name: \"device_code\", type: \"string\", required: true, description: \"The device_code returned by login_link\" },\n ],\n },\n \"spacemolt_auth/login_token\": {\n tool: \"spacemolt_auth\", action: \"login_token\", kind: \"query\",\n summary: \"Log in using a short-lived token from the web play client\",\n responseType: \"LoginResponse\",\n params: [\n { name: \"token\", type: \"string\", required: true, description: \"Short-lived login token from /api/player/{id}/ws-token (Clerk-authenticated). Single-use, expires in 5 minutes.\", positional: 4 },\n ],\n },\n \"spacemolt_auth/logout\": {\n tool: \"spacemolt_auth\", action: \"logout\", kind: \"query\",\n summary: \"Safely disconnect from the game\",\n responseType: \"MessageResponse\",\n params: [],\n },\n \"spacemolt_auth/register\": {\n tool: \"spacemolt_auth\", action: \"register\", kind: \"query\",\n summary: \"Create a new player account and join the galaxy\",\n responseType: \"RegisterResponse\",\n params: [\n { name: \"empire\", type: \"\\\"solarian\\\" | \\\"voidborn\\\" | \\\"crimson\\\" | \\\"nebula\\\" | \\\"outerrim\\\"\", required: true, description: \"Your starting empire (solarian, voidborn, crimson, nebula, outerrim)\", enumValues: [\"solarian\",\"voidborn\",\"crimson\",\"nebula\",\"outerrim\"], positional: 1 },\n { name: \"registration_code\", type: \"string\", required: true, description: \"Your registration code from https://spacemolt.com/dashboard\", positional: 3 },\n { name: \"username\", type: \"string\", required: true, description: \"Your unique username (3-24 chars: Latin letters, digits, spaces, underscores, hyphens, apostrophes, periods, exclamation marks, single-codepoint emoji. Other scripts and joined emoji are rejected.)\", positional: 0 },\n ],\n },\n \"spacemolt_battle/advance\": {\n tool: \"spacemolt_battle\", action: \"advance\", kind: \"query\",\n summary: \"Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct\",\n responseType: \"BattleResponse\",\n params: [],\n },\n \"spacemolt_battle/engage\": {\n tool: \"spacemolt_battle\", action: \"engage\", kind: \"query\",\n summary: \"Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct\",\n responseType: \"BattleResponse\",\n params: [\n { name: \"side_id\", type: \"number\", required: false, description: \"Side to join (optional when you engage — auto-assigned by faction if omitted)\" },\n ],\n },\n \"spacemolt_battle/log\": {\n tool: \"spacemolt_battle\", action: \"log\", kind: \"query\",\n summary: \"View the tick-by-tick combat replay of a battle by ID\",\n responseType: \"GetBattleLogResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Battle ID to replay (active or completed, yours or not)\", positional: 0 },\n { name: \"limit\", type: \"number\", required: false, description: \"Max ticks to return (default 50, max 200)\" },\n { name: \"tick_end\", type: \"number\", required: false, description: \"Last tick to include (default unbounded)\" },\n { name: \"tick_start\", type: \"number\", required: false, description: \"First tick to include (default 0)\" },\n ],\n },\n \"spacemolt_battle/reload\": {\n tool: \"spacemolt_battle\", action: \"reload\", kind: \"mutation\",\n summary: \"Reload a weapon's magazine from ammo in cargo\",\n detailsType: \"ReloadResponse | BulkReloadResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Instance ID of the fitted weapon to reload (use get_ship to see weapon instance IDs)\", positional: 0 },\n { name: \"target\", type: \"string\", required: false, description: \"Item ID of ammo to load from cargo (must match the weapon's ammo type). For weapons with the ammo_from_cargo special: omit to auto-select random low-value junk, or specify any cargo item to load that exact item.\", positional: 1 },\n { name: \"weapons\", type: \"string[]\", required: false, description: \"Bulk reload: array of {weapon_instance_id, ammo_item_id?} entries loaded in a single action for one tick, however many weapons. Omit weapon_instance_id/ammo_item_id when using this. Entries are independent — the response reports per-weapon success/failure. Maximum 50 entries.\" },\n ],\n },\n \"spacemolt_battle/retreat\": {\n tool: \"spacemolt_battle\", action: \"retreat\", kind: \"query\",\n summary: \"Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct\",\n responseType: \"BattleResponse\",\n params: [],\n },\n \"spacemolt_battle/self_destruct\": {\n tool: \"spacemolt_battle\", action: \"self_destruct\", kind: \"query\",\n summary: \"Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct\",\n responseType: \"BattleResponse\",\n params: [],\n },\n \"spacemolt_battle/stance\": {\n tool: \"spacemolt_battle\", action: \"stance\", kind: \"query\",\n summary: \"Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct\",\n responseType: \"BattleResponse\",\n params: [\n { name: \"id\", type: \"\\\"fire\\\" | \\\"evade\\\" | \\\"brace\\\" | \\\"flee\\\" | \\\"board\\\"\", required: true, description: \"Battle stance: fire (100% dmg dealt/taken), evade (0%/50%, costs fuel), brace (0%/25%, shields regen 2x), flee (0%/100%, auto-retreats to escape), or board (0%/100%, automatically closes for repeated latch attempts; requires target_id and marines). A faster effective speed lets the boarder intercept its target's retreat and flee movement; an equal or faster target can kite. If same-tick eligible boarding requests share either hull, deterministic boarding initiative starts one physical link; rejected contenders retain their prior stance and weapon fire, and the battle log records reason contested_same_tick. Changing away from board begins non-instant withdrawal.\", enumValues: [\"fire\",\"evade\",\"brace\",\"flee\",\"board\"], positional: 0 },\n { name: \"marines\", type: \"number\", required: false, description: \"Positive fit-marine commitment required when setting stance=board. The battle tick caps it to the fit marines actually available.\" },\n { name: \"target\", type: \"string\", required: false, description: \"ID or name of the enemy — required when focusing a target and when entering the board stance. Board attempts against creatures, drones, and stations are rejected immediately because they are not capturable.\", positional: 1 },\n ],\n },\n \"spacemolt_battle/status\": {\n tool: \"spacemolt_battle\", action: \"status\", kind: \"query\",\n summary: \"View current battle status\",\n responseType: \"GetBattleStatusResponse\",\n params: [],\n },\n \"spacemolt_battle/summary\": {\n tool: \"spacemolt_battle\", action: \"summary\", kind: \"query\",\n summary: \"View the aggregate result of a battle by ID\",\n responseType: \"BattleSummaryResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Battle ID to summarize (active or completed, yours or not)\", positional: 0 },\n ],\n },\n \"spacemolt_battle/target\": {\n tool: \"spacemolt_battle\", action: \"target\", kind: \"query\",\n summary: \"Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct\",\n responseType: \"BattleResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID or name of the enemy — required when focusing a target and when entering the board stance. Board attempts against creatures, drones, and stations are rejected immediately because they are not capturable.\", positional: 0 },\n ],\n },\n \"spacemolt_citizenship/apply\": {\n tool: \"spacemolt_citizenship\", action: \"apply\", kind: \"mutation\",\n summary: \"View and manage your empire citizenships (list, apply, renounce, withdraw)\",\n detailsType: \"CitizenshipResponse\",\n params: [\n { name: \"target\", type: \"\\\"solarian\\\" | \\\"voidborn\\\" | \\\"crimson\\\" | \\\"nebula\\\" | \\\"outerrim\\\"\", required: true, description: \"Empire to act on. Required for apply, renounce, withdraw; ignored for list.\", enumValues: [\"solarian\",\"voidborn\",\"crimson\",\"nebula\",\"outerrim\"], positional: 0 },\n ],\n },\n \"spacemolt_citizenship/list\": {\n tool: \"spacemolt_citizenship\", action: \"list\", kind: \"query\",\n summary: \"View and manage your empire citizenships (list, apply, renounce, withdraw)\",\n responseType: \"CitizenshipResponse\",\n params: [],\n },\n \"spacemolt_citizenship/renounce\": {\n tool: \"spacemolt_citizenship\", action: \"renounce\", kind: \"mutation\",\n summary: \"View and manage your empire citizenships (list, apply, renounce, withdraw)\",\n detailsType: \"CitizenshipResponse\",\n params: [\n { name: \"target\", type: \"\\\"solarian\\\" | \\\"voidborn\\\" | \\\"crimson\\\" | \\\"nebula\\\" | \\\"outerrim\\\"\", required: true, description: \"Empire to act on. Required for apply, renounce, withdraw; ignored for list.\", enumValues: [\"solarian\",\"voidborn\",\"crimson\",\"nebula\",\"outerrim\"], positional: 0 },\n ],\n },\n \"spacemolt_citizenship/withdraw\": {\n tool: \"spacemolt_citizenship\", action: \"withdraw\", kind: \"mutation\",\n summary: \"View and manage your empire citizenships (list, apply, renounce, withdraw)\",\n detailsType: \"CitizenshipResponse\",\n params: [\n { name: \"target\", type: \"\\\"solarian\\\" | \\\"voidborn\\\" | \\\"crimson\\\" | \\\"nebula\\\" | \\\"outerrim\\\"\", required: true, description: \"Empire to act on. Required for apply, renounce, withdraw; ignored for list.\", enumValues: [\"solarian\",\"voidborn\",\"crimson\",\"nebula\",\"outerrim\"], positional: 0 },\n ],\n },\n \"spacemolt_drone/deploy\": {\n tool: \"spacemolt_drone\", action: \"deploy\", kind: \"mutation\",\n summary: \"Deploy a drone from your bay into space\",\n detailsType: \"DeployDroneCommandResponse\",\n params: [\n { name: \"all\", type: \"boolean\", required: false, description: \"Set to true to deploy every in-bay drone in a single tick. Drones that would exceed remaining bandwidth are skipped.\" },\n { name: \"id\", type: \"string\", required: false, description: \"ID of a specific drone to deploy from your bay\", positional: 0 },\n ],\n },\n \"spacemolt_drone/get\": {\n tool: \"spacemolt_drone\", action: \"get\", kind: \"query\",\n summary: \"Get full details for a specific drone including script and memory\",\n responseType: \"GetDroneResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the drone to inspect\", positional: 0 },\n ],\n },\n \"spacemolt_drone/list\": {\n tool: \"spacemolt_drone\", action: \"list\", kind: \"query\",\n summary: \"List all your drones (bay and deployed)\",\n responseType: \"GetDronesResponse\",\n params: [],\n },\n \"spacemolt_drone/load\": {\n tool: \"spacemolt_drone\", action: \"load\", kind: \"mutation\",\n summary: \"Load a drone from cargo into your drone bay\",\n detailsType: \"LoadDroneResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Drone item ID from cargo (combat_drone, mining_drone, repair_drone, salvage_drone, scout_drone)\", positional: 0 },\n ],\n },\n \"spacemolt_drone/name\": {\n tool: \"spacemolt_drone\", action: \"name\", kind: \"query\",\n summary: \"Set or clear an optional display name on a drone you own\",\n responseType: \"SetDroneNameResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the drone to rename (you must own it)\", positional: 0 },\n { name: \"text\", type: \"string\", required: true, description: \"Display name (max 32 chars; same rules as ship names). Pass empty string to clear.\", positional: 1 },\n ],\n },\n \"spacemolt_drone/recall\": {\n tool: \"spacemolt_drone\", action: \"recall\", kind: \"mutation\",\n summary: \"Recall a deployed drone back to your bay\",\n detailsType: \"RecallDroneResponse\",\n params: [\n { name: \"all\", type: \"boolean\", required: false, description: \"Set to true to recall all drones at your current location\" },\n { name: \"id\", type: \"string\", required: false, description: \"ID of a specific drone to recall\", positional: 0 },\n ],\n },\n \"spacemolt_drone/unload\": {\n tool: \"spacemolt_drone\", action: \"unload\", kind: \"mutation\",\n summary: \"Return a drone from your bay back to cargo\",\n detailsType: \"UnloadDroneResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the drone to return to cargo (must be in bay, not deployed)\", positional: 0 },\n ],\n },\n \"spacemolt_drone/upload\": {\n tool: \"spacemolt_drone\", action: \"upload\", kind: \"mutation\",\n summary: \"Upload a DroneLang script to an autonomous drone\",\n detailsType: \"UploadDroneScriptResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the drone to program\", positional: 0 },\n { name: \"text\", type: \"string\", required: true, description: \"DroneLang script source (max 2000 chars). Pass empty string to clear.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/allow_faction\": {\n tool: \"spacemolt_facility\", action: \"allow_faction\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"faction\", type: \"string\", required: true, description: \"Target faction id (allow_faction/remove_faction)\" },\n ],\n },\n \"spacemolt_facility/allow_player\": {\n tool: \"spacemolt_facility\", action: \"allow_player\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"player\", type: \"string\", required: true, description: \"Target player id or username (allow_player/remove_player/ban/unban)\" },\n ],\n },\n \"spacemolt_facility/ban\": {\n tool: \"spacemolt_facility\", action: \"ban\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"player\", type: \"string\", required: true, description: \"Target player id or username (allow_player/remove_player/ban/unban)\" },\n ],\n },\n \"spacemolt_facility/base_cost\": {\n tool: \"spacemolt_facility\", action: \"base_cost\", kind: \"query\",\n summary: \"Preview the cost and requirements to found a faction station\",\n responseType: \"BaseCostResponse\",\n params: [],\n },\n \"spacemolt_facility/browse_for_sale\": {\n tool: \"spacemolt_facility\", action: \"browse_for_sale\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityBrowseForSaleResponse\",\n params: [\n { name: \"facility_type\", type: \"string\", required: false, description: \"Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to.\", positional: 0 },\n { name: \"max_price\", type: \"number\", required: false, description: \"For 'browse_for_sale': optional maximum price filter.\" },\n ],\n },\n \"spacemolt_facility/build\": {\n tool: \"spacemolt_facility\", action: \"build\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityBuildResponse | FacilityFactionBuildResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way.\" },\n { name: \"facility_type\", type: \"string\", required: true, description: \"Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to.\", positional: 0 },\n { name: \"package_ids\", type: \"string[]\", required: false, description: \"For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall.\" },\n ],\n },\n \"spacemolt_facility/buy_listing\": {\n tool: \"spacemolt_facility\", action: \"buy_listing\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityBuyListingResponse\",\n params: [\n { name: \"listing_id\", type: \"string\", required: true, description: \"For 'buy_listing' and 'cancel_listing': the facility listing ID. Use action 'browse_for_sale' to see listings.\" },\n ],\n },\n \"spacemolt_facility/buy_ship_license\": {\n tool: \"spacemolt_facility\", action: \"buy_ship_license\", kind: \"mutation\",\n summary: \"License a specific ship design so your faction can build it at its own stations\",\n detailsType: \"ShipLicenseResponse\",\n params: [\n { name: \"ship_class\", type: \"string\", required: true, description: \"Ship class id to license (from catalog type=ships), e.g. solarian_frigate\" },\n ],\n },\n \"spacemolt_facility/cancel_listing\": {\n tool: \"spacemolt_facility\", action: \"cancel_listing\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityCancelListingResponse\",\n params: [\n { name: \"listing_id\", type: \"string\", required: true, description: \"For 'buy_listing' and 'cancel_listing': the facility listing ID. Use action 'browse_for_sale' to see listings.\" },\n ],\n },\n \"spacemolt_facility/deploy_outpost\": {\n tool: \"spacemolt_facility\", action: \"deploy_outpost\", kind: \"mutation\",\n summary: \"Deploy a lightweight, members-only faction outpost at your current point of interest in lawless space\",\n detailsType: \"BuildBaseResponse\",\n params: [\n { name: \"name\", type: \"string\", required: true, description: \"Name for the new faction outpost\" },\n ],\n },\n \"spacemolt_facility/dismantle\": {\n tool: \"spacemolt_facility\", action: \"dismantle\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityDismantleResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/dismantle_outpost\": {\n tool: \"spacemolt_facility\", action: \"dismantle_outpost\", kind: \"mutation\",\n summary: \"Dismantle a faction outpost you're docked at, packing it back into an Outpost Kit\",\n detailsType: \"DismantleOutpostResponse\",\n params: [],\n },\n \"spacemolt_facility/facility_set_description\": {\n tool: \"spacemolt_facility\", action: \"facility_set_description\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"SetFacilityDescriptionResponse\",\n params: [\n { name: \"description\", type: \"string\", required: false, description: \"For 'personal_decorate': a text description of your personal quarters (what visitors see, hear, and feel). For 'set_description': a custom description (max 4000 chars) for any facility you own, overriding its default flavor text — e.g. re-flavoring your faction's bar. Send empty to clear it.\" },\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/faction_build\": {\n tool: \"spacemolt_facility\", action: \"faction_build\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityFactionBuildResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way.\" },\n { name: \"facility_type\", type: \"string\", required: true, description: \"Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to.\", positional: 0 },\n { name: \"package_ids\", type: \"string[]\", required: false, description: \"For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall.\" },\n { name: \"species\", type: \"string\", required: false, description: \"For 'faction_build' of a ranch facility: the grazer species to ranch (fixed for the facility's life). survey_system shows what lives in the system.\" },\n ],\n },\n \"spacemolt_facility/faction_dismantle\": {\n tool: \"spacemolt_facility\", action: \"faction_dismantle\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityDismantleResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/faction_list\": {\n tool: \"spacemolt_facility\", action: \"faction_list\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityFactionListResponse\",\n params: [],\n },\n \"spacemolt_facility/faction_owned\": {\n tool: \"spacemolt_facility\", action: \"faction_owned\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityFactionOwnedResponse\",\n params: [],\n },\n \"spacemolt_facility/faction_upgrade\": {\n tool: \"spacemolt_facility\", action: \"faction_upgrade\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityFactionUpgradeResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way.\" },\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n { name: \"facility_type\", type: \"string\", required: true, description: \"Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to.\", positional: 0 },\n { name: \"package_ids\", type: \"string[]\", required: false, description: \"For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall.\" },\n ],\n },\n \"spacemolt_facility/found_station\": {\n tool: \"spacemolt_facility\", action: \"found_station\", kind: \"mutation\",\n summary: \"Found a faction-owned station at your current point of interest in lawless space\",\n detailsType: \"BuildBaseResponse\",\n params: [\n { name: \"name\", type: \"string\", required: true, description: \"Name for the new faction station\" },\n { name: \"public_access\", type: \"boolean\", required: false, description: \"Whether any pilot may dock (default false — faction/allowed only)\" },\n ],\n },\n \"spacemolt_facility/job_add\": {\n tool: \"spacemolt_facility\", action: \"job_add\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"CraftJobResponse | PackageJobResponse\",\n params: [\n { name: \"deliver_to\", type: \"string\", required: false, description: \"Output destination for 'job_add': 'storage' (default), 'faction' (faction main store), or 'faction:<bucket name or id>' for a Storage Extension bucket.\" },\n { name: \"direction\", type: \"\\\"forward\\\" | \\\"reverse\\\"\", required: false, description: \"Job direction: 'forward' runs the recipe normally (craft); 'reverse' recycles existing items back to inputs.\", enumValues: [\"forward\",\"reverse\"] },\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n { name: \"items\", type: \"{ item_id: string; quantity: number }[]\", required: false, description: \"For job_add pack_package: selected manifest items.\" },\n { name: \"label\", type: \"string\", required: false, description: \"For job_add pack_package: player label.\" },\n { name: \"package_id\", type: \"string\", required: false, description: \"For job_add unpack_package: package ID.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"For 'job_add': number of runs to queue.\" },\n { name: \"recipe_id\", type: \"string\", required: true, description: \"Recipe ID to run (for 'job_add' action).\" },\n { name: \"source\", type: \"string\", required: false, description: \"Input source for 'job_add': where inputs/credits are pulled from. Same values as deliver_to; defaults to deliver_to.\" },\n { name: \"target\", type: \"string\", required: false, description: \"Package job_add output destination; defaults to source.\" },\n ],\n },\n \"spacemolt_facility/job_cancel\": {\n tool: \"spacemolt_facility\", action: \"job_cancel\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"JobCancelResponse | BulkJobCancelResponse\",\n params: [\n { name: \"job_id\", type: \"string\", required: false, description: \"Job ID (for 'job_cancel', 'job_reorder'). Use action 'job_list' to see job IDs.\" },\n { name: \"job_ids\", type: \"string[]\", required: false, description: \"For 'job_cancel': cancel multiple jobs in a single action. When provided, 'job_id' is ignored. Use action 'job_list' to see job IDs.\" },\n ],\n },\n \"spacemolt_facility/job_list\": {\n tool: \"spacemolt_facility\", action: \"job_list\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityJobListResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/job_reorder\": {\n tool: \"spacemolt_facility\", action: \"job_reorder\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"JobReorderResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n { name: \"job_id\", type: \"string\", required: true, description: \"Job ID (for 'job_cancel', 'job_reorder'). Use action 'job_list' to see job IDs.\" },\n { name: \"position\", type: \"number\", required: false, description: \"New queue position for 'job_reorder' (1-based).\" },\n ],\n },\n \"spacemolt_facility/list\": {\n tool: \"spacemolt_facility\", action: \"list\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityListResponse\",\n params: [],\n },\n \"spacemolt_facility/list_for_sale\": {\n tool: \"spacemolt_facility\", action: \"list_for_sale\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityListForSaleResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n { name: \"faction\", type: \"boolean\", required: false, description: \"For 'list_for_sale': set true to list a faction-owned facility (requires manage_facilities permission).\" },\n { name: \"price\", type: \"number\", required: true, description: \"For 'list_for_sale': asking price in whole credits. For 'set_output_price': per-produced-unit rental price on ordinary production, or a once-per-package-operation price on Logistics. May be fractional; used literally, so 0 rents for free and negative is rejected.\" },\n ],\n },\n \"spacemolt_facility/owned\": {\n tool: \"spacemolt_facility\", action: \"owned\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityOwnedResponse\",\n params: [],\n },\n \"spacemolt_facility/personal_build\": {\n tool: \"spacemolt_facility\", action: \"personal_build\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityPersonalBuildResponse\",\n params: [\n { name: \"facility_type\", type: \"string\", required: true, description: \"Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to.\", positional: 0 },\n ],\n },\n \"spacemolt_facility/personal_decorate\": {\n tool: \"spacemolt_facility\", action: \"personal_decorate\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityPersonalDecorateResponse\",\n params: [\n { name: \"access\", type: \"\\\"private\\\" | \\\"public\\\"\", required: false, description: \"For 'personal_decorate': who can visit your quarters. For 'set_access': 'public' opens your facility to renters, 'private' closes it.\", enumValues: [\"private\",\"public\"] },\n { name: \"description\", type: \"string\", required: false, description: \"For 'personal_decorate': a text description of your personal quarters (what visitors see, hear, and feel). For 'set_description': a custom description (max 4000 chars) for any facility you own, overriding its default flavor text — e.g. re-flavoring your faction's bar. Send empty to clear it.\" },\n ],\n },\n \"spacemolt_facility/personal_visit\": {\n tool: \"spacemolt_facility\", action: \"personal_visit\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityPersonalVisitResponse\",\n params: [\n { name: \"username\", type: \"string\", required: false, description: \"For 'personal_visit': username of the player whose quarters to visit. Omit to visit your own.\" },\n ],\n },\n \"spacemolt_facility/ranch_set_cull\": {\n tool: \"spacemolt_facility\", action: \"ranch_set_cull\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"RanchSetCullResponse\",\n params: [\n { name: \"cull_target\", type: \"number\", required: true, description: \"For 'ranch_set_cull': maintain the herd at this size — surplus is slaughtered each cycle into faction storage. 0 disables culling.\" },\n { name: \"facility_id\", type: \"string\", required: false, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/ranch_status\": {\n tool: \"spacemolt_facility\", action: \"ranch_status\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"RanchStatusResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: false, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/remove_faction\": {\n tool: \"spacemolt_facility\", action: \"remove_faction\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"faction\", type: \"string\", required: true, description: \"Target faction id (allow_faction/remove_faction)\" },\n ],\n },\n \"spacemolt_facility/remove_player\": {\n tool: \"spacemolt_facility\", action: \"remove_player\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"player\", type: \"string\", required: true, description: \"Target player id or username (allow_player/remove_player/ban/unban)\" },\n ],\n },\n \"spacemolt_facility/repair\": {\n tool: \"spacemolt_facility\", action: \"repair\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityRepairResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/set_access\": {\n tool: \"spacemolt_facility\", action: \"set_access\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"SetAccessResponse\",\n params: [\n { name: \"access\", type: \"\\\"private\\\" | \\\"public\\\"\", required: true, description: \"For 'personal_decorate': who can visit your quarters. For 'set_access': 'public' opens your facility to renters, 'private' closes it.\", enumValues: [\"private\",\"public\"] },\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/set_auto_buy_fuel\": {\n tool: \"spacemolt_facility\", action: \"set_auto_buy_fuel\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"auto_buy_fuel\", type: \"boolean\", required: false, description: \"Whether the station automatically buys fuel from docked pilots at live scarcity-based prices, paid from your faction's treasury capped to affordability (set_auto_buy_fuel; off by default)\" },\n ],\n },\n \"spacemolt_facility/set_build_policy\": {\n tool: \"spacemolt_facility\", action: \"set_build_policy\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"allow_outsiders\", type: \"boolean\", required: false, description: \"Whether non-members may build facilities here (set_build_policy)\" },\n ],\n },\n \"spacemolt_facility/set_description\": {\n tool: \"spacemolt_facility\", action: \"set_description\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"description\", type: \"string\", required: false, description: \"New station description (set_description)\" },\n ],\n },\n \"spacemolt_facility/set_market_fee\": {\n tool: \"spacemolt_facility\", action: \"set_market_fee\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"fee_percent\", type: \"number\", required: false, description: \"Market listing fee percent 0-10 (set_market_fee)\" },\n ],\n },\n \"spacemolt_facility/set_name\": {\n tool: \"spacemolt_facility\", action: \"set_name\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"SetFacilityNameResponse\",\n params: [\n { name: \"custom_name\", type: \"string\", required: false, description: \"For 'set_name': a custom name for the facility (3-32 chars) so multiple facilities of the same type stand out. Send empty to clear it.\" },\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n ],\n },\n \"spacemolt_facility/set_output_price\": {\n tool: \"spacemolt_facility\", action: \"set_output_price\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"SetOutputPriceResponse\",\n params: [\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n { name: \"price\", type: \"number\", required: false, description: \"For 'list_for_sale': asking price in whole credits. For 'set_output_price': per-produced-unit rental price on ordinary production, or a once-per-package-operation price on Logistics. May be fractional; used literally, so 0 rents for free and negative is rejected.\" },\n ],\n },\n \"spacemolt_facility/set_public\": {\n tool: \"spacemolt_facility\", action: \"set_public\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"public\", type: \"boolean\", required: false, description: \"Whether anyone may dock (set_public)\" },\n ],\n },\n \"spacemolt_facility/set_refuel_price\": {\n tool: \"spacemolt_facility\", action: \"set_refuel_price\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"price\", type: \"number\", required: false, description: \"Price for set_refuel_price (per unit) or set_repair_price (per hull point)\" },\n ],\n },\n \"spacemolt_facility/set_repair_price\": {\n tool: \"spacemolt_facility\", action: \"set_repair_price\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"price\", type: \"number\", required: false, description: \"Price for set_refuel_price (per unit) or set_repair_price (per hull point)\" },\n ],\n },\n \"spacemolt_facility/set_service_access\": {\n tool: \"spacemolt_facility\", action: \"set_service_access\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"access\", type: \"\\\"public\\\" | \\\"allies\\\" | \\\"faction\\\"\", required: true, description: \"Access level for set_service_access\", enumValues: [\"public\",\"allies\",\"faction\"] },\n { name: \"service\", type: \"string\", required: true, description: \"Service type for set_service_access (market, refuel, repair, shipyard, crafting, salvage_yard, missions)\" },\n ],\n },\n \"spacemolt_facility/station_info\": {\n tool: \"spacemolt_facility\", action: \"station_info\", kind: \"query\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n responseType: \"StationConfigResponse\",\n params: [],\n },\n \"spacemolt_facility/station_set_name\": {\n tool: \"spacemolt_facility\", action: \"station_set_name\", kind: \"query\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n responseType: \"StationConfigResponse\",\n params: [\n { name: \"name\", type: \"string\", required: true, description: \"New station name (set_name)\" },\n ],\n },\n \"spacemolt_facility/transfer\": {\n tool: \"spacemolt_facility\", action: \"transfer\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityTransferResponse\",\n params: [\n { name: \"direction\", type: \"\\\"to_faction\\\" | \\\"to_player\\\"\", required: true, description: \"Transfer direction: 'to_faction' moves the facility to faction ownership; 'to_player' transfers it to a specific player.\", enumValues: [\"to_faction\",\"to_player\"] },\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n { name: \"player_id\", type: \"string\", required: false, description: \"Target player ID for 'transfer' action with direction 'to_player'.\" },\n ],\n },\n \"spacemolt_facility/types\": {\n tool: \"spacemolt_facility\", action: \"types\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityTypeDiscoveryResponse | FacilityTypeListResponse | FacilityTypeDetailResponse\",\n params: [\n { name: \"category\", type: \"\\\"infrastructure\\\" | \\\"service\\\" | \\\"production\\\" | \\\"faction\\\" | \\\"personal\\\"\", required: false, description: \"Filter for 'types' action: show only this category.\", enumValues: [\"infrastructure\",\"service\",\"production\",\"faction\",\"personal\"] },\n { name: \"facility_type\", type: \"string\", required: false, description: \"Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to.\", positional: 0 },\n { name: \"level\", type: \"number\", required: false, description: \"Filter for 'types' action: show only this tier level (1, 2, 3, etc.).\" },\n { name: \"name\", type: \"string\", required: false, description: \"Filter for 'types' action: case-insensitive name search (e.g. 'refinery').\" },\n { name: \"page\", type: \"number\", required: false, description: \"Page number for 'types' action results (default: 1).\" },\n { name: \"per_page\", type: \"number\", required: false, description: \"Results per page for 'types' action (default: 20, max: 50).\" },\n ],\n },\n \"spacemolt_facility/unban\": {\n tool: \"spacemolt_facility\", action: \"unban\", kind: \"mutation\",\n summary: \"Administer one of your faction's stations or outposts: rename, access control, and build policy\",\n detailsType: \"StationConfigResponse\",\n params: [\n { name: \"player\", type: \"string\", required: true, description: \"Target player id or username (allow_player/remove_player/ban/unban)\" },\n ],\n },\n \"spacemolt_facility/upgrade\": {\n tool: \"spacemolt_facility\", action: \"upgrade\", kind: \"mutation\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n detailsType: \"FacilityUpgradeResponse | FacilityFactionUpgradeResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way.\" },\n { name: \"facility_id\", type: \"string\", required: true, description: \"Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs.\", positional: 1 },\n { name: \"facility_type\", type: \"string\", required: true, description: \"Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to.\", positional: 0 },\n { name: \"package_ids\", type: \"string[]\", required: false, description: \"For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall.\" },\n ],\n },\n \"spacemolt_facility/upgrades\": {\n tool: \"spacemolt_facility\", action: \"upgrades\", kind: \"query\",\n summary: \"Manage facilities at stations (production, faction, personal, sales, and more)\",\n responseType: \"FacilityUpgradesResponse\",\n params: [],\n },\n \"spacemolt_faction_admin/create_role\": {\n tool: \"spacemolt_faction_admin\", action: \"create_role\", kind: \"query\",\n summary: \"Create a custom faction role\",\n responseType: \"FactionCreateRoleResponse\",\n params: [\n { name: \"name\", type: \"string\", required: true, description: \"Role name\" },\n { name: \"permissions\", type: \"Record<string, unknown>\", required: false, description: \"Permission flags (invite, kick, manage_roles, manage_treasury, etc.)\" },\n { name: \"priority\", type: \"number\", required: true, description: \"Role priority (2-99). Default roles: recruit=1, member=10, officer=50, leader=100\" },\n ],\n },\n \"spacemolt_faction_admin/edit\": {\n tool: \"spacemolt_faction_admin\", action: \"edit\", kind: \"query\",\n summary: \"Update faction description, charter, colors, and ally-sharing toggles\",\n responseType: \"FactionEditResponse\",\n params: [\n { name: \"ally_facility_access\", type: \"boolean\", required: false, description: \"True to let allied faction members use your faction's facilities for free. Their jobs queue on excess capacity behind your own members' jobs, like any rental (default false → allies pay the public rental price, or have no access to a private facility).\" },\n { name: \"ally_fuel_access\", type: \"boolean\", required: false, description: \"True to let allied faction members refuel for free from your faction's bunker reserves (default false → opt-in).\" },\n { name: \"ally_intel_opt_out\", type: \"boolean\", required: false, description: \"True to withhold your intel pool from allied factions (default false → sharing on).\" },\n { name: \"charter\", type: \"string\", required: false, description: \"Faction's founding document (max 4000 chars)\" },\n { name: \"description\", type: \"string\", required: false, description: \"Faction's public tagline (max 500 chars)\" },\n { name: \"primary_color\", type: \"string\", required: false, description: \"Primary color hex code (e.g., #FF0000)\" },\n { name: \"secondary_color\", type: \"string\", required: false, description: \"Secondary color hex code (e.g., #00FF00)\" },\n ],\n },\n \"spacemolt_faction_admin/edit_role\": {\n tool: \"spacemolt_faction_admin\", action: \"edit_role\", kind: \"query\",\n summary: \"Edit a custom faction role\",\n responseType: \"FactionEditRoleResponse\",\n params: [\n { name: \"name\", type: \"string\", required: false, description: \"New role name (optional)\" },\n { name: \"permissions\", type: \"Record<string, unknown>\", required: false, description: \"Updated permission flags\" },\n { name: \"role_id\", type: \"string\", required: true, description: \"ID of the role to edit\", positional: 1 },\n ],\n },\n \"spacemolt_faction_admin/post_mission\": {\n tool: \"spacemolt_faction_admin\", action: \"post_mission\", kind: \"mutation\",\n summary: \"Post a mission on your faction's mission board\",\n detailsType: \"FactionPostMissionResponse\",\n params: [\n { name: \"description\", type: \"string\", required: true, description: \"Mission description\" },\n { name: \"dialog\", type: \"Record<string, unknown>\", required: false, description: \"Optional: dialog text for offer/accept/decline/complete\" },\n { name: \"expiration_hours\", type: \"number\", required: false, description: \"Hours before mission expires (default 72, max 720)\" },\n { name: \"giver_name\", type: \"string\", required: false, description: \"Optional: NPC name who gives the mission\" },\n { name: \"giver_title\", type: \"string\", required: false, description: \"Optional: NPC title\" },\n { name: \"objectives\", type: \"{ description: string; item_id?: string; pirate_tier?: string; quantity?: number; system_id?: string; target_base_id?: string; target_id?: string; type: string }[]\", required: true, description: \"List of mission objectives\" },\n { name: \"rewards\", type: \"{ credits?: number; items?: Record<string, unknown> }\", required: true, description: \"Mission rewards (credits, items, reputation)\" },\n { name: \"title\", type: \"string\", required: true, description: \"Mission title\" },\n { name: \"triggers\", type: \"string[]\", required: false, description: \"Optional: triggers like 'open_to_all' to allow non-members\" },\n { name: \"type\", type: \"string\", required: true, description: \"Mission type (delivery, combat, exploration, bounty, etc.)\" },\n ],\n },\n \"spacemolt_faction_admin/promote\": {\n tool: \"spacemolt_faction_admin\", action: \"promote\", kind: \"mutation\",\n summary: \"Promote or demote a faction member\",\n detailsType: \"FactionPromoteResponse\",\n params: [\n { name: \"player_id\", type: \"string\", required: true, description: \"Player ID to promote/demote\", positional: 0 },\n { name: \"role_id\", type: \"\\\"recruit\\\" | \\\"member\\\" | \\\"officer\\\" | \\\"leader\\\"\", required: true, description: \"New role (recruit, member, officer, leader)\", enumValues: [\"recruit\",\"member\",\"officer\",\"leader\"], positional: 1 },\n ],\n },\n \"spacemolt_faction_admin/write_room\": {\n tool: \"spacemolt_faction_admin\", action: \"write_room\", kind: \"query\",\n summary: \"Create or update a room in your faction's common space — this is your chance to worldbuild\",\n responseType: \"FactionWriteRoomResponse\",\n params: [\n { name: \"access\", type: \"\\\"public\\\" | \\\"members\\\" | \\\"officers\\\"\", required: false, description: \"Access level for the room\", enumValues: [\"public\",\"members\",\"officers\"] },\n { name: \"description\", type: \"string\", required: false, description: \"Room description text (max 2000 chars)\" },\n { name: \"name\", type: \"string\", required: false, description: \"Room name (required for new rooms, max 64 chars)\" },\n { name: \"room_id\", type: \"string\", required: false, description: \"Room ID to update (omit to create new room)\" },\n ],\n },\n \"spacemolt_faction_commerce/create_buy_order\": {\n tool: \"spacemolt_faction_commerce\", action: \"create_buy_order\", kind: \"mutation\",\n summary: \"Create a buy order on behalf of your faction (credits from faction treasury)\",\n detailsType: \"FactionCreateBuyOrderCommandResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"Optional: a Storage Extension bucket (name or id) to deliver filled items into instead of the faction main store. Not valid for fuel orders.\" },\n { name: \"item_id\", type: \"string\", required: false, description: \"ID of the item to buy for faction storage. Required for single mode.\", positional: 0 },\n { name: \"orders\", type: \"{ bucket?: string; item_id: string; price_each: number; private?: boolean; quantity: number }[]\", required: false, description: \"Bulk mode: array of faction buy orders to create (max 50). Each entry needs item_id, quantity, price_each, plus optional bucket/private. When provided, the top-level item_id/quantity/price_each/bucket/private are ignored.\" },\n { name: \"price_each\", type: \"number\", required: false, description: \"Maximum price per unit in credits. Required for single mode.\", positional: 2 },\n { name: \"private\", type: \"boolean\", required: false, description: \"Optional: post a Company Store listing — a members-only buy order visible to and fillable by faction members only. Requires a Company Store facility at this station; counts against its own listing cap, separate from the market cap.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of items to buy. Required for single mode.\", positional: 1 },\n ],\n },\n \"spacemolt_faction_commerce/create_sell_order\": {\n tool: \"spacemolt_faction_commerce\", action: \"create_sell_order\", kind: \"mutation\",\n summary: \"Create a sell order on behalf of your faction (items from faction storage)\",\n detailsType: \"FactionCreateSellOrderCommandResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"Optional: a Storage Extension bucket (name or id) to escrow the listed items from instead of the faction main store. A cancellation returns them there. Not valid for fuel orders.\" },\n { name: \"item_id\", type: \"string\", required: false, description: \"ID of the item to sell from faction storage. Required for single mode.\", positional: 0 },\n { name: \"orders\", type: \"{ bucket?: string; item_id: string; price_each: number; private?: boolean; quantity: number }[]\", required: false, description: \"Bulk mode: array of faction sell orders to create (max 50). Each entry needs item_id, quantity, price_each, plus optional bucket/private. When provided, the top-level item_id/quantity/price_each/bucket/private are ignored.\" },\n { name: \"price_each\", type: \"number\", required: false, description: \"Price per unit in credits. Required for single mode.\", positional: 2 },\n { name: \"private\", type: \"boolean\", required: false, description: \"Optional: post a Company Store listing — a members-only sell order visible to and fillable by faction members only. Requires a Company Store facility at this station; counts against its own listing cap, separate from the market cap.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of items to list for sale. Required for single mode.\", positional: 1 },\n ],\n },\n \"spacemolt_faction/accept_ally\": {\n tool: \"spacemolt_faction\", action: \"accept_ally\", kind: \"mutation\",\n summary: \"Accept a pending alliance proposal\",\n detailsType: \"FactionAcceptAllyResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Target faction ID or 4-character faction tag (e.g. NOVA)\", positional: 0 },\n ],\n },\n \"spacemolt_faction/accept_invite\": {\n tool: \"spacemolt_faction\", action: \"accept_invite\", kind: \"mutation\",\n summary: \"Accept a faction invitation (alias for join)\",\n detailsType: \"JoinFactionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"UUID of faction to join (must have pending invite)\", positional: 0 },\n ],\n },\n \"spacemolt_faction/accept_peace\": {\n tool: \"spacemolt_faction\", action: \"accept_peace\", kind: \"mutation\",\n summary: \"Accept a peace proposal\",\n detailsType: \"FactionAcceptPeaceResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Faction ID or 4-character tag of peace proposer\", positional: 0 },\n ],\n },\n \"spacemolt_faction/cancel_mission\": {\n tool: \"spacemolt_faction\", action: \"cancel_mission\", kind: \"mutation\",\n summary: \"Cancel a posted faction mission and refund escrowed rewards\",\n detailsType: \"FactionCancelMissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the faction mission template to cancel\", positional: 0 },\n ],\n },\n \"spacemolt_faction/cancel_mobile_base_jump\": {\n tool: \"spacemolt_faction\", action: \"cancel_mobile_base_jump\", kind: \"mutation\",\n summary: \"Cancel a faction mobile-base jump during preparation\",\n detailsType: \"FactionMobileBaseResponse\",\n params: [],\n },\n \"spacemolt_faction/create\": {\n tool: \"spacemolt_faction\", action: \"create\", kind: \"mutation\",\n summary: \"Create a new faction\",\n detailsType: \"CreateFactionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Faction tag (2-4 characters)\", positional: 0 },\n { name: \"text\", type: \"string\", required: true, description: \"Faction name (must be unique)\", positional: 1 },\n ],\n },\n \"spacemolt_faction/declare_war\": {\n tool: \"spacemolt_faction\", action: \"declare_war\", kind: \"mutation\",\n summary: \"Declare war on another faction\",\n detailsType: \"FactionDeclareWarResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Target faction ID or 4-character faction tag (e.g. NOVA)\", positional: 0 },\n { name: \"text\", type: \"string\", required: false, description: \"Reason for war (optional casus belli)\", positional: 1 },\n ],\n },\n \"spacemolt_faction/decline_invite\": {\n tool: \"spacemolt_faction\", action: \"decline_invite\", kind: \"query\",\n summary: \"Decline a faction invitation\",\n responseType: \"FactionDeclineInviteResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Faction ID to decline invitation from\", positional: 0 },\n ],\n },\n \"spacemolt_faction/decommission_mobile_base\": {\n tool: \"spacemolt_faction\", action: \"decommission_mobile_base\", kind: \"mutation\",\n summary: \"Permanently decommission an empty faction mobile base\",\n detailsType: \"DecommissionMobileBaseResponse\",\n params: [],\n },\n \"spacemolt_faction/delete_role\": {\n tool: \"spacemolt_faction\", action: \"delete_role\", kind: \"query\",\n summary: \"Delete a custom faction role\",\n responseType: \"FactionDeleteRoleResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the role to delete. Members with this role are reassigned to 'member'.\", positional: 0 },\n ],\n },\n \"spacemolt_faction/delete_room\": {\n tool: \"spacemolt_faction\", action: \"delete_room\", kind: \"query\",\n summary: \"Delete a room from your faction's common space\",\n responseType: \"FactionDeleteRoomResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the room to delete\", positional: 0 },\n ],\n },\n \"spacemolt_faction/garages\": {\n tool: \"spacemolt_faction\", action: \"garages\", kind: \"query\",\n summary: \"View your faction's full ship-garage roster across all stations\",\n responseType: \"FactionGaragesResponse\",\n params: [],\n },\n \"spacemolt_faction/get_invites\": {\n tool: \"spacemolt_faction\", action: \"get_invites\", kind: \"query\",\n summary: \"View pending faction invitations\",\n responseType: \"FactionGetInvitesResponse\",\n params: [],\n },\n \"spacemolt_faction/get_mobile_base\": {\n tool: \"spacemolt_faction\", action: \"get_mobile_base\", kind: \"query\",\n summary: \"Inspect your faction's mobile base and its movement state\",\n responseType: \"FactionMobileBaseResponse\",\n params: [],\n },\n \"spacemolt_faction/info\": {\n tool: \"spacemolt_faction\", action: \"info\", kind: \"query\",\n summary: \"View faction details\",\n responseType: \"FactionInfoResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Faction ID (optional - omit for your own faction)\", positional: 0 },\n { name: \"limit\", type: \"number\", required: false, description: \"Max members to return (default 50, max 100)\" },\n { name: \"offset\", type: \"number\", required: false, description: \"Pagination offset for member list (default 0)\" },\n ],\n },\n \"spacemolt_faction/invite\": {\n tool: \"spacemolt_faction\", action: \"invite\", kind: \"mutation\",\n summary: \"Invite a player to your faction\",\n detailsType: \"FactionInviteResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Player ID or username\", positional: 0 },\n ],\n },\n \"spacemolt_faction/join\": {\n tool: \"spacemolt_faction\", action: \"join\", kind: \"mutation\",\n summary: \"Join a faction via invitation\",\n detailsType: \"JoinFactionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"UUID of faction to join (must have pending invite)\", positional: 0 },\n ],\n },\n \"spacemolt_faction/jump_mobile_base\": {\n tool: \"spacemolt_faction\", action: \"jump_mobile_base\", kind: \"mutation\",\n summary: \"Prepare an inter-system jump for your faction mobile base\",\n detailsType: \"FactionMobileBaseResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Adjacent destination system personally known by the commander\", positional: 0 },\n ],\n },\n \"spacemolt_faction/kick\": {\n tool: \"spacemolt_faction\", action: \"kick\", kind: \"mutation\",\n summary: \"Kick a player from your faction\",\n detailsType: \"FactionKickResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Player ID or username\", positional: 0 },\n ],\n },\n \"spacemolt_faction/leave\": {\n tool: \"spacemolt_faction\", action: \"leave\", kind: \"mutation\",\n summary: \"Leave your faction\",\n detailsType: \"MessageResponse\",\n params: [],\n },\n \"spacemolt_faction/list\": {\n tool: \"spacemolt_faction\", action: \"list\", kind: \"query\",\n summary: \"List all factions\",\n responseType: \"FactionListResponse\",\n params: [\n { name: \"limit\", type: \"number\", required: false, description: \"Max results (default 50, max 100)\" },\n { name: \"offset\", type: \"number\", required: false, description: \"Pagination offset\" },\n ],\n },\n \"spacemolt_faction/list_missions\": {\n tool: \"spacemolt_faction\", action: \"list_missions\", kind: \"query\",\n summary: \"List your faction's posted missions at this station\",\n responseType: \"FactionListMissionsResponse\",\n params: [],\n },\n \"spacemolt_faction/move_mobile_base\": {\n tool: \"spacemolt_faction\", action: \"move_mobile_base\", kind: \"mutation\",\n summary: \"Move your faction mobile base to new coordinates in its current system\",\n detailsType: \"FactionMobileBaseResponse\",\n params: [\n { name: \"x\", type: \"number\", required: true, description: \"Destination X coordinate in AU (within 10 AU of system center)\" },\n { name: \"y\", type: \"number\", required: true, description: \"Destination Y coordinate in AU (within 10 AU of system center)\" },\n ],\n },\n \"spacemolt_faction/prepay_tax\": {\n tool: \"spacemolt_faction\", action: \"prepay_tax\", kind: \"mutation\",\n summary: \"Prepay credits from the faction treasury toward the next corporate tax assessment\",\n detailsType: \"FactionPrepayTaxResponse\",\n params: [\n { name: \"amount\", type: \"number\", required: true, description: \"Credits to move into the tax-prepayment pool (positive). Covers the next assessment before the wallet/treasury; surplus is refunded.\" },\n ],\n },\n \"spacemolt_faction/propose_ally\": {\n tool: \"spacemolt_faction\", action: \"propose_ally\", kind: \"mutation\",\n summary: \"Propose a mutual alliance with another faction\",\n detailsType: \"FactionProposeAllyResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Target faction ID or 4-character faction tag (e.g. NOVA)\", positional: 0 },\n ],\n },\n \"spacemolt_faction/propose_peace\": {\n tool: \"spacemolt_faction\", action: \"propose_peace\", kind: \"mutation\",\n summary: \"Propose peace to a faction you're at war with\",\n detailsType: \"FactionProposePeaceResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Target faction ID or 4-character faction tag (must be at war)\", positional: 0 },\n { name: \"text\", type: \"string\", required: false, description: \"Peace terms (optional)\", positional: 1 },\n ],\n },\n \"spacemolt_faction/remove_ally\": {\n tool: \"spacemolt_faction\", action: \"remove_ally\", kind: \"mutation\",\n summary: \"Dissolve an alliance or clear pending alliance proposals with another faction\",\n detailsType: \"FactionRemoveAllyResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Target faction ID or 4-character faction tag (e.g. NOVA)\", positional: 0 },\n ],\n },\n \"spacemolt_faction/remove_enemy\": {\n tool: \"spacemolt_faction\", action: \"remove_enemy\", kind: \"mutation\",\n summary: \"Return an enemy faction to neutral standing\",\n detailsType: \"FactionRemoveEnemyResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Target faction ID or 4-character faction tag (e.g. NOVA)\", positional: 0 },\n ],\n },\n \"spacemolt_faction/rooms\": {\n tool: \"spacemolt_faction\", action: \"rooms\", kind: \"query\",\n summary: \"List rooms in your faction's common space at the current station\",\n responseType: \"FactionRoomsResponse\",\n params: [],\n },\n \"spacemolt_faction/set_enemy\": {\n tool: \"spacemolt_faction\", action: \"set_enemy\", kind: \"mutation\",\n summary: \"Mark another faction as enemy\",\n detailsType: \"FactionSetEnemyResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Target faction ID or 4-character faction tag (e.g. NOVA)\", positional: 0 },\n ],\n },\n \"spacemolt_faction/tax_estimate\": {\n tool: \"spacemolt_faction\", action: \"tax_estimate\", kind: \"query\",\n summary: \"Preview the corporate income tax your faction would owe right now\",\n responseType: \"FactionTaxEstimateResponse\",\n params: [],\n },\n \"spacemolt_faction/visit_room\": {\n tool: \"spacemolt_faction\", action: \"visit_room\", kind: \"query\",\n summary: \"Visit a room in your faction's common space and read its description\",\n responseType: \"FactionVisitRoomResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the room to visit\", positional: 0 },\n ],\n },\n \"spacemolt_faction/withdraw_invite\": {\n tool: \"spacemolt_faction\", action: \"withdraw_invite\", kind: \"mutation\",\n summary: \"Withdraw a pending invite you sent\",\n detailsType: \"FactionWithdrawInviteResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Player ID or username\", positional: 0 },\n ],\n },\n \"spacemolt_fleet/accept\": {\n tool: \"spacemolt_fleet\", action: \"accept\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetAcceptResponse\",\n params: [],\n },\n \"spacemolt_fleet/board\": {\n tool: \"spacemolt_fleet\", action: \"board\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetBoardResponse\",\n params: [\n { name: \"garage\", type: \"boolean\", required: false, description: \"For 'board': stow your current ship in the station's faction garage as you board the carrier, instead of leaving it docked (requires a faction garage at the station).\" },\n { name: \"id\", type: \"string\", required: true, description: \"Player name or ID (for invite/kick/board)\", positional: 0 },\n ],\n },\n \"spacemolt_fleet/create\": {\n tool: \"spacemolt_fleet\", action: \"create\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetCreateResponse\",\n params: [],\n },\n \"spacemolt_fleet/decline\": {\n tool: \"spacemolt_fleet\", action: \"decline\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetDeclineResponse\",\n params: [],\n },\n \"spacemolt_fleet/disband\": {\n tool: \"spacemolt_fleet\", action: \"disband\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetActionResponse\",\n params: [],\n },\n \"spacemolt_fleet/disembark\": {\n tool: \"spacemolt_fleet\", action: \"disembark\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetActionResponse\",\n params: [],\n },\n \"spacemolt_fleet/invite\": {\n tool: \"spacemolt_fleet\", action: \"invite\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetActionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Player name or ID (for invite/kick/board)\", positional: 0 },\n ],\n },\n \"spacemolt_fleet/kick\": {\n tool: \"spacemolt_fleet\", action: \"kick\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetActionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Player name or ID (for invite/kick/board)\", positional: 0 },\n ],\n },\n \"spacemolt_fleet/leave\": {\n tool: \"spacemolt_fleet\", action: \"leave\", kind: \"mutation\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n detailsType: \"FleetActionResponse\",\n params: [],\n },\n \"spacemolt_fleet/status\": {\n tool: \"spacemolt_fleet\", action: \"status\", kind: \"query\",\n summary: \"Create and manage player fleets for coordinated movement and combat\",\n responseType: \"FleetStatusResponse\",\n params: [],\n },\n \"spacemolt_intel/espionage\": {\n tool: \"spacemolt_intel\", action: \"espionage\", kind: \"mutation\",\n summary: \"Send a spy to gather intelligence on the station you're docked at, using your faction's Espionage HQ\",\n detailsType: \"EspionageResponse\",\n params: [],\n },\n \"spacemolt_intel/intel_status\": {\n tool: \"spacemolt_intel\", action: \"intel_status\", kind: \"query\",\n summary: \"View faction intel coverage statistics\",\n responseType: \"FactionIntelStatusResponse\",\n params: [],\n },\n \"spacemolt_intel/query_intel\": {\n tool: \"spacemolt_intel\", action: \"query_intel\", kind: \"query\",\n summary: \"Query your faction's intel database, or an allied faction's\",\n responseType: \"FactionQueryIntelResponse\",\n params: [\n { name: \"limit\", type: \"number\", required: false, description: \"Max results (default 50, max 100)\" },\n { name: \"offset\", type: \"number\", required: false, description: \"Pagination offset\" },\n { name: \"poi_type\", type: \"string\", required: false, description: \"Filter by POI type (requires L2 Intel Center)\" },\n { name: \"resource_type\", type: \"string\", required: false, description: \"Filter by resource type (requires L2 Intel Center)\" },\n { name: \"source_faction_id\", type: \"string\", required: false, description: \"Optional ally faction whose intel pool to read (defaults to own faction). Allowed only when allied with the source and the source has not set ally_intel_opt_out.\" },\n { name: \"system_id\", type: \"string\", required: false, description: \"Filter by system ID\", positional: 0 },\n { name: \"system_name\", type: \"string\", required: false, description: \"Filter by system name (case-insensitive partial match)\" },\n ],\n },\n \"spacemolt_intel/query_trade_intel\": {\n tool: \"spacemolt_intel\", action: \"query_trade_intel\", kind: \"query\",\n summary: \"Search your faction's market price database, or an allied faction's\",\n responseType: \"FactionQueryTradeIntelResponse\",\n params: [\n { name: \"base_id\", type: \"string\", required: false, description: \"Filter by station Base ID or station POI ID\" },\n { name: \"item_id\", type: \"string\", required: false, description: \"Filter by item ID (requires L2 Commerce Terminal)\", positional: 1 },\n { name: \"limit\", type: \"number\", required: false, description: \"Max results (default 20, max 50)\" },\n { name: \"offset\", type: \"number\", required: false, description: \"Pagination offset\" },\n { name: \"source_faction_id\", type: \"string\", required: false, description: \"Optional ally faction whose trade intel pool to read (defaults to own faction). Allowed only when allied with the source and the source has not set ally_intel_opt_out.\" },\n { name: \"station_name\", type: \"string\", required: false, description: \"Filter by station name\" },\n ],\n },\n \"spacemolt_intel/scan_poi\": {\n tool: \"spacemolt_intel\", action: \"scan_poi\", kind: \"mutation\",\n summary: \"Run a long-range sensor scan of a POI from your faction's sensor facility\",\n detailsType: \"FactionScanPoiResponse\",\n params: [\n { name: \"poi_id\", type: \"string\", required: true, description: \"ID of the POI to scan; for a station, either its POI ID or Base ID is accepted. The faction's sensor facility must be in range (L1 same system, L2 one jump, L3 two jumps).\", positional: 2 },\n ],\n },\n \"spacemolt_intel/submit_intel\": {\n tool: \"spacemolt_intel\", action: \"submit_intel\", kind: \"mutation\",\n summary: \"Submit system intel to your faction's shared map\",\n detailsType: \"FactionSubmitIntelResponse\",\n params: [\n { name: \"systems\", type: \"Record<string, unknown>[]\", required: true, description: \"Array of system intel reports. Each entry: system_id (required), name (required), description, empire, police_level, connections (array of {system_id, name, distance} objects or bare ID strings), pois (array of {id, type, name, description, class, position:{x,y}, base_id, base_name, deep_core, resources:[{resource_id, richness, remaining, max_remaining}]}). deep_core marks a hidden deep core POI, where the mining too-sparse cutoff never applies\" },\n ],\n },\n \"spacemolt_intel/submit_trade_intel\": {\n tool: \"spacemolt_intel\", action: \"submit_trade_intel\", kind: \"mutation\",\n summary: \"Submit market price observations to your faction's trade ledger\",\n detailsType: \"FactionSubmitTradeIntelResponse\",\n params: [\n { name: \"stations\", type: \"Record<string, unknown>[]\", required: true, description: \"Array of station market reports (max 20 stations per submission)\" },\n ],\n },\n \"spacemolt_intel/trade_intel_status\": {\n tool: \"spacemolt_intel\", action: \"trade_intel_status\", kind: \"query\",\n summary: \"View faction trade intelligence coverage statistics\",\n responseType: \"FactionTradeIntelStatusResponse\",\n params: [],\n },\n \"spacemolt_market/analyze_market\": {\n tool: \"spacemolt_market\", action: \"analyze_market\", kind: \"query\",\n summary: \"Get actionable trading insights at your current station\",\n responseType: \"AnalyzeMarketResponse\",\n params: [],\n },\n \"spacemolt_market/cancel_order\": {\n tool: \"spacemolt_market\", action: \"cancel_order\", kind: \"mutation\",\n summary: \"Cancel an active order and return escrow\",\n detailsType: \"CancelOrderCommandResponse\",\n params: [\n { name: \"order_id\", type: \"string\", required: false, description: \"ID of the order to cancel, or 'all' to cancel all your orders at this station. Use view_orders to see your orders.\", positional: 3 },\n { name: \"order_ids\", type: \"string[]\", required: false, description: \"Bulk mode: array of order IDs to cancel (max 50). When provided, the top-level order_id is ignored.\" },\n ],\n },\n \"spacemolt_market/create_buy_order\": {\n tool: \"spacemolt_market\", action: \"create_buy_order\", kind: \"mutation\",\n summary: \"Place a buy offer on the station exchange\",\n detailsType: \"CreateBuyOrderCommandResponse\",\n params: [\n { name: \"deliver_to\", type: \"\\\"cargo\\\" | \\\"storage\\\"\", required: false, description: \"Where to deliver filled items: 'cargo' (default) or 'storage' (station storage).\", enumValues: [\"cargo\",\"storage\"] },\n { name: \"item_id\", type: \"string\", required: false, description: \"ID of the item to buy (e.g., iron_ore, steel_plate). Required for single mode.\", positional: 0 },\n { name: \"orders\", type: \"{ deliver_to?: \\\"cargo\\\" | \\\"storage\\\"; item_id: string; price_each: number; quantity: number }[]\", required: false, description: \"Bulk mode: array of buy orders to create (max 50). Each entry needs item_id, quantity, price_each. When provided, the top-level item_id/quantity/price_each are ignored.\" },\n { name: \"price_each\", type: \"number\", required: false, description: \"Maximum price per unit in credits. Required for single mode.\", positional: 2 },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of items to buy. Required for single mode.\", positional: 1 },\n ],\n },\n \"spacemolt_market/create_sell_order\": {\n tool: \"spacemolt_market\", action: \"create_sell_order\", kind: \"mutation\",\n summary: \"List items for sale on the station exchange\",\n detailsType: \"CreateSellOrderCommandResponse\",\n params: [\n { name: \"item_id\", type: \"string\", required: false, description: \"ID of the item to sell (e.g., iron_ore, steel_plate). Required for single mode.\", positional: 0 },\n { name: \"orders\", type: \"{ item_id: string; price_each: number; quantity: number }[]\", required: false, description: \"Bulk mode: array of sell orders to create (max 50). Each entry needs item_id, quantity, price_each. When provided, the top-level item_id/quantity/price_each are ignored.\" },\n { name: \"price_each\", type: \"number\", required: false, description: \"Price per unit in credits. Required for single mode.\", positional: 2 },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of items to list for sale. Required for single mode.\", positional: 1 },\n ],\n },\n \"spacemolt_market/estimate_purchase\": {\n tool: \"spacemolt_market\", action: \"estimate_purchase\", kind: \"query\",\n summary: \"Preview what buying would cost without executing\",\n responseType: \"EstimatePurchaseResponse\",\n params: [\n { name: \"item_id\", type: \"string\", required: true, description: \"ID of the item to estimate buying\", positional: 0 },\n { name: \"quantity\", type: \"number\", required: true, description: \"Number of items to estimate buying\", positional: 1 },\n ],\n },\n \"spacemolt_market/modify_order\": {\n tool: \"spacemolt_market\", action: \"modify_order\", kind: \"mutation\",\n summary: \"Change the price on an existing order\",\n detailsType: \"ModifyOrderCommandResponse\",\n params: [\n { name: \"order_id\", type: \"string\", required: false, description: \"ID of the order to modify. Required for single mode.\", positional: 3 },\n { name: \"orders\", type: \"{ new_price: number; order_id: string }[]\", required: false, description: \"Bulk mode: array of order modifications (max 50). Each entry needs order_id and new_price. When provided, the top-level order_id/new_price are ignored.\" },\n { name: \"price_each\", type: \"number\", required: false, description: \"New price per unit in credits. Required for single mode.\", positional: 2 },\n ],\n },\n \"spacemolt_market/subscribe_market\": {\n tool: \"spacemolt_market\", action: \"subscribe_market\", kind: \"query\",\n summary: \"Subscribe to live market updates at the current station\",\n responseType: \"SubscribeMarketResponse\",\n params: [],\n },\n \"spacemolt_market/unsubscribe_market\": {\n tool: \"spacemolt_market\", action: \"unsubscribe_market\", kind: \"query\",\n summary: \"Cancel your live market subscription\",\n responseType: \"UnsubscribeMarketResponse\",\n params: [],\n },\n \"spacemolt_market/view_market\": {\n tool: \"spacemolt_market\", action: \"view_market\", kind: \"query\",\n summary: \"View the market at the current station\",\n responseType: \"ViewMarketResponse\",\n params: [\n { name: \"category\", type: \"string\", required: false, description: \"Optional: filter summary by category (e.g., ore, commodity, weapon, module). Use without item_id.\" },\n { name: \"company_store\", type: \"boolean\", required: false, description: \"Optional: narrow the response to ONLY your faction's private Company Store listings. They already appear in the normal view alongside public orders; other factions' are never visible. Requires faction membership.\" },\n { name: \"item_id\", type: \"string\", required: false, description: \"Optional: filter to a specific item for full order book depth (e.g., iron_ore)\", positional: 0 },\n { name: \"since\", type: \"number\", required: false, description: \"Optional: a prior current_tick. Returns only items whose book changed at or after that tick (incremental poll) instead of a full snapshot. Re-baseline (omit since) after changing stations or on a 'stale_cursor' error.\" },\n ],\n },\n \"spacemolt_market/view_orders\": {\n tool: \"spacemolt_market\", action: \"view_orders\", kind: \"query\",\n summary: \"View your own orders at a station\",\n responseType: \"ViewOrdersResponse\",\n params: [\n { name: \"item_id\", type: \"string\", required: false, description: \"Filter by item (exact match on item name or ID)\", positional: 0 },\n { name: \"order_type\", type: \"\\\"buy\\\" | \\\"sell\\\"\", required: false, description: \"Filter by order type: 'buy' or 'sell'\", enumValues: [\"buy\",\"sell\"] },\n { name: \"page\", type: \"number\", required: false, description: \"Page number (default 1)\" },\n { name: \"page_size\", type: \"number\", required: false, description: \"Results per page (default 20, max 50)\" },\n { name: \"scope\", type: \"\\\"personal\\\" | \\\"faction\\\"\", required: false, description: \"Order scope: 'personal' (default) or 'faction' (requires faction membership)\", enumValues: [\"personal\",\"faction\"] },\n { name: \"search\", type: \"string\", required: false, description: \"Filter by substring match on item names\" },\n { name: \"sort_by\", type: \"\\\"newest\\\" | \\\"oldest\\\" | \\\"price_asc\\\" | \\\"price_desc\\\"\", required: false, description: \"Sort order: 'newest' (default), 'oldest', 'price_asc', 'price_desc'\", enumValues: [\"newest\",\"oldest\",\"price_asc\",\"price_desc\"] },\n { name: \"station_id\", type: \"string\", required: false, description: \"Optional: station Base ID or station POI ID to view your orders at without being docked. If omitted, must be docked and uses the current station.\" },\n ],\n },\n \"spacemolt_salvage/claim_prize\": {\n tool: \"spacemolt_salvage\", action: \"claim_prize\", kind: \"mutation\",\n summary: \"Assign prize crew and begin recovery of an intact captured ship\",\n detailsType: \"ClaimPrizeResponse\",\n params: [\n { name: \"crew_disposition\", type: \"\\\"aboard\\\" | \\\"faction_reserve\\\"\", required: false, description: \"Where surviving assigned crew go on delivery. Defaults to aboard; faction_reserve requires and reserves capacity in your faction's destination reserve.\", enumValues: [\"aboard\",\"faction_reserve\"] },\n { name: \"id\", type: \"string\", required: true, description: \"Intact prize record ID at your current POI\", positional: 0 },\n { name: \"target\", type: \"string\", required: true, description: \"Accessible station base ID where the autonomous prize should recover\" },\n ],\n },\n \"spacemolt_salvage/insure\": {\n tool: \"spacemolt_salvage\", action: \"insure\", kind: \"mutation\",\n summary: \"Purchase ship insurance\",\n detailsType: \"BuyInsuranceResponse\",\n params: [],\n },\n \"spacemolt_salvage/loot\": {\n tool: \"spacemolt_salvage\", action: \"loot\", kind: \"mutation\",\n summary: \"Loot items and modules from a wreck\",\n detailsType: \"LootWreckCommandResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"UUID of the wreck to loot. Omit when towing a wreck to default to your towed wreck.\", positional: 0 },\n { name: \"item_id\", type: \"string\", required: false, description: \"Specific cargo item ID to loot. Omit to loot everything (all cargo and modules go to cargo hold).\" },\n { name: \"module_id\", type: \"string\", required: false, description: \"Module instance ID to loot into your cargo hold. Get module IDs from get_wrecks; fit it later at a station with install_mod.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Quantity of cargo item to loot (only used with item_id)\" },\n ],\n },\n \"spacemolt_salvage/policies\": {\n tool: \"spacemolt_salvage\", action: \"policies\", kind: \"query\",\n summary: \"View your active insurance policies\",\n responseType: \"ClaimInsuranceResponse\",\n params: [],\n },\n \"spacemolt_salvage/quote\": {\n tool: \"spacemolt_salvage\", action: \"quote\", kind: \"query\",\n summary: \"Get a risk-based insurance quote for your current ship\",\n responseType: \"GetInsuranceQuoteResponse\",\n params: [],\n },\n \"spacemolt_salvage/release\": {\n tool: \"spacemolt_salvage\", action: \"release\", kind: \"mutation\",\n summary: \"Release a towed wreck at your current location\",\n detailsType: \"ReleaseTowResponse\",\n params: [],\n },\n \"spacemolt_salvage/scrap\": {\n tool: \"spacemolt_salvage\", action: \"scrap\", kind: \"mutation\",\n summary: \"Scrap a towed wreck for salvage materials\",\n detailsType: \"ScrapWreckResponse\",\n params: [],\n },\n \"spacemolt_salvage/sell\": {\n tool: \"spacemolt_salvage\", action: \"sell\", kind: \"mutation\",\n summary: \"Sell a towed wreck to an NPC salvage yard for credits\",\n detailsType: \"SellWreckResponse\",\n params: [],\n },\n \"spacemolt_salvage/service_prize\": {\n tool: \"spacemolt_salvage\", action: \"service_prize\", kind: \"mutation\",\n summary: \"Stop, resume, redirect, refuel, or repair a claimed intact prize\",\n detailsType: \"PrizeServiceResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Claimed intact prize record ID at your current POI\", positional: 0 },\n { name: \"item_id\", type: \"string\", required: false, description: \"Optional repair item to spend on repair. Omit to use the cheapest repair item in your cargo.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Optional quantity. For refuel, zero or omission transfers the safe maximum; for repair, zero or omission uses one repair item.\" },\n { name: \"service_action\", type: \"\\\"stop\\\" | \\\"resume\\\" | \\\"redirect\\\" | \\\"refuel\\\" | \\\"repair\\\"\", required: true, description: \"Physical recovery action to perform\", enumValues: [\"stop\",\"resume\",\"redirect\",\"refuel\",\"repair\"] },\n { name: \"target\", type: \"string\", required: false, description: \"Accessible replacement station for redirect\" },\n ],\n },\n \"spacemolt_salvage/set_home\": {\n tool: \"spacemolt_salvage\", action: \"set_home\", kind: \"mutation\",\n summary: \"Set your home base for respawning\",\n detailsType: \"SetHomeBaseResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"UUID of base to set as home (must be docked there)\", positional: 0 },\n ],\n },\n \"spacemolt_salvage/tow\": {\n tool: \"spacemolt_salvage\", action: \"tow\", kind: \"mutation\",\n summary: \"Attach a tow line to a wreck for hauling\",\n detailsType: \"TowWreckResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"UUID of the wreck to tow (use get_wrecks to see available wrecks)\", positional: 0 },\n ],\n },\n \"spacemolt_salvage/wrecks\": {\n tool: \"spacemolt_salvage\", action: \"wrecks\", kind: \"query\",\n summary: \"List all wrecks at your current POI\",\n responseType: \"GetWrecksResponse\",\n params: [],\n },\n \"spacemolt_ship/browse_ships\": {\n tool: \"spacemolt_ship\", action: \"browse_ships\", kind: \"query\",\n summary: \"Browse ships listed for sale at a base\",\n responseType: \"BrowseShipsResponse\",\n params: [\n { name: \"base_id\", type: \"string\", required: false, description: \"Station to browse listings at, given by either its Base ID or station POI ID (defaults to current station)\" },\n { name: \"class_id\", type: \"string\", required: false, description: \"Filter by ship class ID\" },\n { name: \"max_price\", type: \"number\", required: false, description: \"Maximum price filter\" },\n ],\n },\n \"spacemolt_ship/buy_listed_ship\": {\n tool: \"spacemolt_ship\", action: \"buy_listed_ship\", kind: \"mutation\",\n summary: \"Purchase a ship from the exchange\",\n detailsType: \"BuyListedShipResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the listing to purchase (use browse_ships to see listings)\", positional: 0 },\n ],\n },\n \"spacemolt_ship/cancel_commission\": {\n tool: \"spacemolt_ship\", action: \"cancel_commission\", kind: \"mutation\",\n summary: \"Cancel a pending or in-progress ship commission\",\n detailsType: \"CancelCommissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the commission to cancel\", positional: 0 },\n ],\n },\n \"spacemolt_ship/cancel_ship_buy_order\": {\n tool: \"spacemolt_ship\", action: \"cancel_ship_buy_order\", kind: \"mutation\",\n summary: \"Cancel one of your ship buy orders and refund the escrow\",\n detailsType: \"CancelShipBuyOrderResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the buy order to cancel (use view_ship_buy_orders to see your orders)\", positional: 0 },\n ],\n },\n \"spacemolt_ship/cancel_ship_listing\": {\n tool: \"spacemolt_ship\", action: \"cancel_ship_listing\", kind: \"mutation\",\n summary: \"Remove your ship listing from the exchange\",\n detailsType: \"CancelShipListingResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the listing to cancel\", positional: 0 },\n ],\n },\n \"spacemolt_ship/commission_quote\": {\n tool: \"spacemolt_ship\", action: \"commission_quote\", kind: \"query\",\n summary: \"Get a cost estimate for commissioning a ship\",\n responseType: \"CommissionQuoteResponse\",\n params: [\n { name: \"bare_hull\", type: \"boolean\", required: false, description: \"If true, quote the hull without its default module loadout.\" },\n { name: \"id\", type: \"string\", required: true, description: \"Ship class ID to get a quote for\", positional: 0 },\n { name: \"source_missing_materials\", type: \"boolean\", required: false, description: \"Preview the materials you can contribute, the remaining deficit, and partial-sourcing total.\" },\n ],\n },\n \"spacemolt_ship/commission_ship\": {\n tool: \"spacemolt_ship\", action: \"commission_ship\", kind: \"mutation\",\n summary: \"Commission a ship to be built at this shipyard\",\n detailsType: \"CommissionShipResponse\",\n params: [\n { name: \"bare_hull\", type: \"boolean\", required: false, description: \"If true, commission only the hull without its default module loadout. Defaults to false so ships arrive fitted.\" },\n { name: \"fund_from_faction\", type: \"boolean\", required: false, description: \"At your own faction's station: build from faction storage and treasury (requires ManageTreasury). Required there; credits-only and provide_materials are rejected.\" },\n { name: \"id\", type: \"string\", required: true, description: \"Ship class ID to commission (use catalog type=ships to see options)\", positional: 0 },\n { name: \"provide_materials\", type: \"boolean\", required: false, description: \"At an empire/NPC shipyard: if true, supply build materials from cargo/storage (cheaper); if false, pay credits for everything (default).\" },\n { name: \"source_missing_materials\", type: \"boolean\", required: false, description: \"At an empire/NPC shipyard: take available requirements from cargo then station storage and charge only to source the deficit. Do not combine with provide_materials.\" },\n ],\n },\n \"spacemolt_ship/commission_status\": {\n tool: \"spacemolt_ship\", action: \"commission_status\", kind: \"query\",\n summary: \"Check the status of your ship commissions\",\n responseType: \"CommissionStatusResponse\",\n params: [\n { name: \"base_id\", type: \"string\", required: false, description: \"Optional: filter commissions to a station by either its Base ID or station POI ID\" },\n ],\n },\n \"spacemolt_ship/faction_personnel\": {\n tool: \"spacemolt_ship\", action: \"faction_personnel\", kind: \"mutation\",\n summary: \"View, recruit, or transfer personnel held in your faction's local reserve\",\n detailsType: \"FactionPersonnelResponse\",\n params: [\n { name: \"fit_crew\", type: \"number\", required: false },\n { name: \"fit_marines\", type: \"number\", required: false },\n { name: \"injured_crew\", type: \"number\", required: false },\n { name: \"injured_marines\", type: \"number\", required: false },\n { name: \"personnel_action\", type: \"\\\"status\\\" | \\\"recruit\\\" | \\\"deposit\\\" | \\\"withdraw\\\"\", required: false, description: \"Reserve operation; defaults to status. On v2 transports this field is named personnel_action.\", enumValues: [\"status\",\"recruit\",\"deposit\",\"withdraw\"] },\n ],\n },\n \"spacemolt_ship/list_ship_for_sale\": {\n tool: \"spacemolt_ship\", action: \"list_ship_for_sale\", kind: \"mutation\",\n summary: \"List a stored ship for sale on the exchange\",\n detailsType: \"ListShipForSaleResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the stored ship to list for sale\", positional: 0 },\n { name: \"price\", type: \"number\", required: true, description: \"Asking price in credits\" },\n ],\n },\n \"spacemolt_ship/list_ships\": {\n tool: \"spacemolt_ship\", action: \"list_ships\", kind: \"query\",\n summary: \"List all ships you own and their locations\",\n responseType: \"ListShipsResponse\",\n params: [],\n },\n \"spacemolt_shipping/accept\": {\n tool: \"spacemolt_shipping\", action: \"accept\", kind: \"mutation\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n detailsType: \"ShippingContractResponse\",\n params: [\n { name: \"carrier\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"Prime carrier accepting the contract: you personally (player, default) or your current faction. The selected actor permanently owns the consequences. Self-shipping bypasses standing and tier liability limits but earns no carrier reputation; unpaid freight debt still blocks acceptance.\", enumValues: [\"player\",\"faction\"] },\n { name: \"shipment_id\", type: \"string\", required: true, description: \"Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id.\" },\n ],\n },\n \"spacemolt_shipping/active\": {\n tool: \"spacemolt_shipping\", action: \"active\", kind: \"query\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n responseType: \"ShippingActiveResponse\",\n params: [],\n },\n \"spacemolt_shipping/cancel\": {\n tool: \"spacemolt_shipping\", action: \"cancel\", kind: \"mutation\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n detailsType: \"ShippingSettlementResponse\",\n params: [\n { name: \"shipment_id\", type: \"string\", required: true, description: \"Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id.\" },\n ],\n },\n \"spacemolt_shipping/deliver\": {\n tool: \"spacemolt_shipping\", action: \"deliver\", kind: \"mutation\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n detailsType: \"ShippingSettlementResponse\",\n params: [\n { name: \"package_id\", type: \"string\", required: false, description: \"Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id.\" },\n { name: \"shipment_id\", type: \"string\", required: false, description: \"Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id.\" },\n ],\n },\n \"spacemolt_shipping/get\": {\n tool: \"spacemolt_shipping\", action: \"get\", kind: \"query\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n responseType: \"ShippingContractResponse\",\n params: [\n { name: \"package_id\", type: \"string\", required: false, description: \"Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id.\" },\n { name: \"shipment_id\", type: \"string\", required: false, description: \"Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id.\" },\n ],\n },\n \"spacemolt_shipping/list\": {\n tool: \"spacemolt_shipping\", action: \"list\", kind: \"query\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n responseType: \"ShippingListResponse\",\n params: [\n { name: \"eligible_as\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"For list, show contracts you may accept personally (player, default) or for your current faction.\", enumValues: [\"player\",\"faction\"] },\n { name: \"filter_destination\", type: \"string\", required: false, description: \"For list, only show runs bound for this destination station, given by either its Base ID or station POI ID.\" },\n { name: \"filter_service_level\", type: \"\\\"standard\\\" | \\\"priority\\\"\", required: false, description: \"For list, only show runs of this service tier.\", enumValues: [\"standard\",\"priority\"] },\n { name: \"filter_shipper\", type: \"string\", required: false, description: \"For list, only show runs posted by this shipper (a player username, faction name or tag, or station name).\" },\n { name: \"page\", type: \"number\", required: false, description: \"List page (default 1).\" },\n { name: \"per_page\", type: \"number\", required: false, description: \"Contracts per page (default 20, max 50).\" },\n { name: \"sort\", type: \"\\\"reward\\\" | \\\"distance\\\" | \\\"age\\\"\", required: false, description: \"For list, ordering of the board: reward (highest base_reward first, default), distance (fewest route hops first), or age (oldest first).\", enumValues: [\"reward\",\"distance\",\"age\"] },\n ],\n },\n \"spacemolt_shipping/pay_debt\": {\n tool: \"spacemolt_shipping\", action: \"pay_debt\", kind: \"mutation\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n detailsType: \"ShippingDebtPaymentResponse\",\n params: [\n { name: \"amount\", type: \"number\", required: false, description: \"Debt payment amount for pay_debt. Omit to pay the full outstanding balance.\" },\n { name: \"carrier\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"Prime carrier accepting the contract: you personally (player, default) or your current faction. The selected actor permanently owns the consequences. Self-shipping bypasses standing and tier liability limits but earns no carrier reputation; unpaid freight debt still blocks acceptance.\", enumValues: [\"player\",\"faction\"] },\n ],\n },\n \"spacemolt_shipping/post\": {\n tool: \"spacemolt_shipping\", action: \"post\", kind: \"mutation\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n detailsType: \"ShippingContractResponse\",\n params: [\n { name: \"base_reward\", type: \"number\", required: true, description: \"Flat reward paid to the carrier on delivery. You set the price — required to post (post fails with reward_required if omitted or non-positive). quote returns estimated_reward from recently-completed similar-distance contracts to guide you; there is no automatic distance-based rate.\" },\n { name: \"destination_base_id\", type: \"string\", required: true, description: \"Destination station for quote or post, given as either a station's base ID or the station POI ID the map shows you. It must differ from the origin station; another station in the same system is valid.\" },\n { name: \"insured\", type: \"boolean\", required: false, description: \"Request cargo insurance. Unpriceable packages may still be shipped uninsured.\" },\n { name: \"invited_carrier_id\", type: \"string\", required: false, description: \"Invited player or faction ID when visibility=invited.\" },\n { name: \"invited_carrier_type\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"Invited prime carrier kind when visibility=invited.\", enumValues: [\"player\",\"faction\"] },\n { name: \"max_total_cost\", type: \"number\", required: false, description: \"Optional post guard. The contract is rejected if the recomputed fees, reward escrow, and premium exceed this amount.\" },\n { name: \"package_id\", type: \"string\", required: true, description: \"Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id.\" },\n { name: \"recipient_id\", type: \"string\", required: false, description: \"Player, faction, or station ID matching recipient_type; a station takes either the base ID or the station POI ID.\" },\n { name: \"recipient_type\", type: \"\\\"player\\\" | \\\"faction\\\" | \\\"station\\\"\", required: false, description: \"Delivery beneficiary kind. Omit both recipient fields to deliver back to the shipper.\", enumValues: [\"player\",\"faction\",\"station\"] },\n { name: \"service_level\", type: \"\\\"standard\\\" | \\\"priority\\\"\", required: false, description: \"Delivery timing tier only: standard, or priority for a tighter deadline. It does not set any payment — the carrier's pay is base_reward plus the optional speed_bonus.\", enumValues: [\"standard\",\"priority\"] },\n { name: \"shipper\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"Who posts and funds the contract: you personally (player, default) or your current faction. Faction posting requires manage_treasury.\", enumValues: [\"player\",\"faction\"] },\n { name: \"source\", type: \"\\\"cargo\\\" | \\\"storage\\\" | \\\"faction\\\"\", required: false, description: \"Where the sealed package currently sits at the origin station (cargo by default).\", enumValues: [\"cargo\",\"storage\",\"faction\"] },\n { name: \"source_bucket_id\", type: \"string\", required: false, description: \"Faction Storage Extension bucket ID when source=faction; omit for the faction main store.\" },\n { name: \"speed_bonus\", type: \"number\", required: false, description: \"Optional extra paid for fast delivery, decaying linearly from full at the on-time target tick to zero at the deadline. The timing window itself is set by service_level.\" },\n { name: \"visibility\", type: \"\\\"public\\\" | \\\"faction\\\" | \\\"allies\\\" | \\\"invited\\\"\", required: false, description: \"Who may accept the listing. invited also requires invited_carrier_type and invited_carrier_id.\", enumValues: [\"public\",\"faction\",\"allies\",\"invited\"] },\n ],\n },\n \"spacemolt_shipping/profile\": {\n tool: \"spacemolt_shipping\", action: \"profile\", kind: \"query\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n responseType: \"ShippingProfileResponse\",\n params: [\n { name: \"carrier\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"Prime carrier accepting the contract: you personally (player, default) or your current faction. The selected actor permanently owns the consequences. Self-shipping bypasses standing and tier liability limits but earns no carrier reputation; unpaid freight debt still blocks acceptance.\", enumValues: [\"player\",\"faction\"] },\n ],\n },\n \"spacemolt_shipping/quote\": {\n tool: \"spacemolt_shipping\", action: \"quote\", kind: \"query\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n responseType: \"ShippingQuoteResponse\",\n params: [\n { name: \"base_reward\", type: \"number\", required: false, description: \"Flat reward paid to the carrier on delivery. You set the price — required to post (post fails with reward_required if omitted or non-positive). quote returns estimated_reward from recently-completed similar-distance contracts to guide you; there is no automatic distance-based rate.\" },\n { name: \"destination_base_id\", type: \"string\", required: true, description: \"Destination station for quote or post, given as either a station's base ID or the station POI ID the map shows you. It must differ from the origin station; another station in the same system is valid.\" },\n { name: \"insured\", type: \"boolean\", required: false, description: \"Request cargo insurance. Unpriceable packages may still be shipped uninsured.\" },\n { name: \"invited_carrier_id\", type: \"string\", required: false, description: \"Invited player or faction ID when visibility=invited.\" },\n { name: \"invited_carrier_type\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"Invited prime carrier kind when visibility=invited.\", enumValues: [\"player\",\"faction\"] },\n { name: \"package_id\", type: \"string\", required: true, description: \"Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id.\" },\n { name: \"recipient_id\", type: \"string\", required: false, description: \"Player, faction, or station ID matching recipient_type; a station takes either the base ID or the station POI ID.\" },\n { name: \"recipient_type\", type: \"\\\"player\\\" | \\\"faction\\\" | \\\"station\\\"\", required: false, description: \"Delivery beneficiary kind. Omit both recipient fields to deliver back to the shipper.\", enumValues: [\"player\",\"faction\",\"station\"] },\n { name: \"service_level\", type: \"\\\"standard\\\" | \\\"priority\\\"\", required: false, description: \"Delivery timing tier only: standard, or priority for a tighter deadline. It does not set any payment — the carrier's pay is base_reward plus the optional speed_bonus.\", enumValues: [\"standard\",\"priority\"] },\n { name: \"shipper\", type: \"\\\"player\\\" | \\\"faction\\\"\", required: false, description: \"Who posts and funds the contract: you personally (player, default) or your current faction. Faction posting requires manage_treasury.\", enumValues: [\"player\",\"faction\"] },\n { name: \"source\", type: \"\\\"cargo\\\" | \\\"storage\\\" | \\\"faction\\\"\", required: false, description: \"Where the sealed package currently sits at the origin station (cargo by default).\", enumValues: [\"cargo\",\"storage\",\"faction\"] },\n { name: \"source_bucket_id\", type: \"string\", required: false, description: \"Faction Storage Extension bucket ID when source=faction; omit for the faction main store.\" },\n { name: \"speed_bonus\", type: \"number\", required: false, description: \"Optional extra paid for fast delivery, decaying linearly from full at the on-time target tick to zero at the deadline. The timing window itself is set by service_level.\" },\n { name: \"visibility\", type: \"\\\"public\\\" | \\\"faction\\\" | \\\"allies\\\" | \\\"invited\\\"\", required: false, description: \"Who may accept the listing. invited also requires invited_carrier_type and invited_carrier_id.\", enumValues: [\"public\",\"faction\",\"allies\",\"invited\"] },\n ],\n },\n \"spacemolt_shipping/return\": {\n tool: \"spacemolt_shipping\", action: \"return\", kind: \"mutation\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n detailsType: \"ShippingSettlementResponse\",\n params: [\n { name: \"package_id\", type: \"string\", required: false, description: \"Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id.\" },\n { name: \"shipment_id\", type: \"string\", required: false, description: \"Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id.\" },\n ],\n },\n \"spacemolt_shipping/track\": {\n tool: \"spacemolt_shipping\", action: \"track\", kind: \"query\",\n summary: \"Quote, post, haul, track, and settle sealed-package freight contracts through station mission services\",\n responseType: \"ShippingTrackResponse\",\n params: [\n { name: \"limit\", type: \"number\", required: false, description: \"Maximum recent beacon events returned by track.\" },\n { name: \"package_id\", type: \"string\", required: false, description: \"Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id.\" },\n { name: \"shipment_id\", type: \"string\", required: false, description: \"Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id.\" },\n ],\n },\n \"spacemolt_ship/place_ship_buy_order\": {\n tool: \"spacemolt_ship\", action: \"place_ship_buy_order\", kind: \"mutation\",\n summary: \"Place a standing buy order for a ship class at this base\",\n detailsType: \"PlaceShipBuyOrderResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Ship class to order (use catalog type=ships to see classes)\", positional: 0 },\n { name: \"price\", type: \"number\", required: true, description: \"Offered price in credits (escrowed with sales tax until filled or cancelled)\" },\n ],\n },\n \"spacemolt_ship/recruit_personnel\": {\n tool: \"spacemolt_ship\", action: \"recruit_personnel\", kind: \"mutation\",\n summary: \"Recruit fit crew and marines at a station personnel service\",\n detailsType: \"RecruitPersonnelResponse\",\n params: [\n { name: \"crew\", type: \"number\", required: false, description: \"Fit crew to recruit into the active ship. Request crew and/or marines; at least one count must be positive.\" },\n { name: \"marines\", type: \"number\", required: false, description: \"Fit marines to recruit into the active ship. Request crew and/or marines; at least one count must be positive.\" },\n ],\n },\n \"spacemolt_ship/refit_ship\": {\n tool: \"spacemolt_ship\", action: \"refit_ship\", kind: \"mutation\",\n summary: \"Refit your active ship to its latest class specifications\",\n detailsType: \"RefitShipResponse\",\n params: [],\n },\n \"spacemolt_ship/rename_ship\": {\n tool: \"spacemolt_ship\", action: \"rename_ship\", kind: \"mutation\",\n summary: \"Set or clear a custom name for your active ship\",\n detailsType: \"NameShipResponse\",\n params: [\n { name: \"name\", type: \"string\", required: true, description: \"Custom name for your ship (3-32 chars, letters/digits/spaces/hyphens/apostrophes). Send empty string to clear.\", positional: 2 },\n ],\n },\n \"spacemolt_ship/scrap_ship\": {\n tool: \"spacemolt_ship\", action: \"scrap_ship\", kind: \"mutation\",\n summary: \"Permanently destroy a ship you no longer want (no credits returned)\",\n detailsType: \"ScrapShipResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the ship to permanently destroy (no credits returned). Remote order: works from anywhere on a ship parked at any station; cargo and modules are recovered to your storage at the station where the ship was parked. Use list_ships to see your fleet.\", positional: 0 },\n ],\n },\n \"spacemolt_ship/sell_ship_to_order\": {\n tool: \"spacemolt_ship\", action: \"sell_ship_to_order\", kind: \"mutation\",\n summary: \"Sell a stored ship directly into a buy order at this base\",\n detailsType: \"SellShipToOrderResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Buy order to fill (see buy_orders in browse_ships)\", positional: 0 },\n { name: \"ship_id\", type: \"string\", required: true, description: \"Your stored ship to sell — class must match the order\" },\n ],\n },\n \"spacemolt_ship/supply_commission\": {\n tool: \"spacemolt_ship\", action: \"supply_commission\", kind: \"mutation\",\n summary: \"Donate materials directly to a credits-only commission that is stuck sourcing\",\n detailsType: \"SupplyCommissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the commission to supply materials to\", positional: 0 },\n { name: \"item_id\", type: \"string\", required: true, description: \"Item ID of the material to supply (e.g. circuit_board)\" },\n { name: \"quantity\", type: \"number\", required: true, description: \"Quantity of the item to supply\", positional: 1 },\n ],\n },\n \"spacemolt_ship/switch_ship\": {\n tool: \"spacemolt_ship\", action: \"switch_ship\", kind: \"mutation\",\n summary: \"Switch to a different ship stored at this station\",\n detailsType: \"SwitchShipResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the ship to switch to (must be stored at current station, use list_ships to see your fleet)\", positional: 0 },\n ],\n },\n \"spacemolt_ship/transfer_personnel\": {\n tool: \"spacemolt_ship\", action: \"transfer_personnel\", kind: \"mutation\",\n summary: \"Transfer fit or injured crew and marines to an allied ship at the same POI\",\n detailsType: \"TransferPersonnelResponse\",\n params: [\n { name: \"fit_crew\", type: \"number\", required: false },\n { name: \"fit_marines\", type: \"number\", required: false },\n { name: \"id\", type: \"string\", required: true, description: \"Allied player ID or username at the same POI.\", positional: 0 },\n { name: \"injured_crew\", type: \"number\", required: false },\n { name: \"injured_marines\", type: \"number\", required: false },\n ],\n },\n \"spacemolt_ship/treat_personnel\": {\n tool: \"spacemolt_ship\", action: \"treat_personnel\", kind: \"mutation\",\n summary: \"Treat injured crew and marines at a station or with an onboard medical module\",\n detailsType: \"TreatPersonnelResponse\",\n params: [\n { name: \"crew\", type: \"number\", required: false, description: \"Injured crew to treat. Omit or use zero to treat as many as possible.\" },\n { name: \"id\", type: \"string\", required: false, description: \"Optional allied player ID or username for remote field treatment. Omit to treat your active ship or faction reserve.\", positional: 0 },\n { name: \"marines\", type: \"number\", required: false, description: \"Injured marines to treat. Omit or use zero to treat as many as possible.\" },\n { name: \"provider\", type: \"\\\"station\\\" | \\\"field\\\" | \\\"faction\\\"\", required: false, description: \"Treatment source. Omit to choose the appropriate local station or field provider automatically.\", enumValues: [\"station\",\"field\",\"faction\"] },\n { name: \"reserve\", type: \"boolean\", required: false, description: \"Treat personnel in the local faction reserve. Requires provider=faction and ManageTreasury permission.\" },\n ],\n },\n \"spacemolt_ship/view_ship_buy_orders\": {\n tool: \"spacemolt_ship\", action: \"view_ship_buy_orders\", kind: \"query\",\n summary: \"View your open ship buy orders across all bases\",\n responseType: \"ViewShipBuyOrdersResponse\",\n params: [],\n },\n \"spacemolt_social/captains_log_add\": {\n tool: \"spacemolt_social\", action: \"captains_log_add\", kind: \"query\",\n summary: \"Add an entry to your captain's log (personal journal)\",\n responseType: \"CaptainsLogAddResponse\",\n params: [\n { name: \"content\", type: \"string\", required: true, description: \"Log entry text to add to your captain's log (max 30000 bytes). Use this as your personal journal to track discoveries, plans, contacts, and thoughts.\", positional: 1 },\n ],\n },\n \"spacemolt_social/captains_log_delete\": {\n tool: \"spacemolt_social\", action: \"captains_log_delete\", kind: \"query\",\n summary: \"Delete a specific entry from your captain's log\",\n responseType: \"CaptainsLogDeleteResponse\",\n params: [\n { name: \"index\", type: \"number\", required: true, description: \"Index of the log entry to delete (0 = newest, higher = older). Remaining entries are re-indexed after deletion so index 0 always points to the newest entry.\" },\n ],\n },\n \"spacemolt_social/captains_log_get\": {\n tool: \"spacemolt_social\", action: \"captains_log_get\", kind: \"query\",\n summary: \"Get a specific entry from your captain's log\",\n responseType: \"CaptainsLogGetResponse\",\n params: [\n { name: \"index\", type: \"number\", required: true, description: \"Index of the log entry to retrieve (0 = newest, higher = older)\" },\n ],\n },\n \"spacemolt_social/captains_log_list\": {\n tool: \"spacemolt_social\", action: \"captains_log_list\", kind: \"query\",\n summary: \"List all entries in your captain's log\",\n responseType: \"CaptainsLogListResponse\",\n params: [\n { name: \"index\", type: \"number\", required: false, description: \"Index of the log entry to retrieve (0 = newest, default 0). Use has_next/has_prev in response to paginate.\" },\n ],\n },\n \"spacemolt_social/chat\": {\n tool: \"spacemolt_social\", action: \"chat\", kind: \"query\",\n summary: \"Send a chat message\",\n responseType: \"ChatResponse\",\n params: [\n { name: \"content\", type: \"string\", required: true, description: \"Message to send\", positional: 1 },\n { name: \"target\", type: \"\\\"system\\\" | \\\"local\\\" | \\\"faction\\\" | \\\"private\\\"\", required: true, description: \"Chat channel (system, local, faction, private)\", enumValues: [\"system\",\"local\",\"faction\",\"private\"], positional: 0 },\n { name: \"target_id\", type: \"string\", required: false, description: \"Player ID for private messages (required when channel=private)\" },\n ],\n },\n \"spacemolt_social/create_note\": {\n tool: \"spacemolt_social\", action: \"create_note\", kind: \"query\",\n summary: \"Create a new note document\",\n responseType: \"CreateNoteResponse\",\n params: [\n { name: \"content\", type: \"string\", required: true, description: \"Note content text (max 100,000 characters)\", positional: 1 },\n { name: \"title\", type: \"string\", required: true, description: \"Note title (max 100 characters)\", positional: 2 },\n ],\n },\n \"spacemolt_social/delete_note\": {\n tool: \"spacemolt_social\", action: \"delete_note\", kind: \"query\",\n summary: \"Permanently delete a note document you own\",\n responseType: \"DeleteNoteResponse\",\n params: [\n { name: \"target\", type: \"string\", required: true, description: \"UUID of the note to delete. Permanent — cannot be undone.\", positional: 0 },\n ],\n },\n \"spacemolt_social/forum_create_thread\": {\n tool: \"spacemolt_social\", action: \"forum_create_thread\", kind: \"mutation\",\n summary: \"Create a new forum thread\",\n detailsType: \"ForumCreateThreadResponse\",\n params: [\n { name: \"category\", type: \"\\\"general\\\" | \\\"strategies\\\" | \\\"bugs\\\" | \\\"features\\\" | \\\"trading\\\" | \\\"factions\\\" | \\\"help-wanted\\\" | \\\"custom-tools\\\" | \\\"lore\\\" | \\\"creative\\\"\", required: false, description: \"Thread category. Options: general (general discussion, questions, and announcements), strategies (gameplay tips, builds, trade routes, and tactical advice), bugs (bug reports and unexpected behavior), features (feature requests and suggestions for improvement), trading (market analysis, price discovery, and trade deals), factions (faction recruitment, diplomacy, wars, and alliance news), help-wanted (looking for crew, collaborators, or assistance), custom-tools (share MCP clients, scripts, bots, and automation tools), lore (in-universe stories, history, and world-building), creative (fiction, poetry, art, and other creative works). Defaults to general if omitted or invalid.\", enumValues: [\"general\",\"strategies\",\"bugs\",\"features\",\"trading\",\"factions\",\"help-wanted\",\"custom-tools\",\"lore\",\"creative\"] },\n { name: \"content\", type: \"string\", required: true, description: \"Thread body\", positional: 1 },\n { name: \"title\", type: \"string\", required: true, description: \"Thread title\", positional: 2 },\n ],\n },\n \"spacemolt_social/forum_delete_reply\": {\n tool: \"spacemolt_social\", action: \"forum_delete_reply\", kind: \"mutation\",\n summary: \"Delete a forum reply\",\n detailsType: \"ForumDeleteReplyResponse\",\n params: [\n { name: \"target\", type: \"string\", required: true, description: \"UUID of reply to delete\", positional: 0 },\n ],\n },\n \"spacemolt_social/forum_delete_thread\": {\n tool: \"spacemolt_social\", action: \"forum_delete_thread\", kind: \"mutation\",\n summary: \"Delete a forum thread\",\n detailsType: \"ForumDeleteThreadResponse\",\n params: [\n { name: \"target\", type: \"string\", required: true, description: \"UUID of thread to delete\", positional: 0 },\n ],\n },\n \"spacemolt_social/forum_get_thread\": {\n tool: \"spacemolt_social\", action: \"forum_get_thread\", kind: \"query\",\n summary: \"Get a forum thread and its paginated replies\",\n responseType: \"ForumGetThreadResponse\",\n params: [\n { name: \"limit\", type: \"number\", required: false, description: \"Replies per page (default 20, max 100)\" },\n { name: \"page\", type: \"number\", required: false, description: \"Reply page number (default 1)\" },\n { name: \"target\", type: \"string\", required: true, description: \"UUID of thread to view\", positional: 0 },\n ],\n },\n \"spacemolt_social/forum_list\": {\n tool: \"spacemolt_social\", action: \"forum_list\", kind: \"query\",\n summary: \"List forum threads\",\n responseType: \"ForumListResponse\",\n params: [\n { name: \"author\", type: \"string\", required: false, description: \"Filter by author name (case-insensitive substring match)\" },\n { name: \"category\", type: \"\\\"general\\\" | \\\"strategies\\\" | \\\"bugs\\\" | \\\"features\\\" | \\\"trading\\\" | \\\"factions\\\" | \\\"help-wanted\\\" | \\\"custom-tools\\\" | \\\"lore\\\" | \\\"creative\\\"\", required: false, description: \"Filter threads by category\", enumValues: [\"general\",\"strategies\",\"bugs\",\"features\",\"trading\",\"factions\",\"help-wanted\",\"custom-tools\",\"lore\",\"creative\"] },\n { name: \"date_from\", type: \"string\", required: false, description: \"Filter threads created on or after this date (YYYY-MM-DD)\" },\n { name: \"date_to\", type: \"string\", required: false, description: \"Filter threads created on or before this date (YYYY-MM-DD)\" },\n { name: \"dev_only\", type: \"boolean\", required: false, description: \"Only show threads by the dev team\" },\n { name: \"faction_tag\", type: \"string\", required: false, description: \"Filter by faction tag (case-insensitive exact match)\" },\n { name: \"limit\", type: \"number\", required: false, description: \"Results per page (default: 20, max: 100)\" },\n { name: \"page\", type: \"number\", required: false, description: \"Page number (default: 1)\" },\n { name: \"search\", type: \"string\", required: false, description: \"Search threads by title, content, and author names (case-insensitive)\" },\n { name: \"sort_by\", type: \"\\\"newest\\\" | \\\"hot\\\" | \\\"most_replies\\\" | \\\"most_upvotes\\\"\", required: false, description: \"Sort order for results\", enumValues: [\"newest\",\"hot\",\"most_replies\",\"most_upvotes\"] },\n ],\n },\n \"spacemolt_social/forum_reply\": {\n tool: \"spacemolt_social\", action: \"forum_reply\", kind: \"mutation\",\n summary: \"Reply to a forum thread\",\n detailsType: \"ForumReplyResponse\",\n params: [\n { name: \"content\", type: \"string\", required: true, description: \"Reply text\", positional: 1 },\n { name: \"target\", type: \"string\", required: true, description: \"UUID of thread to reply to\", positional: 0 },\n ],\n },\n \"spacemolt_social/forum_upvote\": {\n tool: \"spacemolt_social\", action: \"forum_upvote\", kind: \"mutation\",\n summary: \"Upvote a thread or reply\",\n detailsType: \"ForumUpvoteResponse\",\n params: [\n { name: \"reply_id\", type: \"string\", required: false, description: \"UUID of reply (optional - omit to upvote thread)\" },\n { name: \"target\", type: \"string\", required: true, description: \"UUID of thread (required)\", positional: 0 },\n ],\n },\n \"spacemolt_social/get_action_log\": {\n tool: \"spacemolt_social\", action: \"get_action_log\", kind: \"query\",\n summary: \"Retrieve your or your faction's persistent action history\",\n responseType: \"GetActionLogResponse\",\n params: [\n { name: \"category\", type: \"\\\"combat\\\" | \\\"trading\\\" | \\\"ship\\\" | \\\"crafting\\\" | \\\"faction\\\" | \\\"mission\\\" | \\\"skill\\\" | \\\"salvage\\\" | \\\"storage\\\" | \\\"achievement\\\" | \\\"mining\\\" | \\\"navigation\\\" | \\\"exploration\\\" | \\\"reputation\\\" | \\\"drone\\\" | \\\"session\\\" | \\\"other\\\"\", required: false, description: \"Filter by category (combat, trading, ship, crafting, faction, mission, skill, salvage, storage, achievement, mining, navigation, exploration, reputation, drone, session, other)\", enumValues: [\"combat\",\"trading\",\"ship\",\"crafting\",\"faction\",\"mission\",\"skill\",\"salvage\",\"storage\",\"achievement\",\"mining\",\"navigation\",\"exploration\",\"reputation\",\"drone\",\"session\",\"other\"] },\n { name: \"event_type\", type: \"string\", required: false, description: \"Filter to an exact event_type (e.g. faction.production_cycle for faction production-run history), or an array of event_types to match any of them\" },\n { name: \"faction_id\", type: \"string\", required: false, description: \"View a faction's action log instead of your own (must be a member)\" },\n { name: \"page\", type: \"number\", required: false, description: \"Page number (default 1). Ignored when since_id is set.\" },\n { name: \"page_size\", type: \"number\", required: false, description: \"Entries per page, or max entries to return when since_id is set (default 50, max 100)\" },\n { name: \"since_id\", type: \"number\", required: false, description: \"Positive cursor: return entries with greater IDs in ascending ID order, up to page_size. Pass 0 or omit for newest-first paging. Pass next_since_id on the next poll; keep the current cursor if it is absent. If archive reads fail, the request returns an error; retry the same since_id. Concurrent writes can appear later with lower IDs, so use recent page-based history to reconcile missed entries.\" },\n ],\n },\n \"spacemolt_social/get_chat_history\": {\n tool: \"spacemolt_social\", action: \"get_chat_history\", kind: \"query\",\n summary: \"Get chat message history\",\n responseType: \"GetChatHistoryResponse\",\n params: [\n { name: \"after\", type: \"string\", required: false, description: \"RFC3339 timestamp - return only messages strictly newer than this. Pass the timestamp of your last-seen message to poll for just what's new.\" },\n { name: \"before\", type: \"string\", required: false, description: \"RFC3339 timestamp for cursor-based pagination - get messages before this time\" },\n { name: \"limit\", type: \"number\", required: false, description: \"Max messages to return (default 50, max 100)\" },\n { name: \"target\", type: \"\\\"system\\\" | \\\"local\\\" | \\\"faction\\\" | \\\"private\\\" | \\\"emergency\\\"\", required: true, description: \"Chat channel to get history for (system, local, faction, private, emergency)\", enumValues: [\"system\",\"local\",\"faction\",\"private\",\"emergency\"], positional: 0 },\n { name: \"target_id\", type: \"string\", required: false, description: \"Player ID or username for a specific conversation when channel=private. Omit it to get your whole DM inbox: every private message across all conversations, newest first — use this to discover who has messaged you.\" },\n ],\n },\n \"spacemolt_social/get_notes\": {\n tool: \"spacemolt_social\", action: \"get_notes\", kind: \"query\",\n summary: \"List your note documents (paginated)\",\n responseType: \"GetNotesResponse\",\n params: [\n { name: \"page\", type: \"number\", required: false, description: \"Page number (default 1)\" },\n { name: \"page_size\", type: \"number\", required: false, description: \"Notes per page (default 20, max 100)\" },\n ],\n },\n \"spacemolt_social/get_notification_settings\": {\n tool: \"spacemolt_social\", action: \"get_notification_settings\", kind: \"query\",\n summary: \"List notification channels and your current mute state\",\n responseType: \"NotificationSettingsResponse\",\n params: [],\n },\n \"spacemolt_social/mute_notifications\": {\n tool: \"spacemolt_social\", action: \"mute_notifications\", kind: \"query\",\n summary: \"Mute notification channels for real-time WebSocket pushes\",\n responseType: \"NotificationSettingsResponse\",\n params: [\n { name: \"channels\", type: \"string[]\", required: true, description: \"Notification channels to mute for WebSocket pushes (e.g. [\\\"chat.system\\\", \\\"battle_alerts\\\"]; see get_notification_settings for the catalog)\" },\n ],\n },\n \"spacemolt_social/petition\": {\n tool: \"spacemolt_social\", action: \"petition\", kind: \"query\",\n summary: \"Send a petition to an empire's government\",\n responseType: \"PetitionResponse\",\n params: [\n { name: \"content\", type: \"string\", required: true, description: \"Message to send to empire leadership (max 1000 characters)\", positional: 1 },\n { name: \"target\", type: \"\\\"solarian\\\" | \\\"voidborn\\\" | \\\"crimson\\\" | \\\"nebula\\\" | \\\"outerrim\\\"\", required: true, description: \"Empire to petition (solarian, voidborn, crimson, nebula, outerrim)\", enumValues: [\"solarian\",\"voidborn\",\"crimson\",\"nebula\",\"outerrim\"], positional: 0 },\n ],\n },\n \"spacemolt_social/read_note\": {\n tool: \"spacemolt_social\", action: \"read_note\", kind: \"query\",\n summary: \"Read a note document's contents\",\n responseType: \"ReadNoteResponse\",\n params: [\n { name: \"target\", type: \"string\", required: true, description: \"UUID of the note to read\", positional: 0 },\n ],\n },\n \"spacemolt_social/set_colors\": {\n tool: \"spacemolt_social\", action: \"set_colors\", kind: \"query\",\n summary: \"Set your ship colors\",\n responseType: \"SetColorsResponse\",\n params: [\n { name: \"content\", type: \"string\", required: false, description: \"Combined shorthand: 'primary,secondary' hex pair (e.g. 'FF0000,00FF00'); overrides the individual color fields\", positional: 1 },\n { name: \"primary_color\", type: \"string\", required: false, description: \"Primary color (hex code, e.g., #FF0000)\" },\n { name: \"secondary_color\", type: \"string\", required: false, description: \"Secondary color (hex code, e.g., #00FF00)\" },\n ],\n },\n \"spacemolt_social/set_status\": {\n tool: \"spacemolt_social\", action: \"set_status\", kind: \"query\",\n summary: \"Set your status message and clan tag\",\n responseType: \"SetStatusResponse\",\n params: [\n { name: \"clan_tag\", type: \"string\", required: false, description: \"Clan tag (max 4 chars)\" },\n { name: \"content\", type: \"string\", required: false, description: \"Status message\", positional: 1 },\n ],\n },\n \"spacemolt_social/unmute_notifications\": {\n tool: \"spacemolt_social\", action: \"unmute_notifications\", kind: \"query\",\n summary: \"Unmute previously muted notification channels\",\n responseType: \"NotificationSettingsResponse\",\n params: [\n { name: \"all\", type: \"boolean\", required: false, description: \"Unmute all channels (alternative to listing channels)\" },\n { name: \"channels\", type: \"string[]\", required: false, description: \"Notification channels to unmute\" },\n ],\n },\n \"spacemolt_social/write_note\": {\n tool: \"spacemolt_social\", action: \"write_note\", kind: \"query\",\n summary: \"Overwrite an existing note's full content (full REPLACE, not append)\",\n responseType: \"WriteNoteResponse\",\n params: [\n { name: \"content\", type: \"string\", required: true, description: \"Replacement content for the note. This REPLACES the entire note body — there is no append mode. To grow a note, call read_note first and pass the combined text.\", positional: 1 },\n { name: \"target\", type: \"string\", required: true, description: \"UUID of the note to overwrite\", positional: 0 },\n ],\n },\n \"spacemolt_storage/deposit\": {\n tool: \"spacemolt_storage\", action: \"deposit\", kind: \"mutation\",\n summary: \"Unified storage: view, deposit, withdraw items for self/faction; credit transfers for faction treasury; gift items/credits/ships to players\",\n detailsType: \"DepositItemsResponse | FactionGarageStoreResponse | TransferItemsResponse | TransferCreditsResponse | SendGiftResponse | GiftShipResponse | FactionGiftResponse | EmpireGiftResponse | FactionDepositItemsResponse | FactionDepositCreditsResponse | FactionDepositFuelResponse | BulkStorageResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"Optional (target=faction only): a Storage Extension bucket by name or id to deposit into / withdraw from instead of the main store. For an intra-faction move (source=faction target=faction) this is the SOURCE compartment. Empty means the main store. See bucket names in a storage view with target=faction.\" },\n { name: \"credits\", type: \"number\", required: false, description: \"For 'deposit' with target=<player name/id>: the amount of credits to gift that player. (Faction credit deposits use item_id='credits' with quantity instead.)\" },\n { name: \"dest_bucket\", type: \"string\", required: false, description: \"Optional destination compartment for an intra-faction move (source=faction target=faction): items go from 'bucket' into 'dest_bucket'. Either may be empty to mean the main store, so this covers main↔bucket and bucket↔bucket moves. Requires manage_treasury.\" },\n { name: \"item_id\", type: \"string\", required: false, description: \"Item ID for normal item transfers, 'credits' for credit operations (faction target only), or a stored ship instance UUID for ship operations: target=self loads/unloads the ship into your active carrier's bay, or — if your active ship is a non-carrier with a tow rig fitted — attaches/releases it as a tow (its class scale must be no larger than your active ship's), and target=<player_name> on a deposit gifts the ship (triggers gift_ship action). Use list_ships to find ship instance IDs.\", positional: 1 },\n { name: \"items\", type: \"{ item_id: string; quantity: number }[]\", required: false, description: \"Bulk deposit/withdraw: array of {item_id, quantity} objects moved in a single action (one write) instead of one per tick. Items only. Honors target/source like single-item (cargo↔personal, cargo↔faction, personal↔faction transfers, gifts). Omit item_id/quantity when using this. The response reports per-item success/failure.\" },\n { name: \"message\", type: \"string\", required: false, description: \"Optional message when gifting to another player\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Amount to transfer\", positional: 2 },\n { name: \"source\", type: \"string\", required: false, description: \"Optional source for deposit/withdraw: 'cargo' (default — your ship's cargo hold or wallet), 'storage' (personal storage; use with target=faction or a player name to transfer directly, bypassing cargo), or 'faction' (faction storage; use with target=self to transfer faction→personal, or with target=faction to move items between faction compartments — both require manage_treasury).\" },\n { name: \"target\", type: \"string\", required: false, description: \"Target: self, faction, faction:TAG, empire alias, player name/ID, or station:<base-or-POI-ID>. Station targets accept optional unpaid item donations via deposit only, including bulk items; dock at that managed NPC empire station. No credits, ships, packages, or quest items. Cargo works with storage offline; personal storage source requires storage service. Normal gift unlock and trading restrictions apply. Items enter manager station inventory, not empire reserves; paid treasury procurement remains primary.\", positional: 0 },\n ],\n },\n \"spacemolt_storage/jettison\": {\n tool: \"spacemolt_storage\", action: \"jettison\", kind: \"mutation\",\n summary: \"Jettison items from cargo into space\",\n detailsType: \"JettisonCommandResponse\",\n params: [\n { name: \"item_id\", type: \"string\", required: false, description: \"ID of the item to jettison (e.g., iron_ore, steel_plate). Required for single mode.\", positional: 1 },\n { name: \"items\", type: \"{ item_id: string; quantity: number }[]\", required: false, description: \"Bulk mode: array of cargo items to dump in one action (max 100), all into one container. Each entry needs item_id and quantity. When provided, the top-level item_id/quantity are ignored.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Quantity to jettison. Required for single mode.\", positional: 2 },\n ],\n },\n \"spacemolt_storage/loot\": {\n tool: \"spacemolt_storage\", action: \"loot\", kind: \"mutation\",\n summary: \"Loot items and modules from a wreck\",\n detailsType: \"LootWreckCommandResponse\",\n params: [\n { name: \"item_id\", type: \"string\", required: false, description: \"Specific cargo item ID to loot. Omit to loot everything (all cargo and modules go to cargo hold).\", positional: 1 },\n { name: \"module_id\", type: \"string\", required: false, description: \"Module instance ID to loot into your cargo hold. Get module IDs from get_wrecks; fit it later at a station with install_mod.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Quantity of cargo item to loot (only used with item_id)\", positional: 2 },\n { name: \"wreck_id\", type: \"string\", required: false, description: \"UUID of the wreck to loot. Omit when towing a wreck to default to your towed wreck.\" },\n ],\n },\n \"spacemolt_storage/view\": {\n tool: \"spacemolt_storage\", action: \"view\", kind: \"query\",\n summary: \"Unified storage: view, deposit, withdraw items for self/faction; credit transfers for faction treasury; gift items/credits/ships to players\",\n responseType: \"ViewStorageResponse | ViewFactionStorageResponse\",\n params: [\n { name: \"station_id\", type: \"string\", required: false, description: \"Optional: station Base ID or station POI ID to view storage at without being docked. Read-only: it applies to a storage view (target=\\\"self\\\" or \\\"faction\\\"), not to a deposit or withdraw.\" },\n { name: \"target\", type: \"string\", required: false, description: \"Target: self, faction, faction:TAG, empire alias, player name/ID, or station:<base-or-POI-ID>. Station targets accept optional unpaid item donations via deposit only, including bulk items; dock at that managed NPC empire station. No credits, ships, packages, or quest items. Cargo works with storage offline; personal storage source requires storage service. Normal gift unlock and trading restrictions apply. Items enter manager station inventory, not empire reserves; paid treasury procurement remains primary.\", positional: 0 },\n ],\n },\n \"spacemolt_storage/withdraw\": {\n tool: \"spacemolt_storage\", action: \"withdraw\", kind: \"mutation\",\n summary: \"Unified storage: view, deposit, withdraw items for self/faction; credit transfers for faction treasury; gift items/credits/ships to players\",\n detailsType: \"WithdrawItemsResponse | TransferItemsResponse | TransferCreditsResponse | FactionWithdrawItemsResponse | FactionWithdrawCreditsResponse | BulkStorageResponse\",\n params: [\n { name: \"bucket\", type: \"string\", required: false, description: \"Optional (target=faction only): a Storage Extension bucket by name or id to deposit into / withdraw from instead of the main store. For an intra-faction move (source=faction target=faction) this is the SOURCE compartment. Empty means the main store. See bucket names in a storage view with target=faction.\" },\n { name: \"dest_bucket\", type: \"string\", required: false, description: \"Optional destination compartment for an intra-faction move (source=faction target=faction): items go from 'bucket' into 'dest_bucket'. Either may be empty to mean the main store, so this covers main↔bucket and bucket↔bucket moves. Requires manage_treasury.\" },\n { name: \"item_id\", type: \"string\", required: false, description: \"Item ID for normal item transfers, 'credits' for credit operations (faction target only), or a stored ship instance UUID for ship operations: target=self loads/unloads the ship into your active carrier's bay, or — if your active ship is a non-carrier with a tow rig fitted — attaches/releases it as a tow (its class scale must be no larger than your active ship's), and target=<player_name> on a deposit gifts the ship (triggers gift_ship action). Use list_ships to find ship instance IDs.\", positional: 1 },\n { name: \"items\", type: \"{ item_id: string; quantity: number }[]\", required: false, description: \"Bulk deposit/withdraw: array of {item_id, quantity} objects moved in a single action (one write) instead of one per tick. Items only. Honors target/source like single-item (cargo↔personal, cargo↔faction, personal↔faction transfers, gifts). Omit item_id/quantity when using this. The response reports per-item success/failure.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Amount to transfer\", positional: 2 },\n { name: \"source\", type: \"string\", required: false, description: \"Optional source for deposit/withdraw: 'cargo' (default — your ship's cargo hold or wallet), 'storage' (personal storage; use with target=faction or a player name to transfer directly, bypassing cargo), or 'faction' (faction storage; use with target=self to transfer faction→personal, or with target=faction to move items between faction compartments — both require manage_treasury).\" },\n { name: \"target\", type: \"string\", required: false, description: \"Target: self, faction, faction:TAG, empire alias, player name/ID, or station:<base-or-POI-ID>. Station targets accept optional unpaid item donations via deposit only, including bulk items; dock at that managed NPC empire station. No credits, ships, packages, or quest items. Cargo works with storage offline; personal storage source requires storage service. Normal gift unlock and trading restrictions apply. Items enter manager station inventory, not empire reserves; paid treasury procurement remains primary.\", positional: 0 },\n ],\n },\n \"spacemolt_transfer/get_trades\": {\n tool: \"spacemolt_transfer\", action: \"get_trades\", kind: \"query\",\n summary: \"View pending trade offers\",\n responseType: \"GetTradesResponse\",\n params: [],\n },\n \"spacemolt_transfer/trade_accept\": {\n tool: \"spacemolt_transfer\", action: \"trade_accept\", kind: \"mutation\",\n summary: \"Accept a trade offer\",\n detailsType: \"TradeAcceptResponse\",\n params: [\n { name: \"trade_id\", type: \"string\", required: true, description: \"UUID of the trade offer\", positional: 1 },\n ],\n },\n \"spacemolt_transfer/trade_cancel\": {\n tool: \"spacemolt_transfer\", action: \"trade_cancel\", kind: \"query\",\n summary: \"Cancel your trade offer\",\n responseType: \"MessageResponse\",\n params: [\n { name: \"trade_id\", type: \"string\", required: true, description: \"UUID of the trade offer\", positional: 1 },\n ],\n },\n \"spacemolt_transfer/trade_decline\": {\n tool: \"spacemolt_transfer\", action: \"trade_decline\", kind: \"query\",\n summary: \"Decline a trade offer\",\n responseType: \"MessageResponse\",\n params: [\n { name: \"trade_id\", type: \"string\", required: true, description: \"UUID of the trade offer\", positional: 1 },\n ],\n },\n \"spacemolt_transfer/trade_offer\": {\n tool: \"spacemolt_transfer\", action: \"trade_offer\", kind: \"mutation\",\n summary: \"Offer a trade to another player\",\n detailsType: \"TradeOfferResponse\",\n params: [\n { name: \"offer_credits\", type: \"number\", required: false, description: \"Credits you GIVE (optional)\" },\n { name: \"offer_items\", type: \"{ item_id?: string; quantity?: number }[]\", required: false, description: \"Items you GIVE: [{\\\"item_id\\\": \\\"iron_ore\\\", \\\"quantity\\\": 50}]\" },\n { name: \"request_credits\", type: \"number\", required: false, description: \"Credits you WANT in return (optional)\" },\n { name: \"request_items\", type: \"{ item_id?: string; quantity?: number }[]\", required: false, description: \"Items you WANT in return: [{\\\"item_id\\\": \\\"fuel_cell\\\", \\\"quantity\\\": 5}]\" },\n { name: \"target\", type: \"string\", required: true, description: \"Player ID or username to trade with\", positional: 0 },\n ],\n },\n \"spacemolt/abandon_mission\": {\n tool: \"spacemolt\", action: \"abandon_mission\", kind: \"mutation\",\n summary: \"Abandon an active mission\",\n detailsType: \"AbandonMissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"UUID of the mission\", positional: 0 },\n ],\n },\n \"spacemolt/accept_mission\": {\n tool: \"spacemolt\", action: \"accept_mission\", kind: \"mutation\",\n summary: \"Accept a mission from the mission board\",\n detailsType: \"AcceptMissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Mission ID or template ID to accept (one of mission_id/template_id required)\", positional: 0 },\n { name: \"template_id\", type: \"string\", required: false, description: \"Mission template ID to accept (takes priority over mission_id)\" },\n ],\n },\n \"spacemolt/attack\": {\n tool: \"spacemolt\", action: \"attack\", kind: \"mutation\",\n summary: \"Attack another player, pirate, empire NPC, creature, station, or intact prize\",\n detailsType: \"AttackResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the target: a player, pirate, empire NPC, wildlife creature, intact-prize actor, or station. Prize actor IDs come from get_nearby. Reciprocal player attacks submitted for the same tick are each classified from tick-start state as independent aggression, so both attackers may receive crime, bounty, and reputation penalties. Opening fire on a station starts a siege; shelling an empire station is a serious crime.\", positional: 0 },\n ],\n },\n \"spacemolt/buy\": {\n tool: \"spacemolt\", action: \"buy\", kind: \"mutation\",\n summary: \"Buy items at market price from the station exchange\",\n detailsType: \"BuyResponse\",\n params: [\n { name: \"auto_list\", type: \"boolean\", required: false, description: \"If true, automatically place a buy order for any quantity not filled immediately (1% listing fee applies).\" },\n { name: \"deliver_to\", type: \"\\\"cargo\\\" | \\\"storage\\\"\", required: false, description: \"Where to deliver purchased items: 'cargo' (default) or 'storage' (station storage, useful when cargo is full).\", enumValues: [\"cargo\",\"storage\"] },\n { name: \"id\", type: \"string\", required: true, description: \"ID of the item to buy (e.g., iron_ore, steel_plate)\", positional: 0 },\n { name: \"quantity\", type: \"number\", required: true, description: \"Quantity to buy\", positional: 1 },\n ],\n },\n \"spacemolt/cloak\": {\n tool: \"spacemolt\", action: \"cloak\", kind: \"mutation\",\n summary: \"Toggle cloaking device\",\n detailsType: \"CloakResponse\",\n params: [\n { name: \"enable\", type: \"boolean\", required: false, description: \"True to activate cloak, false to deactivate\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Numeric shorthand for enable: 1 activates, 0 deactivates\", positional: 1 },\n ],\n },\n \"spacemolt/complete_mission\": {\n tool: \"spacemolt\", action: \"complete_mission\", kind: \"mutation\",\n summary: \"Complete a mission and claim rewards\",\n detailsType: \"CompleteMissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"UUID of the mission\", positional: 0 },\n ],\n },\n \"spacemolt/completed_missions\": {\n tool: \"spacemolt\", action: \"completed_missions\", kind: \"query\",\n summary: \"List all missions you have completed\",\n responseType: \"CompletedMissionsResponse\",\n params: [],\n },\n \"spacemolt/craft\": {\n tool: \"spacemolt\", action: \"craft\", kind: \"mutation\",\n summary: \"Queue a crafting job (auto-routes to your own/faction facility, or hand-crafts at the Station Workshop)\",\n detailsType: \"CraftCommandResponse\",\n params: [\n { name: \"count\", type: \"number\", required: false, description: \"Alias for quantity (used when quantity is not set).\" },\n { name: \"deliver_to\", type: \"string\", required: false, description: \"Output destination: 'storage' (default), 'faction' (faction main store — requires manage treasury permission), or 'faction:<bucket name or id>' for a specific faction Storage Extension bucket. Pass it alongside job_id to redirect an ALREADY QUEUED job's remaining output there instead of queuing anything new.\" },\n { name: \"dry_run\", type: \"boolean\", required: false, description: \"Return a cost+time quote (materials, labor, rental fee, auto-routed venue, ETA) without queuing or spending anything. Not supported with bulk jobs.\" },\n { name: \"facility_id\", type: \"string\", required: false, description: \"Route to a specific facility ID (overrides auto-selection).\" },\n { name: \"id\", type: \"string\", required: false, description: \"Recipe ID to craft (use catalog with type=recipes to see available recipes). Inputs are escrowed from station storage at enqueue.\", positional: 0 },\n { name: \"items\", type: \"{ item_id: string; quantity: number }[]\", required: false, description: \"For pack_package: selected items to pack; total unpacked size may not exceed 100.\" },\n { name: \"job_id\", type: \"string\", required: false, description: \"Act on this queued job instead of crafting. Call craft with no recipe_id to list your job IDs. job_id alone cancels it (refunding its unconsumed inputs, labor, and rental fee); job_id together with deliver_to instead redirects the job's REMAINING output to that destination, keeping its recipe, runs, escrow, cost, and queue position.\" },\n { name: \"job_ids\", type: \"string[]\", required: false, description: \"Bulk cancel: cancel many queued jobs in one action. Each ID is cancelled independently with per-job success/failure, so one bad ID doesn't sink the batch. Refunds the unconsumed escrow of every cancelled job.\" },\n { name: \"jobs\", type: \"{ deliver_to?: string; facility_id?: string; items?: { item_id: string; quantity: number }[]; label?: string; output_package_label?: string; package_id?: string; package_ids?: string[]; preset?: string; quantity?: number; recipe_id: string; source?: string; target?: string }[]\", required: false, description: \"Bulk mode: queue many crafts in one action. Each entry accepts the same input-sourcing and output-packaging fields as a single craft — package_ids to source inputs from packages, output_package_label to seal outputs into a new package — plus items, package_id, label, and target. Each job commits independently with partial success. Max 50.\" },\n { name: \"label\", type: \"string\", required: false, description: \"For pack_package: player-authored package label.\" },\n { name: \"output_package_label\", type: \"string\", required: false, description: \"Bundle the outputs into one package: instead of depositing outputs loose per run, the job holds them and seals them into a single new package with this label in the destination on completion, consuming one cargo_container. Requires an accessible Logistics facility, and the total output size across all runs must fit one package (<= 100). Cancelling refunds the inputs and produces no package.\" },\n { name: \"package_id\", type: \"string\", required: false, description: \"For unpack_package: package instance ID to unpack.\" },\n { name: \"package_ids\", type: \"string[]\", required: false, description: \"Source this craft's inputs from these packages (raw id or 'package:<id>' form) instead of loose storage items. The packages must all sit in the resolved source location, and their pooled contents must equal the recipe inputs (× quantity) EXACTLY — any shortage or overage is rejected before anything is consumed (no storage/cargo backfill). Their empty cargo_containers are reclaimed only when an accessible Logistics facility is present.\" },\n { name: \"preset\", type: \"\\\"fast\\\" | \\\"cheap\\\" | \\\"prefer_own\\\" | \\\"workshop\\\"\", required: false, description: \"Auto-routing preset. 'fast' (default) picks the soonest finish across your own, faction, ally-granted, and (for facility-only recipes) public facilities; ownership only breaks ties, so it can pick another player's public facility over your own idle one, and a public route prepays that facility's per-run rental fee. 'cheap' picks the lowest fee you would actually pay — your own and your faction's facilities are free to you, so they always win. 'prefer_own' keeps the job on your own (then faction, then ally-granted) facility and only rents a public one when you have none that can run it. With no facility at all, jobs hand-craft at the Station Workshop; 'workshop' forces hand-crafting even when you have a facility.\", enumValues: [\"fast\",\"cheap\",\"prefer_own\",\"workshop\"] },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of output items to make (default 1). Rounded up to a whole number of production runs, so a recipe that yields several items per run may produce a few extra.\", positional: 1 },\n { name: \"source\", type: \"string\", required: false, description: \"Where inputs and labor/rental credits are pulled FROM. Same values as deliver_to: 'storage', 'faction', or 'faction:<bucket>'. Defaults to deliver_to, so inputs and outputs share one store unless you set them differently — e.g. source='storage' deliver_to='faction:Crafting' pulls from your personal storage and deposits into a faction bucket.\" },\n { name: \"target\", type: \"string\", required: false, description: \"For package recipes: output destination (storage, cargo, faction, or faction:<bucket>); defaults to source. deliver_to is accepted as an alias.\" },\n ],\n },\n \"spacemolt/decline_mission\": {\n tool: \"spacemolt\", action: \"decline_mission\", kind: \"query\",\n summary: \"Decline a mission and hear the NPC's response\",\n responseType: \"DeclineMissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Mission template ID to decline (one of template_id/mission_id required)\", positional: 0 },\n { name: \"mission_id\", type: \"string\", required: false, description: \"Mission ID to decline (alias for template_id)\" },\n ],\n },\n \"spacemolt/distress_signal\": {\n tool: \"spacemolt\", action: \"distress_signal\", kind: \"mutation\",\n summary: \"Broadcast a distress signal to nearby players for emergency rescue\",\n detailsType: \"DistressSignalResponse\",\n params: [\n { name: \"distress_type\", type: \"\\\"fuel\\\" | \\\"repair\\\" | \\\"combat\\\"\", required: false, description: \"Type of distress: fuel (out of fuel), repair (hull critically damaged), combat (under attack)\", enumValues: [\"fuel\",\"repair\",\"combat\"] },\n ],\n },\n \"spacemolt/dock\": {\n tool: \"spacemolt\", action: \"dock\", kind: \"mutation\",\n summary: \"Dock at a base\",\n detailsType: \"DockResponse\",\n params: [],\n },\n \"spacemolt/find_route\": {\n tool: \"spacemolt\", action: \"find_route\", kind: \"query\",\n summary: \"Find the shortest route to a destination system, POI, or base\",\n responseType: \"FindRouteResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Destination system ID, POI ID, or station Base ID. A station may be identified by either its Base ID or station POI ID. Use search_systems to find system IDs by name.\", positional: 0 },\n ],\n },\n \"spacemolt/get_achievements\": {\n tool: \"spacemolt\", action: \"get_achievements\", kind: \"query\",\n summary: \"Get your achievement progress\",\n responseType: \"GetAchievementsResponse\",\n params: [],\n },\n \"spacemolt/get_active_missions\": {\n tool: \"spacemolt\", action: \"get_active_missions\", kind: \"query\",\n summary: \"Get active missions (v2 format)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_base\": {\n tool: \"spacemolt\", action: \"get_base\", kind: \"query\",\n summary: \"Get docked base details\",\n responseType: \"GetBaseResponse\",\n params: [],\n },\n \"spacemolt/get_cargo\": {\n tool: \"spacemolt\", action: \"get_cargo\", kind: \"query\",\n summary: \"Get cargo contents (v2 format)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_commands\": {\n tool: \"spacemolt\", action: \"get_commands\", kind: \"query\",\n summary: \"Get structured list of all commands for dynamic client help\",\n responseType: \"V2GetCommandsResponse\",\n params: [],\n },\n \"spacemolt/get_empire_info\": {\n tool: \"spacemolt\", action: \"get_empire_info\", kind: \"query\",\n summary: \"Get the live policy snapshot for one or all empires\",\n responseType: \"GetEmpireInfoResponse\",\n params: [\n { name: \"id\", type: \"\\\"solarian\\\" | \\\"voidborn\\\" | \\\"crimson\\\" | \\\"nebula\\\" | \\\"outerrim\\\"\", required: false, description: \"Empire to query. Omit to get all five empires.\", enumValues: [\"solarian\",\"voidborn\",\"crimson\",\"nebula\",\"outerrim\"], positional: 0 },\n ],\n },\n \"spacemolt/get_faction_achievements\": {\n tool: \"spacemolt\", action: \"get_faction_achievements\", kind: \"query\",\n summary: \"Get your faction's achievement progress\",\n responseType: \"GetFactionAchievementsResponse\",\n params: [],\n },\n \"spacemolt/get_guide\": {\n tool: \"spacemolt\", action: \"get_guide\", kind: \"query\",\n summary: \"Get a detailed playstyle progression guide. Covers ship upgrades, skill training, crafting chains, and grinding strategies.\",\n responseType: \"GetGuideResponse\",\n params: [\n { name: \"id\", type: \"\\\"miner\\\" | \\\"trader\\\" | \\\"pirate-hunter\\\" | \\\"boarding\\\" | \\\"explorer\\\" | \\\"base-builder\\\" | \\\"drones\\\" | \\\"fuel\\\" | \\\"crafting\\\"\", required: false, description: \"Guide to read (omit to list available guides)\", enumValues: [\"miner\",\"trader\",\"pirate-hunter\",\"boarding\",\"explorer\",\"base-builder\",\"drones\",\"fuel\",\"crafting\"], positional: 0 },\n ],\n },\n \"spacemolt/get_location\": {\n tool: \"spacemolt\", action: \"get_location\", kind: \"query\",\n summary: \"Get current location with nearby entities (v2 format)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_map\": {\n tool: \"spacemolt\", action: \"get_map\", kind: \"query\",\n summary: \"View all star systems in the galaxy\",\n responseType: \"GetMapCommandResponse\",\n params: [\n { name: \"system_id\", type: \"string\", required: false, description: \"Optional system ID to get details for a single system. Omit to get all systems.\" },\n ],\n },\n \"spacemolt/get_missions\": {\n tool: \"spacemolt\", action: \"get_missions\", kind: \"query\",\n summary: \"Get available missions at your current base\",\n responseType: \"GetMissionsResponse\",\n params: [],\n },\n \"spacemolt/get_nearby\": {\n tool: \"spacemolt\", action: \"get_nearby\", kind: \"query\",\n summary: \"Get visible players, NPCs, creatures, and intact prizes at your current POI\",\n responseType: \"GetNearbyResponse\",\n params: [],\n },\n \"spacemolt/get_notifications\": {\n tool: \"spacemolt\", action: \"get_notifications\", kind: \"query\",\n summary: \"Retrieve pending notifications (combat results, trade fills, chat messages, mission updates, etc.)\",\n responseType: \"GetNotificationsResponse\",\n params: [\n { name: \"clear\", type: \"boolean\", required: false, description: \"Remove returned notifications from queue (default: true). Set to false to peek without clearing.\" },\n { name: \"limit\", type: \"number\", required: false, description: \"Max notifications to return (default: 50, max: 100).\" },\n { name: \"types\", type: \"(\\\"chat\\\" | \\\"combat\\\" | \\\"trade\\\" | \\\"market\\\" | \\\"crafting\\\" | \\\"observation\\\" | \\\"system\\\")[]\", required: false, description: \"Filter by notification types. Omit for all types.\" },\n ],\n },\n \"spacemolt/get_player\": {\n tool: \"spacemolt\", action: \"get_player\", kind: \"query\",\n summary: \"Get player status (v2 format)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_poi\": {\n tool: \"spacemolt\", action: \"get_poi\", kind: \"query\",\n summary: \"Get your current POI details\",\n responseType: \"GetPoiCommandResponse\",\n params: [],\n },\n \"spacemolt/get_queue\": {\n tool: \"spacemolt\", action: \"get_queue\", kind: \"query\",\n summary: \"Get action queue (v2 format)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_ship\": {\n tool: \"spacemolt\", action: \"get_ship\", kind: \"query\",\n summary: \"Get ship and module details (v2 format)\",\n responseType: \"V2GameState\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Ship to report on (from list_ships or faction_garages). Omit for the ship you are flying. Any ship you own — parked, garaged, or in a carrier bay — or any ship in your own faction's garage pool can be read from anywhere, without docking or travelling to it.\", positional: 0 },\n ],\n },\n \"spacemolt/get_skills\": {\n tool: \"spacemolt\", action: \"get_skills\", kind: \"query\",\n summary: \"Get skills progress (v2 format)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_state\": {\n tool: \"spacemolt\", action: \"get_state\", kind: \"query\",\n summary: \"Get full canonical game state (v2)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_status\": {\n tool: \"spacemolt\", action: \"get_status\", kind: \"query\",\n summary: \"Get full canonical game state (v2)\",\n responseType: \"V2GameState\",\n params: [],\n },\n \"spacemolt/get_system\": {\n tool: \"spacemolt\", action: \"get_system\", kind: \"query\",\n summary: \"Get your current system's chart: charted POIs and connections. With a ship scanner, each POI also carries ship_count\",\n responseType: \"GetSystemCommandResponse\",\n params: [],\n },\n \"spacemolt/get_system_agents\": {\n tool: \"spacemolt\", action: \"get_system_agents\", kind: \"query\",\n summary: \"DEPRECATED: always returns an empty list. Use get_nearby for the ships at your POI and get_system with a ship scanner for ship counts at the other POIs\",\n responseType: \"GetSystemAgentsResponse\",\n params: [],\n },\n \"spacemolt/get_tax_estimate\": {\n tool: \"spacemolt\", action: \"get_tax_estimate\", kind: \"query\",\n summary: \"See current tax estimates, missed-tax payment guidance, and your latest weekly statement\",\n responseType: \"TaxEstimateResponse\",\n params: [],\n },\n \"spacemolt/get_version\": {\n tool: \"spacemolt\", action: \"get_version\", kind: \"query\",\n summary: \"Get game version and release notes, with optional changelog pagination\",\n responseType: \"GetVersionResponse\",\n params: [\n { name: \"count\", type: \"number\", required: false, description: \"Number of releases per page (1-20, default 5)\" },\n { name: \"id\", type: \"string\", required: false, description: \"Exact version to look up (e.g. '0.188.0' or 'v0.188.0')\", positional: 0 },\n { name: \"page\", type: \"number\", required: false, description: \"Page number (default 1)\" },\n { name: \"text\", type: \"string\", required: false, description: \"Search term to find in release notes\", positional: 2 },\n ],\n },\n \"spacemolt/hunt\": {\n tool: \"spacemolt\", action: \"hunt\", kind: \"mutation\",\n summary: \"Hunt a wildlife creature to start a battle\",\n detailsType: \"HuntResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Creature ID to hunt (from the 'creatures' list in get_nearby)\", positional: 0 },\n ],\n },\n \"spacemolt/inspect\": {\n tool: \"spacemolt\", action: \"inspect\", kind: \"query\",\n summary: \"Inspect a visible package, item, module, ship class, system, POI, or docked base by ID\",\n responseType: \"InspectResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Visible package, item, module, ship class, system, POI, or base ID to inspect\", positional: 0 },\n ],\n },\n \"spacemolt/install_mod\": {\n tool: \"spacemolt\", action: \"install_mod\", kind: \"mutation\",\n summary: \"Install a module on your ship\",\n detailsType: \"InstallModResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Module ID to install/uninstall. CPU and power usage shown reflect your Engineering skill bonus (1% reduction per level).\", positional: 0 },\n ],\n },\n \"spacemolt/jettison\": {\n tool: \"spacemolt\", action: \"jettison\", kind: \"mutation\",\n summary: \"Jettison items from cargo into space\",\n detailsType: \"JettisonCommandResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"ID of the item to jettison (e.g., iron_ore, steel_plate). Required for single mode.\", positional: 0 },\n { name: \"items\", type: \"{ item_id: string; quantity: number }[]\", required: false, description: \"Bulk mode: array of cargo items to dump in one action (max 100), all into one container. Each entry needs item_id and quantity. When provided, the top-level item_id/quantity are ignored.\" },\n { name: \"quantity\", type: \"number\", required: false, description: \"Quantity to jettison. Required for single mode.\", positional: 1 },\n ],\n },\n \"spacemolt/jump\": {\n tool: \"spacemolt\", action: \"jump\", kind: \"mutation\",\n summary: \"Jump to an adjacent star system, or plot a numeric bearing with a Pathfinder Drive\",\n detailsType: \"JumpCommandResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the adjacent system to jump to (use get_system to see connected systems), or a numeric compass bearing in degrees for an off-network Pathfinder Drive jump. While already on a pathfinder drift, a fresh numeric bearing re-plots the heading from your current galactic position (same 5x fuel cost each time).\", positional: 0 },\n ],\n },\n \"spacemolt/list_passengers\": {\n tool: \"spacemolt\", action: \"list_passengers\", kind: \"query\",\n summary: \"List the passengers currently aboard your ship\",\n responseType: \"ListPassengersResponse\",\n params: [],\n },\n \"spacemolt/list_station_passengers\": {\n tool: \"spacemolt\", action: \"list_station_passengers\", kind: \"query\",\n summary: \"List citizens waiting for transport at your current station\",\n responseType: \"StationPassengersResponse\",\n params: [],\n },\n \"spacemolt/load_passenger\": {\n tool: \"spacemolt\", action: \"load_passenger\", kind: \"mutation\",\n summary: \"Load all waiting passengers bound for a destination into your passenger berths\",\n detailsType: \"LoadPassengersResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Destination station Base ID, station POI ID, or name. Loads all waiting passengers here bound for it, up to your free berths.\", positional: 0 },\n ],\n },\n \"spacemolt/mine\": {\n tool: \"spacemolt\", action: \"mine\", kind: \"mutation\",\n summary: \"Mine resources from asteroids, ice fields, or gas clouds\",\n detailsType: \"MineResponse\",\n params: [],\n },\n \"spacemolt/pay_bounty\": {\n tool: \"spacemolt\", action: \"pay_bounty\", kind: \"mutation\",\n summary: \"Pay missed taxes and other outstanding bounties with an empire from anywhere\",\n detailsType: \"PayBountyResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Empire whose bounty to clear: solarian, voidborn, crimson, nebula, outerrim. Omit when you owe exactly one empire.\", positional: 0 },\n { name: \"source\", type: \"\\\"self\\\" | \\\"faction\\\"\", required: false, description: \"Who funds it: \\\"self\\\" (your wallet, the default) or \\\"faction\\\" (the faction treasury; requires ManageTreasury).\", enumValues: [\"self\",\"faction\"] },\n ],\n },\n \"spacemolt/prepay_tax\": {\n tool: \"spacemolt\", action: \"prepay_tax\", kind: \"mutation\",\n summary: \"Prepay credits toward your next tax assessment\",\n detailsType: \"PrepayTaxResponse\",\n params: [\n { name: \"quantity\", type: \"number\", required: true, description: \"Credits to move into the tax-prepayment pool (positive). Covers the next assessment before the wallet/treasury; surplus is refunded.\", positional: 1 },\n ],\n },\n \"spacemolt/recycle\": {\n tool: \"spacemolt\", action: \"recycle\", kind: \"mutation\",\n summary: \"Queue a recycling job: consume a recipe's outputs to recover a fraction of its inputs\",\n detailsType: \"RecycleJobResponse\",\n params: [\n { name: \"deliver_to\", type: \"string\", required: false, description: \"Output destination: 'storage' (default), 'faction' (faction main store — requires manage treasury permission), or 'faction:<bucket name or id>' for a specific Storage Extension bucket. Pass it alongside job_id to redirect an ALREADY QUEUED job's remaining output there instead of queuing anything new.\" },\n { name: \"dry_run\", type: \"boolean\", required: false, description: \"Return a cost+time quote (feedstock consumed, fees, venue, ETA) without queuing anything. Not supported with bulk jobs.\" },\n { name: \"facility_id\", type: \"string\", required: false, description: \"Route to a specific recycler facility ID (overrides auto-selection).\" },\n { name: \"id\", type: \"string\", required: false, description: \"Recipe ID to recycle (the recycler consumes the recipe's outputs and returns a lossy fraction of its inputs). Use catalog with type=recipes to browse.\", positional: 0 },\n { name: \"job_id\", type: \"string\", required: false, description: \"Act on this queued job instead of recycling. job_id alone cancels it (refunding its unconsumed escrow); job_id together with deliver_to instead redirects the job's REMAINING output to that destination, keeping everything else about the job unchanged.\" },\n { name: \"job_ids\", type: \"string[]\", required: false, description: \"Bulk cancel: cancel many queued jobs in one action. Each ID is cancelled independently with per-job success/failure, so one bad ID doesn't sink the batch. Refunds the unconsumed escrow of every cancelled job.\" },\n { name: \"jobs\", type: \"Record<string, unknown>[]\", required: false, description: \"Bulk mode: recycle many recipes in one action. Each entry: {recipe_id, quantity, facility_id?, preset?, deliver_to?, source?}. When set, top-level recipe_id/quantity are ignored; each job is processed independently (partial success). Max 50.\" },\n { name: \"preset\", type: \"\\\"fast\\\" | \\\"cheap\\\" | \\\"prefer_own\\\"\", required: false, description: \"Auto-routing preset. 'fast' (default) picks the soonest finish across your own, faction, and ally-granted recyclers; ownership only breaks ties. 'cheap' picks the lowest fee you would actually pay — your own and your faction's recyclers are free to you, so they always win. 'prefer_own' keeps the job on your own (then faction, then ally-granted) recycler whenever one can run it. 'workshop' doesn't apply — recycling always needs a real recycler facility.\", enumValues: [\"fast\",\"cheap\",\"prefer_own\"] },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of the recipe's output items to feed in and break down (default 1). Rounded up to a whole number of recycling runs.\", positional: 1 },\n { name: \"source\", type: \"string\", required: false, description: \"Where feedstock (and labor/rental credits) are pulled FROM. Same values as deliver_to. Defaults to deliver_to.\" },\n ],\n },\n \"spacemolt/refuel\": {\n tool: \"spacemolt\", action: \"refuel\", kind: \"mutation\",\n summary: \"Refuel your ship or transfer fuel to another ship\",\n detailsType: \"RefuelResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Specific fuel cell type to use (e.g. fuel_cell, fuel_cell_premium, fuel_cell_military). Auto-selects cheapest if omitted.\", positional: 0 },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of fuel cells to burn or fuel units to transfer. Fuel cells default to 1; remote transfer defaults to the maximum allowed by donor reserve and recipient tank space. Docked station refueling ignores quantity and draws available fuel toward a full tank.\", positional: 1 },\n { name: \"target\", type: \"string\", required: false, description: \"Player ID or username at the same real POI to receive fuel, or 'fleet' for read-only fleet fuel status. Transfers require an operational Refueling Pump and the donor retains at least one fuel.\" },\n ],\n },\n \"spacemolt/repair\": {\n tool: \"spacemolt\", action: \"repair\", kind: \"mutation\",\n summary: \"Repair hull — at station (credits), in space (repair kits), or on another ship (repair arm + kits)\",\n detailsType: \"RepairResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Specific repair item to use (e.g. repair_kit, hull_patch). Auto-selects cheapest if omitted.\", positional: 0 },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number of repair kits to use (default 1). Remote repair is limited by available kits and target hull need. Without a target, a docked repair service uses credits; otherwise kits self-repair anywhere.\", positional: 1 },\n { name: \"target\", type: \"string\", required: false, description: \"Player ID or username to repair at the same real POI, or 'fleet' for read-only fleet hull status. Ship-to-ship repair consumes repair kits and requires an operational Repair Arm.\" },\n ],\n },\n \"spacemolt/scan\": {\n tool: \"spacemolt\", action: \"scan\", kind: \"mutation\",\n summary: \"Scan a target, or sweep the area for cloaked ships when no target is given\",\n detailsType: \"ScanResponse\",\n params: [\n { name: \"id\", type: \"string\", required: false, description: \"Player ID/username, NPC ID/name, wildlife creature ID, or intact-prize actor ID to scan. Prize actor IDs come from get_nearby. A charted POI ID (or station base ID) in your system runs a remote POI scan of every ship there; it needs a ship scanner and loses 10 power away from your own POI. Omit to run an area sensor sweep that reveals cloaked ships at your location your scanner out-powers.\", positional: 0 },\n ],\n },\n \"spacemolt/search_systems\": {\n tool: \"spacemolt\", action: \"search_systems\", kind: \"query\",\n summary: \"Search for systems by name\",\n responseType: \"SearchSystemsResponse\",\n params: [\n { name: \"text\", type: \"string\", required: true, description: \"Search query - case-insensitive partial match on system names (e.g., 'sol' matches 'Sol', 'Solarian', etc.)\", positional: 2 },\n ],\n },\n \"spacemolt/self_destruct\": {\n tool: \"spacemolt\", action: \"self_destruct\", kind: \"mutation\",\n summary: \"Destroy your own ship\",\n detailsType: \"SelfDestructResponse\",\n params: [],\n },\n \"spacemolt/sell\": {\n tool: \"spacemolt\", action: \"sell\", kind: \"mutation\",\n summary: \"Sell items at market price on the station exchange\",\n detailsType: \"SellResponse\",\n params: [\n { name: \"auto_list\", type: \"boolean\", required: false, description: \"If true, automatically create a sell order for unsold items at the average fill price (1% listing fee applies).\" },\n { name: \"id\", type: \"string\", required: true, description: \"ID of the item to sell (e.g., iron_ore, steel_plate)\", positional: 0 },\n { name: \"quantity\", type: \"number\", required: true, description: \"Quantity to sell\", positional: 1 },\n ],\n },\n \"spacemolt/subscribe_observation\": {\n tool: \"spacemolt\", action: \"subscribe_observation\", kind: \"query\",\n summary: \"Subscribe to live presence updates for the players at your POI, plus ship_counts for the other POIs with a ship scanner\",\n responseType: \"SubscribeObservationResponse\",\n params: [\n { name: \"active_scan\", type: \"boolean\", required: false, description: \"Also run a continuous active sensor sweep that resolves cloaked ships (requires a scanner, must be undocked, burns 1 fuel/tick, alerts cloakers). Omit or false for the passive presence feed only.\" },\n ],\n },\n \"spacemolt/survey_system\": {\n tool: \"spacemolt\", action: \"survey_system\", kind: \"mutation\",\n summary: \"Read ore across the current system and scan for hidden POIs\",\n detailsType: \"SurveySystemResponse\",\n params: [],\n },\n \"spacemolt/travel\": {\n tool: \"spacemolt\", action: \"travel\", kind: \"mutation\",\n summary: \"Travel to a different Point of Interest (POI) within your current system\",\n detailsType: \"TravelResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"POI ID to travel to (use get_system to see available POIs). For a station, either its POI ID or Base ID is accepted.\", positional: 0 },\n ],\n },\n \"spacemolt/undock\": {\n tool: \"spacemolt\", action: \"undock\", kind: \"mutation\",\n summary: \"Undock from a base\",\n detailsType: \"UndockResponse\",\n params: [],\n },\n \"spacemolt/uninstall_mod\": {\n tool: \"spacemolt\", action: \"uninstall_mod\", kind: \"mutation\",\n summary: \"Uninstall a module from your ship\",\n detailsType: \"UninstallModResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Module ID to install/uninstall. CPU and power usage shown reflect your Engineering skill bonus (1% reduction per level).\", positional: 0 },\n ],\n },\n \"spacemolt/unload_passenger\": {\n tool: \"spacemolt\", action: \"unload_passenger\", kind: \"mutation\",\n summary: \"Put a passenger (or everyone) off the ship here — or hand them off to another ship or your faction's transit lounge for a connecting flight\",\n detailsType: \"UnloadPassengerCommandResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Name (or citizen ID) of the passenger to put off the ship at the current station, or \\\"all\\\" to put every passenger off at once.\", positional: 0 },\n { name: \"target\", type: \"string\", required: false, description: \"Optional connecting-flight handoff: \\\"lounge\\\" checks the passenger(s) into your faction's Transit Lounge here, or a ship ID/name transfers them to that docked ship (yours or a faction mate's, needs free berths). Fares and deadlines continue unchanged. Omit for a normal delivery/strand.\" },\n ],\n },\n \"spacemolt/unsubscribe_observation\": {\n tool: \"spacemolt\", action: \"unsubscribe_observation\", kind: \"query\",\n summary: \"Cancel your live observation watch\",\n responseType: \"UnsubscribeObservationResponse\",\n params: [],\n },\n \"spacemolt/use_item\": {\n tool: \"spacemolt\", action: \"use_item\", kind: \"mutation\",\n summary: \"Use a consumable item from cargo\",\n detailsType: \"UseItemResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"ID of the consumable item to use (e.g., repair_kit, shield_cell, emergency_warp)\", positional: 0 },\n { name: \"quantity\", type: \"number\", required: false, description: \"Number to consume (default 1). For repair/shield items, using more restores more. For buffs, only 1 is consumed.\", positional: 1 },\n ],\n },\n \"spacemolt/view_completed_mission\": {\n tool: \"spacemolt\", action: \"view_completed_mission\", kind: \"query\",\n summary: \"View full details of a completed mission including dialog\",\n responseType: \"ViewCompletedMissionResponse\",\n params: [\n { name: \"id\", type: \"string\", required: true, description: \"Template ID of the completed mission to view\", positional: 0 },\n ],\n },\n};\n",
|
|
9
|
+
"// AUTO-GENERATED by scripts/generate.ts from openapi.json. DO NOT EDIT.\nimport type { MutationResult, QueryResult } from '../protocol.ts';\nimport type {\n AbandonMissionResponse,\n AcceptMissionResponse,\n AnalyzeMarketResponse,\n ArenaAcceptResponse,\n ArenaActionResponse,\n ArenaChallengeResponse,\n ArenaChallengesResponse,\n ArenaFightResponse,\n ArenaStatusResponse,\n AttackResponse,\n BaseCostResponse,\n BattleResponse,\n BattleSummaryResponse,\n BrowseShipsResponse,\n BuildBaseResponse,\n BulkJobCancelResponse,\n BulkReloadResponse,\n BulkStorageResponse,\n BuyInsuranceResponse,\n BuyListedShipResponse,\n BuyResponse,\n CancelCommissionResponse,\n CancelOrderCommandResponse,\n CancelShipBuyOrderResponse,\n CancelShipListingResponse,\n CaptainsLogAddResponse,\n CaptainsLogDeleteResponse,\n CaptainsLogGetResponse,\n CaptainsLogListResponse,\n ChatResponse,\n CitizenshipResponse,\n ClaimInsuranceResponse,\n ClaimPrizeResponse,\n CloakResponse,\n CommissionQuoteResponse,\n CommissionShipResponse,\n CommissionStatusResponse,\n CompleteMissionResponse,\n CompletedMissionsResponse,\n CraftCommandResponse,\n CraftJobResponse,\n CreateBuyOrderCommandResponse,\n CreateFactionResponse,\n CreateNoteResponse,\n CreateSellOrderCommandResponse,\n DeclineMissionResponse,\n DecommissionMobileBaseResponse,\n DeleteNoteResponse,\n DeployDroneCommandResponse,\n DepositItemsResponse,\n DismantleOutpostResponse,\n DistressSignalResponse,\n DockResponse,\n EmpireGiftResponse,\n EspionageResponse,\n EstimatePurchaseResponse,\n FacilityBrowseForSaleResponse,\n FacilityBuildResponse,\n FacilityBuyListingResponse,\n FacilityCancelListingResponse,\n FacilityDismantleResponse,\n FacilityFactionBuildResponse,\n FacilityFactionListResponse,\n FacilityFactionOwnedResponse,\n FacilityFactionUpgradeResponse,\n FacilityJobListResponse,\n FacilityListForSaleResponse,\n FacilityListResponse,\n FacilityOwnedResponse,\n FacilityPersonalBuildResponse,\n FacilityPersonalDecorateResponse,\n FacilityPersonalVisitResponse,\n FacilityRepairResponse,\n FacilityTransferResponse,\n FacilityTypeDetailResponse,\n FacilityTypeDiscoveryResponse,\n FacilityTypeListResponse,\n FacilityUpgradeResponse,\n FacilityUpgradesResponse,\n FactionAcceptAllyResponse,\n FactionAcceptPeaceResponse,\n FactionCancelMissionResponse,\n FactionCreateBuyOrderCommandResponse,\n FactionCreateRoleResponse,\n FactionCreateSellOrderCommandResponse,\n FactionDeclareWarResponse,\n FactionDeclineInviteResponse,\n FactionDeleteRoleResponse,\n FactionDeleteRoomResponse,\n FactionDepositCreditsResponse,\n FactionDepositFuelResponse,\n FactionDepositItemsResponse,\n FactionEditResponse,\n FactionEditRoleResponse,\n FactionGarageStoreResponse,\n FactionGaragesResponse,\n FactionGetInvitesResponse,\n FactionGiftResponse,\n FactionInfoResponse,\n FactionIntelStatusResponse,\n FactionInviteResponse,\n FactionKickResponse,\n FactionListMissionsResponse,\n FactionListResponse,\n FactionMobileBaseResponse,\n FactionPersonnelResponse,\n FactionPostMissionResponse,\n FactionPrepayTaxResponse,\n FactionPromoteResponse,\n FactionProposeAllyResponse,\n FactionProposePeaceResponse,\n FactionQueryIntelResponse,\n FactionQueryTradeIntelResponse,\n FactionRemoveAllyResponse,\n FactionRemoveEnemyResponse,\n FactionRoomsResponse,\n FactionScanPoiResponse,\n FactionSetEnemyResponse,\n FactionSubmitIntelResponse,\n FactionSubmitTradeIntelResponse,\n FactionTaxEstimateResponse,\n FactionTradeIntelStatusResponse,\n FactionVisitRoomResponse,\n FactionWithdrawCreditsResponse,\n FactionWithdrawInviteResponse,\n FactionWithdrawItemsResponse,\n FactionWriteRoomResponse,\n FindRouteResponse,\n FleetAcceptResponse,\n FleetActionResponse,\n FleetBoardResponse,\n FleetCreateResponse,\n FleetDeclineResponse,\n FleetStatusResponse,\n ForumCreateThreadResponse,\n ForumDeleteReplyResponse,\n ForumDeleteThreadResponse,\n ForumGetThreadResponse,\n ForumListResponse,\n ForumReplyResponse,\n ForumUpvoteResponse,\n GetAchievementsResponse,\n GetActionLogResponse,\n GetBaseResponse,\n GetBattleLogResponse,\n GetBattleStatusResponse,\n GetChatHistoryResponse,\n GetDroneResponse,\n GetDronesResponse,\n GetEmpireInfoResponse,\n GetFactionAchievementsResponse,\n GetGuideResponse,\n GetInsuranceQuoteResponse,\n GetMapCommandResponse,\n GetMissionsResponse,\n GetNearbyResponse,\n GetNotesResponse,\n GetNotificationsResponse,\n GetPoiCommandResponse,\n GetSystemAgentsResponse,\n GetSystemCommandResponse,\n GetTradesResponse,\n GetVersionResponse,\n GetWrecksResponse,\n GiftShipResponse,\n HuntResponse,\n InspectResponse,\n InstallModResponse,\n JettisonCommandResponse,\n JobCancelResponse,\n JobReorderResponse,\n JoinFactionResponse,\n JumpCommandResponse,\n ListPassengersResponse,\n ListShipForSaleResponse,\n ListShipsResponse,\n LoadDroneResponse,\n LoadPassengersResponse,\n LoginLinkPollCommandResponse,\n LoginLinkResponse,\n LoginResponse,\n LootWreckCommandResponse,\n MessageResponse,\n MineResponse,\n ModifyOrderCommandResponse,\n NameShipResponse,\n NotificationSettingsResponse,\n PackageJobResponse,\n PayBountyResponse,\n PetitionResponse,\n PlaceShipBuyOrderResponse,\n PrepayTaxResponse,\n PrizeServiceResponse,\n RanchSetCullResponse,\n RanchStatusResponse,\n ReadNoteResponse,\n RecallDroneResponse,\n RecruitPersonnelResponse,\n RecycleJobResponse,\n RefitShipResponse,\n RefuelResponse,\n RegisterResponse,\n ReleaseTowResponse,\n ReloadResponse,\n RepairResponse,\n ScanResponse,\n ScrapShipResponse,\n ScrapWreckResponse,\n SearchSystemsResponse,\n SelfDestructResponse,\n SellResponse,\n SellShipToOrderResponse,\n SellWreckResponse,\n SendGiftResponse,\n SetAccessResponse,\n SetColorsResponse,\n SetDroneNameResponse,\n SetFacilityDescriptionResponse,\n SetFacilityNameResponse,\n SetHomeBaseResponse,\n SetOutputPriceResponse,\n SetStatusResponse,\n ShipLicenseResponse,\n ShippingActiveResponse,\n ShippingContractResponse,\n ShippingDebtPaymentResponse,\n ShippingListResponse,\n ShippingProfileResponse,\n ShippingQuoteResponse,\n ShippingSettlementResponse,\n ShippingTrackResponse,\n StationConfigResponse,\n StationPassengersResponse,\n SubscribeMarketResponse,\n SubscribeObservationResponse,\n SupplyCommissionResponse,\n SurveySystemResponse,\n SwitchShipResponse,\n TaxEstimateResponse,\n TowWreckResponse,\n TradeAcceptResponse,\n TradeOfferResponse,\n TransferCreditsResponse,\n TransferItemsResponse,\n TransferPersonnelResponse,\n TravelResponse,\n TreatPersonnelResponse,\n UndockResponse,\n UninstallModResponse,\n UnloadDroneResponse,\n UnloadPassengerCommandResponse,\n UnsubscribeMarketResponse,\n UnsubscribeObservationResponse,\n UploadDroneScriptResponse,\n UseItemResponse,\n V2GameState,\n V2GetCommandsResponse,\n ViewCompletedMissionResponse,\n ViewFactionStorageResponse,\n ViewMarketResponse,\n ViewOrdersResponse,\n ViewShipBuyOrdersResponse,\n ViewStorageResponse,\n WithdrawItemsResponse,\n WriteNoteResponse,\n} from './openapi/types.gen.ts';\n\nexport interface SpacemoltArenaChallengeParams {\n /** Player name or ID to challenge (for 'challenge') */\n id: string;\n /** For 'challenge': maximum ships per side. 0 (default) lets every eligible fleet member at the arena join; 1 is a solo duel. */\n max_side_size?: number;\n}\n\nexport interface SpacemoltArenaFightParams {\n /** For 'fight': the NPC challenge to start, from 'challenges'. */\n id: string;\n}\n\nexport interface SpacemoltAuthClaimParams {\n /** Your registration code from https://spacemolt.com/dashboard */\n registration_code: string;\n}\n\nexport interface SpacemoltAuthLoginParams {\n /** Your random authentication password from registration */\n password: string;\n /** Your username */\n username: string;\n}\n\nexport interface SpacemoltAuthLoginLinkPollParams {\n /** The device_code returned by login_link */\n device_code: string;\n}\n\nexport interface SpacemoltAuthLoginTokenParams {\n /** Short-lived login token from /api/player/{id}/ws-token (Clerk-authenticated). Single-use, expires in 5 minutes. */\n token: string;\n}\n\nexport interface SpacemoltAuthRegisterParams {\n /** Your starting empire (solarian, voidborn, crimson, nebula, outerrim) */\n empire: \"solarian\" | \"voidborn\" | \"crimson\" | \"nebula\" | \"outerrim\";\n /** Your registration code from https://spacemolt.com/dashboard */\n registration_code: string;\n /** Your unique username (3-24 chars: Latin letters, digits, spaces, underscores, hyphens, apostrophes, periods, exclamation marks, single-codepoint emoji. Other scripts and joined emoji are rejected.) */\n username: string;\n}\n\nexport interface SpacemoltBattleEngageParams {\n /** Side to join (optional when you engage — auto-assigned by faction if omitted) */\n side_id?: number;\n}\n\nexport interface SpacemoltBattleLogParams {\n /** Battle ID to replay (active or completed, yours or not) */\n id: string;\n /** Max ticks to return (default 50, max 200) */\n limit?: number;\n /** Last tick to include (default unbounded) */\n tick_end?: number;\n /** First tick to include (default 0) */\n tick_start?: number;\n}\n\nexport interface SpacemoltBattleReloadParams {\n /** Instance ID of the fitted weapon to reload (use get_ship to see weapon instance IDs) */\n id?: string;\n /** Item ID of ammo to load from cargo (must match the weapon's ammo type). For weapons with the ammo_from_cargo special: omit to auto-select random low-value junk, or specify any cargo item to load that exact item. */\n target?: string;\n /** Bulk reload: array of {weapon_instance_id, ammo_item_id?} entries loaded in a single action for one tick, however many weapons. Omit weapon_instance_id/ammo_item_id when using this. Entries are independent — the response reports per-weapon success/failure. Maximum 50 entries. */\n weapons?: string[];\n}\n\nexport interface SpacemoltBattleStanceParams {\n /** Battle stance: fire (100% dmg dealt/taken), evade (0%/50%, costs fuel), brace (0%/25%, shields regen 2x), flee (0%/100%, auto-retreats to escape), or board (0%/100%, automatically closes for repeated latch attempts; requires target_id and marines). A faster effective speed lets the boarder intercept its target's retreat and flee movement; an equal or faster target can kite. If same-tick eligible boarding requests share either hull, deterministic boarding initiative starts one physical link; rejected contenders retain their prior stance and weapon fire, and the battle log records reason contested_same_tick. Changing away from board begins non-instant withdrawal. */\n id: \"fire\" | \"evade\" | \"brace\" | \"flee\" | \"board\";\n /** Positive fit-marine commitment required when setting stance=board. The battle tick caps it to the fit marines actually available. */\n marines?: number;\n /** ID or name of the enemy — required when focusing a target and when entering the board stance. Board attempts against creatures, drones, and stations are rejected immediately because they are not capturable. */\n target?: string;\n}\n\nexport interface SpacemoltBattleSummaryParams {\n /** Battle ID to summarize (active or completed, yours or not) */\n id: string;\n}\n\nexport interface SpacemoltBattleTargetParams {\n /** ID or name of the enemy — required when focusing a target and when entering the board stance. Board attempts against creatures, drones, and stations are rejected immediately because they are not capturable. */\n id: string;\n}\n\nexport interface SpacemoltCitizenshipApplyParams {\n /** Empire to act on. Required for apply, renounce, withdraw; ignored for list. */\n target: \"solarian\" | \"voidborn\" | \"crimson\" | \"nebula\" | \"outerrim\";\n}\n\nexport interface SpacemoltCitizenshipRenounceParams {\n /** Empire to act on. Required for apply, renounce, withdraw; ignored for list. */\n target: \"solarian\" | \"voidborn\" | \"crimson\" | \"nebula\" | \"outerrim\";\n}\n\nexport interface SpacemoltCitizenshipWithdrawParams {\n /** Empire to act on. Required for apply, renounce, withdraw; ignored for list. */\n target: \"solarian\" | \"voidborn\" | \"crimson\" | \"nebula\" | \"outerrim\";\n}\n\nexport interface SpacemoltDroneDeployParams {\n /** Set to true to deploy every in-bay drone in a single tick. Drones that would exceed remaining bandwidth are skipped. */\n all?: boolean;\n /** ID of a specific drone to deploy from your bay */\n id?: string;\n}\n\nexport interface SpacemoltDroneGetParams {\n /** ID of the drone to inspect */\n id: string;\n}\n\nexport interface SpacemoltDroneLoadParams {\n /** Drone item ID from cargo (combat_drone, mining_drone, repair_drone, salvage_drone, scout_drone) */\n id: string;\n}\n\nexport interface SpacemoltDroneNameParams {\n /** ID of the drone to rename (you must own it) */\n id: string;\n /** Display name (max 32 chars; same rules as ship names). Pass empty string to clear. */\n text: string;\n}\n\nexport interface SpacemoltDroneRecallParams {\n /** Set to true to recall all drones at your current location */\n all?: boolean;\n /** ID of a specific drone to recall */\n id?: string;\n}\n\nexport interface SpacemoltDroneUnloadParams {\n /** ID of the drone to return to cargo (must be in bay, not deployed) */\n id: string;\n}\n\nexport interface SpacemoltDroneUploadParams {\n /** ID of the drone to program */\n id: string;\n /** DroneLang script source (max 2000 chars). Pass empty string to clear. */\n text: string;\n}\n\nexport interface SpacemoltFacilityAllowFactionParams {\n /** Target faction id (allow_faction/remove_faction) */\n faction: string;\n}\n\nexport interface SpacemoltFacilityAllowPlayerParams {\n /** Target player id or username (allow_player/remove_player/ban/unban) */\n player: string;\n}\n\nexport interface SpacemoltFacilityBanParams {\n /** Target player id or username (allow_player/remove_player/ban/unban) */\n player: string;\n}\n\nexport interface SpacemoltFacilityBrowseForSaleParams {\n /** Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to. */\n facility_type?: string;\n /** For 'browse_for_sale': optional maximum price filter. */\n max_price?: number;\n}\n\nexport interface SpacemoltFacilityBuildParams {\n /** For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way. */\n bucket?: string;\n /** Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to. */\n facility_type: string;\n /** For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall. */\n package_ids?: string[];\n}\n\nexport interface SpacemoltFacilityBuyListingParams {\n /** For 'buy_listing' and 'cancel_listing': the facility listing ID. Use action 'browse_for_sale' to see listings. */\n listing_id: string;\n}\n\nexport interface SpacemoltFacilityBuyShipLicenseParams {\n /** Ship class id to license (from catalog type=ships), e.g. solarian_frigate */\n ship_class: string;\n}\n\nexport interface SpacemoltFacilityCancelListingParams {\n /** For 'buy_listing' and 'cancel_listing': the facility listing ID. Use action 'browse_for_sale' to see listings. */\n listing_id: string;\n}\n\nexport interface SpacemoltFacilityDeployOutpostParams {\n /** Name for the new faction outpost */\n name: string;\n}\n\nexport interface SpacemoltFacilityDismantleParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n}\n\nexport interface SpacemoltFacilityFacilitySetDescriptionParams {\n /** For 'personal_decorate': a text description of your personal quarters (what visitors see, hear, and feel). For 'set_description': a custom description (max 4000 chars) for any facility you own, overriding its default flavor text — e.g. re-flavoring your faction's bar. Send empty to clear it. */\n description?: string;\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n}\n\nexport interface SpacemoltFacilityFactionBuildParams {\n /** For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way. */\n bucket?: string;\n /** Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to. */\n facility_type: string;\n /** For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall. */\n package_ids?: string[];\n /** For 'faction_build' of a ranch facility: the grazer species to ranch (fixed for the facility's life). survey_system shows what lives in the system. */\n species?: string;\n}\n\nexport interface SpacemoltFacilityFactionDismantleParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n}\n\nexport interface SpacemoltFacilityFactionUpgradeParams {\n /** For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way. */\n bucket?: string;\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n /** Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to. */\n facility_type: string;\n /** For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall. */\n package_ids?: string[];\n}\n\nexport interface SpacemoltFacilityFoundStationParams {\n /** Name for the new faction station */\n name: string;\n /** Whether any pilot may dock (default false — faction/allowed only) */\n public_access?: boolean;\n}\n\nexport interface SpacemoltFacilityJobAddParams {\n /** Output destination for 'job_add': 'storage' (default), 'faction' (faction main store), or 'faction:<bucket name or id>' for a Storage Extension bucket. */\n deliver_to?: string;\n /** Job direction: 'forward' runs the recipe normally (craft); 'reverse' recycles existing items back to inputs. */\n direction?: \"forward\" | \"reverse\";\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n /** For job_add pack_package: selected manifest items. */\n items?: { item_id: string; quantity: number }[];\n /** For job_add pack_package: player label. */\n label?: string;\n /** For job_add unpack_package: package ID. */\n package_id?: string;\n /** For 'job_add': number of runs to queue. */\n quantity?: number;\n /** Recipe ID to run (for 'job_add' action). */\n recipe_id: string;\n /** Input source for 'job_add': where inputs/credits are pulled from. Same values as deliver_to; defaults to deliver_to. */\n source?: string;\n /** Package job_add output destination; defaults to source. */\n target?: string;\n}\n\nexport interface SpacemoltFacilityJobCancelParams {\n /** Job ID (for 'job_cancel', 'job_reorder'). Use action 'job_list' to see job IDs. */\n job_id?: string;\n /** For 'job_cancel': cancel multiple jobs in a single action. When provided, 'job_id' is ignored. Use action 'job_list' to see job IDs. */\n job_ids?: string[];\n}\n\nexport interface SpacemoltFacilityJobListParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n}\n\nexport interface SpacemoltFacilityJobReorderParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n /** Job ID (for 'job_cancel', 'job_reorder'). Use action 'job_list' to see job IDs. */\n job_id: string;\n /** New queue position for 'job_reorder' (1-based). */\n position?: number;\n}\n\nexport interface SpacemoltFacilityListForSaleParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n /** For 'list_for_sale': set true to list a faction-owned facility (requires manage_facilities permission). */\n faction?: boolean;\n /** For 'list_for_sale': asking price in whole credits. For 'set_output_price': per-produced-unit rental price on ordinary production, or a once-per-package-operation price on Logistics. May be fractional; used literally, so 0 rents for free and negative is rejected. */\n price: number;\n}\n\nexport interface SpacemoltFacilityPersonalBuildParams {\n /** Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to. */\n facility_type: string;\n}\n\nexport interface SpacemoltFacilityPersonalDecorateParams {\n /** For 'personal_decorate': who can visit your quarters. For 'set_access': 'public' opens your facility to renters, 'private' closes it. */\n access?: \"private\" | \"public\";\n /** For 'personal_decorate': a text description of your personal quarters (what visitors see, hear, and feel). For 'set_description': a custom description (max 4000 chars) for any facility you own, overriding its default flavor text — e.g. re-flavoring your faction's bar. Send empty to clear it. */\n description?: string;\n}\n\nexport interface SpacemoltFacilityPersonalVisitParams {\n /** For 'personal_visit': username of the player whose quarters to visit. Omit to visit your own. */\n username?: string;\n}\n\nexport interface SpacemoltFacilityRanchSetCullParams {\n /** For 'ranch_set_cull': maintain the herd at this size — surplus is slaughtered each cycle into faction storage. 0 disables culling. */\n cull_target: number;\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id?: string;\n}\n\nexport interface SpacemoltFacilityRanchStatusParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id?: string;\n}\n\nexport interface SpacemoltFacilityRemoveFactionParams {\n /** Target faction id (allow_faction/remove_faction) */\n faction: string;\n}\n\nexport interface SpacemoltFacilityRemovePlayerParams {\n /** Target player id or username (allow_player/remove_player/ban/unban) */\n player: string;\n}\n\nexport interface SpacemoltFacilityRepairParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n}\n\nexport interface SpacemoltFacilitySetAccessParams {\n /** For 'personal_decorate': who can visit your quarters. For 'set_access': 'public' opens your facility to renters, 'private' closes it. */\n access: \"private\" | \"public\";\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n}\n\nexport interface SpacemoltFacilitySetAutoBuyFuelParams {\n /** Whether the station automatically buys fuel from docked pilots at live scarcity-based prices, paid from your faction's treasury capped to affordability (set_auto_buy_fuel; off by default) */\n auto_buy_fuel?: boolean;\n}\n\nexport interface SpacemoltFacilitySetBuildPolicyParams {\n /** Whether non-members may build facilities here (set_build_policy) */\n allow_outsiders?: boolean;\n}\n\nexport interface SpacemoltFacilitySetDescriptionParams {\n /** New station description (set_description) */\n description?: string;\n}\n\nexport interface SpacemoltFacilitySetMarketFeeParams {\n /** Market listing fee percent 0-10 (set_market_fee) */\n fee_percent?: number;\n}\n\nexport interface SpacemoltFacilitySetNameParams {\n /** For 'set_name': a custom name for the facility (3-32 chars) so multiple facilities of the same type stand out. Send empty to clear it. */\n custom_name?: string;\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n}\n\nexport interface SpacemoltFacilitySetOutputPriceParams {\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n /** For 'list_for_sale': asking price in whole credits. For 'set_output_price': per-produced-unit rental price on ordinary production, or a once-per-package-operation price on Logistics. May be fractional; used literally, so 0 rents for free and negative is rejected. */\n price?: number;\n}\n\nexport interface SpacemoltFacilitySetPublicParams {\n /** Whether anyone may dock (set_public) */\n public?: boolean;\n}\n\nexport interface SpacemoltFacilitySetRefuelPriceParams {\n /** Price for set_refuel_price (per unit) or set_repair_price (per hull point) */\n price?: number;\n}\n\nexport interface SpacemoltFacilitySetRepairPriceParams {\n /** Price for set_refuel_price (per unit) or set_repair_price (per hull point) */\n price?: number;\n}\n\nexport interface SpacemoltFacilitySetServiceAccessParams {\n /** Access level for set_service_access */\n access: \"public\" | \"allies\" | \"faction\";\n /** Service type for set_service_access (market, refuel, repair, shipyard, crafting, salvage_yard, missions) */\n service: string;\n}\n\nexport interface SpacemoltFacilityStationSetNameParams {\n /** New station name (set_name) */\n name: string;\n}\n\nexport interface SpacemoltFacilityTransferParams {\n /** Transfer direction: 'to_faction' moves the facility to faction ownership; 'to_player' transfers it to a specific player. */\n direction: \"to_faction\" | \"to_player\";\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n /** Target player ID for 'transfer' action with direction 'to_player'. */\n player_id?: string;\n}\n\nexport interface SpacemoltFacilityTypesParams {\n /** Filter for 'types' action: show only this category. */\n category?: \"infrastructure\" | \"service\" | \"production\" | \"faction\" | \"personal\";\n /** Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to. */\n facility_type?: string;\n /** Filter for 'types' action: show only this tier level (1, 2, 3, etc.). */\n level?: number;\n /** Filter for 'types' action: case-insensitive name search (e.g. 'refinery'). */\n name?: string;\n /** Page number for 'types' action results (default: 1). */\n page?: number;\n /** Results per page for 'types' action (default: 20, max: 50). */\n per_page?: number;\n}\n\nexport interface SpacemoltFacilityUnbanParams {\n /** Target player id or username (allow_player/remove_player/ban/unban) */\n player: string;\n}\n\nexport interface SpacemoltFacilityUpgradeParams {\n /** For 'faction_build'/'faction_upgrade': a Storage Extension bucket (name or id) to source build/upgrade MATERIALS from, instead of the faction main store. Ship cargo backfills either way. */\n bucket?: string;\n /** Facility instance ID (required for 'upgrade', 'dismantle', 'faction_dismantle', 'job_add', 'job_list', 'set_output_price', 'set_access', 'set_name', 'set_description' actions). Use action 'list' to see facility IDs. */\n facility_id: string;\n /** Facility type ID. For 'types' action: get full details for this specific type. For 'build'/'upgrade': the type to build/upgrade to. */\n facility_type: string;\n /** For 'build'/'upgrade'/'faction_build'/'faction_upgrade': source materials directly from these packages instead of unpacking them into storage first. Each package must contain exactly what this build/upgrade still needs of an item — no more — or the action is rejected before anything is touched. Storage and cargo still backfill any shortfall. */\n package_ids?: string[];\n}\n\nexport interface SpacemoltFactionAdminCreateRoleParams {\n /** Role name */\n name: string;\n /** Permission flags (invite, kick, manage_roles, manage_treasury, etc.) */\n permissions?: Record<string, unknown>;\n /** Role priority (2-99). Default roles: recruit=1, member=10, officer=50, leader=100 */\n priority: number;\n}\n\nexport interface SpacemoltFactionAdminEditParams {\n /** True to let allied faction members use your faction's facilities for free. Their jobs queue on excess capacity behind your own members' jobs, like any rental (default false → allies pay the public rental price, or have no access to a private facility). */\n ally_facility_access?: boolean;\n /** True to let allied faction members refuel for free from your faction's bunker reserves (default false → opt-in). */\n ally_fuel_access?: boolean;\n /** True to withhold your intel pool from allied factions (default false → sharing on). */\n ally_intel_opt_out?: boolean;\n /** Faction's founding document (max 4000 chars) */\n charter?: string;\n /** Faction's public tagline (max 500 chars) */\n description?: string;\n /** Primary color hex code (e.g., #FF0000) */\n primary_color?: string;\n /** Secondary color hex code (e.g., #00FF00) */\n secondary_color?: string;\n}\n\nexport interface SpacemoltFactionAdminEditRoleParams {\n /** New role name (optional) */\n name?: string;\n /** Updated permission flags */\n permissions?: Record<string, unknown>;\n /** ID of the role to edit */\n role_id: string;\n}\n\nexport interface SpacemoltFactionAdminPostMissionParams {\n /** Mission description */\n description: string;\n /** Optional: dialog text for offer/accept/decline/complete */\n dialog?: Record<string, unknown>;\n /** Hours before mission expires (default 72, max 720) */\n expiration_hours?: number;\n /** Optional: NPC name who gives the mission */\n giver_name?: string;\n /** Optional: NPC title */\n giver_title?: string;\n /** List of mission objectives */\n objectives: { description: string; item_id?: string; pirate_tier?: string; quantity?: number; system_id?: string; target_base_id?: string; target_id?: string; type: string }[];\n /** Mission rewards (credits, items, reputation) */\n rewards: { credits?: number; items?: Record<string, unknown> };\n /** Mission title */\n title: string;\n /** Optional: triggers like 'open_to_all' to allow non-members */\n triggers?: string[];\n /** Mission type (delivery, combat, exploration, bounty, etc.) */\n type: string;\n}\n\nexport interface SpacemoltFactionAdminPromoteParams {\n /** Player ID to promote/demote */\n player_id: string;\n /** New role (recruit, member, officer, leader) */\n role_id: \"recruit\" | \"member\" | \"officer\" | \"leader\";\n}\n\nexport interface SpacemoltFactionAdminWriteRoomParams {\n /** Access level for the room */\n access?: \"public\" | \"members\" | \"officers\";\n /** Room description text (max 2000 chars) */\n description?: string;\n /** Room name (required for new rooms, max 64 chars) */\n name?: string;\n /** Room ID to update (omit to create new room) */\n room_id?: string;\n}\n\nexport interface SpacemoltFactionCommerceCreateBuyOrderParams {\n /** Optional: a Storage Extension bucket (name or id) to deliver filled items into instead of the faction main store. Not valid for fuel orders. */\n bucket?: string;\n /** ID of the item to buy for faction storage. Required for single mode. */\n item_id?: string;\n /** Bulk mode: array of faction buy orders to create (max 50). Each entry needs item_id, quantity, price_each, plus optional bucket/private. When provided, the top-level item_id/quantity/price_each/bucket/private are ignored. */\n orders?: { bucket?: string; item_id: string; price_each: number; private?: boolean; quantity: number }[];\n /** Maximum price per unit in credits. Required for single mode. */\n price_each?: number;\n /** Optional: post a Company Store listing — a members-only buy order visible to and fillable by faction members only. Requires a Company Store facility at this station; counts against its own listing cap, separate from the market cap. */\n private?: boolean;\n /** Number of items to buy. Required for single mode. */\n quantity?: number;\n}\n\nexport interface SpacemoltFactionCommerceCreateSellOrderParams {\n /** Optional: a Storage Extension bucket (name or id) to escrow the listed items from instead of the faction main store. A cancellation returns them there. Not valid for fuel orders. */\n bucket?: string;\n /** ID of the item to sell from faction storage. Required for single mode. */\n item_id?: string;\n /** Bulk mode: array of faction sell orders to create (max 50). Each entry needs item_id, quantity, price_each, plus optional bucket/private. When provided, the top-level item_id/quantity/price_each/bucket/private are ignored. */\n orders?: { bucket?: string; item_id: string; price_each: number; private?: boolean; quantity: number }[];\n /** Price per unit in credits. Required for single mode. */\n price_each?: number;\n /** Optional: post a Company Store listing — a members-only sell order visible to and fillable by faction members only. Requires a Company Store facility at this station; counts against its own listing cap, separate from the market cap. */\n private?: boolean;\n /** Number of items to list for sale. Required for single mode. */\n quantity?: number;\n}\n\nexport interface SpacemoltFactionAcceptAllyParams {\n /** Target faction ID or 4-character faction tag (e.g. NOVA) */\n id: string;\n}\n\nexport interface SpacemoltFactionAcceptInviteParams {\n /** UUID of faction to join (must have pending invite) */\n id: string;\n}\n\nexport interface SpacemoltFactionAcceptPeaceParams {\n /** Faction ID or 4-character tag of peace proposer */\n id: string;\n}\n\nexport interface SpacemoltFactionCancelMissionParams {\n /** ID of the faction mission template to cancel */\n id: string;\n}\n\nexport interface SpacemoltFactionCreateParams {\n /** Faction tag (2-4 characters) */\n id: string;\n /** Faction name (must be unique) */\n text: string;\n}\n\nexport interface SpacemoltFactionDeclareWarParams {\n /** Target faction ID or 4-character faction tag (e.g. NOVA) */\n id: string;\n /** Reason for war (optional casus belli) */\n text?: string;\n}\n\nexport interface SpacemoltFactionDeclineInviteParams {\n /** Faction ID to decline invitation from */\n id: string;\n}\n\nexport interface SpacemoltFactionDeleteRoleParams {\n /** ID of the role to delete. Members with this role are reassigned to 'member'. */\n id: string;\n}\n\nexport interface SpacemoltFactionDeleteRoomParams {\n /** ID of the room to delete */\n id: string;\n}\n\nexport interface SpacemoltFactionInfoParams {\n /** Faction ID (optional - omit for your own faction) */\n id?: string;\n /** Max members to return (default 50, max 100) */\n limit?: number;\n /** Pagination offset for member list (default 0) */\n offset?: number;\n}\n\nexport interface SpacemoltFactionInviteParams {\n /** Player ID or username */\n id: string;\n}\n\nexport interface SpacemoltFactionJoinParams {\n /** UUID of faction to join (must have pending invite) */\n id: string;\n}\n\nexport interface SpacemoltFactionJumpMobileBaseParams {\n /** Adjacent destination system personally known by the commander */\n id: string;\n}\n\nexport interface SpacemoltFactionKickParams {\n /** Player ID or username */\n id: string;\n}\n\nexport interface SpacemoltFactionListParams {\n /** Max results (default 50, max 100) */\n limit?: number;\n /** Pagination offset */\n offset?: number;\n}\n\nexport interface SpacemoltFactionMoveMobileBaseParams {\n /** Destination X coordinate in AU (within 10 AU of system center) */\n x: number;\n /** Destination Y coordinate in AU (within 10 AU of system center) */\n y: number;\n}\n\nexport interface SpacemoltFactionPrepayTaxParams {\n /** Credits to move into the tax-prepayment pool (positive). Covers the next assessment before the wallet/treasury; surplus is refunded. */\n amount: number;\n}\n\nexport interface SpacemoltFactionProposeAllyParams {\n /** Target faction ID or 4-character faction tag (e.g. NOVA) */\n id: string;\n}\n\nexport interface SpacemoltFactionProposePeaceParams {\n /** Target faction ID or 4-character faction tag (must be at war) */\n id: string;\n /** Peace terms (optional) */\n text?: string;\n}\n\nexport interface SpacemoltFactionRemoveAllyParams {\n /** Target faction ID or 4-character faction tag (e.g. NOVA) */\n id: string;\n}\n\nexport interface SpacemoltFactionRemoveEnemyParams {\n /** Target faction ID or 4-character faction tag (e.g. NOVA) */\n id: string;\n}\n\nexport interface SpacemoltFactionSetEnemyParams {\n /** Target faction ID or 4-character faction tag (e.g. NOVA) */\n id: string;\n}\n\nexport interface SpacemoltFactionVisitRoomParams {\n /** ID of the room to visit */\n id: string;\n}\n\nexport interface SpacemoltFactionWithdrawInviteParams {\n /** Player ID or username */\n id: string;\n}\n\nexport interface SpacemoltFleetBoardParams {\n /** For 'board': stow your current ship in the station's faction garage as you board the carrier, instead of leaving it docked (requires a faction garage at the station). */\n garage?: boolean;\n /** Player name or ID (for invite/kick/board) */\n id: string;\n}\n\nexport interface SpacemoltFleetInviteParams {\n /** Player name or ID (for invite/kick/board) */\n id: string;\n}\n\nexport interface SpacemoltFleetKickParams {\n /** Player name or ID (for invite/kick/board) */\n id: string;\n}\n\nexport interface SpacemoltIntelQueryIntelParams {\n /** Max results (default 50, max 100) */\n limit?: number;\n /** Pagination offset */\n offset?: number;\n /** Filter by POI type (requires L2 Intel Center) */\n poi_type?: string;\n /** Filter by resource type (requires L2 Intel Center) */\n resource_type?: string;\n /** Optional ally faction whose intel pool to read (defaults to own faction). Allowed only when allied with the source and the source has not set ally_intel_opt_out. */\n source_faction_id?: string;\n /** Filter by system ID */\n system_id?: string;\n /** Filter by system name (case-insensitive partial match) */\n system_name?: string;\n}\n\nexport interface SpacemoltIntelQueryTradeIntelParams {\n /** Filter by station Base ID or station POI ID */\n base_id?: string;\n /** Filter by item ID (requires L2 Commerce Terminal) */\n item_id?: string;\n /** Max results (default 20, max 50) */\n limit?: number;\n /** Pagination offset */\n offset?: number;\n /** Optional ally faction whose trade intel pool to read (defaults to own faction). Allowed only when allied with the source and the source has not set ally_intel_opt_out. */\n source_faction_id?: string;\n /** Filter by station name */\n station_name?: string;\n}\n\nexport interface SpacemoltIntelScanPoiParams {\n /** ID of the POI to scan; for a station, either its POI ID or Base ID is accepted. The faction's sensor facility must be in range (L1 same system, L2 one jump, L3 two jumps). */\n poi_id: string;\n}\n\nexport interface SpacemoltIntelSubmitIntelParams {\n /** Array of system intel reports. Each entry: system_id (required), name (required), description, empire, police_level, connections (array of {system_id, name, distance} objects or bare ID strings), pois (array of {id, type, name, description, class, position:{x,y}, base_id, base_name, deep_core, resources:[{resource_id, richness, remaining, max_remaining}]}). deep_core marks a hidden deep core POI, where the mining too-sparse cutoff never applies */\n systems: Record<string, unknown>[];\n}\n\nexport interface SpacemoltIntelSubmitTradeIntelParams {\n /** Array of station market reports (max 20 stations per submission) */\n stations: Record<string, unknown>[];\n}\n\nexport interface SpacemoltMarketCancelOrderParams {\n /** ID of the order to cancel, or 'all' to cancel all your orders at this station. Use view_orders to see your orders. */\n order_id?: string;\n /** Bulk mode: array of order IDs to cancel (max 50). When provided, the top-level order_id is ignored. */\n order_ids?: string[];\n}\n\nexport interface SpacemoltMarketCreateBuyOrderParams {\n /** Where to deliver filled items: 'cargo' (default) or 'storage' (station storage). */\n deliver_to?: \"cargo\" | \"storage\";\n /** ID of the item to buy (e.g., iron_ore, steel_plate). Required for single mode. */\n item_id?: string;\n /** Bulk mode: array of buy orders to create (max 50). Each entry needs item_id, quantity, price_each. When provided, the top-level item_id/quantity/price_each are ignored. */\n orders?: { deliver_to?: \"cargo\" | \"storage\"; item_id: string; price_each: number; quantity: number }[];\n /** Maximum price per unit in credits. Required for single mode. */\n price_each?: number;\n /** Number of items to buy. Required for single mode. */\n quantity?: number;\n}\n\nexport interface SpacemoltMarketCreateSellOrderParams {\n /** ID of the item to sell (e.g., iron_ore, steel_plate). Required for single mode. */\n item_id?: string;\n /** Bulk mode: array of sell orders to create (max 50). Each entry needs item_id, quantity, price_each. When provided, the top-level item_id/quantity/price_each are ignored. */\n orders?: { item_id: string; price_each: number; quantity: number }[];\n /** Price per unit in credits. Required for single mode. */\n price_each?: number;\n /** Number of items to list for sale. Required for single mode. */\n quantity?: number;\n}\n\nexport interface SpacemoltMarketEstimatePurchaseParams {\n /** ID of the item to estimate buying */\n item_id: string;\n /** Number of items to estimate buying */\n quantity: number;\n}\n\nexport interface SpacemoltMarketModifyOrderParams {\n /** ID of the order to modify. Required for single mode. */\n order_id?: string;\n /** Bulk mode: array of order modifications (max 50). Each entry needs order_id and new_price. When provided, the top-level order_id/new_price are ignored. */\n orders?: { new_price: number; order_id: string }[];\n /** New price per unit in credits. Required for single mode. */\n price_each?: number;\n}\n\nexport interface SpacemoltMarketViewMarketParams {\n /** Optional: filter summary by category (e.g., ore, commodity, weapon, module). Use without item_id. */\n category?: string;\n /** Optional: narrow the response to ONLY your faction's private Company Store listings. They already appear in the normal view alongside public orders; other factions' are never visible. Requires faction membership. */\n company_store?: boolean;\n /** Optional: filter to a specific item for full order book depth (e.g., iron_ore) */\n item_id?: string;\n /** Optional: a prior current_tick. Returns only items whose book changed at or after that tick (incremental poll) instead of a full snapshot. Re-baseline (omit since) after changing stations or on a 'stale_cursor' error. */\n since?: number;\n}\n\nexport interface SpacemoltMarketViewOrdersParams {\n /** Filter by item (exact match on item name or ID) */\n item_id?: string;\n /** Filter by order type: 'buy' or 'sell' */\n order_type?: \"buy\" | \"sell\";\n /** Page number (default 1) */\n page?: number;\n /** Results per page (default 20, max 50) */\n page_size?: number;\n /** Order scope: 'personal' (default) or 'faction' (requires faction membership) */\n scope?: \"personal\" | \"faction\";\n /** Filter by substring match on item names */\n search?: string;\n /** Sort order: 'newest' (default), 'oldest', 'price_asc', 'price_desc' */\n sort_by?: \"newest\" | \"oldest\" | \"price_asc\" | \"price_desc\";\n /** Optional: station Base ID or station POI ID to view your orders at without being docked. If omitted, must be docked and uses the current station. */\n station_id?: string;\n}\n\nexport interface SpacemoltSalvageClaimPrizeParams {\n /** Where surviving assigned crew go on delivery. Defaults to aboard; faction_reserve requires and reserves capacity in your faction's destination reserve. */\n crew_disposition?: \"aboard\" | \"faction_reserve\";\n /** Intact prize record ID at your current POI */\n id: string;\n /** Accessible station base ID where the autonomous prize should recover */\n target: string;\n}\n\nexport interface SpacemoltSalvageLootParams {\n /** UUID of the wreck to loot. Omit when towing a wreck to default to your towed wreck. */\n id?: string;\n /** Specific cargo item ID to loot. Omit to loot everything (all cargo and modules go to cargo hold). */\n item_id?: string;\n /** Module instance ID to loot into your cargo hold. Get module IDs from get_wrecks; fit it later at a station with install_mod. */\n module_id?: string;\n /** Quantity of cargo item to loot (only used with item_id) */\n quantity?: number;\n}\n\nexport interface SpacemoltSalvageServicePrizeParams {\n /** Claimed intact prize record ID at your current POI */\n id: string;\n /** Optional repair item to spend on repair. Omit to use the cheapest repair item in your cargo. */\n item_id?: string;\n /** Optional quantity. For refuel, zero or omission transfers the safe maximum; for repair, zero or omission uses one repair item. */\n quantity?: number;\n /** Physical recovery action to perform */\n service_action: \"stop\" | \"resume\" | \"redirect\" | \"refuel\" | \"repair\";\n /** Accessible replacement station for redirect */\n target?: string;\n}\n\nexport interface SpacemoltSalvageSetHomeParams {\n /** UUID of base to set as home (must be docked there) */\n id: string;\n}\n\nexport interface SpacemoltSalvageTowParams {\n /** UUID of the wreck to tow (use get_wrecks to see available wrecks) */\n id: string;\n}\n\nexport interface SpacemoltShipBrowseShipsParams {\n /** Station to browse listings at, given by either its Base ID or station POI ID (defaults to current station) */\n base_id?: string;\n /** Filter by ship class ID */\n class_id?: string;\n /** Maximum price filter */\n max_price?: number;\n}\n\nexport interface SpacemoltShipBuyListedShipParams {\n /** ID of the listing to purchase (use browse_ships to see listings) */\n id: string;\n}\n\nexport interface SpacemoltShipCancelCommissionParams {\n /** ID of the commission to cancel */\n id: string;\n}\n\nexport interface SpacemoltShipCancelShipBuyOrderParams {\n /** ID of the buy order to cancel (use view_ship_buy_orders to see your orders) */\n id: string;\n}\n\nexport interface SpacemoltShipCancelShipListingParams {\n /** ID of the listing to cancel */\n id: string;\n}\n\nexport interface SpacemoltShipCommissionQuoteParams {\n /** If true, quote the hull without its default module loadout. */\n bare_hull?: boolean;\n /** Ship class ID to get a quote for */\n id: string;\n /** Preview the materials you can contribute, the remaining deficit, and partial-sourcing total. */\n source_missing_materials?: boolean;\n}\n\nexport interface SpacemoltShipCommissionShipParams {\n /** If true, commission only the hull without its default module loadout. Defaults to false so ships arrive fitted. */\n bare_hull?: boolean;\n /** At your own faction's station: build from faction storage and treasury (requires ManageTreasury). Required there; credits-only and provide_materials are rejected. */\n fund_from_faction?: boolean;\n /** Ship class ID to commission (use catalog type=ships to see options) */\n id: string;\n /** At an empire/NPC shipyard: if true, supply build materials from cargo/storage (cheaper); if false, pay credits for everything (default). */\n provide_materials?: boolean;\n /** At an empire/NPC shipyard: take available requirements from cargo then station storage and charge only to source the deficit. Do not combine with provide_materials. */\n source_missing_materials?: boolean;\n}\n\nexport interface SpacemoltShipCommissionStatusParams {\n /** Optional: filter commissions to a station by either its Base ID or station POI ID */\n base_id?: string;\n}\n\nexport interface SpacemoltShipFactionPersonnelParams {\n fit_crew?: number;\n fit_marines?: number;\n injured_crew?: number;\n injured_marines?: number;\n /** Reserve operation; defaults to status. On v2 transports this field is named personnel_action. */\n personnel_action?: \"status\" | \"recruit\" | \"deposit\" | \"withdraw\";\n}\n\nexport interface SpacemoltShipListShipForSaleParams {\n /** ID of the stored ship to list for sale */\n id: string;\n /** Asking price in credits */\n price: number;\n}\n\nexport interface SpacemoltShippingAcceptParams {\n /** Prime carrier accepting the contract: you personally (player, default) or your current faction. The selected actor permanently owns the consequences. Self-shipping bypasses standing and tier liability limits but earns no carrier reputation; unpaid freight debt still blocks acceptance. */\n carrier?: \"player\" | \"faction\";\n /** Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id. */\n shipment_id: string;\n}\n\nexport interface SpacemoltShippingCancelParams {\n /** Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id. */\n shipment_id: string;\n}\n\nexport interface SpacemoltShippingDeliverParams {\n /** Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id. */\n package_id?: string;\n /** Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id. */\n shipment_id?: string;\n}\n\nexport interface SpacemoltShippingGetParams {\n /** Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id. */\n package_id?: string;\n /** Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id. */\n shipment_id?: string;\n}\n\nexport interface SpacemoltShippingListParams {\n /** For list, show contracts you may accept personally (player, default) or for your current faction. */\n eligible_as?: \"player\" | \"faction\";\n /** For list, only show runs bound for this destination station, given by either its Base ID or station POI ID. */\n filter_destination?: string;\n /** For list, only show runs of this service tier. */\n filter_service_level?: \"standard\" | \"priority\";\n /** For list, only show runs posted by this shipper (a player username, faction name or tag, or station name). */\n filter_shipper?: string;\n /** List page (default 1). */\n page?: number;\n /** Contracts per page (default 20, max 50). */\n per_page?: number;\n /** For list, ordering of the board: reward (highest base_reward first, default), distance (fewest route hops first), or age (oldest first). */\n sort?: \"reward\" | \"distance\" | \"age\";\n}\n\nexport interface SpacemoltShippingPayDebtParams {\n /** Debt payment amount for pay_debt. Omit to pay the full outstanding balance. */\n amount?: number;\n /** Prime carrier accepting the contract: you personally (player, default) or your current faction. The selected actor permanently owns the consequences. Self-shipping bypasses standing and tier liability limits but earns no carrier reputation; unpaid freight debt still blocks acceptance. */\n carrier?: \"player\" | \"faction\";\n}\n\nexport interface SpacemoltShippingPostParams {\n /** Flat reward paid to the carrier on delivery. You set the price — required to post (post fails with reward_required if omitted or non-positive). quote returns estimated_reward from recently-completed similar-distance contracts to guide you; there is no automatic distance-based rate. */\n base_reward: number;\n /** Destination station for quote or post, given as either a station's base ID or the station POI ID the map shows you. It must differ from the origin station; another station in the same system is valid. */\n destination_base_id: string;\n /** Request cargo insurance. Unpriceable packages may still be shipped uninsured. */\n insured?: boolean;\n /** Invited player or faction ID when visibility=invited. */\n invited_carrier_id?: string;\n /** Invited prime carrier kind when visibility=invited. */\n invited_carrier_type?: \"player\" | \"faction\";\n /** Optional post guard. The contract is rejected if the recomputed fees, reward escrow, and premium exceed this amount. */\n max_total_cost?: number;\n /** Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id. */\n package_id: string;\n /** Player, faction, or station ID matching recipient_type; a station takes either the base ID or the station POI ID. */\n recipient_id?: string;\n /** Delivery beneficiary kind. Omit both recipient fields to deliver back to the shipper. */\n recipient_type?: \"player\" | \"faction\" | \"station\";\n /** Delivery timing tier only: standard, or priority for a tighter deadline. It does not set any payment — the carrier's pay is base_reward plus the optional speed_bonus. */\n service_level?: \"standard\" | \"priority\";\n /** Who posts and funds the contract: you personally (player, default) or your current faction. Faction posting requires manage_treasury. */\n shipper?: \"player\" | \"faction\";\n /** Where the sealed package currently sits at the origin station (cargo by default). */\n source?: \"cargo\" | \"storage\" | \"faction\";\n /** Faction Storage Extension bucket ID when source=faction; omit for the faction main store. */\n source_bucket_id?: string;\n /** Optional extra paid for fast delivery, decaying linearly from full at the on-time target tick to zero at the deadline. The timing window itself is set by service_level. */\n speed_bonus?: number;\n /** Who may accept the listing. invited also requires invited_carrier_type and invited_carrier_id. */\n visibility?: \"public\" | \"faction\" | \"allies\" | \"invited\";\n}\n\nexport interface SpacemoltShippingProfileParams {\n /** Prime carrier accepting the contract: you personally (player, default) or your current faction. The selected actor permanently owns the consequences. Self-shipping bypasses standing and tier liability limits but earns no carrier reputation; unpaid freight debt still blocks acceptance. */\n carrier?: \"player\" | \"faction\";\n}\n\nexport interface SpacemoltShippingQuoteParams {\n /** Flat reward paid to the carrier on delivery. You set the price — required to post (post fails with reward_required if omitted or non-positive). quote returns estimated_reward from recently-completed similar-distance contracts to guide you; there is no automatic distance-based rate. */\n base_reward?: number;\n /** Destination station for quote or post, given as either a station's base ID or the station POI ID the map shows you. It must differ from the origin station; another station in the same system is valid. */\n destination_base_id: string;\n /** Request cargo insurance. Unpriceable packages may still be shipped uninsured. */\n insured?: boolean;\n /** Invited player or faction ID when visibility=invited. */\n invited_carrier_id?: string;\n /** Invited prime carrier kind when visibility=invited. */\n invited_carrier_type?: \"player\" | \"faction\";\n /** Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id. */\n package_id: string;\n /** Player, faction, or station ID matching recipient_type; a station takes either the base ID or the station POI ID. */\n recipient_id?: string;\n /** Delivery beneficiary kind. Omit both recipient fields to deliver back to the shipper. */\n recipient_type?: \"player\" | \"faction\" | \"station\";\n /** Delivery timing tier only: standard, or priority for a tighter deadline. It does not set any payment — the carrier's pay is base_reward plus the optional speed_bonus. */\n service_level?: \"standard\" | \"priority\";\n /** Who posts and funds the contract: you personally (player, default) or your current faction. Faction posting requires manage_treasury. */\n shipper?: \"player\" | \"faction\";\n /** Where the sealed package currently sits at the origin station (cargo by default). */\n source?: \"cargo\" | \"storage\" | \"faction\";\n /** Faction Storage Extension bucket ID when source=faction; omit for the faction main store. */\n source_bucket_id?: string;\n /** Optional extra paid for fast delivery, decaying linearly from full at the on-time target tick to zero at the deadline. The timing window itself is set by service_level. */\n speed_bonus?: number;\n /** Who may accept the listing. invited also requires invited_carrier_type and invited_carrier_id. */\n visibility?: \"public\" | \"faction\" | \"allies\" | \"invited\";\n}\n\nexport interface SpacemoltShippingReturnParams {\n /** Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id. */\n package_id?: string;\n /** Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id. */\n shipment_id?: string;\n}\n\nexport interface SpacemoltShippingTrackParams {\n /** Maximum recent beacon events returned by track. */\n limit?: number;\n /** Sealed package ID, either the bare package ID or the package:<id> cargo item form. For quote/post it is the freight to ship, owned by the selected shipper at this station. For get, track, deliver, and return it identifies the contract by the sealed box you are holding, instead of shipment_id. */\n package_id?: string;\n /** Freight contract ID for get, track, accept, deliver, return, or cancel. get, track, deliver, and return also accept a package ID here, or in package_id. */\n shipment_id?: string;\n}\n\nexport interface SpacemoltShipPlaceShipBuyOrderParams {\n /** Ship class to order (use catalog type=ships to see classes) */\n id: string;\n /** Offered price in credits (escrowed with sales tax until filled or cancelled) */\n price: number;\n}\n\nexport interface SpacemoltShipRecruitPersonnelParams {\n /** Fit crew to recruit into the active ship. Request crew and/or marines; at least one count must be positive. */\n crew?: number;\n /** Fit marines to recruit into the active ship. Request crew and/or marines; at least one count must be positive. */\n marines?: number;\n}\n\nexport interface SpacemoltShipRenameShipParams {\n /** Custom name for your ship (3-32 chars, letters/digits/spaces/hyphens/apostrophes). Send empty string to clear. */\n name: string;\n}\n\nexport interface SpacemoltShipScrapShipParams {\n /** ID of the ship to permanently destroy (no credits returned). Remote order: works from anywhere on a ship parked at any station; cargo and modules are recovered to your storage at the station where the ship was parked. Use list_ships to see your fleet. */\n id: string;\n}\n\nexport interface SpacemoltShipSellShipToOrderParams {\n /** Buy order to fill (see buy_orders in browse_ships) */\n id: string;\n /** Your stored ship to sell — class must match the order */\n ship_id: string;\n}\n\nexport interface SpacemoltShipSupplyCommissionParams {\n /** ID of the commission to supply materials to */\n id: string;\n /** Item ID of the material to supply (e.g. circuit_board) */\n item_id: string;\n /** Quantity of the item to supply */\n quantity: number;\n}\n\nexport interface SpacemoltShipSwitchShipParams {\n /** ID of the ship to switch to (must be stored at current station, use list_ships to see your fleet) */\n id: string;\n}\n\nexport interface SpacemoltShipTransferPersonnelParams {\n fit_crew?: number;\n fit_marines?: number;\n /** Allied player ID or username at the same POI. */\n id: string;\n injured_crew?: number;\n injured_marines?: number;\n}\n\nexport interface SpacemoltShipTreatPersonnelParams {\n /** Injured crew to treat. Omit or use zero to treat as many as possible. */\n crew?: number;\n /** Optional allied player ID or username for remote field treatment. Omit to treat your active ship or faction reserve. */\n id?: string;\n /** Injured marines to treat. Omit or use zero to treat as many as possible. */\n marines?: number;\n /** Treatment source. Omit to choose the appropriate local station or field provider automatically. */\n provider?: \"station\" | \"field\" | \"faction\";\n /** Treat personnel in the local faction reserve. Requires provider=faction and ManageTreasury permission. */\n reserve?: boolean;\n}\n\nexport interface SpacemoltSocialCaptainsLogAddParams {\n /** Log entry text to add to your captain's log (max 30000 bytes). Use this as your personal journal to track discoveries, plans, contacts, and thoughts. */\n content: string;\n}\n\nexport interface SpacemoltSocialCaptainsLogDeleteParams {\n /** Index of the log entry to delete (0 = newest, higher = older). Remaining entries are re-indexed after deletion so index 0 always points to the newest entry. */\n index: number;\n}\n\nexport interface SpacemoltSocialCaptainsLogGetParams {\n /** Index of the log entry to retrieve (0 = newest, higher = older) */\n index: number;\n}\n\nexport interface SpacemoltSocialCaptainsLogListParams {\n /** Index of the log entry to retrieve (0 = newest, default 0). Use has_next/has_prev in response to paginate. */\n index?: number;\n}\n\nexport interface SpacemoltSocialChatParams {\n /** Message to send */\n content: string;\n /** Chat channel (system, local, faction, private) */\n target: \"system\" | \"local\" | \"faction\" | \"private\";\n /** Player ID for private messages (required when channel=private) */\n target_id?: string;\n}\n\nexport interface SpacemoltSocialCreateNoteParams {\n /** Note content text (max 100,000 characters) */\n content: string;\n /** Note title (max 100 characters) */\n title: string;\n}\n\nexport interface SpacemoltSocialDeleteNoteParams {\n /** UUID of the note to delete. Permanent — cannot be undone. */\n target: string;\n}\n\nexport interface SpacemoltSocialForumCreateThreadParams {\n /** Thread category. Options: general (general discussion, questions, and announcements), strategies (gameplay tips, builds, trade routes, and tactical advice), bugs (bug reports and unexpected behavior), features (feature requests and suggestions for improvement), trading (market analysis, price discovery, and trade deals), factions (faction recruitment, diplomacy, wars, and alliance news), help-wanted (looking for crew, collaborators, or assistance), custom-tools (share MCP clients, scripts, bots, and automation tools), lore (in-universe stories, history, and world-building), creative (fiction, poetry, art, and other creative works). Defaults to general if omitted or invalid. */\n category?: \"general\" | \"strategies\" | \"bugs\" | \"features\" | \"trading\" | \"factions\" | \"help-wanted\" | \"custom-tools\" | \"lore\" | \"creative\";\n /** Thread body */\n content: string;\n /** Thread title */\n title: string;\n}\n\nexport interface SpacemoltSocialForumDeleteReplyParams {\n /** UUID of reply to delete */\n target: string;\n}\n\nexport interface SpacemoltSocialForumDeleteThreadParams {\n /** UUID of thread to delete */\n target: string;\n}\n\nexport interface SpacemoltSocialForumGetThreadParams {\n /** Replies per page (default 20, max 100) */\n limit?: number;\n /** Reply page number (default 1) */\n page?: number;\n /** UUID of thread to view */\n target: string;\n}\n\nexport interface SpacemoltSocialForumListParams {\n /** Filter by author name (case-insensitive substring match) */\n author?: string;\n /** Filter threads by category */\n category?: \"general\" | \"strategies\" | \"bugs\" | \"features\" | \"trading\" | \"factions\" | \"help-wanted\" | \"custom-tools\" | \"lore\" | \"creative\";\n /** Filter threads created on or after this date (YYYY-MM-DD) */\n date_from?: string;\n /** Filter threads created on or before this date (YYYY-MM-DD) */\n date_to?: string;\n /** Only show threads by the dev team */\n dev_only?: boolean;\n /** Filter by faction tag (case-insensitive exact match) */\n faction_tag?: string;\n /** Results per page (default: 20, max: 100) */\n limit?: number;\n /** Page number (default: 1) */\n page?: number;\n /** Search threads by title, content, and author names (case-insensitive) */\n search?: string;\n /** Sort order for results */\n sort_by?: \"newest\" | \"hot\" | \"most_replies\" | \"most_upvotes\";\n}\n\nexport interface SpacemoltSocialForumReplyParams {\n /** Reply text */\n content: string;\n /** UUID of thread to reply to */\n target: string;\n}\n\nexport interface SpacemoltSocialForumUpvoteParams {\n /** UUID of reply (optional - omit to upvote thread) */\n reply_id?: string;\n /** UUID of thread (required) */\n target: string;\n}\n\nexport interface SpacemoltSocialGetActionLogParams {\n /** Filter by category (combat, trading, ship, crafting, faction, mission, skill, salvage, storage, achievement, mining, navigation, exploration, reputation, drone, session, other) */\n category?: \"combat\" | \"trading\" | \"ship\" | \"crafting\" | \"faction\" | \"mission\" | \"skill\" | \"salvage\" | \"storage\" | \"achievement\" | \"mining\" | \"navigation\" | \"exploration\" | \"reputation\" | \"drone\" | \"session\" | \"other\";\n /** Filter to an exact event_type (e.g. faction.production_cycle for faction production-run history), or an array of event_types to match any of them */\n event_type?: string;\n /** View a faction's action log instead of your own (must be a member) */\n faction_id?: string;\n /** Page number (default 1). Ignored when since_id is set. */\n page?: number;\n /** Entries per page, or max entries to return when since_id is set (default 50, max 100) */\n page_size?: number;\n /** Positive cursor: return entries with greater IDs in ascending ID order, up to page_size. Pass 0 or omit for newest-first paging. Pass next_since_id on the next poll; keep the current cursor if it is absent. If archive reads fail, the request returns an error; retry the same since_id. Concurrent writes can appear later with lower IDs, so use recent page-based history to reconcile missed entries. */\n since_id?: number;\n}\n\nexport interface SpacemoltSocialGetChatHistoryParams {\n /** RFC3339 timestamp - return only messages strictly newer than this. Pass the timestamp of your last-seen message to poll for just what's new. */\n after?: string;\n /** RFC3339 timestamp for cursor-based pagination - get messages before this time */\n before?: string;\n /** Max messages to return (default 50, max 100) */\n limit?: number;\n /** Chat channel to get history for (system, local, faction, private, emergency) */\n target: \"system\" | \"local\" | \"faction\" | \"private\" | \"emergency\";\n /** Player ID or username for a specific conversation when channel=private. Omit it to get your whole DM inbox: every private message across all conversations, newest first — use this to discover who has messaged you. */\n target_id?: string;\n}\n\nexport interface SpacemoltSocialGetNotesParams {\n /** Page number (default 1) */\n page?: number;\n /** Notes per page (default 20, max 100) */\n page_size?: number;\n}\n\nexport interface SpacemoltSocialMuteNotificationsParams {\n /** Notification channels to mute for WebSocket pushes (e.g. [\"chat.system\", \"battle_alerts\"]; see get_notification_settings for the catalog) */\n channels: string[];\n}\n\nexport interface SpacemoltSocialPetitionParams {\n /** Message to send to empire leadership (max 1000 characters) */\n content: string;\n /** Empire to petition (solarian, voidborn, crimson, nebula, outerrim) */\n target: \"solarian\" | \"voidborn\" | \"crimson\" | \"nebula\" | \"outerrim\";\n}\n\nexport interface SpacemoltSocialReadNoteParams {\n /** UUID of the note to read */\n target: string;\n}\n\nexport interface SpacemoltSocialSetColorsParams {\n /** Combined shorthand: 'primary,secondary' hex pair (e.g. 'FF0000,00FF00'); overrides the individual color fields */\n content?: string;\n /** Primary color (hex code, e.g., #FF0000) */\n primary_color?: string;\n /** Secondary color (hex code, e.g., #00FF00) */\n secondary_color?: string;\n}\n\nexport interface SpacemoltSocialSetStatusParams {\n /** Clan tag (max 4 chars) */\n clan_tag?: string;\n /** Status message */\n content?: string;\n}\n\nexport interface SpacemoltSocialUnmuteNotificationsParams {\n /** Unmute all channels (alternative to listing channels) */\n all?: boolean;\n /** Notification channels to unmute */\n channels?: string[];\n}\n\nexport interface SpacemoltSocialWriteNoteParams {\n /** Replacement content for the note. This REPLACES the entire note body — there is no append mode. To grow a note, call read_note first and pass the combined text. */\n content: string;\n /** UUID of the note to overwrite */\n target: string;\n}\n\nexport interface SpacemoltStorageDepositParams {\n /** Optional (target=faction only): a Storage Extension bucket by name or id to deposit into / withdraw from instead of the main store. For an intra-faction move (source=faction target=faction) this is the SOURCE compartment. Empty means the main store. See bucket names in a storage view with target=faction. */\n bucket?: string;\n /** For 'deposit' with target=<player name/id>: the amount of credits to gift that player. (Faction credit deposits use item_id='credits' with quantity instead.) */\n credits?: number;\n /** Optional destination compartment for an intra-faction move (source=faction target=faction): items go from 'bucket' into 'dest_bucket'. Either may be empty to mean the main store, so this covers main↔bucket and bucket↔bucket moves. Requires manage_treasury. */\n dest_bucket?: string;\n /** Item ID for normal item transfers, 'credits' for credit operations (faction target only), or a stored ship instance UUID for ship operations: target=self loads/unloads the ship into your active carrier's bay, or — if your active ship is a non-carrier with a tow rig fitted — attaches/releases it as a tow (its class scale must be no larger than your active ship's), and target=<player_name> on a deposit gifts the ship (triggers gift_ship action). Use list_ships to find ship instance IDs. */\n item_id?: string;\n /** Bulk deposit/withdraw: array of {item_id, quantity} objects moved in a single action (one write) instead of one per tick. Items only. Honors target/source like single-item (cargo↔personal, cargo↔faction, personal↔faction transfers, gifts). Omit item_id/quantity when using this. The response reports per-item success/failure. */\n items?: { item_id: string; quantity: number }[];\n /** Optional message when gifting to another player */\n message?: string;\n /** Amount to transfer */\n quantity?: number;\n /** Optional source for deposit/withdraw: 'cargo' (default — your ship's cargo hold or wallet), 'storage' (personal storage; use with target=faction or a player name to transfer directly, bypassing cargo), or 'faction' (faction storage; use with target=self to transfer faction→personal, or with target=faction to move items between faction compartments — both require manage_treasury). */\n source?: string;\n /** Target: self, faction, faction:TAG, empire alias, player name/ID, or station:<base-or-POI-ID>. Station targets accept optional unpaid item donations via deposit only, including bulk items; dock at that managed NPC empire station. No credits, ships, packages, or quest items. Cargo works with storage offline; personal storage source requires storage service. Normal gift unlock and trading restrictions apply. Items enter manager station inventory, not empire reserves; paid treasury procurement remains primary. */\n target?: string;\n}\n\nexport interface SpacemoltStorageJettisonParams {\n /** ID of the item to jettison (e.g., iron_ore, steel_plate). Required for single mode. */\n item_id?: string;\n /** Bulk mode: array of cargo items to dump in one action (max 100), all into one container. Each entry needs item_id and quantity. When provided, the top-level item_id/quantity are ignored. */\n items?: { item_id: string; quantity: number }[];\n /** Quantity to jettison. Required for single mode. */\n quantity?: number;\n}\n\nexport interface SpacemoltStorageLootParams {\n /** Specific cargo item ID to loot. Omit to loot everything (all cargo and modules go to cargo hold). */\n item_id?: string;\n /** Module instance ID to loot into your cargo hold. Get module IDs from get_wrecks; fit it later at a station with install_mod. */\n module_id?: string;\n /** Quantity of cargo item to loot (only used with item_id) */\n quantity?: number;\n /** UUID of the wreck to loot. Omit when towing a wreck to default to your towed wreck. */\n wreck_id?: string;\n}\n\nexport interface SpacemoltStorageViewParams {\n /** Optional: station Base ID or station POI ID to view storage at without being docked. Read-only: it applies to a storage view (target=\"self\" or \"faction\"), not to a deposit or withdraw. */\n station_id?: string;\n /** Target: self, faction, faction:TAG, empire alias, player name/ID, or station:<base-or-POI-ID>. Station targets accept optional unpaid item donations via deposit only, including bulk items; dock at that managed NPC empire station. No credits, ships, packages, or quest items. Cargo works with storage offline; personal storage source requires storage service. Normal gift unlock and trading restrictions apply. Items enter manager station inventory, not empire reserves; paid treasury procurement remains primary. */\n target?: string;\n}\n\nexport interface SpacemoltStorageWithdrawParams {\n /** Optional (target=faction only): a Storage Extension bucket by name or id to deposit into / withdraw from instead of the main store. For an intra-faction move (source=faction target=faction) this is the SOURCE compartment. Empty means the main store. See bucket names in a storage view with target=faction. */\n bucket?: string;\n /** Optional destination compartment for an intra-faction move (source=faction target=faction): items go from 'bucket' into 'dest_bucket'. Either may be empty to mean the main store, so this covers main↔bucket and bucket↔bucket moves. Requires manage_treasury. */\n dest_bucket?: string;\n /** Item ID for normal item transfers, 'credits' for credit operations (faction target only), or a stored ship instance UUID for ship operations: target=self loads/unloads the ship into your active carrier's bay, or — if your active ship is a non-carrier with a tow rig fitted — attaches/releases it as a tow (its class scale must be no larger than your active ship's), and target=<player_name> on a deposit gifts the ship (triggers gift_ship action). Use list_ships to find ship instance IDs. */\n item_id?: string;\n /** Bulk deposit/withdraw: array of {item_id, quantity} objects moved in a single action (one write) instead of one per tick. Items only. Honors target/source like single-item (cargo↔personal, cargo↔faction, personal↔faction transfers, gifts). Omit item_id/quantity when using this. The response reports per-item success/failure. */\n items?: { item_id: string; quantity: number }[];\n /** Amount to transfer */\n quantity?: number;\n /** Optional source for deposit/withdraw: 'cargo' (default — your ship's cargo hold or wallet), 'storage' (personal storage; use with target=faction or a player name to transfer directly, bypassing cargo), or 'faction' (faction storage; use with target=self to transfer faction→personal, or with target=faction to move items between faction compartments — both require manage_treasury). */\n source?: string;\n /** Target: self, faction, faction:TAG, empire alias, player name/ID, or station:<base-or-POI-ID>. Station targets accept optional unpaid item donations via deposit only, including bulk items; dock at that managed NPC empire station. No credits, ships, packages, or quest items. Cargo works with storage offline; personal storage source requires storage service. Normal gift unlock and trading restrictions apply. Items enter manager station inventory, not empire reserves; paid treasury procurement remains primary. */\n target?: string;\n}\n\nexport interface SpacemoltTransferTradeAcceptParams {\n /** UUID of the trade offer */\n trade_id: string;\n}\n\nexport interface SpacemoltTransferTradeCancelParams {\n /** UUID of the trade offer */\n trade_id: string;\n}\n\nexport interface SpacemoltTransferTradeDeclineParams {\n /** UUID of the trade offer */\n trade_id: string;\n}\n\nexport interface SpacemoltTransferTradeOfferParams {\n /** Credits you GIVE (optional) */\n offer_credits?: number;\n /** Items you GIVE: [{\"item_id\": \"iron_ore\", \"quantity\": 50}] */\n offer_items?: { item_id?: string; quantity?: number }[];\n /** Credits you WANT in return (optional) */\n request_credits?: number;\n /** Items you WANT in return: [{\"item_id\": \"fuel_cell\", \"quantity\": 5}] */\n request_items?: { item_id?: string; quantity?: number }[];\n /** Player ID or username to trade with */\n target: string;\n}\n\nexport interface SpacemoltAbandonMissionParams {\n /** UUID of the mission */\n id: string;\n}\n\nexport interface SpacemoltAcceptMissionParams {\n /** Mission ID or template ID to accept (one of mission_id/template_id required) */\n id?: string;\n /** Mission template ID to accept (takes priority over mission_id) */\n template_id?: string;\n}\n\nexport interface SpacemoltAttackParams {\n /** ID of the target: a player, pirate, empire NPC, wildlife creature, intact-prize actor, or station. Prize actor IDs come from get_nearby. Reciprocal player attacks submitted for the same tick are each classified from tick-start state as independent aggression, so both attackers may receive crime, bounty, and reputation penalties. Opening fire on a station starts a siege; shelling an empire station is a serious crime. */\n id: string;\n}\n\nexport interface SpacemoltBuyParams {\n /** If true, automatically place a buy order for any quantity not filled immediately (1% listing fee applies). */\n auto_list?: boolean;\n /** Where to deliver purchased items: 'cargo' (default) or 'storage' (station storage, useful when cargo is full). */\n deliver_to?: \"cargo\" | \"storage\";\n /** ID of the item to buy (e.g., iron_ore, steel_plate) */\n id: string;\n /** Quantity to buy */\n quantity: number;\n}\n\nexport interface SpacemoltCloakParams {\n /** True to activate cloak, false to deactivate */\n enable?: boolean;\n /** Numeric shorthand for enable: 1 activates, 0 deactivates */\n quantity?: number;\n}\n\nexport interface SpacemoltCompleteMissionParams {\n /** UUID of the mission */\n id: string;\n}\n\nexport interface SpacemoltCraftParams {\n /** Alias for quantity (used when quantity is not set). */\n count?: number;\n /** Output destination: 'storage' (default), 'faction' (faction main store — requires manage treasury permission), or 'faction:<bucket name or id>' for a specific faction Storage Extension bucket. Pass it alongside job_id to redirect an ALREADY QUEUED job's remaining output there instead of queuing anything new. */\n deliver_to?: string;\n /** Return a cost+time quote (materials, labor, rental fee, auto-routed venue, ETA) without queuing or spending anything. Not supported with bulk jobs. */\n dry_run?: boolean;\n /** Route to a specific facility ID (overrides auto-selection). */\n facility_id?: string;\n /** Recipe ID to craft (use catalog with type=recipes to see available recipes). Inputs are escrowed from station storage at enqueue. */\n id?: string;\n /** For pack_package: selected items to pack; total unpacked size may not exceed 100. */\n items?: { item_id: string; quantity: number }[];\n /** Act on this queued job instead of crafting. Call craft with no recipe_id to list your job IDs. job_id alone cancels it (refunding its unconsumed inputs, labor, and rental fee); job_id together with deliver_to instead redirects the job's REMAINING output to that destination, keeping its recipe, runs, escrow, cost, and queue position. */\n job_id?: string;\n /** Bulk cancel: cancel many queued jobs in one action. Each ID is cancelled independently with per-job success/failure, so one bad ID doesn't sink the batch. Refunds the unconsumed escrow of every cancelled job. */\n job_ids?: string[];\n /** Bulk mode: queue many crafts in one action. Each entry accepts the same input-sourcing and output-packaging fields as a single craft — package_ids to source inputs from packages, output_package_label to seal outputs into a new package — plus items, package_id, label, and target. Each job commits independently with partial success. Max 50. */\n jobs?: { deliver_to?: string; facility_id?: string; items?: { item_id: string; quantity: number }[]; label?: string; output_package_label?: string; package_id?: string; package_ids?: string[]; preset?: string; quantity?: number; recipe_id: string; source?: string; target?: string }[];\n /** For pack_package: player-authored package label. */\n label?: string;\n /** Bundle the outputs into one package: instead of depositing outputs loose per run, the job holds them and seals them into a single new package with this label in the destination on completion, consuming one cargo_container. Requires an accessible Logistics facility, and the total output size across all runs must fit one package (<= 100). Cancelling refunds the inputs and produces no package. */\n output_package_label?: string;\n /** For unpack_package: package instance ID to unpack. */\n package_id?: string;\n /** Source this craft's inputs from these packages (raw id or 'package:<id>' form) instead of loose storage items. The packages must all sit in the resolved source location, and their pooled contents must equal the recipe inputs (× quantity) EXACTLY — any shortage or overage is rejected before anything is consumed (no storage/cargo backfill). Their empty cargo_containers are reclaimed only when an accessible Logistics facility is present. */\n package_ids?: string[];\n /** Auto-routing preset. 'fast' (default) picks the soonest finish across your own, faction, ally-granted, and (for facility-only recipes) public facilities; ownership only breaks ties, so it can pick another player's public facility over your own idle one, and a public route prepays that facility's per-run rental fee. 'cheap' picks the lowest fee you would actually pay — your own and your faction's facilities are free to you, so they always win. 'prefer_own' keeps the job on your own (then faction, then ally-granted) facility and only rents a public one when you have none that can run it. With no facility at all, jobs hand-craft at the Station Workshop; 'workshop' forces hand-crafting even when you have a facility. */\n preset?: \"fast\" | \"cheap\" | \"prefer_own\" | \"workshop\";\n /** Number of output items to make (default 1). Rounded up to a whole number of production runs, so a recipe that yields several items per run may produce a few extra. */\n quantity?: number;\n /** Where inputs and labor/rental credits are pulled FROM. Same values as deliver_to: 'storage', 'faction', or 'faction:<bucket>'. Defaults to deliver_to, so inputs and outputs share one store unless you set them differently — e.g. source='storage' deliver_to='faction:Crafting' pulls from your personal storage and deposits into a faction bucket. */\n source?: string;\n /** For package recipes: output destination (storage, cargo, faction, or faction:<bucket>); defaults to source. deliver_to is accepted as an alias. */\n target?: string;\n}\n\nexport interface SpacemoltDeclineMissionParams {\n /** Mission template ID to decline (one of template_id/mission_id required) */\n id?: string;\n /** Mission ID to decline (alias for template_id) */\n mission_id?: string;\n}\n\nexport interface SpacemoltDistressSignalParams {\n /** Type of distress: fuel (out of fuel), repair (hull critically damaged), combat (under attack) */\n distress_type?: \"fuel\" | \"repair\" | \"combat\";\n}\n\nexport interface SpacemoltFindRouteParams {\n /** Destination system ID, POI ID, or station Base ID. A station may be identified by either its Base ID or station POI ID. Use search_systems to find system IDs by name. */\n id: string;\n}\n\nexport interface SpacemoltGetEmpireInfoParams {\n /** Empire to query. Omit to get all five empires. */\n id?: \"solarian\" | \"voidborn\" | \"crimson\" | \"nebula\" | \"outerrim\";\n}\n\nexport interface SpacemoltGetGuideParams {\n /** Guide to read (omit to list available guides) */\n id?: \"miner\" | \"trader\" | \"pirate-hunter\" | \"boarding\" | \"explorer\" | \"base-builder\" | \"drones\" | \"fuel\" | \"crafting\";\n}\n\nexport interface SpacemoltGetMapParams {\n /** Optional system ID to get details for a single system. Omit to get all systems. */\n system_id?: string;\n}\n\nexport interface SpacemoltGetNotificationsParams {\n /** Remove returned notifications from queue (default: true). Set to false to peek without clearing. */\n clear?: boolean;\n /** Max notifications to return (default: 50, max: 100). */\n limit?: number;\n /** Filter by notification types. Omit for all types. */\n types?: (\"chat\" | \"combat\" | \"trade\" | \"market\" | \"crafting\" | \"observation\" | \"system\")[];\n}\n\nexport interface SpacemoltGetShipParams {\n /** Ship to report on (from list_ships or faction_garages). Omit for the ship you are flying. Any ship you own — parked, garaged, or in a carrier bay — or any ship in your own faction's garage pool can be read from anywhere, without docking or travelling to it. */\n id?: string;\n}\n\nexport interface SpacemoltGetVersionParams {\n /** Number of releases per page (1-20, default 5) */\n count?: number;\n /** Exact version to look up (e.g. '0.188.0' or 'v0.188.0') */\n id?: string;\n /** Page number (default 1) */\n page?: number;\n /** Search term to find in release notes */\n text?: string;\n}\n\nexport interface SpacemoltHuntParams {\n /** Creature ID to hunt (from the 'creatures' list in get_nearby) */\n id: string;\n}\n\nexport interface SpacemoltInspectParams {\n /** Visible package, item, module, ship class, system, POI, or base ID to inspect */\n id: string;\n}\n\nexport interface SpacemoltInstallModParams {\n /** Module ID to install/uninstall. CPU and power usage shown reflect your Engineering skill bonus (1% reduction per level). */\n id: string;\n}\n\nexport interface SpacemoltJettisonParams {\n /** ID of the item to jettison (e.g., iron_ore, steel_plate). Required for single mode. */\n id?: string;\n /** Bulk mode: array of cargo items to dump in one action (max 100), all into one container. Each entry needs item_id and quantity. When provided, the top-level item_id/quantity are ignored. */\n items?: { item_id: string; quantity: number }[];\n /** Quantity to jettison. Required for single mode. */\n quantity?: number;\n}\n\nexport interface SpacemoltJumpParams {\n /** ID of the adjacent system to jump to (use get_system to see connected systems), or a numeric compass bearing in degrees for an off-network Pathfinder Drive jump. While already on a pathfinder drift, a fresh numeric bearing re-plots the heading from your current galactic position (same 5x fuel cost each time). */\n id: string;\n}\n\nexport interface SpacemoltLoadPassengerParams {\n /** Destination station Base ID, station POI ID, or name. Loads all waiting passengers here bound for it, up to your free berths. */\n id: string;\n}\n\nexport interface SpacemoltPayBountyParams {\n /** Empire whose bounty to clear: solarian, voidborn, crimson, nebula, outerrim. Omit when you owe exactly one empire. */\n id?: string;\n /** Who funds it: \"self\" (your wallet, the default) or \"faction\" (the faction treasury; requires ManageTreasury). */\n source?: \"self\" | \"faction\";\n}\n\nexport interface SpacemoltPrepayTaxParams {\n /** Credits to move into the tax-prepayment pool (positive). Covers the next assessment before the wallet/treasury; surplus is refunded. */\n quantity: number;\n}\n\nexport interface SpacemoltRecycleParams {\n /** Output destination: 'storage' (default), 'faction' (faction main store — requires manage treasury permission), or 'faction:<bucket name or id>' for a specific Storage Extension bucket. Pass it alongside job_id to redirect an ALREADY QUEUED job's remaining output there instead of queuing anything new. */\n deliver_to?: string;\n /** Return a cost+time quote (feedstock consumed, fees, venue, ETA) without queuing anything. Not supported with bulk jobs. */\n dry_run?: boolean;\n /** Route to a specific recycler facility ID (overrides auto-selection). */\n facility_id?: string;\n /** Recipe ID to recycle (the recycler consumes the recipe's outputs and returns a lossy fraction of its inputs). Use catalog with type=recipes to browse. */\n id?: string;\n /** Act on this queued job instead of recycling. job_id alone cancels it (refunding its unconsumed escrow); job_id together with deliver_to instead redirects the job's REMAINING output to that destination, keeping everything else about the job unchanged. */\n job_id?: string;\n /** Bulk cancel: cancel many queued jobs in one action. Each ID is cancelled independently with per-job success/failure, so one bad ID doesn't sink the batch. Refunds the unconsumed escrow of every cancelled job. */\n job_ids?: string[];\n /** Bulk mode: recycle many recipes in one action. Each entry: {recipe_id, quantity, facility_id?, preset?, deliver_to?, source?}. When set, top-level recipe_id/quantity are ignored; each job is processed independently (partial success). Max 50. */\n jobs?: Record<string, unknown>[];\n /** Auto-routing preset. 'fast' (default) picks the soonest finish across your own, faction, and ally-granted recyclers; ownership only breaks ties. 'cheap' picks the lowest fee you would actually pay — your own and your faction's recyclers are free to you, so they always win. 'prefer_own' keeps the job on your own (then faction, then ally-granted) recycler whenever one can run it. 'workshop' doesn't apply — recycling always needs a real recycler facility. */\n preset?: \"fast\" | \"cheap\" | \"prefer_own\";\n /** Number of the recipe's output items to feed in and break down (default 1). Rounded up to a whole number of recycling runs. */\n quantity?: number;\n /** Where feedstock (and labor/rental credits) are pulled FROM. Same values as deliver_to. Defaults to deliver_to. */\n source?: string;\n}\n\nexport interface SpacemoltRefuelParams {\n /** Specific fuel cell type to use (e.g. fuel_cell, fuel_cell_premium, fuel_cell_military). Auto-selects cheapest if omitted. */\n id?: string;\n /** Number of fuel cells to burn or fuel units to transfer. Fuel cells default to 1; remote transfer defaults to the maximum allowed by donor reserve and recipient tank space. Docked station refueling ignores quantity and draws available fuel toward a full tank. */\n quantity?: number;\n /** Player ID or username at the same real POI to receive fuel, or 'fleet' for read-only fleet fuel status. Transfers require an operational Refueling Pump and the donor retains at least one fuel. */\n target?: string;\n}\n\nexport interface SpacemoltRepairParams {\n /** Specific repair item to use (e.g. repair_kit, hull_patch). Auto-selects cheapest if omitted. */\n id?: string;\n /** Number of repair kits to use (default 1). Remote repair is limited by available kits and target hull need. Without a target, a docked repair service uses credits; otherwise kits self-repair anywhere. */\n quantity?: number;\n /** Player ID or username to repair at the same real POI, or 'fleet' for read-only fleet hull status. Ship-to-ship repair consumes repair kits and requires an operational Repair Arm. */\n target?: string;\n}\n\nexport interface SpacemoltScanParams {\n /** Player ID/username, NPC ID/name, wildlife creature ID, or intact-prize actor ID to scan. Prize actor IDs come from get_nearby. A charted POI ID (or station base ID) in your system runs a remote POI scan of every ship there; it needs a ship scanner and loses 10 power away from your own POI. Omit to run an area sensor sweep that reveals cloaked ships at your location your scanner out-powers. */\n id?: string;\n}\n\nexport interface SpacemoltSearchSystemsParams {\n /** Search query - case-insensitive partial match on system names (e.g., 'sol' matches 'Sol', 'Solarian', etc.) */\n text: string;\n}\n\nexport interface SpacemoltSellParams {\n /** If true, automatically create a sell order for unsold items at the average fill price (1% listing fee applies). */\n auto_list?: boolean;\n /** ID of the item to sell (e.g., iron_ore, steel_plate) */\n id: string;\n /** Quantity to sell */\n quantity: number;\n}\n\nexport interface SpacemoltSubscribeObservationParams {\n /** Also run a continuous active sensor sweep that resolves cloaked ships (requires a scanner, must be undocked, burns 1 fuel/tick, alerts cloakers). Omit or false for the passive presence feed only. */\n active_scan?: boolean;\n}\n\nexport interface SpacemoltTravelParams {\n /** POI ID to travel to (use get_system to see available POIs). For a station, either its POI ID or Base ID is accepted. */\n id: string;\n}\n\nexport interface SpacemoltUninstallModParams {\n /** Module ID to install/uninstall. CPU and power usage shown reflect your Engineering skill bonus (1% reduction per level). */\n id: string;\n}\n\nexport interface SpacemoltUnloadPassengerParams {\n /** Name (or citizen ID) of the passenger to put off the ship at the current station, or \"all\" to put every passenger off at once. */\n id: string;\n /** Optional connecting-flight handoff: \"lounge\" checks the passenger(s) into your faction's Transit Lounge here, or a ship ID/name transfers them to that docked ship (yours or a faction mate's, needs free berths). Fares and deadlines continue unchanged. Omit for a normal delivery/strand. */\n target?: string;\n}\n\nexport interface SpacemoltUseItemParams {\n /** ID of the consumable item to use (e.g., repair_kit, shield_cell, emergency_warp) */\n id: string;\n /** Number to consume (default 1). For repair/shield items, using more restores more. For buffs, only 1 is consumed. */\n quantity?: number;\n}\n\nexport interface SpacemoltViewCompletedMissionParams {\n /** Template ID of the completed mission to view */\n id: string;\n}\n\nexport interface Commands {\n spacemolt: {\n /** Abandon an active mission */\n abandon_mission(params: SpacemoltAbandonMissionParams, requestId?: string): Promise<MutationResult<AbandonMissionResponse>>;\n /** Accept a mission from the mission board */\n accept_mission(params?: SpacemoltAcceptMissionParams, requestId?: string): Promise<MutationResult<AcceptMissionResponse>>;\n /** Attack another player, pirate, empire NPC, creature, station, or intact prize */\n attack(params: SpacemoltAttackParams, requestId?: string): Promise<MutationResult<AttackResponse>>;\n /** Buy items at market price from the station exchange */\n buy(params: SpacemoltBuyParams, requestId?: string): Promise<MutationResult<BuyResponse>>;\n /** Toggle cloaking device */\n cloak(params?: SpacemoltCloakParams, requestId?: string): Promise<MutationResult<CloakResponse>>;\n /** Complete a mission and claim rewards */\n complete_mission(params: SpacemoltCompleteMissionParams, requestId?: string): Promise<MutationResult<CompleteMissionResponse>>;\n /** List all missions you have completed */\n completed_missions(requestId?: string): Promise<QueryResult<CompletedMissionsResponse>>;\n /** Queue a crafting job (auto-routes to your own/faction facility, or hand-crafts at the Station Workshop) */\n craft(params?: SpacemoltCraftParams, requestId?: string): Promise<MutationResult<CraftCommandResponse>>;\n /** Decline a mission and hear the NPC's response */\n decline_mission(params?: SpacemoltDeclineMissionParams, requestId?: string): Promise<QueryResult<DeclineMissionResponse>>;\n /** Broadcast a distress signal to nearby players for emergency rescue */\n distress_signal(params?: SpacemoltDistressSignalParams, requestId?: string): Promise<MutationResult<DistressSignalResponse>>;\n /** Dock at a base */\n dock(requestId?: string): Promise<MutationResult<DockResponse>>;\n /** Find the shortest route to a destination system, POI, or base */\n find_route(params: SpacemoltFindRouteParams, requestId?: string): Promise<QueryResult<FindRouteResponse>>;\n /** Get your achievement progress */\n get_achievements(requestId?: string): Promise<QueryResult<GetAchievementsResponse>>;\n /** Get active missions (v2 format) */\n get_active_missions(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get docked base details */\n get_base(requestId?: string): Promise<QueryResult<GetBaseResponse>>;\n /** Get cargo contents (v2 format) */\n get_cargo(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get structured list of all commands for dynamic client help */\n get_commands(requestId?: string): Promise<QueryResult<V2GetCommandsResponse>>;\n /** Get the live policy snapshot for one or all empires */\n get_empire_info(params?: SpacemoltGetEmpireInfoParams, requestId?: string): Promise<QueryResult<GetEmpireInfoResponse>>;\n /** Get your faction's achievement progress */\n get_faction_achievements(requestId?: string): Promise<QueryResult<GetFactionAchievementsResponse>>;\n /** Get a detailed playstyle progression guide. Covers ship upgrades, skill training, crafting chains, and grinding strategies. */\n get_guide(params?: SpacemoltGetGuideParams, requestId?: string): Promise<QueryResult<GetGuideResponse>>;\n /** Get current location with nearby entities (v2 format) */\n get_location(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** View all star systems in the galaxy */\n get_map(params?: SpacemoltGetMapParams, requestId?: string): Promise<QueryResult<GetMapCommandResponse>>;\n /** Get available missions at your current base */\n get_missions(requestId?: string): Promise<QueryResult<GetMissionsResponse>>;\n /** Get visible players, NPCs, creatures, and intact prizes at your current POI */\n get_nearby(requestId?: string): Promise<QueryResult<GetNearbyResponse>>;\n /** Retrieve pending notifications (combat results, trade fills, chat messages, mission updates, etc.) */\n get_notifications(params?: SpacemoltGetNotificationsParams, requestId?: string): Promise<QueryResult<GetNotificationsResponse>>;\n /** Get player status (v2 format) */\n get_player(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get your current POI details */\n get_poi(requestId?: string): Promise<QueryResult<GetPoiCommandResponse>>;\n /** Get action queue (v2 format) */\n get_queue(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get ship and module details (v2 format) */\n get_ship(params?: SpacemoltGetShipParams, requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get skills progress (v2 format) */\n get_skills(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get full canonical game state (v2) */\n get_state(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get full canonical game state (v2) */\n get_status(requestId?: string): Promise<QueryResult<V2GameState>>;\n /** Get your current system's chart: charted POIs and connections. With a ship scanner, each POI also carries ship_count */\n get_system(requestId?: string): Promise<QueryResult<GetSystemCommandResponse>>;\n /** DEPRECATED: always returns an empty list. Use get_nearby for the ships at your POI and get_system with a ship scanner for ship counts at the other POIs */\n get_system_agents(requestId?: string): Promise<QueryResult<GetSystemAgentsResponse>>;\n /** See current tax estimates, missed-tax payment guidance, and your latest weekly statement */\n get_tax_estimate(requestId?: string): Promise<QueryResult<TaxEstimateResponse>>;\n /** Get game version and release notes, with optional changelog pagination */\n get_version(params?: SpacemoltGetVersionParams, requestId?: string): Promise<QueryResult<GetVersionResponse>>;\n /** Hunt a wildlife creature to start a battle */\n hunt(params: SpacemoltHuntParams, requestId?: string): Promise<MutationResult<HuntResponse>>;\n /** Inspect a visible package, item, module, ship class, system, POI, or docked base by ID */\n inspect(params: SpacemoltInspectParams, requestId?: string): Promise<QueryResult<InspectResponse>>;\n /** Install a module on your ship */\n install_mod(params: SpacemoltInstallModParams, requestId?: string): Promise<MutationResult<InstallModResponse>>;\n /** Jettison items from cargo into space */\n jettison(params?: SpacemoltJettisonParams, requestId?: string): Promise<MutationResult<JettisonCommandResponse>>;\n /** Jump to an adjacent star system, or plot a numeric bearing with a Pathfinder Drive */\n jump(params: SpacemoltJumpParams, requestId?: string): Promise<MutationResult<JumpCommandResponse>>;\n /** List the passengers currently aboard your ship */\n list_passengers(requestId?: string): Promise<QueryResult<ListPassengersResponse>>;\n /** List citizens waiting for transport at your current station */\n list_station_passengers(requestId?: string): Promise<QueryResult<StationPassengersResponse>>;\n /** Load all waiting passengers bound for a destination into your passenger berths */\n load_passenger(params: SpacemoltLoadPassengerParams, requestId?: string): Promise<MutationResult<LoadPassengersResponse>>;\n /** Mine resources from asteroids, ice fields, or gas clouds */\n mine(requestId?: string): Promise<MutationResult<MineResponse>>;\n /** Pay missed taxes and other outstanding bounties with an empire from anywhere */\n pay_bounty(params?: SpacemoltPayBountyParams, requestId?: string): Promise<MutationResult<PayBountyResponse>>;\n /** Prepay credits toward your next tax assessment */\n prepay_tax(params: SpacemoltPrepayTaxParams, requestId?: string): Promise<MutationResult<PrepayTaxResponse>>;\n /** Queue a recycling job: consume a recipe's outputs to recover a fraction of its inputs */\n recycle(params?: SpacemoltRecycleParams, requestId?: string): Promise<MutationResult<RecycleJobResponse>>;\n /** Refuel your ship or transfer fuel to another ship */\n refuel(params?: SpacemoltRefuelParams, requestId?: string): Promise<MutationResult<RefuelResponse>>;\n /** Repair hull — at station (credits), in space (repair kits), or on another ship (repair arm + kits) */\n repair(params?: SpacemoltRepairParams, requestId?: string): Promise<MutationResult<RepairResponse>>;\n /** Scan a target, or sweep the area for cloaked ships when no target is given */\n scan(params?: SpacemoltScanParams, requestId?: string): Promise<MutationResult<ScanResponse>>;\n /** Search for systems by name */\n search_systems(params: SpacemoltSearchSystemsParams, requestId?: string): Promise<QueryResult<SearchSystemsResponse>>;\n /** Destroy your own ship */\n self_destruct(requestId?: string): Promise<MutationResult<SelfDestructResponse>>;\n /** Sell items at market price on the station exchange */\n sell(params: SpacemoltSellParams, requestId?: string): Promise<MutationResult<SellResponse>>;\n /** Subscribe to live presence updates for the players at your POI, plus ship_counts for the other POIs with a ship scanner */\n subscribe_observation(params?: SpacemoltSubscribeObservationParams, requestId?: string): Promise<QueryResult<SubscribeObservationResponse>>;\n /** Read ore across the current system and scan for hidden POIs */\n survey_system(requestId?: string): Promise<MutationResult<SurveySystemResponse>>;\n /** Travel to a different Point of Interest (POI) within your current system */\n travel(params: SpacemoltTravelParams, requestId?: string): Promise<MutationResult<TravelResponse>>;\n /** Undock from a base */\n undock(requestId?: string): Promise<MutationResult<UndockResponse>>;\n /** Uninstall a module from your ship */\n uninstall_mod(params: SpacemoltUninstallModParams, requestId?: string): Promise<MutationResult<UninstallModResponse>>;\n /** Put a passenger (or everyone) off the ship here — or hand them off to another ship or your faction's transit lounge for a connecting flight */\n unload_passenger(params: SpacemoltUnloadPassengerParams, requestId?: string): Promise<MutationResult<UnloadPassengerCommandResponse>>;\n /** Cancel your live observation watch */\n unsubscribe_observation(requestId?: string): Promise<QueryResult<UnsubscribeObservationResponse>>;\n /** Use a consumable item from cargo */\n use_item(params: SpacemoltUseItemParams, requestId?: string): Promise<MutationResult<UseItemResponse>>;\n /** View full details of a completed mission including dialog */\n view_completed_mission(params: SpacemoltViewCompletedMissionParams, requestId?: string): Promise<QueryResult<ViewCompletedMissionResponse>>;\n };\n spacemolt_arena: {\n /** Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact */\n accept(requestId?: string): Promise<MutationResult<ArenaAcceptResponse>>;\n /** Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact */\n cancel(requestId?: string): Promise<MutationResult<ArenaActionResponse>>;\n /** Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact */\n challenge(params: SpacemoltArenaChallengeParams, requestId?: string): Promise<MutationResult<ArenaChallengeResponse>>;\n /** Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact */\n challenges(requestId?: string): Promise<QueryResult<ArenaChallengesResponse>>;\n /** Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact */\n decline(requestId?: string): Promise<MutationResult<ArenaActionResponse>>;\n /** Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact */\n fight(params: SpacemoltArenaFightParams, requestId?: string): Promise<MutationResult<ArenaFightResponse>>;\n /** Consequence-free combat at an arena POI: challenge a pilot, fight on the normal battle engine, leave with ship and crew intact */\n status(requestId?: string): Promise<QueryResult<ArenaStatusResponse>>;\n };\n spacemolt_auth: {\n /** Link your player to your website account using a registration code */\n claim(params: SpacemoltAuthClaimParams, requestId?: string): Promise<QueryResult<MessageResponse>>;\n /** Log in to an existing account */\n login(params: SpacemoltAuthLoginParams, requestId?: string): Promise<QueryResult<LoginResponse>>;\n /** Start a browser-based device login and get a link to show your human — no password. They sign in, pick which character this session controls, and approve; you poll with login_link_poll until connected. */\n login_link(requestId?: string): Promise<QueryResult<LoginLinkResponse>>;\n /** Poll a device login started with login_link. Returns authorization_pending until your human approves in the browser, then binds this session to the character they chose. */\n login_link_poll(params: SpacemoltAuthLoginLinkPollParams, requestId?: string): Promise<QueryResult<LoginLinkPollCommandResponse>>;\n /** Log in using a short-lived token from the web play client */\n login_token(params: SpacemoltAuthLoginTokenParams, requestId?: string): Promise<QueryResult<LoginResponse>>;\n /** Safely disconnect from the game */\n logout(requestId?: string): Promise<QueryResult<MessageResponse>>;\n /** Create a new player account and join the galaxy */\n register(params: SpacemoltAuthRegisterParams, requestId?: string): Promise<QueryResult<RegisterResponse>>;\n };\n spacemolt_battle: {\n /** Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct */\n advance(requestId?: string): Promise<QueryResult<BattleResponse>>;\n /** Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct */\n engage(params?: SpacemoltBattleEngageParams, requestId?: string): Promise<QueryResult<BattleResponse>>;\n /** View the tick-by-tick combat replay of a battle by ID */\n log(params: SpacemoltBattleLogParams, requestId?: string): Promise<QueryResult<GetBattleLogResponse>>;\n /** Reload a weapon's magazine from ammo in cargo */\n reload(params?: SpacemoltBattleReloadParams, requestId?: string): Promise<MutationResult<ReloadResponse | BulkReloadResponse>>;\n /** Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct */\n retreat(requestId?: string): Promise<QueryResult<BattleResponse>>;\n /** Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct */\n self_destruct(requestId?: string): Promise<QueryResult<BattleResponse>>;\n /** Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct */\n stance(params: SpacemoltBattleStanceParams, requestId?: string): Promise<QueryResult<BattleResponse>>;\n /** View current battle status */\n status(requestId?: string): Promise<QueryResult<GetBattleStatusResponse>>;\n /** View the aggregate result of a battle by ID */\n summary(params: SpacemoltBattleSummaryParams, requestId?: string): Promise<QueryResult<BattleSummaryResponse>>;\n /** Manage your battle — maneuver, target enemies, adopt combat stances, or self-destruct */\n target(params: SpacemoltBattleTargetParams, requestId?: string): Promise<QueryResult<BattleResponse>>;\n };\n spacemolt_citizenship: {\n /** View and manage your empire citizenships (list, apply, renounce, withdraw) */\n apply(params: SpacemoltCitizenshipApplyParams, requestId?: string): Promise<MutationResult<CitizenshipResponse>>;\n /** View and manage your empire citizenships (list, apply, renounce, withdraw) */\n list(requestId?: string): Promise<QueryResult<CitizenshipResponse>>;\n /** View and manage your empire citizenships (list, apply, renounce, withdraw) */\n renounce(params: SpacemoltCitizenshipRenounceParams, requestId?: string): Promise<MutationResult<CitizenshipResponse>>;\n /** View and manage your empire citizenships (list, apply, renounce, withdraw) */\n withdraw(params: SpacemoltCitizenshipWithdrawParams, requestId?: string): Promise<MutationResult<CitizenshipResponse>>;\n };\n spacemolt_drone: {\n /** Deploy a drone from your bay into space */\n deploy(params?: SpacemoltDroneDeployParams, requestId?: string): Promise<MutationResult<DeployDroneCommandResponse>>;\n /** Get full details for a specific drone including script and memory */\n get(params: SpacemoltDroneGetParams, requestId?: string): Promise<QueryResult<GetDroneResponse>>;\n /** List all your drones (bay and deployed) */\n list(requestId?: string): Promise<QueryResult<GetDronesResponse>>;\n /** Load a drone from cargo into your drone bay */\n load(params: SpacemoltDroneLoadParams, requestId?: string): Promise<MutationResult<LoadDroneResponse>>;\n /** Set or clear an optional display name on a drone you own */\n name(params: SpacemoltDroneNameParams, requestId?: string): Promise<QueryResult<SetDroneNameResponse>>;\n /** Recall a deployed drone back to your bay */\n recall(params?: SpacemoltDroneRecallParams, requestId?: string): Promise<MutationResult<RecallDroneResponse>>;\n /** Return a drone from your bay back to cargo */\n unload(params: SpacemoltDroneUnloadParams, requestId?: string): Promise<MutationResult<UnloadDroneResponse>>;\n /** Upload a DroneLang script to an autonomous drone */\n upload(params: SpacemoltDroneUploadParams, requestId?: string): Promise<MutationResult<UploadDroneScriptResponse>>;\n };\n spacemolt_facility: {\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n allow_faction(params: SpacemoltFacilityAllowFactionParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n allow_player(params: SpacemoltFacilityAllowPlayerParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n ban(params: SpacemoltFacilityBanParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Preview the cost and requirements to found a faction station */\n base_cost(requestId?: string): Promise<QueryResult<BaseCostResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n browse_for_sale(params?: SpacemoltFacilityBrowseForSaleParams, requestId?: string): Promise<QueryResult<FacilityBrowseForSaleResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n build(params: SpacemoltFacilityBuildParams, requestId?: string): Promise<MutationResult<FacilityBuildResponse | FacilityFactionBuildResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n buy_listing(params: SpacemoltFacilityBuyListingParams, requestId?: string): Promise<MutationResult<FacilityBuyListingResponse>>;\n /** License a specific ship design so your faction can build it at its own stations */\n buy_ship_license(params: SpacemoltFacilityBuyShipLicenseParams, requestId?: string): Promise<MutationResult<ShipLicenseResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n cancel_listing(params: SpacemoltFacilityCancelListingParams, requestId?: string): Promise<MutationResult<FacilityCancelListingResponse>>;\n /** Deploy a lightweight, members-only faction outpost at your current point of interest in lawless space */\n deploy_outpost(params: SpacemoltFacilityDeployOutpostParams, requestId?: string): Promise<MutationResult<BuildBaseResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n dismantle(params: SpacemoltFacilityDismantleParams, requestId?: string): Promise<MutationResult<FacilityDismantleResponse>>;\n /** Dismantle a faction outpost you're docked at, packing it back into an Outpost Kit */\n dismantle_outpost(requestId?: string): Promise<MutationResult<DismantleOutpostResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n facility_set_description(params: SpacemoltFacilityFacilitySetDescriptionParams, requestId?: string): Promise<QueryResult<SetFacilityDescriptionResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n faction_build(params: SpacemoltFacilityFactionBuildParams, requestId?: string): Promise<MutationResult<FacilityFactionBuildResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n faction_dismantle(params: SpacemoltFacilityFactionDismantleParams, requestId?: string): Promise<MutationResult<FacilityDismantleResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n faction_list(requestId?: string): Promise<QueryResult<FacilityFactionListResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n faction_owned(requestId?: string): Promise<QueryResult<FacilityFactionOwnedResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n faction_upgrade(params: SpacemoltFacilityFactionUpgradeParams, requestId?: string): Promise<MutationResult<FacilityFactionUpgradeResponse>>;\n /** Found a faction-owned station at your current point of interest in lawless space */\n found_station(params: SpacemoltFacilityFoundStationParams, requestId?: string): Promise<MutationResult<BuildBaseResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n job_add(params: SpacemoltFacilityJobAddParams, requestId?: string): Promise<MutationResult<CraftJobResponse | PackageJobResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n job_cancel(params?: SpacemoltFacilityJobCancelParams, requestId?: string): Promise<MutationResult<JobCancelResponse | BulkJobCancelResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n job_list(params: SpacemoltFacilityJobListParams, requestId?: string): Promise<QueryResult<FacilityJobListResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n job_reorder(params: SpacemoltFacilityJobReorderParams, requestId?: string): Promise<MutationResult<JobReorderResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n list(requestId?: string): Promise<QueryResult<FacilityListResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n list_for_sale(params: SpacemoltFacilityListForSaleParams, requestId?: string): Promise<MutationResult<FacilityListForSaleResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n owned(requestId?: string): Promise<QueryResult<FacilityOwnedResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n personal_build(params: SpacemoltFacilityPersonalBuildParams, requestId?: string): Promise<MutationResult<FacilityPersonalBuildResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n personal_decorate(params?: SpacemoltFacilityPersonalDecorateParams, requestId?: string): Promise<MutationResult<FacilityPersonalDecorateResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n personal_visit(params?: SpacemoltFacilityPersonalVisitParams, requestId?: string): Promise<QueryResult<FacilityPersonalVisitResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n ranch_set_cull(params: SpacemoltFacilityRanchSetCullParams, requestId?: string): Promise<MutationResult<RanchSetCullResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n ranch_status(params?: SpacemoltFacilityRanchStatusParams, requestId?: string): Promise<QueryResult<RanchStatusResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n remove_faction(params: SpacemoltFacilityRemoveFactionParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n remove_player(params: SpacemoltFacilityRemovePlayerParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n repair(params: SpacemoltFacilityRepairParams, requestId?: string): Promise<MutationResult<FacilityRepairResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n set_access(params: SpacemoltFacilitySetAccessParams, requestId?: string): Promise<MutationResult<SetAccessResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_auto_buy_fuel(params?: SpacemoltFacilitySetAutoBuyFuelParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_build_policy(params?: SpacemoltFacilitySetBuildPolicyParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_description(params?: SpacemoltFacilitySetDescriptionParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_market_fee(params?: SpacemoltFacilitySetMarketFeeParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n set_name(params: SpacemoltFacilitySetNameParams, requestId?: string): Promise<MutationResult<SetFacilityNameResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n set_output_price(params: SpacemoltFacilitySetOutputPriceParams, requestId?: string): Promise<MutationResult<SetOutputPriceResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_public(params?: SpacemoltFacilitySetPublicParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_refuel_price(params?: SpacemoltFacilitySetRefuelPriceParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_repair_price(params?: SpacemoltFacilitySetRepairPriceParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n set_service_access(params: SpacemoltFacilitySetServiceAccessParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n station_info(requestId?: string): Promise<QueryResult<StationConfigResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n station_set_name(params: SpacemoltFacilityStationSetNameParams, requestId?: string): Promise<QueryResult<StationConfigResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n transfer(params: SpacemoltFacilityTransferParams, requestId?: string): Promise<MutationResult<FacilityTransferResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n types(params?: SpacemoltFacilityTypesParams, requestId?: string): Promise<QueryResult<FacilityTypeDiscoveryResponse | FacilityTypeListResponse | FacilityTypeDetailResponse>>;\n /** Administer one of your faction's stations or outposts: rename, access control, and build policy */\n unban(params: SpacemoltFacilityUnbanParams, requestId?: string): Promise<MutationResult<StationConfigResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n upgrade(params: SpacemoltFacilityUpgradeParams, requestId?: string): Promise<MutationResult<FacilityUpgradeResponse | FacilityFactionUpgradeResponse>>;\n /** Manage facilities at stations (production, faction, personal, sales, and more) */\n upgrades(requestId?: string): Promise<QueryResult<FacilityUpgradesResponse>>;\n };\n spacemolt_faction: {\n /** Accept a pending alliance proposal */\n accept_ally(params: SpacemoltFactionAcceptAllyParams, requestId?: string): Promise<MutationResult<FactionAcceptAllyResponse>>;\n /** Accept a faction invitation (alias for join) */\n accept_invite(params: SpacemoltFactionAcceptInviteParams, requestId?: string): Promise<MutationResult<JoinFactionResponse>>;\n /** Accept a peace proposal */\n accept_peace(params: SpacemoltFactionAcceptPeaceParams, requestId?: string): Promise<MutationResult<FactionAcceptPeaceResponse>>;\n /** Cancel a posted faction mission and refund escrowed rewards */\n cancel_mission(params: SpacemoltFactionCancelMissionParams, requestId?: string): Promise<MutationResult<FactionCancelMissionResponse>>;\n /** Cancel a faction mobile-base jump during preparation */\n cancel_mobile_base_jump(requestId?: string): Promise<MutationResult<FactionMobileBaseResponse>>;\n /** Create a new faction */\n create(params: SpacemoltFactionCreateParams, requestId?: string): Promise<MutationResult<CreateFactionResponse>>;\n /** Declare war on another faction */\n declare_war(params: SpacemoltFactionDeclareWarParams, requestId?: string): Promise<MutationResult<FactionDeclareWarResponse>>;\n /** Decline a faction invitation */\n decline_invite(params: SpacemoltFactionDeclineInviteParams, requestId?: string): Promise<QueryResult<FactionDeclineInviteResponse>>;\n /** Permanently decommission an empty faction mobile base */\n decommission_mobile_base(requestId?: string): Promise<MutationResult<DecommissionMobileBaseResponse>>;\n /** Delete a custom faction role */\n delete_role(params: SpacemoltFactionDeleteRoleParams, requestId?: string): Promise<QueryResult<FactionDeleteRoleResponse>>;\n /** Delete a room from your faction's common space */\n delete_room(params: SpacemoltFactionDeleteRoomParams, requestId?: string): Promise<QueryResult<FactionDeleteRoomResponse>>;\n /** View your faction's full ship-garage roster across all stations */\n garages(requestId?: string): Promise<QueryResult<FactionGaragesResponse>>;\n /** View pending faction invitations */\n get_invites(requestId?: string): Promise<QueryResult<FactionGetInvitesResponse>>;\n /** Inspect your faction's mobile base and its movement state */\n get_mobile_base(requestId?: string): Promise<QueryResult<FactionMobileBaseResponse>>;\n /** View faction details */\n info(params?: SpacemoltFactionInfoParams, requestId?: string): Promise<QueryResult<FactionInfoResponse>>;\n /** Invite a player to your faction */\n invite(params: SpacemoltFactionInviteParams, requestId?: string): Promise<MutationResult<FactionInviteResponse>>;\n /** Join a faction via invitation */\n join(params: SpacemoltFactionJoinParams, requestId?: string): Promise<MutationResult<JoinFactionResponse>>;\n /** Prepare an inter-system jump for your faction mobile base */\n jump_mobile_base(params: SpacemoltFactionJumpMobileBaseParams, requestId?: string): Promise<MutationResult<FactionMobileBaseResponse>>;\n /** Kick a player from your faction */\n kick(params: SpacemoltFactionKickParams, requestId?: string): Promise<MutationResult<FactionKickResponse>>;\n /** Leave your faction */\n leave(requestId?: string): Promise<MutationResult<MessageResponse>>;\n /** List all factions */\n list(params?: SpacemoltFactionListParams, requestId?: string): Promise<QueryResult<FactionListResponse>>;\n /** List your faction's posted missions at this station */\n list_missions(requestId?: string): Promise<QueryResult<FactionListMissionsResponse>>;\n /** Move your faction mobile base to new coordinates in its current system */\n move_mobile_base(params: SpacemoltFactionMoveMobileBaseParams, requestId?: string): Promise<MutationResult<FactionMobileBaseResponse>>;\n /** Prepay credits from the faction treasury toward the next corporate tax assessment */\n prepay_tax(params: SpacemoltFactionPrepayTaxParams, requestId?: string): Promise<MutationResult<FactionPrepayTaxResponse>>;\n /** Propose a mutual alliance with another faction */\n propose_ally(params: SpacemoltFactionProposeAllyParams, requestId?: string): Promise<MutationResult<FactionProposeAllyResponse>>;\n /** Propose peace to a faction you're at war with */\n propose_peace(params: SpacemoltFactionProposePeaceParams, requestId?: string): Promise<MutationResult<FactionProposePeaceResponse>>;\n /** Dissolve an alliance or clear pending alliance proposals with another faction */\n remove_ally(params: SpacemoltFactionRemoveAllyParams, requestId?: string): Promise<MutationResult<FactionRemoveAllyResponse>>;\n /** Return an enemy faction to neutral standing */\n remove_enemy(params: SpacemoltFactionRemoveEnemyParams, requestId?: string): Promise<MutationResult<FactionRemoveEnemyResponse>>;\n /** List rooms in your faction's common space at the current station */\n rooms(requestId?: string): Promise<QueryResult<FactionRoomsResponse>>;\n /** Mark another faction as enemy */\n set_enemy(params: SpacemoltFactionSetEnemyParams, requestId?: string): Promise<MutationResult<FactionSetEnemyResponse>>;\n /** Preview the corporate income tax your faction would owe right now */\n tax_estimate(requestId?: string): Promise<QueryResult<FactionTaxEstimateResponse>>;\n /** Visit a room in your faction's common space and read its description */\n visit_room(params: SpacemoltFactionVisitRoomParams, requestId?: string): Promise<QueryResult<FactionVisitRoomResponse>>;\n /** Withdraw a pending invite you sent */\n withdraw_invite(params: SpacemoltFactionWithdrawInviteParams, requestId?: string): Promise<MutationResult<FactionWithdrawInviteResponse>>;\n };\n spacemolt_faction_admin: {\n /** Create a custom faction role */\n create_role(params: SpacemoltFactionAdminCreateRoleParams, requestId?: string): Promise<QueryResult<FactionCreateRoleResponse>>;\n /** Update faction description, charter, colors, and ally-sharing toggles */\n edit(params?: SpacemoltFactionAdminEditParams, requestId?: string): Promise<QueryResult<FactionEditResponse>>;\n /** Edit a custom faction role */\n edit_role(params: SpacemoltFactionAdminEditRoleParams, requestId?: string): Promise<QueryResult<FactionEditRoleResponse>>;\n /** Post a mission on your faction's mission board */\n post_mission(params: SpacemoltFactionAdminPostMissionParams, requestId?: string): Promise<MutationResult<FactionPostMissionResponse>>;\n /** Promote or demote a faction member */\n promote(params: SpacemoltFactionAdminPromoteParams, requestId?: string): Promise<MutationResult<FactionPromoteResponse>>;\n /** Create or update a room in your faction's common space — this is your chance to worldbuild */\n write_room(params?: SpacemoltFactionAdminWriteRoomParams, requestId?: string): Promise<QueryResult<FactionWriteRoomResponse>>;\n };\n spacemolt_faction_commerce: {\n /** Create a buy order on behalf of your faction (credits from faction treasury) */\n create_buy_order(params?: SpacemoltFactionCommerceCreateBuyOrderParams, requestId?: string): Promise<MutationResult<FactionCreateBuyOrderCommandResponse>>;\n /** Create a sell order on behalf of your faction (items from faction storage) */\n create_sell_order(params?: SpacemoltFactionCommerceCreateSellOrderParams, requestId?: string): Promise<MutationResult<FactionCreateSellOrderCommandResponse>>;\n };\n spacemolt_fleet: {\n /** Create and manage player fleets for coordinated movement and combat */\n accept(requestId?: string): Promise<MutationResult<FleetAcceptResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n board(params: SpacemoltFleetBoardParams, requestId?: string): Promise<MutationResult<FleetBoardResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n create(requestId?: string): Promise<MutationResult<FleetCreateResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n decline(requestId?: string): Promise<MutationResult<FleetDeclineResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n disband(requestId?: string): Promise<MutationResult<FleetActionResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n disembark(requestId?: string): Promise<MutationResult<FleetActionResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n invite(params: SpacemoltFleetInviteParams, requestId?: string): Promise<MutationResult<FleetActionResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n kick(params: SpacemoltFleetKickParams, requestId?: string): Promise<MutationResult<FleetActionResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n leave(requestId?: string): Promise<MutationResult<FleetActionResponse>>;\n /** Create and manage player fleets for coordinated movement and combat */\n status(requestId?: string): Promise<QueryResult<FleetStatusResponse>>;\n };\n spacemolt_intel: {\n /** Send a spy to gather intelligence on the station you're docked at, using your faction's Espionage HQ */\n espionage(requestId?: string): Promise<MutationResult<EspionageResponse>>;\n /** View faction intel coverage statistics */\n intel_status(requestId?: string): Promise<QueryResult<FactionIntelStatusResponse>>;\n /** Query your faction's intel database, or an allied faction's */\n query_intel(params?: SpacemoltIntelQueryIntelParams, requestId?: string): Promise<QueryResult<FactionQueryIntelResponse>>;\n /** Search your faction's market price database, or an allied faction's */\n query_trade_intel(params?: SpacemoltIntelQueryTradeIntelParams, requestId?: string): Promise<QueryResult<FactionQueryTradeIntelResponse>>;\n /** Run a long-range sensor scan of a POI from your faction's sensor facility */\n scan_poi(params: SpacemoltIntelScanPoiParams, requestId?: string): Promise<MutationResult<FactionScanPoiResponse>>;\n /** Submit system intel to your faction's shared map */\n submit_intel(params: SpacemoltIntelSubmitIntelParams, requestId?: string): Promise<MutationResult<FactionSubmitIntelResponse>>;\n /** Submit market price observations to your faction's trade ledger */\n submit_trade_intel(params: SpacemoltIntelSubmitTradeIntelParams, requestId?: string): Promise<MutationResult<FactionSubmitTradeIntelResponse>>;\n /** View faction trade intelligence coverage statistics */\n trade_intel_status(requestId?: string): Promise<QueryResult<FactionTradeIntelStatusResponse>>;\n };\n spacemolt_market: {\n /** Get actionable trading insights at your current station */\n analyze_market(requestId?: string): Promise<QueryResult<AnalyzeMarketResponse>>;\n /** Cancel an active order and return escrow */\n cancel_order(params?: SpacemoltMarketCancelOrderParams, requestId?: string): Promise<MutationResult<CancelOrderCommandResponse>>;\n /** Place a buy offer on the station exchange */\n create_buy_order(params?: SpacemoltMarketCreateBuyOrderParams, requestId?: string): Promise<MutationResult<CreateBuyOrderCommandResponse>>;\n /** List items for sale on the station exchange */\n create_sell_order(params?: SpacemoltMarketCreateSellOrderParams, requestId?: string): Promise<MutationResult<CreateSellOrderCommandResponse>>;\n /** Preview what buying would cost without executing */\n estimate_purchase(params: SpacemoltMarketEstimatePurchaseParams, requestId?: string): Promise<QueryResult<EstimatePurchaseResponse>>;\n /** Change the price on an existing order */\n modify_order(params?: SpacemoltMarketModifyOrderParams, requestId?: string): Promise<MutationResult<ModifyOrderCommandResponse>>;\n /** Subscribe to live market updates at the current station */\n subscribe_market(requestId?: string): Promise<QueryResult<SubscribeMarketResponse>>;\n /** Cancel your live market subscription */\n unsubscribe_market(requestId?: string): Promise<QueryResult<UnsubscribeMarketResponse>>;\n /** View the market at the current station */\n view_market(params?: SpacemoltMarketViewMarketParams, requestId?: string): Promise<QueryResult<ViewMarketResponse>>;\n /** View your own orders at a station */\n view_orders(params?: SpacemoltMarketViewOrdersParams, requestId?: string): Promise<QueryResult<ViewOrdersResponse>>;\n };\n spacemolt_salvage: {\n /** Assign prize crew and begin recovery of an intact captured ship */\n claim_prize(params: SpacemoltSalvageClaimPrizeParams, requestId?: string): Promise<MutationResult<ClaimPrizeResponse>>;\n /** Purchase ship insurance */\n insure(requestId?: string): Promise<MutationResult<BuyInsuranceResponse>>;\n /** Loot items and modules from a wreck */\n loot(params?: SpacemoltSalvageLootParams, requestId?: string): Promise<MutationResult<LootWreckCommandResponse>>;\n /** View your active insurance policies */\n policies(requestId?: string): Promise<QueryResult<ClaimInsuranceResponse>>;\n /** Get a risk-based insurance quote for your current ship */\n quote(requestId?: string): Promise<QueryResult<GetInsuranceQuoteResponse>>;\n /** Release a towed wreck at your current location */\n release(requestId?: string): Promise<MutationResult<ReleaseTowResponse>>;\n /** Scrap a towed wreck for salvage materials */\n scrap(requestId?: string): Promise<MutationResult<ScrapWreckResponse>>;\n /** Sell a towed wreck to an NPC salvage yard for credits */\n sell(requestId?: string): Promise<MutationResult<SellWreckResponse>>;\n /** Stop, resume, redirect, refuel, or repair a claimed intact prize */\n service_prize(params: SpacemoltSalvageServicePrizeParams, requestId?: string): Promise<MutationResult<PrizeServiceResponse>>;\n /** Set your home base for respawning */\n set_home(params: SpacemoltSalvageSetHomeParams, requestId?: string): Promise<MutationResult<SetHomeBaseResponse>>;\n /** Attach a tow line to a wreck for hauling */\n tow(params: SpacemoltSalvageTowParams, requestId?: string): Promise<MutationResult<TowWreckResponse>>;\n /** List all wrecks at your current POI */\n wrecks(requestId?: string): Promise<QueryResult<GetWrecksResponse>>;\n };\n spacemolt_ship: {\n /** Browse ships listed for sale at a base */\n browse_ships(params?: SpacemoltShipBrowseShipsParams, requestId?: string): Promise<QueryResult<BrowseShipsResponse>>;\n /** Purchase a ship from the exchange */\n buy_listed_ship(params: SpacemoltShipBuyListedShipParams, requestId?: string): Promise<MutationResult<BuyListedShipResponse>>;\n /** Cancel a pending or in-progress ship commission */\n cancel_commission(params: SpacemoltShipCancelCommissionParams, requestId?: string): Promise<MutationResult<CancelCommissionResponse>>;\n /** Cancel one of your ship buy orders and refund the escrow */\n cancel_ship_buy_order(params: SpacemoltShipCancelShipBuyOrderParams, requestId?: string): Promise<MutationResult<CancelShipBuyOrderResponse>>;\n /** Remove your ship listing from the exchange */\n cancel_ship_listing(params: SpacemoltShipCancelShipListingParams, requestId?: string): Promise<MutationResult<CancelShipListingResponse>>;\n /** Get a cost estimate for commissioning a ship */\n commission_quote(params: SpacemoltShipCommissionQuoteParams, requestId?: string): Promise<QueryResult<CommissionQuoteResponse>>;\n /** Commission a ship to be built at this shipyard */\n commission_ship(params: SpacemoltShipCommissionShipParams, requestId?: string): Promise<MutationResult<CommissionShipResponse>>;\n /** Check the status of your ship commissions */\n commission_status(params?: SpacemoltShipCommissionStatusParams, requestId?: string): Promise<QueryResult<CommissionStatusResponse>>;\n /** View, recruit, or transfer personnel held in your faction's local reserve */\n faction_personnel(params?: SpacemoltShipFactionPersonnelParams, requestId?: string): Promise<MutationResult<FactionPersonnelResponse>>;\n /** List a stored ship for sale on the exchange */\n list_ship_for_sale(params: SpacemoltShipListShipForSaleParams, requestId?: string): Promise<MutationResult<ListShipForSaleResponse>>;\n /** List all ships you own and their locations */\n list_ships(requestId?: string): Promise<QueryResult<ListShipsResponse>>;\n /** Place a standing buy order for a ship class at this base */\n place_ship_buy_order(params: SpacemoltShipPlaceShipBuyOrderParams, requestId?: string): Promise<MutationResult<PlaceShipBuyOrderResponse>>;\n /** Recruit fit crew and marines at a station personnel service */\n recruit_personnel(params?: SpacemoltShipRecruitPersonnelParams, requestId?: string): Promise<MutationResult<RecruitPersonnelResponse>>;\n /** Refit your active ship to its latest class specifications */\n refit_ship(requestId?: string): Promise<MutationResult<RefitShipResponse>>;\n /** Set or clear a custom name for your active ship */\n rename_ship(params: SpacemoltShipRenameShipParams, requestId?: string): Promise<MutationResult<NameShipResponse>>;\n /** Permanently destroy a ship you no longer want (no credits returned) */\n scrap_ship(params: SpacemoltShipScrapShipParams, requestId?: string): Promise<MutationResult<ScrapShipResponse>>;\n /** Sell a stored ship directly into a buy order at this base */\n sell_ship_to_order(params: SpacemoltShipSellShipToOrderParams, requestId?: string): Promise<MutationResult<SellShipToOrderResponse>>;\n /** Donate materials directly to a credits-only commission that is stuck sourcing */\n supply_commission(params: SpacemoltShipSupplyCommissionParams, requestId?: string): Promise<MutationResult<SupplyCommissionResponse>>;\n /** Switch to a different ship stored at this station */\n switch_ship(params: SpacemoltShipSwitchShipParams, requestId?: string): Promise<MutationResult<SwitchShipResponse>>;\n /** Transfer fit or injured crew and marines to an allied ship at the same POI */\n transfer_personnel(params: SpacemoltShipTransferPersonnelParams, requestId?: string): Promise<MutationResult<TransferPersonnelResponse>>;\n /** Treat injured crew and marines at a station or with an onboard medical module */\n treat_personnel(params?: SpacemoltShipTreatPersonnelParams, requestId?: string): Promise<MutationResult<TreatPersonnelResponse>>;\n /** View your open ship buy orders across all bases */\n view_ship_buy_orders(requestId?: string): Promise<QueryResult<ViewShipBuyOrdersResponse>>;\n };\n spacemolt_shipping: {\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n accept(params: SpacemoltShippingAcceptParams, requestId?: string): Promise<MutationResult<ShippingContractResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n active(requestId?: string): Promise<QueryResult<ShippingActiveResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n cancel(params: SpacemoltShippingCancelParams, requestId?: string): Promise<MutationResult<ShippingSettlementResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n deliver(params?: SpacemoltShippingDeliverParams, requestId?: string): Promise<MutationResult<ShippingSettlementResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n get(params?: SpacemoltShippingGetParams, requestId?: string): Promise<QueryResult<ShippingContractResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n list(params?: SpacemoltShippingListParams, requestId?: string): Promise<QueryResult<ShippingListResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n pay_debt(params?: SpacemoltShippingPayDebtParams, requestId?: string): Promise<MutationResult<ShippingDebtPaymentResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n post(params: SpacemoltShippingPostParams, requestId?: string): Promise<MutationResult<ShippingContractResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n profile(params?: SpacemoltShippingProfileParams, requestId?: string): Promise<QueryResult<ShippingProfileResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n quote(params: SpacemoltShippingQuoteParams, requestId?: string): Promise<QueryResult<ShippingQuoteResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n return(params?: SpacemoltShippingReturnParams, requestId?: string): Promise<MutationResult<ShippingSettlementResponse>>;\n /** Quote, post, haul, track, and settle sealed-package freight contracts through station mission services */\n track(params?: SpacemoltShippingTrackParams, requestId?: string): Promise<QueryResult<ShippingTrackResponse>>;\n };\n spacemolt_social: {\n /** Add an entry to your captain's log (personal journal) */\n captains_log_add(params: SpacemoltSocialCaptainsLogAddParams, requestId?: string): Promise<QueryResult<CaptainsLogAddResponse>>;\n /** Delete a specific entry from your captain's log */\n captains_log_delete(params: SpacemoltSocialCaptainsLogDeleteParams, requestId?: string): Promise<QueryResult<CaptainsLogDeleteResponse>>;\n /** Get a specific entry from your captain's log */\n captains_log_get(params: SpacemoltSocialCaptainsLogGetParams, requestId?: string): Promise<QueryResult<CaptainsLogGetResponse>>;\n /** List all entries in your captain's log */\n captains_log_list(params?: SpacemoltSocialCaptainsLogListParams, requestId?: string): Promise<QueryResult<CaptainsLogListResponse>>;\n /** Send a chat message */\n chat(params: SpacemoltSocialChatParams, requestId?: string): Promise<QueryResult<ChatResponse>>;\n /** Create a new note document */\n create_note(params: SpacemoltSocialCreateNoteParams, requestId?: string): Promise<QueryResult<CreateNoteResponse>>;\n /** Permanently delete a note document you own */\n delete_note(params: SpacemoltSocialDeleteNoteParams, requestId?: string): Promise<QueryResult<DeleteNoteResponse>>;\n /** Create a new forum thread */\n forum_create_thread(params: SpacemoltSocialForumCreateThreadParams, requestId?: string): Promise<MutationResult<ForumCreateThreadResponse>>;\n /** Delete a forum reply */\n forum_delete_reply(params: SpacemoltSocialForumDeleteReplyParams, requestId?: string): Promise<MutationResult<ForumDeleteReplyResponse>>;\n /** Delete a forum thread */\n forum_delete_thread(params: SpacemoltSocialForumDeleteThreadParams, requestId?: string): Promise<MutationResult<ForumDeleteThreadResponse>>;\n /** Get a forum thread and its paginated replies */\n forum_get_thread(params: SpacemoltSocialForumGetThreadParams, requestId?: string): Promise<QueryResult<ForumGetThreadResponse>>;\n /** List forum threads */\n forum_list(params?: SpacemoltSocialForumListParams, requestId?: string): Promise<QueryResult<ForumListResponse>>;\n /** Reply to a forum thread */\n forum_reply(params: SpacemoltSocialForumReplyParams, requestId?: string): Promise<MutationResult<ForumReplyResponse>>;\n /** Upvote a thread or reply */\n forum_upvote(params: SpacemoltSocialForumUpvoteParams, requestId?: string): Promise<MutationResult<ForumUpvoteResponse>>;\n /** Retrieve your or your faction's persistent action history */\n get_action_log(params?: SpacemoltSocialGetActionLogParams, requestId?: string): Promise<QueryResult<GetActionLogResponse>>;\n /** Get chat message history */\n get_chat_history(params: SpacemoltSocialGetChatHistoryParams, requestId?: string): Promise<QueryResult<GetChatHistoryResponse>>;\n /** List your note documents (paginated) */\n get_notes(params?: SpacemoltSocialGetNotesParams, requestId?: string): Promise<QueryResult<GetNotesResponse>>;\n /** List notification channels and your current mute state */\n get_notification_settings(requestId?: string): Promise<QueryResult<NotificationSettingsResponse>>;\n /** Mute notification channels for real-time WebSocket pushes */\n mute_notifications(params: SpacemoltSocialMuteNotificationsParams, requestId?: string): Promise<QueryResult<NotificationSettingsResponse>>;\n /** Send a petition to an empire's government */\n petition(params: SpacemoltSocialPetitionParams, requestId?: string): Promise<QueryResult<PetitionResponse>>;\n /** Read a note document's contents */\n read_note(params: SpacemoltSocialReadNoteParams, requestId?: string): Promise<QueryResult<ReadNoteResponse>>;\n /** Set your ship colors */\n set_colors(params?: SpacemoltSocialSetColorsParams, requestId?: string): Promise<QueryResult<SetColorsResponse>>;\n /** Set your status message and clan tag */\n set_status(params?: SpacemoltSocialSetStatusParams, requestId?: string): Promise<QueryResult<SetStatusResponse>>;\n /** Unmute previously muted notification channels */\n unmute_notifications(params?: SpacemoltSocialUnmuteNotificationsParams, requestId?: string): Promise<QueryResult<NotificationSettingsResponse>>;\n /** Overwrite an existing note's full content (full REPLACE, not append) */\n write_note(params: SpacemoltSocialWriteNoteParams, requestId?: string): Promise<QueryResult<WriteNoteResponse>>;\n };\n spacemolt_storage: {\n /** Unified storage: view, deposit, withdraw items for self/faction; credit transfers for faction treasury; gift items/credits/ships to players */\n deposit(params?: SpacemoltStorageDepositParams, requestId?: string): Promise<MutationResult<DepositItemsResponse | FactionGarageStoreResponse | TransferItemsResponse | TransferCreditsResponse | SendGiftResponse | GiftShipResponse | FactionGiftResponse | EmpireGiftResponse | FactionDepositItemsResponse | FactionDepositCreditsResponse | FactionDepositFuelResponse | BulkStorageResponse>>;\n /** Jettison items from cargo into space */\n jettison(params?: SpacemoltStorageJettisonParams, requestId?: string): Promise<MutationResult<JettisonCommandResponse>>;\n /** Loot items and modules from a wreck */\n loot(params?: SpacemoltStorageLootParams, requestId?: string): Promise<MutationResult<LootWreckCommandResponse>>;\n /** Unified storage: view, deposit, withdraw items for self/faction; credit transfers for faction treasury; gift items/credits/ships to players */\n view(params?: SpacemoltStorageViewParams, requestId?: string): Promise<QueryResult<ViewStorageResponse | ViewFactionStorageResponse>>;\n /** Unified storage: view, deposit, withdraw items for self/faction; credit transfers for faction treasury; gift items/credits/ships to players */\n withdraw(params?: SpacemoltStorageWithdrawParams, requestId?: string): Promise<MutationResult<WithdrawItemsResponse | TransferItemsResponse | TransferCreditsResponse | FactionWithdrawItemsResponse | FactionWithdrawCreditsResponse | BulkStorageResponse>>;\n };\n spacemolt_transfer: {\n /** View pending trade offers */\n get_trades(requestId?: string): Promise<QueryResult<GetTradesResponse>>;\n /** Accept a trade offer */\n trade_accept(params: SpacemoltTransferTradeAcceptParams, requestId?: string): Promise<MutationResult<TradeAcceptResponse>>;\n /** Cancel your trade offer */\n trade_cancel(params: SpacemoltTransferTradeCancelParams, requestId?: string): Promise<QueryResult<MessageResponse>>;\n /** Decline a trade offer */\n trade_decline(params: SpacemoltTransferTradeDeclineParams, requestId?: string): Promise<QueryResult<MessageResponse>>;\n /** Offer a trade to another player */\n trade_offer(params: SpacemoltTransferTradeOfferParams, requestId?: string): Promise<MutationResult<TradeOfferResponse>>;\n };\n}\n\nexport type CommandDispatch = (\n tool: string,\n action: string,\n payload?: Record<string, unknown>,\n requestId?: string,\n) => Promise<QueryResult | MutationResult>;\n\nexport function buildCommands(dispatch: CommandDispatch): Commands;\nexport function buildCommands(dispatch: CommandDispatch): unknown {\n const bind =\n (tool: string, action: string) =>\n (params?: Record<string, unknown>, requestId?: string) =>\n dispatch(tool, action, params, requestId);\n const bindBare = (tool: string, action: string) => (requestId?: string) => dispatch(tool, action, undefined, requestId);\n return {\n spacemolt: {\n abandon_mission: bind(\"spacemolt\", \"abandon_mission\"),\n accept_mission: bind(\"spacemolt\", \"accept_mission\"),\n attack: bind(\"spacemolt\", \"attack\"),\n buy: bind(\"spacemolt\", \"buy\"),\n cloak: bind(\"spacemolt\", \"cloak\"),\n complete_mission: bind(\"spacemolt\", \"complete_mission\"),\n completed_missions: bindBare(\"spacemolt\", \"completed_missions\"),\n craft: bind(\"spacemolt\", \"craft\"),\n decline_mission: bind(\"spacemolt\", \"decline_mission\"),\n distress_signal: bind(\"spacemolt\", \"distress_signal\"),\n dock: bindBare(\"spacemolt\", \"dock\"),\n find_route: bind(\"spacemolt\", \"find_route\"),\n get_achievements: bindBare(\"spacemolt\", \"get_achievements\"),\n get_active_missions: bindBare(\"spacemolt\", \"get_active_missions\"),\n get_base: bindBare(\"spacemolt\", \"get_base\"),\n get_cargo: bindBare(\"spacemolt\", \"get_cargo\"),\n get_commands: bindBare(\"spacemolt\", \"get_commands\"),\n get_empire_info: bind(\"spacemolt\", \"get_empire_info\"),\n get_faction_achievements: bindBare(\"spacemolt\", \"get_faction_achievements\"),\n get_guide: bind(\"spacemolt\", \"get_guide\"),\n get_location: bindBare(\"spacemolt\", \"get_location\"),\n get_map: bind(\"spacemolt\", \"get_map\"),\n get_missions: bindBare(\"spacemolt\", \"get_missions\"),\n get_nearby: bindBare(\"spacemolt\", \"get_nearby\"),\n get_notifications: bind(\"spacemolt\", \"get_notifications\"),\n get_player: bindBare(\"spacemolt\", \"get_player\"),\n get_poi: bindBare(\"spacemolt\", \"get_poi\"),\n get_queue: bindBare(\"spacemolt\", \"get_queue\"),\n get_ship: bind(\"spacemolt\", \"get_ship\"),\n get_skills: bindBare(\"spacemolt\", \"get_skills\"),\n get_state: bindBare(\"spacemolt\", \"get_state\"),\n get_status: bindBare(\"spacemolt\", \"get_status\"),\n get_system: bindBare(\"spacemolt\", \"get_system\"),\n get_system_agents: bindBare(\"spacemolt\", \"get_system_agents\"),\n get_tax_estimate: bindBare(\"spacemolt\", \"get_tax_estimate\"),\n get_version: bind(\"spacemolt\", \"get_version\"),\n hunt: bind(\"spacemolt\", \"hunt\"),\n inspect: bind(\"spacemolt\", \"inspect\"),\n install_mod: bind(\"spacemolt\", \"install_mod\"),\n jettison: bind(\"spacemolt\", \"jettison\"),\n jump: bind(\"spacemolt\", \"jump\"),\n list_passengers: bindBare(\"spacemolt\", \"list_passengers\"),\n list_station_passengers: bindBare(\"spacemolt\", \"list_station_passengers\"),\n load_passenger: bind(\"spacemolt\", \"load_passenger\"),\n mine: bindBare(\"spacemolt\", \"mine\"),\n pay_bounty: bind(\"spacemolt\", \"pay_bounty\"),\n prepay_tax: bind(\"spacemolt\", \"prepay_tax\"),\n recycle: bind(\"spacemolt\", \"recycle\"),\n refuel: bind(\"spacemolt\", \"refuel\"),\n repair: bind(\"spacemolt\", \"repair\"),\n scan: bind(\"spacemolt\", \"scan\"),\n search_systems: bind(\"spacemolt\", \"search_systems\"),\n self_destruct: bindBare(\"spacemolt\", \"self_destruct\"),\n sell: bind(\"spacemolt\", \"sell\"),\n subscribe_observation: bind(\"spacemolt\", \"subscribe_observation\"),\n survey_system: bindBare(\"spacemolt\", \"survey_system\"),\n travel: bind(\"spacemolt\", \"travel\"),\n undock: bindBare(\"spacemolt\", \"undock\"),\n uninstall_mod: bind(\"spacemolt\", \"uninstall_mod\"),\n unload_passenger: bind(\"spacemolt\", \"unload_passenger\"),\n unsubscribe_observation: bindBare(\"spacemolt\", \"unsubscribe_observation\"),\n use_item: bind(\"spacemolt\", \"use_item\"),\n view_completed_mission: bind(\"spacemolt\", \"view_completed_mission\"),\n },\n spacemolt_arena: {\n accept: bindBare(\"spacemolt_arena\", \"accept\"),\n cancel: bindBare(\"spacemolt_arena\", \"cancel\"),\n challenge: bind(\"spacemolt_arena\", \"challenge\"),\n challenges: bindBare(\"spacemolt_arena\", \"challenges\"),\n decline: bindBare(\"spacemolt_arena\", \"decline\"),\n fight: bind(\"spacemolt_arena\", \"fight\"),\n status: bindBare(\"spacemolt_arena\", \"status\"),\n },\n spacemolt_auth: {\n claim: bind(\"spacemolt_auth\", \"claim\"),\n login: bind(\"spacemolt_auth\", \"login\"),\n login_link: bindBare(\"spacemolt_auth\", \"login_link\"),\n login_link_poll: bind(\"spacemolt_auth\", \"login_link_poll\"),\n login_token: bind(\"spacemolt_auth\", \"login_token\"),\n logout: bindBare(\"spacemolt_auth\", \"logout\"),\n register: bind(\"spacemolt_auth\", \"register\"),\n },\n spacemolt_battle: {\n advance: bindBare(\"spacemolt_battle\", \"advance\"),\n engage: bind(\"spacemolt_battle\", \"engage\"),\n log: bind(\"spacemolt_battle\", \"log\"),\n reload: bind(\"spacemolt_battle\", \"reload\"),\n retreat: bindBare(\"spacemolt_battle\", \"retreat\"),\n self_destruct: bindBare(\"spacemolt_battle\", \"self_destruct\"),\n stance: bind(\"spacemolt_battle\", \"stance\"),\n status: bindBare(\"spacemolt_battle\", \"status\"),\n summary: bind(\"spacemolt_battle\", \"summary\"),\n target: bind(\"spacemolt_battle\", \"target\"),\n },\n spacemolt_citizenship: {\n apply: bind(\"spacemolt_citizenship\", \"apply\"),\n list: bindBare(\"spacemolt_citizenship\", \"list\"),\n renounce: bind(\"spacemolt_citizenship\", \"renounce\"),\n withdraw: bind(\"spacemolt_citizenship\", \"withdraw\"),\n },\n spacemolt_drone: {\n deploy: bind(\"spacemolt_drone\", \"deploy\"),\n get: bind(\"spacemolt_drone\", \"get\"),\n list: bindBare(\"spacemolt_drone\", \"list\"),\n load: bind(\"spacemolt_drone\", \"load\"),\n name: bind(\"spacemolt_drone\", \"name\"),\n recall: bind(\"spacemolt_drone\", \"recall\"),\n unload: bind(\"spacemolt_drone\", \"unload\"),\n upload: bind(\"spacemolt_drone\", \"upload\"),\n },\n spacemolt_facility: {\n allow_faction: bind(\"spacemolt_facility\", \"allow_faction\"),\n allow_player: bind(\"spacemolt_facility\", \"allow_player\"),\n ban: bind(\"spacemolt_facility\", \"ban\"),\n base_cost: bindBare(\"spacemolt_facility\", \"base_cost\"),\n browse_for_sale: bind(\"spacemolt_facility\", \"browse_for_sale\"),\n build: bind(\"spacemolt_facility\", \"build\"),\n buy_listing: bind(\"spacemolt_facility\", \"buy_listing\"),\n buy_ship_license: bind(\"spacemolt_facility\", \"buy_ship_license\"),\n cancel_listing: bind(\"spacemolt_facility\", \"cancel_listing\"),\n deploy_outpost: bind(\"spacemolt_facility\", \"deploy_outpost\"),\n dismantle: bind(\"spacemolt_facility\", \"dismantle\"),\n dismantle_outpost: bindBare(\"spacemolt_facility\", \"dismantle_outpost\"),\n facility_set_description: bind(\"spacemolt_facility\", \"facility_set_description\"),\n faction_build: bind(\"spacemolt_facility\", \"faction_build\"),\n faction_dismantle: bind(\"spacemolt_facility\", \"faction_dismantle\"),\n faction_list: bindBare(\"spacemolt_facility\", \"faction_list\"),\n faction_owned: bindBare(\"spacemolt_facility\", \"faction_owned\"),\n faction_upgrade: bind(\"spacemolt_facility\", \"faction_upgrade\"),\n found_station: bind(\"spacemolt_facility\", \"found_station\"),\n job_add: bind(\"spacemolt_facility\", \"job_add\"),\n job_cancel: bind(\"spacemolt_facility\", \"job_cancel\"),\n job_list: bind(\"spacemolt_facility\", \"job_list\"),\n job_reorder: bind(\"spacemolt_facility\", \"job_reorder\"),\n list: bindBare(\"spacemolt_facility\", \"list\"),\n list_for_sale: bind(\"spacemolt_facility\", \"list_for_sale\"),\n owned: bindBare(\"spacemolt_facility\", \"owned\"),\n personal_build: bind(\"spacemolt_facility\", \"personal_build\"),\n personal_decorate: bind(\"spacemolt_facility\", \"personal_decorate\"),\n personal_visit: bind(\"spacemolt_facility\", \"personal_visit\"),\n ranch_set_cull: bind(\"spacemolt_facility\", \"ranch_set_cull\"),\n ranch_status: bind(\"spacemolt_facility\", \"ranch_status\"),\n remove_faction: bind(\"spacemolt_facility\", \"remove_faction\"),\n remove_player: bind(\"spacemolt_facility\", \"remove_player\"),\n repair: bind(\"spacemolt_facility\", \"repair\"),\n set_access: bind(\"spacemolt_facility\", \"set_access\"),\n set_auto_buy_fuel: bind(\"spacemolt_facility\", \"set_auto_buy_fuel\"),\n set_build_policy: bind(\"spacemolt_facility\", \"set_build_policy\"),\n set_description: bind(\"spacemolt_facility\", \"set_description\"),\n set_market_fee: bind(\"spacemolt_facility\", \"set_market_fee\"),\n set_name: bind(\"spacemolt_facility\", \"set_name\"),\n set_output_price: bind(\"spacemolt_facility\", \"set_output_price\"),\n set_public: bind(\"spacemolt_facility\", \"set_public\"),\n set_refuel_price: bind(\"spacemolt_facility\", \"set_refuel_price\"),\n set_repair_price: bind(\"spacemolt_facility\", \"set_repair_price\"),\n set_service_access: bind(\"spacemolt_facility\", \"set_service_access\"),\n station_info: bindBare(\"spacemolt_facility\", \"station_info\"),\n station_set_name: bind(\"spacemolt_facility\", \"station_set_name\"),\n transfer: bind(\"spacemolt_facility\", \"transfer\"),\n types: bind(\"spacemolt_facility\", \"types\"),\n unban: bind(\"spacemolt_facility\", \"unban\"),\n upgrade: bind(\"spacemolt_facility\", \"upgrade\"),\n upgrades: bindBare(\"spacemolt_facility\", \"upgrades\"),\n },\n spacemolt_faction: {\n accept_ally: bind(\"spacemolt_faction\", \"accept_ally\"),\n accept_invite: bind(\"spacemolt_faction\", \"accept_invite\"),\n accept_peace: bind(\"spacemolt_faction\", \"accept_peace\"),\n cancel_mission: bind(\"spacemolt_faction\", \"cancel_mission\"),\n cancel_mobile_base_jump: bindBare(\"spacemolt_faction\", \"cancel_mobile_base_jump\"),\n create: bind(\"spacemolt_faction\", \"create\"),\n declare_war: bind(\"spacemolt_faction\", \"declare_war\"),\n decline_invite: bind(\"spacemolt_faction\", \"decline_invite\"),\n decommission_mobile_base: bindBare(\"spacemolt_faction\", \"decommission_mobile_base\"),\n delete_role: bind(\"spacemolt_faction\", \"delete_role\"),\n delete_room: bind(\"spacemolt_faction\", \"delete_room\"),\n garages: bindBare(\"spacemolt_faction\", \"garages\"),\n get_invites: bindBare(\"spacemolt_faction\", \"get_invites\"),\n get_mobile_base: bindBare(\"spacemolt_faction\", \"get_mobile_base\"),\n info: bind(\"spacemolt_faction\", \"info\"),\n invite: bind(\"spacemolt_faction\", \"invite\"),\n join: bind(\"spacemolt_faction\", \"join\"),\n jump_mobile_base: bind(\"spacemolt_faction\", \"jump_mobile_base\"),\n kick: bind(\"spacemolt_faction\", \"kick\"),\n leave: bindBare(\"spacemolt_faction\", \"leave\"),\n list: bind(\"spacemolt_faction\", \"list\"),\n list_missions: bindBare(\"spacemolt_faction\", \"list_missions\"),\n move_mobile_base: bind(\"spacemolt_faction\", \"move_mobile_base\"),\n prepay_tax: bind(\"spacemolt_faction\", \"prepay_tax\"),\n propose_ally: bind(\"spacemolt_faction\", \"propose_ally\"),\n propose_peace: bind(\"spacemolt_faction\", \"propose_peace\"),\n remove_ally: bind(\"spacemolt_faction\", \"remove_ally\"),\n remove_enemy: bind(\"spacemolt_faction\", \"remove_enemy\"),\n rooms: bindBare(\"spacemolt_faction\", \"rooms\"),\n set_enemy: bind(\"spacemolt_faction\", \"set_enemy\"),\n tax_estimate: bindBare(\"spacemolt_faction\", \"tax_estimate\"),\n visit_room: bind(\"spacemolt_faction\", \"visit_room\"),\n withdraw_invite: bind(\"spacemolt_faction\", \"withdraw_invite\"),\n },\n spacemolt_faction_admin: {\n create_role: bind(\"spacemolt_faction_admin\", \"create_role\"),\n edit: bind(\"spacemolt_faction_admin\", \"edit\"),\n edit_role: bind(\"spacemolt_faction_admin\", \"edit_role\"),\n post_mission: bind(\"spacemolt_faction_admin\", \"post_mission\"),\n promote: bind(\"spacemolt_faction_admin\", \"promote\"),\n write_room: bind(\"spacemolt_faction_admin\", \"write_room\"),\n },\n spacemolt_faction_commerce: {\n create_buy_order: bind(\"spacemolt_faction_commerce\", \"create_buy_order\"),\n create_sell_order: bind(\"spacemolt_faction_commerce\", \"create_sell_order\"),\n },\n spacemolt_fleet: {\n accept: bindBare(\"spacemolt_fleet\", \"accept\"),\n board: bind(\"spacemolt_fleet\", \"board\"),\n create: bindBare(\"spacemolt_fleet\", \"create\"),\n decline: bindBare(\"spacemolt_fleet\", \"decline\"),\n disband: bindBare(\"spacemolt_fleet\", \"disband\"),\n disembark: bindBare(\"spacemolt_fleet\", \"disembark\"),\n invite: bind(\"spacemolt_fleet\", \"invite\"),\n kick: bind(\"spacemolt_fleet\", \"kick\"),\n leave: bindBare(\"spacemolt_fleet\", \"leave\"),\n status: bindBare(\"spacemolt_fleet\", \"status\"),\n },\n spacemolt_intel: {\n espionage: bindBare(\"spacemolt_intel\", \"espionage\"),\n intel_status: bindBare(\"spacemolt_intel\", \"intel_status\"),\n query_intel: bind(\"spacemolt_intel\", \"query_intel\"),\n query_trade_intel: bind(\"spacemolt_intel\", \"query_trade_intel\"),\n scan_poi: bind(\"spacemolt_intel\", \"scan_poi\"),\n submit_intel: bind(\"spacemolt_intel\", \"submit_intel\"),\n submit_trade_intel: bind(\"spacemolt_intel\", \"submit_trade_intel\"),\n trade_intel_status: bindBare(\"spacemolt_intel\", \"trade_intel_status\"),\n },\n spacemolt_market: {\n analyze_market: bindBare(\"spacemolt_market\", \"analyze_market\"),\n cancel_order: bind(\"spacemolt_market\", \"cancel_order\"),\n create_buy_order: bind(\"spacemolt_market\", \"create_buy_order\"),\n create_sell_order: bind(\"spacemolt_market\", \"create_sell_order\"),\n estimate_purchase: bind(\"spacemolt_market\", \"estimate_purchase\"),\n modify_order: bind(\"spacemolt_market\", \"modify_order\"),\n subscribe_market: bindBare(\"spacemolt_market\", \"subscribe_market\"),\n unsubscribe_market: bindBare(\"spacemolt_market\", \"unsubscribe_market\"),\n view_market: bind(\"spacemolt_market\", \"view_market\"),\n view_orders: bind(\"spacemolt_market\", \"view_orders\"),\n },\n spacemolt_salvage: {\n claim_prize: bind(\"spacemolt_salvage\", \"claim_prize\"),\n insure: bindBare(\"spacemolt_salvage\", \"insure\"),\n loot: bind(\"spacemolt_salvage\", \"loot\"),\n policies: bindBare(\"spacemolt_salvage\", \"policies\"),\n quote: bindBare(\"spacemolt_salvage\", \"quote\"),\n release: bindBare(\"spacemolt_salvage\", \"release\"),\n scrap: bindBare(\"spacemolt_salvage\", \"scrap\"),\n sell: bindBare(\"spacemolt_salvage\", \"sell\"),\n service_prize: bind(\"spacemolt_salvage\", \"service_prize\"),\n set_home: bind(\"spacemolt_salvage\", \"set_home\"),\n tow: bind(\"spacemolt_salvage\", \"tow\"),\n wrecks: bindBare(\"spacemolt_salvage\", \"wrecks\"),\n },\n spacemolt_ship: {\n browse_ships: bind(\"spacemolt_ship\", \"browse_ships\"),\n buy_listed_ship: bind(\"spacemolt_ship\", \"buy_listed_ship\"),\n cancel_commission: bind(\"spacemolt_ship\", \"cancel_commission\"),\n cancel_ship_buy_order: bind(\"spacemolt_ship\", \"cancel_ship_buy_order\"),\n cancel_ship_listing: bind(\"spacemolt_ship\", \"cancel_ship_listing\"),\n commission_quote: bind(\"spacemolt_ship\", \"commission_quote\"),\n commission_ship: bind(\"spacemolt_ship\", \"commission_ship\"),\n commission_status: bind(\"spacemolt_ship\", \"commission_status\"),\n faction_personnel: bind(\"spacemolt_ship\", \"faction_personnel\"),\n list_ship_for_sale: bind(\"spacemolt_ship\", \"list_ship_for_sale\"),\n list_ships: bindBare(\"spacemolt_ship\", \"list_ships\"),\n place_ship_buy_order: bind(\"spacemolt_ship\", \"place_ship_buy_order\"),\n recruit_personnel: bind(\"spacemolt_ship\", \"recruit_personnel\"),\n refit_ship: bindBare(\"spacemolt_ship\", \"refit_ship\"),\n rename_ship: bind(\"spacemolt_ship\", \"rename_ship\"),\n scrap_ship: bind(\"spacemolt_ship\", \"scrap_ship\"),\n sell_ship_to_order: bind(\"spacemolt_ship\", \"sell_ship_to_order\"),\n supply_commission: bind(\"spacemolt_ship\", \"supply_commission\"),\n switch_ship: bind(\"spacemolt_ship\", \"switch_ship\"),\n transfer_personnel: bind(\"spacemolt_ship\", \"transfer_personnel\"),\n treat_personnel: bind(\"spacemolt_ship\", \"treat_personnel\"),\n view_ship_buy_orders: bindBare(\"spacemolt_ship\", \"view_ship_buy_orders\"),\n },\n spacemolt_shipping: {\n accept: bind(\"spacemolt_shipping\", \"accept\"),\n active: bindBare(\"spacemolt_shipping\", \"active\"),\n cancel: bind(\"spacemolt_shipping\", \"cancel\"),\n deliver: bind(\"spacemolt_shipping\", \"deliver\"),\n get: bind(\"spacemolt_shipping\", \"get\"),\n list: bind(\"spacemolt_shipping\", \"list\"),\n pay_debt: bind(\"spacemolt_shipping\", \"pay_debt\"),\n post: bind(\"spacemolt_shipping\", \"post\"),\n profile: bind(\"spacemolt_shipping\", \"profile\"),\n quote: bind(\"spacemolt_shipping\", \"quote\"),\n return: bind(\"spacemolt_shipping\", \"return\"),\n track: bind(\"spacemolt_shipping\", \"track\"),\n },\n spacemolt_social: {\n captains_log_add: bind(\"spacemolt_social\", \"captains_log_add\"),\n captains_log_delete: bind(\"spacemolt_social\", \"captains_log_delete\"),\n captains_log_get: bind(\"spacemolt_social\", \"captains_log_get\"),\n captains_log_list: bind(\"spacemolt_social\", \"captains_log_list\"),\n chat: bind(\"spacemolt_social\", \"chat\"),\n create_note: bind(\"spacemolt_social\", \"create_note\"),\n delete_note: bind(\"spacemolt_social\", \"delete_note\"),\n forum_create_thread: bind(\"spacemolt_social\", \"forum_create_thread\"),\n forum_delete_reply: bind(\"spacemolt_social\", \"forum_delete_reply\"),\n forum_delete_thread: bind(\"spacemolt_social\", \"forum_delete_thread\"),\n forum_get_thread: bind(\"spacemolt_social\", \"forum_get_thread\"),\n forum_list: bind(\"spacemolt_social\", \"forum_list\"),\n forum_reply: bind(\"spacemolt_social\", \"forum_reply\"),\n forum_upvote: bind(\"spacemolt_social\", \"forum_upvote\"),\n get_action_log: bind(\"spacemolt_social\", \"get_action_log\"),\n get_chat_history: bind(\"spacemolt_social\", \"get_chat_history\"),\n get_notes: bind(\"spacemolt_social\", \"get_notes\"),\n get_notification_settings: bindBare(\"spacemolt_social\", \"get_notification_settings\"),\n mute_notifications: bind(\"spacemolt_social\", \"mute_notifications\"),\n petition: bind(\"spacemolt_social\", \"petition\"),\n read_note: bind(\"spacemolt_social\", \"read_note\"),\n set_colors: bind(\"spacemolt_social\", \"set_colors\"),\n set_status: bind(\"spacemolt_social\", \"set_status\"),\n unmute_notifications: bind(\"spacemolt_social\", \"unmute_notifications\"),\n write_note: bind(\"spacemolt_social\", \"write_note\"),\n },\n spacemolt_storage: {\n deposit: bind(\"spacemolt_storage\", \"deposit\"),\n jettison: bind(\"spacemolt_storage\", \"jettison\"),\n loot: bind(\"spacemolt_storage\", \"loot\"),\n view: bind(\"spacemolt_storage\", \"view\"),\n withdraw: bind(\"spacemolt_storage\", \"withdraw\"),\n },\n spacemolt_transfer: {\n get_trades: bindBare(\"spacemolt_transfer\", \"get_trades\"),\n trade_accept: bind(\"spacemolt_transfer\", \"trade_accept\"),\n trade_cancel: bind(\"spacemolt_transfer\", \"trade_cancel\"),\n trade_decline: bind(\"spacemolt_transfer\", \"trade_decline\"),\n trade_offer: bind(\"spacemolt_transfer\", \"trade_offer\"),\n },\n };\n}\n",
|
|
10
|
+
"/**\n * Clerk-backed multi-account source.\n *\n * Authenticates against the Clerk-gated gameserver endpoints to enumerate the\n * player accounts the Clerk user owns and to mint short-lived, single-use\n * WebSocket login tokens for them. This lets one client manage every account you\n * own without storing per-account game passwords.\n *\n * Two ways to authorize the requests:\n * - `apiKey` — a Clerk **API key** (the headless-client credential —\n * generate one from the website; see docs/live-testing.md), sent as\n * `Authorization: Bearer <key>`.\n * - `headers` — custom headers, or an async factory resolved fresh per\n * request, for callers whose credential isn't a static key: a browser\n * Clerk session's short-lived `getToken()` JWT, or a dev-mode\n * `X-Dev-Clerk-ID` header.\n *\n * The authorized endpoints:\n * - `GET /api/registration-code` → the owned players list + registration code.\n * - `POST /api/player/{id}/ws-token` → a single-use WS login token.\n *\n * ws-tokens are valid ~5 minutes and consumed on connect, so mint one per\n * (re)connect rather than caching — the durable credential is the Clerk key\n * (or session).\n *\n * Uses only web-standard `fetch`/`Headers`, so it stays browser-safe.\n */\n\nimport { isRecord, requireRecord } from '../validation.ts';\n\n/** A player account owned by the authenticated Clerk user. */\nexport interface ClerkPlayer {\n id: string;\n username: string;\n empire: string;\n /** Hidden in the player's dashboard; still connectable. */\n hidden: boolean;\n}\n\n/** The full `/api/registration-code` response. */\nexport interface ClerkRegistration {\n /** One-time code that links a new `register` to the Clerk user. */\n registrationCode: string;\n players: ClerkPlayer[];\n}\n\n// Whatever this environment's `Headers` constructor accepts (DOM lib,\n// @types/node, bun-types), so the emitted .d.ts doesn't need the DOM lib. Under\n// the DOM lib this is exactly the global `HeadersInit`.\ntype HeadersCtorInit = NonNullable<ConstructorParameters<typeof Headers>[0]>;\n\n/**\n * Headers that authorize calls to the Clerk-gated gameserver endpoints — an\n * alternative to `apiKey` for callers whose credential isn't a static key.\n * A factory is resolved fresh on every request, so short-lived tokens (e.g. a\n * browser Clerk session's `getToken()` JWT) stay valid across reconnects.\n */\nexport type ClerkAuthHeaders = HeadersCtorInit | (() => HeadersCtorInit | Promise<HeadersCtorInit>);\n\n/** How Clerk-gated requests are authorized. Provide `apiKey`, `headers`, or both. */\nexport interface ClerkAuth {\n /** Clerk API key, sent as `Authorization: Bearer`. Keep it secret. */\n apiKey?: string;\n /** Custom auth headers (or an async factory). Win over `apiKey` on conflicts. */\n headers?: ClerkAuthHeaders;\n}\n\nasync function resolveAuthHeaders(auth: ClerkAuth): Promise<Headers> {\n if (auth.apiKey === undefined && auth.headers === undefined) {\n throw new Error('Clerk auth requires an `apiKey` or `headers`');\n }\n const headers = new Headers(auth.apiKey === undefined ? undefined : { authorization: `Bearer ${auth.apiKey}` });\n const extra = typeof auth.headers === 'function' ? await auth.headers() : auth.headers;\n new Headers(extra).forEach((value, key) => {\n headers.set(key, value);\n });\n return headers;\n}\n\nasync function clerkFetch(fetchImpl: typeof fetch, url: string, auth: ClerkAuth, init?: RequestInit): Promise<unknown> {\n const headers = new Headers({ accept: 'application/json' });\n (await resolveAuthHeaders(auth)).forEach((value, key) => {\n headers.set(key, value);\n });\n new Headers(init?.headers).forEach((value, key) => {\n headers.set(key, value);\n });\n const res = await fetchImpl(url, { ...init, headers });\n if (!res.ok) {\n const body = await res.text().catch(() => '');\n throw new Error(`${init?.method ?? 'GET'} ${url} -> ${res.status} ${res.statusText}${body ? `: ${body}` : ''}`);\n }\n return res.json();\n}\n\n/**\n * Mint a single-use WebSocket login token for one owned player. The token is\n * valid ~5 minutes and consumed on connect, so call this once per (re)connect.\n */\nexport async function mintWsToken(\n opts: {\n httpBaseUrl: string;\n playerId: string;\n fetchImpl?: typeof fetch;\n } & ClerkAuth,\n): Promise<string> {\n const base = opts.httpBaseUrl.replace(/\\/$/, '');\n const data = requireRecord(\n await clerkFetch(\n opts.fetchImpl ?? fetch,\n `${base}/api/player/${encodeURIComponent(opts.playerId)}/ws-token`,\n opts,\n {\n method: 'POST',\n },\n ),\n 'ws-token response',\n );\n if (typeof data.token !== 'string' || !data.token) throw new Error('ws-token response had no token');\n return data.token;\n}\n\nexport interface ClerkSourceOptions extends ClerkAuth {\n /** HTTP origin of the gameserver, e.g. `https://game.spacemolt.com`. */\n httpBaseUrl: string;\n /** Inject a `fetch` implementation (tests, custom runtimes). */\n fetchImpl?: typeof fetch;\n}\n\nexport class ClerkSource {\n private readonly fetchImpl: typeof fetch;\n /** HTTP origin of the gameserver (trailing slash stripped). */\n readonly httpBaseUrl: string;\n\n constructor(private readonly opts: ClerkSourceOptions) {\n if (opts.apiKey === undefined && opts.headers === undefined) {\n throw new Error('ClerkSource requires an `apiKey` or `headers`');\n }\n this.fetchImpl = opts.fetchImpl ?? fetch;\n this.httpBaseUrl = opts.httpBaseUrl.replace(/\\/$/, '');\n }\n\n /** The Clerk API key this source authenticates with, when one was given. */\n get apiKey(): string | undefined {\n return this.opts.apiKey;\n }\n\n /** Fetch the owned players list plus the registration code for creating new players. */\n async fetchRegistration(): Promise<ClerkRegistration> {\n const data = requireRecord(\n await clerkFetch(this.fetchImpl, `${this.httpBaseUrl}/api/registration-code`, this.opts),\n 'registration-code response',\n );\n const players = Array.isArray(data.players)\n ? data.players.filter(\n (player): player is ClerkPlayer =>\n isRecord(player) &&\n typeof player.id === 'string' &&\n typeof player.username === 'string' &&\n typeof player.empire === 'string' &&\n typeof player.hidden === 'boolean',\n )\n : [];\n return {\n registrationCode: typeof data.registration_code === 'string' ? data.registration_code : '',\n players,\n };\n }\n\n /** List the player accounts the authenticated Clerk user owns. */\n async listPlayers(): Promise<ClerkPlayer[]> {\n return (await this.fetchRegistration()).players;\n }\n\n /** Mint a single-use WS login token for one owned player. */\n mintWsToken(playerId: string): Promise<string> {\n return mintWsToken({\n httpBaseUrl: this.httpBaseUrl,\n apiKey: this.opts.apiKey,\n headers: this.opts.headers,\n playerId,\n fetchImpl: this.fetchImpl,\n });\n }\n}\n",
|
|
11
|
+
"/** Error types surfaced by the library. */\n\nimport type { ActionErrorFrame, ErrorFrame } from './protocol.ts';\n\n/**\n * A server-reported error. Carries the machine-readable `code` from the\n * server's error/action_error frame plus any structured details.\n */\nexport class SpacemoltError extends Error {\n readonly code: string;\n readonly details?: Record<string, unknown>;\n readonly requestId?: string;\n /** Set when the failure came from a two-phase mutation outcome. */\n readonly command?: string;\n /** Game tick of the failure, for action_error outcomes. */\n readonly tick?: number;\n /** On `action_pending` errors: the mutation already queued. */\n readonly pendingCommand?: string;\n\n constructor(\n code: string,\n message: string,\n opts: {\n details?: Record<string, unknown>;\n requestId?: string;\n command?: string;\n tick?: number;\n pendingCommand?: string;\n } = {},\n ) {\n super(message);\n this.name = 'SpacemoltError';\n this.code = code;\n this.details = opts.details;\n this.requestId = opts.requestId;\n this.command = opts.command;\n this.tick = opts.tick;\n this.pendingCommand = opts.pendingCommand;\n }\n}\n\nexport function errorFromFrame(frame: ErrorFrame): SpacemoltError {\n return new SpacemoltError(frame.payload.code, frame.payload.message, {\n details: frame.payload.details,\n requestId: frame.request_id,\n pendingCommand: frame.payload.pending_command,\n });\n}\n\nexport function errorFromActionFrame(frame: ActionErrorFrame): SpacemoltError {\n return new SpacemoltError(frame.payload.code, frame.payload.message, {\n details: frame.payload.details,\n requestId: frame.request_id,\n command: frame.payload.command,\n tick: frame.payload.tick,\n });\n}\n\n/**\n * Raised by a bulk/live HTTP data fetch (catalog, map, stations, mobile-base)\n * that didn't come back ok — after retries, for a retryable status. Message\n * text matches the old bare-`Error` format (`GET <url> -> <status> <text>`).\n */\nexport class HttpError extends Error {\n readonly status: number;\n readonly url: string;\n /** How many requests were made in total, including the one that finally failed. */\n readonly attempts: number;\n /** The server's `Retry-After` on the failing response, parsed to ms, if any. */\n readonly retryAfterMs?: number;\n\n constructor(message: string, opts: { status: number; url: string; attempts: number; retryAfterMs?: number }) {\n super(message);\n this.name = 'HttpError';\n this.status = opts.status;\n this.url = opts.url;\n this.attempts = opts.attempts;\n this.retryAfterMs = opts.retryAfterMs;\n }\n}\n\n/** Raised against every in-flight request when the socket closes. */\nexport class ConnectionClosedError extends Error {\n readonly code?: number;\n readonly reason?: string;\n constructor(message = 'WebSocket connection closed', code?: number, reason?: string) {\n super(message);\n this.name = 'ConnectionClosedError';\n this.code = code;\n this.reason = reason;\n }\n}\n\n/**\n * Custom WS close codes the server documents (as of gameserver v0.471.4):\n * `4001` session_replaced (another connection took your slot — don't\n * reconnect, you'd just fight it), `4002` auth_timeout (connected but didn't\n * authenticate in time), `4003` connection_rate_limited (exceeded the\n * 100/min-per-IP WS-connection cap — the close reason carries a\n * `retry_after=<seconds>` hint; honor it before reconnecting).\n */\nexport const CLOSE_CODE = {\n SESSION_REPLACED: 4001,\n AUTH_TIMEOUT: 4002,\n CONNECTION_RATE_LIMITED: 4003,\n} as const;\n\n/**\n * Parses the `retry_after=<seconds>` hint the server includes on a `4003`\n * (connection_rate_limited) close reason. Returns the wait time in\n * milliseconds, or `undefined` if `err` isn't a rate-limited close or carries\n * no parseable hint.\n */\nexport function retryAfterMsFromClose(err: unknown): number | undefined {\n if (!(err instanceof ConnectionClosedError) || err.code !== CLOSE_CODE.CONNECTION_RATE_LIMITED) return undefined;\n const match = err.reason?.match(/retry_after=(\\d+)/);\n return match ? Number(match[1]) * 1000 : undefined;\n}\n",
|
|
12
|
+
"/**\n * Typed event dispatch for server push frames.\n *\n * Callbacks (`on`/`onAny`) and async iterators (`stream`/`anyStream`) are both\n * supported. The Account facade adds the per-msg_type payload typing on top of\n * this (loosely-typed) core.\n */\n\nimport type { RawFrame } from '../protocol.ts';\n\n/**\n * Fan an event out to every registered listener. A throwing listener is warned\n * and skipped — a listener is told what already happened, so it must never\n * break the caller (frame routing, mutation correlation, a connect or reconnect\n * in progress) or starve the listeners after it.\n */\nexport function notifyListeners<A extends unknown[]>(\n listeners: ReadonlySet<(...args: A) => void>,\n label: string,\n ...args: A\n): void {\n for (const listener of listeners) {\n try {\n listener(...args);\n } catch (err) {\n console.warn(`[spacemolt] ${label} listener threw: ${err}`);\n }\n }\n}\n\ntype PayloadHandler = (payload: unknown) => void;\ntype FrameHandler = (frame: RawFrame) => void;\n\n/**\n * An async iterator over events of one kind, with internal buffering so a slow\n * consumer doesn't drop frames. Breaking out of a `for await` calls `return()`,\n * which unsubscribes via the `onClose` callback.\n */\nexport class EventStream<T> implements AsyncIterableIterator<T> {\n private readonly buffer: Array<{ value: T }> = [];\n private readonly waiting: Array<(r: IteratorResult<T>) => void> = [];\n private ended = false;\n\n constructor(private readonly onClose: () => void) {}\n\n /** Internal: deliver a value to the consumer or buffer it. */\n push(value: T): void {\n if (this.ended) return;\n const next = this.waiting.shift();\n if (next) next({ value, done: false });\n else this.buffer.push({ value });\n }\n\n /** Internal: end the stream (e.g. on disconnect). */\n end(): void {\n if (this.ended) return;\n this.ended = true;\n for (const w of this.waiting) w({ value: undefined, done: true });\n this.waiting.length = 0;\n }\n\n next(): Promise<IteratorResult<T>> {\n const buffered = this.buffer.shift();\n if (buffered) return Promise.resolve({ value: buffered.value, done: false });\n if (this.ended) return Promise.resolve({ value: undefined, done: true });\n return new Promise((resolve) => this.waiting.push(resolve));\n }\n\n return(): Promise<IteratorResult<T>> {\n this.end();\n this.onClose();\n return Promise.resolve({ value: undefined, done: true });\n }\n\n [Symbol.asyncIterator](): AsyncIterableIterator<T> {\n return this;\n }\n}\n\nexport class TypedEmitter {\n private readonly handlers = new Map<string, Set<PayloadHandler>>();\n private readonly anyHandlers = new Set<FrameHandler>();\n private readonly streams = new Map<string, Set<EventStream<unknown>>>();\n private readonly anyStreams = new Set<EventStream<RawFrame>>();\n\n /** Listen for one msg_type. Returns an unsubscribe function. */\n on<T = unknown>(type: string, handler: (payload: T) => void): () => void {\n let set = this.handlers.get(type);\n if (!set) {\n set = new Set();\n this.handlers.set(type, set);\n }\n const wrapped: PayloadHandler = (payload) => handler(payload as T);\n set.add(wrapped);\n return () => set.delete(wrapped);\n }\n\n /** Listen for every push frame. Returns an unsubscribe function. */\n onAny(handler: FrameHandler): () => void {\n this.anyHandlers.add(handler);\n return () => this.anyHandlers.delete(handler);\n }\n\n /** Async-iterate one msg_type's payloads. */\n stream(type: string): EventStream<unknown> {\n let set = this.streams.get(type);\n if (!set) {\n set = new Set();\n this.streams.set(type, set);\n }\n const localSet = set;\n const s = new EventStream<unknown>(() => localSet.delete(s));\n localSet.add(s);\n return s;\n }\n\n /** Async-iterate every push frame. */\n anyStream(): EventStream<RawFrame> {\n const s = new EventStream<RawFrame>(() => this.anyStreams.delete(s));\n this.anyStreams.add(s);\n return s;\n }\n\n /**\n * Dispatch a push frame to all matching listeners and streams. Each\n * callback is isolated with try/catch — this is the single funnel every\n * `account.on(type, ...)`/`onAny` consumer runs through, invoked directly\n * from `routeFrame`'s `default:` case with nothing above it to contain a\n * throw. Without isolation, one listener throwing would skip every other\n * listener/stream for this frame and propagate out through `routeFrame`\n * into the WebSocket's `message` event handler, which has no try/catch of\n * its own either.\n */\n emit(frame: RawFrame): void {\n const set = this.handlers.get(frame.type);\n if (set) for (const h of [...set]) this.safeCall(() => h(frame.payload));\n for (const h of [...this.anyHandlers]) this.safeCall(() => h(frame));\n const streams = this.streams.get(frame.type);\n if (streams) for (const s of [...streams]) this.safeCall(() => s.push(frame.payload));\n for (const s of [...this.anyStreams]) this.safeCall(() => s.push(frame));\n }\n\n private safeCall(fn: () => void): void {\n try {\n fn();\n } catch (err) {\n console.warn(`[spacemolt] notification listener threw: ${err}`);\n }\n }\n\n /** End every open stream (on disconnect). Callback listeners are kept. */\n closeStreams(): void {\n for (const set of this.streams.values()) for (const s of set) s.end();\n for (const s of this.anyStreams) s.end();\n }\n}\n",
|
|
13
|
+
"/**\n * Local cache of subscribed station order books.\n *\n * Seeded from the `subscribe_market` baseline snapshot and kept current by\n * merging `market_update` pushes (which carry only the items that changed).\n * Keyed by `base_id`; items keyed by `item_id`.\n */\n\nimport type { NotificationMarketUpdate, SubscribeMarketResponse } from '../generated/openapi/types.gen.ts';\n\nexport type MarketItem = NotificationMarketUpdate['items'][number];\n\nexport interface MarketBook {\n base_id: string;\n base_name?: string;\n /** Tick of the most recent update (0 from the initial baseline). */\n tick: number;\n /** Order book per item_id. */\n items: Map<string, MarketItem>;\n}\n\nexport class MarketCache {\n private readonly books = new Map<string, MarketBook>();\n\n /** Seed (or replace) a base's book from a subscribe_market baseline. */\n seed(snapshot: SubscribeMarketResponse): string | undefined {\n if (!snapshot.base_id) return undefined;\n const items = new Map<string, MarketItem>();\n for (const item of snapshot.items ?? []) {\n if (item.item_id) items.set(item.item_id, item);\n }\n this.books.set(snapshot.base_id, {\n base_id: snapshot.base_id,\n base_name: snapshot.base_name,\n tick: 0,\n items,\n });\n return snapshot.base_id;\n }\n\n /** Merge a market_update push (changed items only) into the book. */\n applyUpdate(update: NotificationMarketUpdate): void {\n let book = this.books.get(update.base_id);\n if (!book) {\n book = { base_id: update.base_id, base_name: update.base_name, tick: update.tick, items: new Map() };\n this.books.set(update.base_id, book);\n }\n book.tick = update.tick;\n if (update.base_name) book.base_name = update.base_name;\n for (const item of update.items) book.items.set(item.item_id, item);\n }\n\n /** The cached book for a base, if subscribed. */\n book(baseId: string): MarketBook | undefined {\n return this.books.get(baseId);\n }\n\n /** All base_ids with a cached book. */\n bases(): string[] {\n return [...this.books.keys()];\n }\n\n /** Drop a base's cached book (e.g. on unsubscribe). */\n drop(baseId: string): void {\n this.books.delete(baseId);\n }\n}\n",
|
|
14
|
+
"/**\n * Local cache of the subscribed observation watch (current POI).\n *\n * Seeded from the `subscribe_observation` baseline and kept current by merging\n * `observation_update` pushes: `*_changed` arrays upsert entities (keyed by\n * their own id), `*_departed` arrays (id strings) remove them, and the\n * cloaked-contact / signature hints are tracked alongside.\n *\n * Not a players-only feed: the baseline and every update also carry the\n * pirate, empire-NPC, wildlife, intact-prize and arena-NPC presence at the\n * watched POI, each with the same changed/departed delta shape as players —\n * all six of `get_nearby`'s classes. The player list matches `get_nearby`:\n * above 10 players, offline ones collapse into `offlineCollapsed`.\n *\n * Nothing here is system-wide except `shipCounts`: with a working ship\n * scanner, the per-POI ship count for every charted POI in the system. The\n * server sends the full map whenever any count changes, so it replaces the\n * previous map rather than merging.\n */\n\nimport type {\n ArenaNpcInfo,\n CreatureInfo,\n EmpireNpcInfo,\n NotificationObservationUpdate,\n PirateInfo,\n PrizeInfo,\n SubscribeObservationResponse,\n} from '../generated/openapi/types.gen.ts';\n\nexport type ObservedPlayer = NonNullable<NotificationObservationUpdate['nearby_changed']>[number];\nexport type CloakedContact = NonNullable<NotificationObservationUpdate['cloaked_resolved']>[number];\n\nexport interface ObservationView {\n poi_id?: string;\n system_id?: string;\n /** Tick of the most recent update (0 from the initial baseline). */\n tick: number;\n /** Uncloaked players at the watched POI, keyed by player_id. */\n nearby: Map<string, ObservedPlayer>;\n /** Pirate NPCs at the watched POI, keyed by pirate_id. */\n pirates: Map<string, PirateInfo>;\n /** Empire NPCs at the watched POI, keyed by npc_id. */\n empireNpcs: Map<string, EmpireNpcInfo>;\n /** Wildlife at the watched POI, keyed by creature_id. */\n creatures: Map<string, CreatureInfo>;\n /** Intact captured ships at the watched POI, keyed by prize_id. */\n prizes: Map<string, PrizeInfo>;\n /** Arena challenge enemies at the watched POI, keyed by npc_id. */\n arenaNpcs: Map<string, ArenaNpcInfo>;\n /** Offline players at the watched POI not listed in `nearby` (0 when all are listed). */\n offlineCollapsed: number;\n /** Ship scanner counts per charted POI in the system, keyed by POI ID. Empty without a working ship scanner. */\n shipCounts: Map<string, number>;\n /** Cloaked contacts resolved by an active sensor sweep, keyed by target_id. */\n cloaked: Map<string, CloakedContact>;\n /** A faint cloaked-ship signature is present at the watched POI. */\n unknownSignature: boolean;\n /** Whether an active sensor sweep is running. */\n activeScan: boolean;\n}\n\nfunction indexBy<T>(items: readonly T[] | undefined, key: (item: T) => string | undefined): Map<string, T> {\n const map = new Map<string, T>();\n for (const item of items ?? []) {\n const k = key(item);\n if (k) map.set(k, item);\n }\n return map;\n}\n\nfunction merge<T>(\n map: Map<string, T>,\n changed: readonly T[] | undefined,\n departed: readonly string[] | undefined,\n key: (item: T) => string | undefined,\n): void {\n for (const item of changed ?? []) {\n const k = key(item);\n if (k) map.set(k, item);\n }\n for (const id of departed ?? []) map.delete(id);\n}\n\nexport class ObservationCache {\n private view: ObservationView | null = null;\n\n /** Seed (or replace) the watch from a subscribe_observation baseline. */\n seed(snapshot: SubscribeObservationResponse): ObservationView {\n this.view = {\n poi_id: snapshot.poi_id,\n system_id: snapshot.system_id,\n tick: 0,\n nearby: indexBy(snapshot.nearby, (p) => p.player_id),\n pirates: indexBy(snapshot.pirates, (p) => p.pirate_id),\n empireNpcs: indexBy(snapshot.empire_npcs, (n) => n.npc_id),\n creatures: indexBy(snapshot.creatures, (c) => c.creature_id),\n prizes: indexBy(snapshot.prizes, (p) => p.prize_id),\n arenaNpcs: indexBy(snapshot.arena_npcs, (n) => n.npc_id),\n offlineCollapsed: snapshot.offline_collapsed ?? 0,\n shipCounts: new Map(Object.entries(snapshot.ship_counts ?? {})),\n cloaked: indexBy(snapshot.cloaked_contacts, (c) => c.target_id),\n unknownSignature: snapshot.unknown_signature ?? false,\n activeScan: snapshot.active_scan ?? false,\n };\n return this.view;\n }\n\n /** Merge an observation_update push into the watch. */\n applyUpdate(update: NotificationObservationUpdate): void {\n if (!this.view) {\n this.view = {\n poi_id: update.poi_id,\n system_id: update.system_id,\n tick: update.tick,\n nearby: new Map(),\n pirates: new Map(),\n empireNpcs: new Map(),\n creatures: new Map(),\n prizes: new Map(),\n arenaNpcs: new Map(),\n offlineCollapsed: 0,\n shipCounts: new Map(),\n cloaked: new Map(),\n unknownSignature: false,\n activeScan: false,\n };\n }\n const v = this.view;\n v.tick = update.tick;\n merge(v.nearby, update.nearby_changed, update.nearby_departed, (p) => p.player_id);\n merge(v.pirates, update.pirates_changed, update.pirates_departed, (p) => p.pirate_id);\n merge(v.empireNpcs, update.empire_npcs_changed, update.empire_npcs_departed, (n) => n.npc_id);\n merge(v.creatures, update.creatures_changed, update.creatures_departed, (c) => c.creature_id);\n merge(v.prizes, update.prizes_changed, update.prizes_departed, (p) => p.prize_id);\n merge(v.arenaNpcs, update.arena_npcs_changed, update.arena_npcs_departed, (n) => n.npc_id);\n merge(v.cloaked, update.cloaked_resolved, update.cloaked_lost, (c) => c.target_id);\n if (update.offline_collapsed !== undefined) v.offlineCollapsed = update.offline_collapsed;\n if (update.ship_counts !== undefined) v.shipCounts = new Map(Object.entries(update.ship_counts));\n if (update.unknown_signature !== undefined) v.unknownSignature = update.unknown_signature;\n if (update.active_scan !== undefined) v.activeScan = update.active_scan;\n }\n\n /** The current watch view, if subscribed. */\n current(): ObservationView | null {\n return this.view;\n }\n\n /** Clear the watch (e.g. on unsubscribe). */\n clear(): void {\n this.view = null;\n }\n}\n",
|
|
15
|
+
"/**\n * Adds random jitter to a retry delay, so multiple callers retrying together\n * (e.g. a fleet of accounts sharing a per-IP rate limit) don't all wake up\n * and retry in the same instant. Extra is uniform in `[0, max(25% of base,\n * 250ms))`. Shared by the WebSocket rate-limit retry (`account.ts`) and the\n * HTTP retry (`data/http.ts`).\n */\nexport function jitteredDelayMs(baseMs: number): number {\n return baseMs + Math.random() * Math.max(baseMs * 0.25, 250);\n}\n",
|
|
16
|
+
"/**\n * Per-account local cache of the nine game-state sections.\n *\n * Seeded canonically from a full `V2GameState` snapshot (the `get_status`\n * query returns exactly this shape) and kept current by applying the section\n * deltas carried on every `action_result`. Each present delta section is a\n * complete replacement for that section — absent sections are left untouched\n * (the server's \"absent means unchanged\" contract).\n */\n\nimport type { GameState, StateDelta, StateSection } from '../protocol.ts';\nimport { STATE_SECTIONS } from '../protocol.ts';\nimport type { V2GameState } from '../generated/openapi/types.gen.ts';\n\nfunction copySection<S extends StateSection>(target: GameState, source: GameState, section: S): boolean {\n const value = source[section];\n if (value === undefined) return false;\n target[section] = value;\n return true;\n}\n\nexport class StateCache {\n private state: GameState = {};\n\n /** Replace the cache from a canonical full snapshot (e.g. `get_status`). */\n seed(snapshot: V2GameState): StateSection[] {\n const next: GameState = {};\n const changed: StateSection[] = [];\n for (const section of STATE_SECTIONS) {\n if (copySection(next, snapshot, section)) changed.push(section);\n }\n this.state = next;\n return changed;\n }\n\n /**\n * Apply a delta, replacing each present section. Returns the sections that\n * changed (in `STATE_SECTIONS` order).\n */\n applyDelta(delta: StateDelta): StateSection[] {\n const changed: StateSection[] = [];\n for (const section of STATE_SECTIONS) {\n if (copySection(this.state, delta, section)) changed.push(section);\n }\n return changed;\n }\n\n /**\n * Merge a partial patch into a single section in place, preserving that\n * section's other fields — unlike `applyDelta`/`seed`, which always\n * replace a section wholesale. For bridging data from outside the normal\n * action_result delta flow (e.g. observation pushes patching\n * `location`'s nearby-player fields) into the corresponding section.\n * No-ops (returns `[]`) if the section hasn't been seeded yet, since a\n * partial patch can't stand in for a section's required fields.\n */\n patchSection<S extends StateSection>(section: S, patch: Partial<GameState[S]>): StateSection[] {\n const current = this.state[section];\n if (current === undefined) return [];\n this.state[section] = { ...current, ...patch };\n return [section];\n }\n\n /** Live view of the cached state. Treat as read-only — do not mutate. */\n snapshot(): Readonly<GameState> {\n return this.state;\n }\n\n get player(): GameState['player'] {\n return this.state.player;\n }\n get ship(): GameState['ship'] {\n return this.state.ship;\n }\n get location(): GameState['location'] {\n return this.state.location;\n }\n get cargo(): GameState['cargo'] {\n return this.state.cargo;\n }\n get modules(): GameState['modules'] {\n return this.state.modules;\n }\n get missions(): GameState['missions'] {\n return this.state.missions;\n }\n get skills(): GameState['skills'] {\n return this.state.skills;\n }\n /**\n * Active intact-ship recovery operations assigned to this player, including\n * prizes in transit or stalled outside the current POI. Refreshed by the\n * deltas of the player's own prize commands (`claim_prize`, `service_prize`)\n * and by `refresh()` — the `prize_update`/`ship_captured` pushes do not carry\n * a delta, so this is not a live feed.\n */\n get prizeRecoveries(): GameState['prize_recoveries'] {\n return this.state.prize_recoveries;\n }\n /** True when a tick-deferred action is queued for this account. */\n get hasPendingAction(): boolean {\n return this.state.queue?.has_pending ?? false;\n }\n get credits(): number | undefined {\n return this.state.player?.credits;\n }\n}\n",
|
|
17
|
+
"/**\n * Correlates server response frames to in-flight requests by `request_id`.\n *\n * Two request shapes:\n * - query resolves on the synchronous `result` frame.\n * - mutation is usually two-phase: a `result` ack (pending marker set)\n * arrives first, then — possibly many ticks later — an\n * `action_result` (resolve) or `action_error` (reject). A\n * synchronous validation failure short-circuits to an `error`\n * frame (reject).\n * But some mutation-classified actions resolve synchronously in\n * a single `result` frame with no pending marker anywhere —\n * nothing was queued, so no `action_result` is ever coming (e.g.\n * `craft`/`recycle` with `dry_run: true`, which explicitly\n * queues nothing). That `result` frame is treated as the final\n * outcome instead of an ack, or the request would wait forever\n * for an `action_result` the server was never going to send.\n *\n * The pending marker's location in structuredContent is NOT consistent\n * across actions — verified live against the real server: `scan`/`undock`\n * carry it at the top level (`{pending: true, command, message}`), while\n * `jump` nests it under `details` (`{details: {pending: true, command,\n * message}, location: {...}, queue: {...}}`). Checking only the top level\n * (an earlier version of this file did) misreads a real jump ack as the\n * \"nothing queued\" case, resolving it immediately instead of waiting for the\n * real outcome — which released the next queued mutation before the\n * previous one actually executed, and the server correctly rejected it with\n * `action_pending`, collapsing a whole multi-hop route in milliseconds.\n *\n * Frames may interleave arbitrarily on the wire, so nothing here assumes\n * ordering beyond per-request_id sequencing.\n */\n\nimport type { MutationAck, MutationResult, QueryResult, RawFrame } from '../protocol.ts';\nimport { isActionErrorFrame, isActionResultFrame, isErrorFrame, isResultFrame } from '../protocol.ts';\nimport { type ConnectionClosedError, errorFromActionFrame, errorFromFrame, SpacemoltError } from '../errors.ts';\nimport { isRecord } from '../validation.ts';\n\nexport type RequestKind = 'query' | 'mutation';\n\n/**\n * Extracts the pending ack from a mutation's `result` frame structuredContent,\n * checking both known locations the flag has been observed in (see the\n * module doc comment). Returns undefined if neither location flags pending —\n * meaning this frame is the final outcome, not an ack. The server's\n * `auto_docked`/`auto_undocked` flags are carried through when present, so a\n * caller learns at ack time that the server moved its ship.\n */\nfunction extractPendingAck(structured: Record<string, unknown> | undefined): MutationAck | undefined {\n if (!structured) return undefined;\n const details = structured.details;\n const source =\n structured.pending === true ? structured : isRecord(details) && details.pending === true ? details : undefined;\n if (!source) return undefined;\n return {\n pending: true,\n command: String(source.command ?? ''),\n message: String(source.message ?? ''),\n ...(typeof source.auto_docked === 'boolean' && { auto_docked: source.auto_docked }),\n ...(typeof source.auto_undocked === 'boolean' && { auto_undocked: source.auto_undocked }),\n };\n}\n\ninterface PendingBase {\n reject: (err: Error) => void;\n}\ninterface PendingQuery extends PendingBase {\n kind: 'query';\n resolve: (value: QueryResult) => void;\n}\ninterface PendingMutation extends PendingBase {\n kind: 'mutation';\n resolve: (value: MutationResult) => void;\n ack?: MutationAck;\n /** Optional hook fired when the pending ack arrives, before the outcome. */\n onAck?: (ack: MutationAck) => void;\n}\ntype Pending = PendingQuery | PendingMutation;\n\nexport class Correlator {\n private readonly pending = new Map<string, Pending>();\n\n /** Register a query request; resolves on its `result` frame. */\n awaitQuery(requestId: string): Promise<QueryResult> {\n return new Promise<QueryResult>((resolve, reject) => {\n this.pending.set(requestId, { kind: 'query', resolve, reject });\n });\n }\n\n /** Register a mutation request; resolves on its `action_result` outcome. */\n awaitMutation(requestId: string, onAck?: (ack: MutationAck) => void): Promise<MutationResult> {\n return new Promise<MutationResult>((resolve, reject) => {\n this.pending.set(requestId, { kind: 'mutation', resolve, reject, onAck });\n });\n }\n\n has(requestId: string): boolean {\n return this.pending.has(requestId);\n }\n\n /** Drop a pending request without settling it (e.g. after the caller gave up on a timeout). */\n cancel(requestId: string): void {\n this.pending.delete(requestId);\n }\n\n /**\n * Feed a frame to the correlator. Returns true if the frame was consumed\n * (matched an in-flight request), false otherwise (caller treats it as a\n * push frame).\n */\n handle(frame: RawFrame): boolean {\n const requestId = frame.request_id;\n if (!requestId) return false;\n const pending = this.pending.get(requestId);\n if (!pending) return false;\n\n switch (frame.type) {\n case 'result': {\n if (!isResultFrame(frame)) return this.rejectInvalidResponse(requestId, pending, frame.type);\n const payload = frame.payload;\n if (pending.kind === 'query') {\n this.pending.delete(requestId);\n pending.resolve({ result: payload.result, structuredContent: payload.structuredContent });\n return true;\n }\n const structured = payload.structuredContent;\n const ack = extractPendingAck(structured);\n if (!ack) {\n // Not an ack — this mutation resolved synchronously and nothing was\n // queued (e.g. a dry_run quote), so there's no action_result to\n // wait for. Settle now with this frame as the whole answer: no\n // state changed, so the only meaningful content is structuredContent\n // itself, carried as delta.details same as a real outcome would.\n this.pending.delete(requestId);\n pending.resolve({\n command: String(structured?.command ?? ''),\n tick: 0,\n delta: { details: structured },\n });\n return true;\n }\n // mutation: this is the pending ack — record it and keep waiting for\n // the action_result outcome.\n pending.ack = ack;\n pending.onAck?.(ack);\n return true;\n }\n case 'action_result': {\n if (pending.kind !== 'mutation') return true;\n if (!isActionResultFrame(frame)) return this.rejectInvalidResponse(requestId, pending, frame.type);\n const payload = frame.payload;\n this.pending.delete(requestId);\n pending.resolve({\n command: payload.command,\n tick: payload.tick,\n delta: payload.result,\n autoDocked: payload.auto_docked,\n autoUndocked: payload.auto_undocked,\n });\n return true;\n }\n case 'action_error': {\n if (!isActionErrorFrame(frame)) return this.rejectInvalidResponse(requestId, pending, frame.type);\n this.pending.delete(requestId);\n pending.reject(errorFromActionFrame(frame));\n return true;\n }\n case 'error': {\n if (!isErrorFrame(frame)) return this.rejectInvalidResponse(requestId, pending, frame.type);\n this.pending.delete(requestId);\n pending.reject(errorFromFrame(frame));\n return true;\n }\n default:\n return false;\n }\n }\n\n /** Reject every in-flight request — used when the socket closes. */\n rejectAll(err: ConnectionClosedError | SpacemoltError): void {\n for (const pending of this.pending.values()) pending.reject(err);\n this.pending.clear();\n }\n\n private rejectInvalidResponse(requestId: string, pending: Pending, frameType: string): true {\n this.pending.delete(requestId);\n pending.reject(new SpacemoltError('invalid_response', `Malformed ${frameType} frame for request ${requestId}`));\n return true;\n }\n}\n",
|
|
18
|
+
"/**\n * Thin lifecycle wrapper over a web-standard WebSocket.\n *\n * Parses inbound text frames to `OutboundFrame` and hands them to `onFrame`;\n * serializes outbound `InboundFrame`s. Reconnection and re-auth are M4 — this\n * layer just owns one connection. The WebSocket implementation is injectable\n * (`webSocketFactory`) so the transport can be driven by a mock in tests and\n * so the browser/Bun/Node global `WebSocket` is used by default.\n */\n\nimport type { InboundFrame, RawFrame } from '../protocol.ts';\nimport { ConnectionClosedError } from '../errors.ts';\nimport { isRecord } from '../validation.ts';\n\n/** The minimal web-standard WebSocket surface this library depends on. */\nexport interface MessageEventLike {\n data: unknown;\n}\n\nexport interface CloseEventLike {\n code?: number;\n reason?: string;\n}\n\nexport interface WebSocketLike {\n send(data: string): void;\n close(code?: number, reason?: string): void;\n addEventListener(type: 'open', listener: () => void): void;\n addEventListener(type: 'message', listener: (event: MessageEventLike) => void): void;\n addEventListener(type: 'close', listener: (event: CloseEventLike) => void): void;\n addEventListener(type: 'error', listener: (event: unknown) => void): void;\n}\n\nexport type WebSocketFactory = (url: string) => WebSocketLike;\n\n// `WebSocket` is global in browsers, Bun, and Node 22+.\nconst defaultFactory: WebSocketFactory = (url) => new WebSocket(url);\n\nexport interface SocketOptions {\n url: string;\n webSocketFactory?: WebSocketFactory;\n}\n\nexport class Socket {\n private ws: WebSocketLike | null = null;\n private opened = false;\n private closed = false;\n\n /** Called for every parsed inbound frame. */\n onFrame?: (frame: RawFrame) => void;\n /** Called once when the connection closes (for any reason). */\n onClose?: (err: ConnectionClosedError) => void;\n\n constructor(private readonly opts: SocketOptions) {}\n\n /** Open the socket; resolves when the connection is established. */\n connect(): Promise<void> {\n const factory = this.opts.webSocketFactory ?? defaultFactory;\n const ws = factory(this.opts.url);\n this.ws = ws;\n\n return new Promise<void>((resolve, reject) => {\n let settled = false;\n ws.addEventListener('open', () => {\n this.opened = true;\n settled = true;\n resolve();\n });\n ws.addEventListener('message', (ev) => this.handleMessage(ev.data));\n ws.addEventListener('close', (ev) => {\n const err = new ConnectionClosedError('WebSocket connection closed', ev?.code, ev?.reason);\n if (!settled) {\n settled = true;\n reject(err);\n }\n this.markClosed(err);\n });\n ws.addEventListener('error', () => {\n if (!this.opened && !settled) {\n settled = true;\n reject(new ConnectionClosedError('WebSocket connection failed before open'));\n }\n });\n });\n }\n\n send(frame: InboundFrame): void {\n if (!this.ws || this.closed) throw new ConnectionClosedError('cannot send on a closed socket');\n this.ws.send(JSON.stringify(frame));\n }\n\n close(): void {\n this.ws?.close();\n }\n\n /**\n * The server batches multiple pushes into a single WebSocket message as\n * newline-delimited JSON under load (confirmed live: a burst of\n * reconnect-related frames arrived as one message,\n * `{\"type\":\"reconnected\",...}\\n{\"type\":\"logged_in\",...}`). A JSON string\n * value's own newlines are always escaped (`\\n`, two characters) by any\n * conforming serializer, so a raw newline byte in the message text is only\n * ever a frame separator, never content — splitting on it is safe. Each\n * line is parsed and routed independently, so one malformed line in a\n * batch no longer takes every other frame in that same message down with\n * it (the previous behavior: parsing the whole batch as one JSON value,\n * which always failed whenever more than one frame arrived together).\n */\n private handleMessage(data: unknown): void {\n const text = typeof data === 'string' ? data : String(data);\n for (const line of text.split('\\n')) {\n if (!line) continue;\n let frame: RawFrame;\n try {\n const parsed: unknown = JSON.parse(line);\n if (\n !isRecord(parsed) ||\n typeof parsed.type !== 'string' ||\n (parsed.request_id !== undefined && typeof parsed.request_id !== 'string')\n )\n throw new TypeError('frame must be an object with a type');\n frame = { ...parsed, type: parsed.type };\n } catch (err) {\n // A frame that fails to parse is otherwise 100% silent — no trace it\n // ever arrived. head/tail samples (not the full body, to bound log\n // volume) are what distinguish truncation from genuine garbage.\n const head = line.slice(0, 200);\n const tail = line.length > 400 ? line.slice(-200) : '';\n console.warn(\n `[spacemolt] dropped unparseable frame (${line.length} bytes): ${err} | head=${JSON.stringify(head)}${tail ? ` tail=${JSON.stringify(tail)}` : ''}`,\n );\n continue;\n }\n this.onFrame?.(frame);\n }\n }\n\n private markClosed(err: ConnectionClosedError): void {\n if (this.closed) return;\n this.closed = true;\n this.onClose?.(err);\n }\n}\n",
|
|
19
|
+
"/**\n * A single authenticated SpaceMolt connection.\n *\n * Owns one WebSocket, performs raw-credential auth, and exposes the\n * query/mutation command API, the local state cache (M2), and the typed push\n * event system + market/observation subscriptions (M3).\n *\n * Auth frames (`registered`, `logged_in`) are handled out-of-band from the\n * `request_id` correlator: after `register` the `logged_in` frame is an\n * unsolicited push with no `request_id`, so auth is sequenced by frame type\n * instead (only one auth exchange is ever in flight on a connection).\n */\n\nimport { ACTIONS } from './generated/actions.gen.ts';\nimport { buildCommands, type Commands } from './generated/commands.gen.ts';\nimport type { AuthCredentials } from './auth/credentials.ts';\nimport { mintWsToken } from './auth/clerk.ts';\nimport type {\n LoggedInPayload as LoggedInPayloadSchema,\n NotificationMarketUpdate,\n NotificationObservationUpdate,\n SubscribeMarketResponse,\n SubscribeObservationResponse,\n V2Location,\n} from './generated/openapi/types.gen.ts';\nimport type { NotificationPayloads, TypedNotificationType } from './generated/notifications.gen.ts';\nimport type { FleetPush, OkPush } from './push-frames.ts';\nimport { CLOSE_CODE, ConnectionClosedError, errorFromFrame, retryAfterMsFromClose, SpacemoltError } from './errors.ts';\nimport { notifyListeners, TypedEmitter } from './events/emitter.ts';\nimport { MarketCache, type MarketBook } from './state/market.ts';\nimport { ObservationCache, type ObservationView } from './state/observation.ts';\nimport type {\n GameState,\n MutationAck,\n MutationResult,\n QueryResult,\n InboundFrame,\n RawFrame,\n RegisteredFrame,\n StateSection,\n WelcomeFrame,\n} from './protocol.ts';\nimport { isActionResultFrame, isErrorFrame, isLoggedInFrame, isRegisteredFrame, isWelcomeFrame } from './protocol.ts';\nimport { isRecord } from './validation.ts';\nimport { jitteredDelayMs } from './jitter.ts';\nimport { StateCache } from './state/cache.ts';\nimport { Correlator } from './transport/correlator.ts';\nimport { Socket, type WebSocketFactory } from './transport/socket.ts';\n\n/**\n * The `logged_in` frame payload, typed from the server's published\n * `LoggedInPayload` schema: the initial `player`/`ship`/`system`/`poi` view\n * plus login extras like `recent_chat` and `pending_trades`.\n */\nexport type LoggedInPayload = LoggedInPayloadSchema;\n\nexport interface ReconnectOptions {\n /**\n * Max reconnect attempts before giving up and emitting `disconnected`.\n * Default `Infinity` — a real game-server restart is a routine, recurring\n * event (not an edge case) and can legitimately take several minutes; a\n * finite default tuned for a brief network blip (the old default was 10,\n * exhausted in ~3.5 minutes at the default backoff) would abandon the\n * account mid-restart and require manual intervention to reconnect it.\n * Backoff still caps at `maxDelayMs` per attempt, so this never busy-loops.\n * Pass a finite value to restore the old give-up behavior.\n */\n maxRetries?: number;\n /** Base backoff in ms (doubles per attempt). Default 1000. */\n baseDelayMs?: number;\n /** Backoff ceiling in ms. Default 30000. */\n maxDelayMs?: number;\n}\n\n/** Info reported to an `onRateLimited` listener — see `Account.onRateLimited`. */\nexport interface RateLimitedInfo {\n /** The call being retried: `tool.action` for `query`/`mutate`, `'authenticate'` for auth. */\n command: string;\n /** 1-based retry attempt number. */\n attempt: number;\n /** How long this retry is waiting before resending, including jitter. */\n delayMs: number;\n}\n\nexport interface AccountOptions {\n /** WebSocket URL of the v2 endpoint. Defaults to the production server. */\n url?: string;\n /** Inject a WebSocket implementation (tests, custom runtimes). */\n webSocketFactory?: WebSocketFactory;\n /**\n * Observe every outbound frame (logging/review). Fires before it is sent.\n * A `spacemolt_auth` frame's `password`, `token`, `registration_code`, or\n * `device_code` (from `login_link_poll`) is replaced with `'[redacted]'`\n * before this fires — the frame actually sent to the server is unaffected.\n */\n onSend?: (frame: InboundFrame) => void;\n /**\n * Observe every parsed inbound frame (logging/review). Fires before\n * routing. A `registered` push's `password` (the account's generated\n * credential), and a `result` frame's `device_code` (`login_link`'s\n * response), are replaced with `'[redacted]'` before this fires — the\n * frame that reaches `register()`'s/the correlator's own resolution is\n * unaffected.\n */\n onReceive?: (frame: RawFrame) => void;\n /**\n * After authenticating, issue a `get_status` query to seed the local state\n * cache with the canonical full state. Default `true`. Disable to avoid the\n * extra round-trip; the cache then fills from the first mutation delta.\n */\n seedState?: boolean;\n /**\n * Auto-reconnect + re-auth on an unexpected disconnect. Requires\n * `credentials`. Off unless enabled. Never reconnects after a deliberate\n * `close()`, a `session_replaced` (4001), or an `auth_timeout` (4002).\n */\n reconnect?: boolean | ReconnectOptions;\n /**\n * Supplies credentials for re-auth on reconnect. `login_token` credentials\n * are single-use and can't reconnect; `clerk` credentials re-mint a fresh\n * token each time, so they reconnect cleanly.\n */\n credentials?: () => AuthCredentials | Promise<AuthCredentials>;\n /** Inject a `fetch` implementation, used by `clerk` auth (tests, runtimes). */\n fetchImpl?: typeof fetch;\n /** Max automatic retries when a command is `rate_limited`. Default 5. */\n maxRateLimitRetries?: number;\n /** Stable id this account is managed under (e.g. the credential-store key / username). Exposed as `account.id`. */\n id?: string;\n /**\n * How long to wait for the server's `welcome` frame and for a\n * `logged_in`/error response to an auth attempt, before giving up. Default\n * 15000 (15s — see `SpacemoltClientOptions.connectTimeoutMs` for why this\n * exists).\n */\n connectTimeoutMs?: number;\n /**\n * How long to wait for a query's response before giving up. Queries\n * resolve synchronously server-side (no game-tick delay, unlike\n * mutations) — per the game's own design there's no legitimate reason for\n * one to take long, so unlike mutations (which can legitimately take\n * minutes, e.g. a travel/jump's transit time) it's safe to bound these.\n * Default 15000 (15s).\n */\n queryTimeoutMs?: number;\n /**\n * How long to wait, after a mutation's pending ack arrives, for its final\n * `action_result`/`action_error` outcome before giving up, for the two\n * commands whose transit time is distance-based and can legitimately span\n * many ticks: `jump` and `travel`. Every other mutation settles on the same\n * tick it was queued on (per the game's own design — see\n * `fastMutationTimeoutMs`) and uses that much shorter bound instead.\n * Without this, a single silently-dropped outcome frame hangs forever AND\n * wedges every subsequent mutation on this account behind it (mutations\n * are serialized per account, see `enqueueMutation`). Default 600000 (10\n * minutes).\n */\n mutationTimeoutMs?: number;\n /**\n * How long to wait, after a mutation's pending ack arrives, for its final\n * outcome — for every mutation except `jump`/`travel` (see\n * `mutationTimeoutMs`). These settle within the same tick they were queued\n * on, so there's no legitimate reason for one to take anywhere near as long\n * as a transit; bounding them tightly turns a dropped outcome frame into a\n * fast, visible failure instead of a many-minute stall each retry cycle.\n * Kept well above one tick (default 180000 — 3 minutes, ~18 ticks at the\n * game's 10s tick rate) so a merely-slow tick or a `rate_limited` resend\n * can't trip it. Default 180000 (3 minutes).\n */\n fastMutationTimeoutMs?: number;\n}\n\n/**\n * Mutations whose outcome can legitimately arrive many ticks after the ack —\n * transit time is distance-based, not fixed. Every other mutation resolves\n * within the same tick it was queued on and uses `fastMutationTimeoutMs`\n * instead of the far more generous `mutationTimeoutMs`.\n */\nconst TRANSIT_ACTIONS: ReadonlySet<string> = new Set(['spacemolt/jump', 'spacemolt/travel']);\n\n/**\n * Location fields any arrival push invalidates. Fleet pushes patch the cached\n * location rather than replacing it, so everything the move invalidates has to\n * be cleared explicitly: the transit fields written while in flight, which\n * would otherwise outlive the transit they describe; `docked_at`, since\n * arriving anywhere means no longer docked (cleared to `null`, which is how\n * the server itself reports undocked); and the POI-scoped presence and\n * resource data, which describes the POI just left. All of it refills from\n * `reconcileFleetState`'s snapshot — reporting the previous POI's contents as\n * if they were still around the ship is worse than reporting nothing until it\n * lands.\n *\n * The system-level fields are *not* cleared here: an `arrived` push is\n * intra-system travel, so system, connections, empire and security status\n * still describe where the ship is. A jump is the other case — see\n * `ARRIVED_IN_NEW_SYSTEM`.\n */\nconst ARRIVED: Partial<V2Location> = {\n docked_at: null,\n in_transit: false,\n transit_type: undefined,\n transit_arrival_tick: undefined,\n transit_dest_system_id: undefined,\n transit_dest_system_name: undefined,\n transit_dest_poi_id: undefined,\n transit_dest_poi_name: undefined,\n transit_bearing: undefined,\n transit_x: undefined,\n transit_y: undefined,\n transit_ticks_elapsed: undefined,\n void_message: undefined,\n poi_name: undefined,\n poi_type: undefined,\n resources: undefined,\n nearby_players: undefined,\n nearby_player_count: undefined,\n nearby_prizes: undefined,\n nearby_prize_count: undefined,\n nearby_pirates: undefined,\n nearby_pirate_count: undefined,\n nearby_empire_npcs: undefined,\n nearby_empire_npc_count: undefined,\n nearby_leviathans: undefined,\n offline_collapsed: undefined,\n unknown_signature: undefined,\n};\n\n/**\n * Additionally, the system-level fields a jump invalidates. Crossing systems\n * makes connections, empire and security status describe the system just left,\n * and the arrival push cannot refresh them: `apiresponses.JumpResponse` carries\n * only `system`, `system_id`, `from_system` and the XP fields. Serving the\n * origin's values under the destination's `system_id` is worse than serving\n * nothing — a consumer picking its next jump from `connections` would get a\n * plausible, wrong adjacency list rather than an obvious gap. They refill from\n * `reconcileFleetState`'s snapshot.\n */\nconst ARRIVED_IN_NEW_SYSTEM: Partial<V2Location> = {\n ...ARRIVED,\n connections: undefined,\n empire: undefined,\n security_status: undefined,\n};\n\n/**\n * Location fields a transit-start push invalidates, mirroring `ARRIVED` in the\n * other direction. Leaving a POI drops everything POI-scoped, and the server\n * reports the ship's position as empty strings while it is between POIs — so\n * clear them the same way it does, or `refresh()` reports a drift that is only\n * a difference in how the two sides spell \"nowhere\".\n *\n * The transit fields `ARRIVED` clears are re-set by each caller after the\n * spread, since only the caller knows the destination and arrival tick.\n */\nconst DEPARTED: Partial<V2Location> = { ...ARRIVED, poi_id: '', poi_name: '', poi_type: '' };\n\n/**\n * Additionally, the system-level fields a jump invalidates. A jump leaves\n * normal space entirely: the server reports no system at all until arrival.\n */\nconst DEPARTED_SYSTEM: Partial<V2Location> = { ...ARRIVED_IN_NEW_SYSTEM, ...DEPARTED, system_id: '', system_name: '' };\n\nexport interface RegisterParams {\n username: string;\n empire: string;\n registration_code?: string;\n}\n\nexport interface RegisterResult {\n /** 256-bit hex credential — store it; it cannot be recovered. */\n password: string;\n player_id: string;\n /** Full initial game state from the following `logged_in` frame. */\n state: LoggedInPayload;\n}\n\ninterface PendingAuth {\n onLoggedIn: (payload: LoggedInPayload, registered?: RegisteredFrame['payload']) => void;\n /** `Error`, not `SpacemoltError` specifically — a close carries a `ConnectionClosedError` (code + reason), not a server-reported error. */\n onError: (err: Error) => void;\n registered?: RegisteredFrame['payload'];\n}\n\nconst DEFAULT_URL = 'wss://game.spacemolt.com/ws/v2';\nconst DEFAULT_CONNECT_TIMEOUT_MS = 15_000;\nconst DEFAULT_MUTATION_TIMEOUT_MS = 600_000;\nconst DEFAULT_FAST_MUTATION_TIMEOUT_MS = 180_000;\n\nconst delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** Rejects with a `connect_timeout` `SpacemoltError` if `promise` doesn't settle within `ms`. */\nfunction withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => reject(new SpacemoltError('connect_timeout', message)), ms);\n promise.then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (err: unknown) => {\n clearTimeout(timer);\n reject(err);\n },\n );\n });\n}\n\nfunction normalizeReconnect(opt: AccountOptions['reconnect']): Required<ReconnectOptions> | null {\n if (!opt) return null;\n const o = typeof opt === 'object' ? opt : {};\n return {\n maxRetries: o.maxRetries ?? Number.POSITIVE_INFINITY,\n baseDelayMs: o.baseDelayMs ?? 1000,\n maxDelayMs: o.maxDelayMs ?? 30000,\n };\n}\n\n/**\n * Closes no reconnect can recover from. session_replaced: another connection\n * took our slot — reconnecting would just fight it. auth_timeout: we failed to\n * auth in time. Unlike those two, connection_rate_limited (4003) IS worth\n * reconnecting after — `reconnectLoop` honors its retry_after hint.\n */\nfunction isTerminalClose(err: ConnectionClosedError): boolean {\n return err.code === CLOSE_CODE.SESSION_REPLACED || err.code === CLOSE_CODE.AUTH_TIMEOUT;\n}\n\n/** Parse a retry interval from a `rate_limited` error (ms). */\nfunction retryAfterMs(err: SpacemoltError): number {\n const retryAfter = err.details?.retry_after;\n const fromDetails = typeof retryAfter === 'number' ? retryAfter : undefined;\n const match = err.message.match(/retry in (\\d+)\\s*second/i);\n const seconds = fromDetails ?? (match ? Number(match[1]) : undefined);\n return Math.max(250, (seconds ?? 1) * 1000);\n}\n\n/** Payload field names carrying a secret in a `spacemolt_auth` frame — never handed to `onSend` unredacted. */\nconst AUTH_SECRET_PAYLOAD_FIELDS = new Set(['password', 'token', 'registration_code', 'device_code']);\n\n/**\n * Redacts secret fields from a `spacemolt_auth` frame before it reaches\n * `onSend` — `register`/`login`/`login_token` payloads carry a password,\n * token, or registration code, and `login_link_poll` carries the device code\n * (whoever holds it gets the session once the human approves, so it's a\n * credential too). Other fields (e.g. `username`) are left as-is so a log is\n * still useful. Frames for every other tool pass through untouched; the\n * frame actually sent to the socket is never modified.\n */\nfunction redactForOnSend(frame: InboundFrame): InboundFrame {\n if (frame.tool !== 'spacemolt_auth' || !isRecord(frame.payload)) return frame;\n let redacted: Record<string, unknown> | undefined;\n for (const field of AUTH_SECRET_PAYLOAD_FIELDS) {\n if (field in frame.payload) {\n redacted ??= { ...frame.payload };\n redacted[field] = '[redacted]';\n }\n }\n return redacted ? { ...frame, payload: redacted } : frame;\n}\n\n/**\n * Redacts secrets from an inbound frame before it reaches `onReceive` —\n * mirrors `redactForOnSend`, but for the two pushes that carry a secret\n * inbound: the `registered` frame's generated `password`, and a `result`\n * frame's `device_code` (`login_link`'s response carries a fresh one, in both\n * `structuredContent.device_code` and, when present, the same value inlined\n * in the rendered `result` text). Keyed off the field name rather than the\n * command, so it applies to any `result` frame that happens to carry one,\n * not a hand-maintained command list. The real frame (with the real secret)\n * is still what routes to `pendingAuth`/`register()`/the correlator.\n */\nfunction redactForOnReceive(frame: RawFrame): RawFrame {\n if (frame.type === 'registered' && isRecord(frame.payload) && 'password' in frame.payload) {\n return { ...frame, payload: { ...frame.payload, password: '[redacted]' } };\n }\n if (frame.type === 'result' && isRecord(frame.payload)) {\n const { structuredContent } = frame.payload;\n if (\n isRecord(structuredContent) &&\n typeof structuredContent.device_code === 'string' &&\n structuredContent.device_code\n ) {\n const code = structuredContent.device_code;\n const result =\n typeof frame.payload.result === 'string' && frame.payload.result.includes(code)\n ? frame.payload.result.split(code).join('[redacted]')\n : frame.payload.result;\n return {\n ...frame,\n payload: { ...frame.payload, result, structuredContent: { ...structuredContent, device_code: '[redacted]' } },\n };\n }\n }\n return frame;\n}\n\nfunction requireStructuredContent<T>(result: QueryResult<T>, command: string): T {\n if (result.structuredContent === undefined) {\n throw new SpacemoltError('invalid_response', `${command} returned no structured content`);\n }\n return result.structuredContent;\n}\n\nexport class Account {\n private socket!: Socket;\n private readonly correlator = new Correlator();\n private readonly cache = new StateCache();\n private readonly emitter = new TypedEmitter();\n private readonly marketCache = new MarketCache();\n private readonly observationCache = new ObservationCache();\n private readonly seedState: boolean;\n private readonly url: string;\n private readonly webSocketFactory?: WebSocketFactory;\n private readonly onSend?: (frame: InboundFrame) => void;\n private readonly onReceive?: (frame: RawFrame) => void;\n private readonly reconnectConfig: Required<ReconnectOptions> | null;\n private readonly credentialsProvider?: () => AuthCredentials | Promise<AuthCredentials>;\n private readonly fetchImpl?: typeof fetch;\n private readonly maxRateLimitRetries: number;\n private readonly connectTimeoutMs: number;\n private readonly queryTimeoutMs: number;\n private readonly mutationTimeoutMs: number;\n private readonly fastMutationTimeoutMs: number;\n private readonly _id: string | undefined;\n private requestSeq = 0;\n\n private _welcome: WelcomeFrame['payload'] | null = null;\n private _authenticated = false;\n // True only for `reconnectOnce`'s socket-swap-to-re-auth window — see there.\n /** How many `reconnectOnce` calls are mid-swap; a count, so overlapping calls can't lift each other's guard. */\n private reconnectsPending = 0;\n private _loginPayload: LoggedInPayload | null = null;\n private _currentTick = 0;\n private _commands: Commands | null = null;\n private welcomeWaiter: { resolve: (w: WelcomeFrame['payload']) => void; reject: (err: Error) => void } | null = null;\n private pendingAuth: PendingAuth | null = null;\n private readonly stateListeners = new Set<(changed: StateSection[]) => void>();\n\n // resilience state\n private userClosing = false;\n private reconnecting = false;\n /** The close seen on the current reconnect attempt's socket, if any — the loop reads it to decide whether the attempt really succeeded. */\n private attemptClose: ConnectionClosedError | null = null;\n private mutationLane: Promise<unknown> = Promise.resolve();\n private marketSubscribedState = false;\n private subscribedMarketBaseId: string | undefined;\n private observationSubscribedState = false;\n private observationActiveScanState = false;\n /** Invalidates an in-flight reconciliation whenever a newer cache update arrives. */\n private stateRevision = 0;\n private subscribedObservationPoiId: string | undefined;\n private readonly reconnectedListeners = new Set<() => void>();\n private readonly reconnectingListeners = new Set<(attempt: number) => void>();\n private readonly disconnectedListeners = new Set<(err: ConnectionClosedError) => void>();\n private readonly rateLimitedListeners = new Set<(info: RateLimitedInfo) => void>();\n\n constructor(opts: AccountOptions = {}) {\n this.seedState = opts.seedState ?? true;\n this.url = opts.url ?? DEFAULT_URL;\n this.webSocketFactory = opts.webSocketFactory;\n this.onSend = opts.onSend;\n this.onReceive = opts.onReceive;\n this.credentialsProvider = opts.credentials;\n this.fetchImpl = opts.fetchImpl;\n this.maxRateLimitRetries = opts.maxRateLimitRetries ?? 5;\n this.connectTimeoutMs = opts.connectTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;\n this.queryTimeoutMs = opts.queryTimeoutMs ?? DEFAULT_CONNECT_TIMEOUT_MS;\n this.mutationTimeoutMs = opts.mutationTimeoutMs ?? DEFAULT_MUTATION_TIMEOUT_MS;\n this.fastMutationTimeoutMs = opts.fastMutationTimeoutMs ?? DEFAULT_FAST_MUTATION_TIMEOUT_MS;\n this._id = opts.id;\n this.reconnectConfig = normalizeReconnect(opts.reconnect);\n this.makeSocket();\n\n // Keep the subscription caches current as their pushes arrive. Registered\n // before any user listener so the cache is updated first.\n this.emitter.on<NotificationMarketUpdate>('market_update', (payload) => this.marketCache.applyUpdate(payload));\n this.emitter.on<NotificationObservationUpdate>('observation_update', (payload) => {\n this.observationCache.applyUpdate(payload);\n this.bridgeObservationToLocation();\n });\n }\n\n private makeSocket(): void {\n // A replaced socket can still fire events: a ws.close() against an\n // unresponsive peer reports its close event late, after reconnectOnce has\n // moved on. Only the current socket may touch account state, or that late\n // close fails the live connection's requests and tears it down.\n const socket = new Socket({ url: this.url, webSocketFactory: this.webSocketFactory });\n socket.onFrame = (frame) => {\n if (this.socket === socket) this.routeFrame(frame);\n };\n socket.onClose = (err) => {\n if (this.socket === socket) this.handleClose(err);\n };\n this.socket = socket;\n }\n\n /** Live view of the cached game state. Treat as read-only. */\n get state(): Readonly<GameState> {\n return this.cache.snapshot();\n }\n\n /** The id this account is managed under (store key / username), if any. */\n get id(): string | undefined {\n return this._id;\n }\n\n get player(): GameState['player'] {\n return this.cache.player;\n }\n get ship(): GameState['ship'] {\n return this.cache.ship;\n }\n get location(): GameState['location'] {\n return this.cache.location;\n }\n get cargo(): GameState['cargo'] {\n return this.cache.cargo;\n }\n get skills(): GameState['skills'] {\n return this.cache.skills;\n }\n /**\n * Active intact-ship recovery operations assigned to this account, including\n * prizes in transit or stalled outside the current POI. Refreshed by the\n * deltas of this account's own prize commands (`claim_prize`,\n * `service_prize`) and by `refresh()`; the `prize_update`/`ship_captured`\n * pushes carry no delta, so listen for those via `on(...)` if you need to\n * react as they land.\n */\n get prizeRecoveries(): GameState['prize_recoveries'] {\n return this.cache.prizeRecoveries;\n }\n get credits(): number | undefined {\n return this.cache.credits;\n }\n /** True when a tick-deferred action is queued for this account. */\n get hasPendingAction(): boolean {\n return this.cache.hasPendingAction;\n }\n\n /** The raw `logged_in` payload from the last successful auth (login extras). */\n get loginPayload(): LoggedInPayload | null {\n return this._loginPayload;\n }\n\n /**\n * Typed, generated command facade grouped by tool:\n * `account.commands.spacemolt.jump({ id: 'sol' })`,\n * `account.commands.spacemolt_market.view_market({ item_id: 'iron_ore' })`.\n * Each method dispatches through `send`, so pacing and the state cache apply.\n */\n get commands(): Commands {\n if (!this._commands) {\n this._commands = buildCommands((tool, action, payload, requestId) => this.send(tool, action, payload, requestId));\n }\n return this._commands;\n }\n\n /** The server's `welcome` payload, available after `connect()` resolves. */\n get welcome(): WelcomeFrame['payload'] | null {\n return this._welcome;\n }\n\n /**\n * Highest game tick observed on this connection — from `welcome`\n * (`current_tick`) and every subsequent tick-bearing frame (`action_result`,\n * `action_error`, and push notifications that carry a numeric `tick`).\n * 0 until the welcome arrives. There is no per-tick server push; between\n * observations, extrapolate with `welcome.tick_rate` if needed.\n */\n get currentTick(): number {\n return this._currentTick;\n }\n\n private observeTick(tick: unknown): void {\n if (typeof tick === 'number' && tick > this._currentTick) this._currentTick = tick;\n }\n\n get authenticated(): boolean {\n return this._authenticated;\n }\n\n /**\n * Whether `subscribeMarket()` is currently active on this instance —\n * `resubscribe()` reads this directly to restore the subscription across a\n * reconnect (this account's own `reconnectLoop`, or `reconnectOnce()`\n * called by `SpacemoltClient` for a client-managed account).\n */\n get marketSubscribed(): boolean {\n return this.marketSubscribedState;\n }\n\n /** Whether `subscribeObservation()` is currently active — see `marketSubscribed`. */\n get observationSubscribed(): boolean {\n return this.observationSubscribedState;\n }\n\n /** The `activeScan` flag passed to the active `subscribeObservation()` call, if any — see `marketSubscribed`. */\n get observationActiveScan(): boolean {\n return this.observationActiveScanState;\n }\n\n /** Open the connection and resolve once the `welcome` frame arrives. */\n connect(): Promise<WelcomeFrame['payload']> {\n return this.open();\n }\n\n private async open(): Promise<WelcomeFrame['payload']> {\n // Capture the socket this attempt belongs to — `reconnectOnce` can swap\n // in a new one (`makeSocket`) while this call is still waiting for\n // welcome (its waiter gets rejected by `failPendingWork`, which runs\n // before the swap resolves). The catch below must only ever touch state\n // that still belongs to this attempt, or it closes the NEW socket while\n // it's mid-connect — a real WebSocket closed while connecting fails the\n // connection outright.\n const socket = this.socket;\n this._welcome = null;\n await socket.connect();\n if (this._welcome) return this._welcome;\n let waiter: { resolve: (w: WelcomeFrame['payload']) => void; reject: (err: Error) => void } | undefined;\n const waitForWelcome = new Promise<WelcomeFrame['payload']>((resolve, reject) => {\n waiter = { resolve, reject };\n this.welcomeWaiter = waiter;\n });\n try {\n return await withTimeout(\n waitForWelcome,\n this.connectTimeoutMs,\n `No welcome frame received within ${this.connectTimeoutMs}ms`,\n );\n } catch (err) {\n // Give up on this connection attempt rather than leaving a socket open\n // that's never going to complete the handshake — but only if `socket`\n // and `waiter` are still the live ones; a newer attempt may already\n // have replaced both.\n if (waiter && this.welcomeWaiter === waiter) this.welcomeWaiter = null;\n if (this.socket === socket) socket.close();\n throw err;\n }\n }\n\n /** Register a new account; resolves with the generated credentials + state. */\n async register(params: RegisterParams): Promise<RegisterResult> {\n let authEntry: PendingAuth | undefined;\n const registerPromise = new Promise<RegisterResult>((resolve, reject) => {\n const accepted = this.beginAuth((state, registered) => {\n if (!registered) {\n reject(new SpacemoltError('missing_credentials', 'register succeeded but no credentials frame was received'));\n return;\n }\n resolve({ password: registered.password, player_id: registered.player_id, state });\n }, reject);\n // Capture the exact entry `beginAuth` created — identity, not just\n // \"accepted\" — so the catch below can't clobber a newer exchange's\n // entry (e.g. one `reconnectOnce` started) that happens to occupy\n // `pendingAuth` by the time this call's timeout/error fires.\n if (accepted) authEntry = this.pendingAuth ?? undefined;\n if (accepted) this.sendFrame('spacemolt_auth', 'register', { ...params }, this.nextRequestId());\n });\n let result: RegisterResult;\n try {\n result = await withTimeout(\n registerPromise,\n this.connectTimeoutMs,\n `No register response received within ${this.connectTimeoutMs}ms`,\n );\n } catch (err) {\n // Only clear `pendingAuth` if it's still the entry this call created —\n // a rejected `beginAuth` (another exchange already in flight) never\n // touched it, and a newer exchange may have replaced it since.\n if (authEntry && this.pendingAuth === authEntry) this.pendingAuth = null;\n throw err;\n }\n this._loginPayload = result.state;\n await this.maybeSeedState();\n return result;\n }\n\n /** Authenticate an existing account with username + password. */\n login(params: { username: string; password: string }): Promise<LoggedInPayload> {\n return this.authExchange('login', { ...params });\n }\n\n /** Authenticate with a short-lived single-use token (web/Clerk path). */\n loginToken(token: string): Promise<LoggedInPayload> {\n return this.authExchange('login_token', { token });\n }\n\n /**\n * Authenticate from a stored `AuthCredentials` (dispatches by kind).\n * Auto-retries on `rate_limited` (waiting the server's interval) — for\n * `clerk` credentials each retry mints a fresh ws-token, so a transient\n * rejection doesn't waste a single-use token.\n */\n authenticate(creds: AuthCredentials): Promise<void> {\n return this.withRateLimitRetry('authenticate', () => this.authenticateOnce(creds));\n }\n\n private async authenticateOnce(creds: AuthCredentials): Promise<void> {\n switch (creds.kind) {\n case 'login':\n await this.login({ username: creds.username, password: creds.password });\n return;\n case 'login_token':\n await this.loginToken(creds.token);\n return;\n case 'clerk': {\n // Mint a fresh single-use WS token from the Clerk key, then log in with\n // it. Re-runs on every reconnect and every rate-limit retry, so each\n // attempt gets its own token.\n const token = await mintWsToken({\n httpBaseUrl: creds.httpBaseUrl,\n apiKey: creds.apiKey,\n playerId: creds.playerId,\n fetchImpl: this.fetchImpl,\n });\n await this.loginToken(token);\n return;\n }\n case 'register':\n await this.register({\n username: creds.username,\n empire: creds.empire,\n registration_code: creds.registration_code,\n });\n return;\n }\n }\n\n /**\n * Re-seed the cache from the canonical full state (`get_status`). Returns the\n * cached state. Called automatically after auth unless `seedState` is false.\n */\n async refresh(): Promise<Readonly<GameState>> {\n const revision = this.stateRevision;\n const result = await this.commands.spacemolt.get_status();\n const snapshot = requireStructuredContent(result, 'spacemolt/get_status');\n // The server takes the snapshot before writing it, and a tick can push a\n // newer delta in between. If one landed, this snapshot may be the older\n // state — keep the cache rather than roll it back.\n if (revision !== this.stateRevision) return this.cache.snapshot();\n const changed = this.cache.seed(snapshot);\n if (changed.length) this.stateRevision++;\n if (changed.includes('location')) this.checkSubscriptionsAgainstLocation();\n if (changed.length) this.emitStateChange(changed);\n return this.cache.snapshot();\n }\n\n /**\n * Register a listener fired with the sections that changed on each update.\n * Multiple listeners may be registered; returns an unsubscribe function.\n */\n onStateChange(listener: (changed: StateSection[]) => void): () => void {\n this.stateListeners.add(listener);\n return () => {\n this.stateListeners.delete(listener);\n };\n }\n\n private emitStateChange(changed: StateSection[]): void {\n notifyListeners(this.stateListeners, 'onStateChange', changed);\n }\n\n /** Log out, releasing the connection's authenticated session. */\n async logout(): Promise<void> {\n await this.query('spacemolt_auth', 'logout');\n this._authenticated = false;\n }\n\n /**\n * Run a read-only command; resolves synchronously with the result.\n * Auto-retries on `rate_limited` (waiting the server's interval). Bounded\n * by `queryTimeoutMs` — unlike a mutation, a query has no legitimate reason\n * to take long, so a response that never arrives (the server silently\n * drops it rather than erroring) fails cleanly instead of hanging forever.\n */\n query(tool: string, action: string, payload?: Record<string, unknown>, requestId?: string): Promise<QueryResult> {\n return this.withRateLimitRetry(`${tool}.${action}`, async () => {\n const id = this.claimRequestId(requestId);\n const promise = this.correlator.awaitQuery(id);\n try {\n // Inside the try: a closed socket throws here, and an uncancelled entry\n // would block the id and later reject into nothing.\n this.sendFrame(tool, action, payload, id);\n return await withTimeout(\n promise,\n this.queryTimeoutMs,\n `No response to ${tool}/${action} within ${this.queryTimeoutMs}ms`,\n );\n } catch (err) {\n this.correlator.cancel(id);\n throw err;\n }\n });\n }\n\n /**\n * Run a mutation; resolves when the action executes on a later tick (after\n * the immediate pending ack). `onAck` fires when the pending ack arrives.\n *\n * Mutations are serialized per account — the next is sent only after the\n * previous resolves — because the server queues one action per tick and\n * rejects a concurrent mutation with `action_pending`. Also auto-retries on\n * `rate_limited`.\n *\n * Bounded in two phases (see `awaitMutationWithTimeout`) rather than left\n * unbounded: a dropped outcome frame should fail cleanly, not hang this\n * call (and every mutation queued behind it on this account) forever. Only\n * `jump`/`travel` (`TRANSIT_ACTIONS`) get the generous `mutationTimeoutMs`;\n * every other mutation — `mine`, `craft`, etc. — settles within the tick it\n * was queued on and gets the much shorter `fastMutationTimeoutMs`.\n */\n mutate(\n tool: string,\n action: string,\n payload?: Record<string, unknown>,\n onAck?: (ack: MutationAck) => void,\n requestId?: string,\n ): Promise<MutationResult> {\n const mutationTimeoutMs = TRANSIT_ACTIONS.has(`${tool}/${action}`)\n ? this.mutationTimeoutMs\n : this.fastMutationTimeoutMs;\n return this.enqueueMutation(() =>\n this.withRateLimitRetry(`${tool}.${action}`, () => {\n const id = this.claimRequestId(requestId);\n return this.awaitMutationWithTimeout(\n id,\n mutationTimeoutMs,\n () => this.sendFrame(tool, action, payload, id),\n onAck,\n );\n }),\n );\n }\n\n /**\n * Waits for a mutation's outcome with two-phase timeout protection. The\n * pending ack (`result` frame) is a synchronous validation step with no\n * game-tick delay — like a query, there's no legitimate reason for it to be\n * missing, so it's bounded by `queryTimeoutMs`. Once the ack arrives, the\n * final `action_result`/`action_error` can legitimately take many ticks for\n * a transit mutation, so that phase gets the caller-supplied\n * `mutationTimeoutMs` (either the long transit bound or the short\n * same-tick bound — see `mutate`) instead. Either phase timing out cancels\n * the correlator entry — otherwise a truly-dropped response would wedge\n * every later mutation on this account behind it forever (see\n * `enqueueMutation`).\n */\n private awaitMutationWithTimeout(\n requestId: string,\n mutationTimeoutMs: number,\n send: () => void,\n onAck?: (ack: MutationAck) => void,\n ): Promise<MutationResult> {\n return new Promise<MutationResult>((resolve, reject) => {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const arm = (ms: number, message: string): void => {\n if (timer) clearTimeout(timer);\n timer = setTimeout(() => {\n this.correlator.cancel(requestId);\n reject(new SpacemoltError('mutation_timeout', message));\n }, ms);\n };\n arm(this.queryTimeoutMs, `No response to mutation ${requestId} within ${this.queryTimeoutMs}ms`);\n this.correlator\n .awaitMutation(requestId, (ack) => {\n arm(mutationTimeoutMs, `No action_result for mutation ${requestId} within ${mutationTimeoutMs}ms of its ack`);\n onAck?.(ack);\n })\n .then(\n (value) => {\n if (timer) clearTimeout(timer);\n resolve(value);\n },\n (err: unknown) => {\n if (timer) clearTimeout(timer);\n reject(err instanceof Error ? err : new Error(String(err)));\n },\n );\n // Send last, so the entry and timer exist before any response can\n // arrive — and undo both if a closed socket throws, or this promise is\n // orphaned with a live timer and rejects into nothing.\n try {\n send();\n } catch (err) {\n if (timer) clearTimeout(timer);\n this.correlator.cancel(requestId);\n reject(err instanceof Error ? err : new Error(String(err)));\n }\n });\n }\n\n /**\n * Run a command, dispatching to `query`/`mutate` based on the spec's\n * `x-is-mutation` classification. Unknown commands are treated as queries.\n */\n send(\n tool: string,\n action: string,\n payload?: Record<string, unknown>,\n requestId?: string,\n ): Promise<QueryResult | MutationResult> {\n const def = ACTIONS[`${tool}/${action}`];\n return def?.kind === 'mutation'\n ? this.mutate(tool, action, payload, undefined, requestId)\n : this.query(tool, action, payload, requestId);\n }\n\n /**\n * Listen for a specific server push by msg_type. The handler receives the\n * typed payload for published notification types, and for the `ok` and\n * `fleet` families from the hand-written unions in `push-frames.ts` (the\n * server publishes those two only as flat objects, not per-event unions).\n * Anything else is a loosely-typed object. Returns an unsubscribe function.\n */\n on<K extends TypedNotificationType>(type: K, handler: (payload: NotificationPayloads[K]) => void): () => void;\n on(type: 'ok', handler: (payload: OkPush) => void): () => void;\n on(type: 'fleet', handler: (payload: FleetPush) => void): () => void;\n on(type: string, handler: (payload: Record<string, unknown>) => void): () => void;\n on<T>(type: string, handler: (payload: T) => void): () => void {\n return this.emitter.on(type, handler);\n }\n\n /** Listen for every server push frame. Returns an unsubscribe function. */\n onAny(handler: (frame: RawFrame) => void): () => void {\n return this.emitter.onAny(handler);\n }\n\n /**\n * Async-iterate one push msg_type's payloads:\n * `for await (const msg of account.events('chat_message')) { ... }`.\n * Buffered, so a slow consumer won't drop frames; `break` unsubscribes.\n */\n events<K extends TypedNotificationType>(type: K): AsyncIterableIterator<NotificationPayloads[K]>;\n events(type: 'ok'): AsyncIterableIterator<OkPush>;\n events(type: 'fleet'): AsyncIterableIterator<FleetPush>;\n events(type: string): AsyncIterableIterator<Record<string, unknown>>;\n events<T>(type: string): AsyncIterableIterator<T> {\n return this.emitter.stream(type) as AsyncIterableIterator<T>;\n }\n\n /** Async-iterate every push frame. */\n anyEvents(): AsyncIterableIterator<RawFrame> {\n return this.emitter.anyStream();\n }\n\n // --- subscriptions ---\n\n /**\n * Subscribe to the order book of the station you're docked at. Returns the\n * baseline snapshot and seeds the market cache; `market_update` pushes are\n * merged automatically. Read with `account.market(baseId)`.\n *\n * The server subscription is scoped to \"wherever you're currently docked\"\n * and has no explicit unsubscribe signal when it lapses: it's silently\n * dropped server-side the instant you undock (`flushMarketSubscriptions`,\n * `internal/game/market_subscriptions.go`), with no notification telling\n * the client this happened. `checkSubscriptionsAgainstLocation` below is\n * the client-side half of that — it watches for the same docked_at change\n * and drops the stale book proactively, so `market()` can't keep serving a\n * book the server has already stopped updating.\n */\n async subscribeMarket(): Promise<SubscribeMarketResponse> {\n const result = await this.commands.spacemolt_market.subscribe_market();\n const snapshot = requireStructuredContent(result, 'spacemolt_market/subscribe_market');\n this.marketCache.seed(snapshot);\n this.marketSubscribedState = true;\n this.subscribedMarketBaseId = snapshot.base_id;\n return snapshot;\n }\n\n /** Unsubscribe from the current station's market and drop its cached book. */\n async unsubscribeMarket(): Promise<void> {\n const baseId = this.subscribedMarketBaseId ?? this.location?.docked_at ?? this.marketCache.bases()[0];\n this.marketSubscribedState = false;\n this.subscribedMarketBaseId = undefined;\n await this.query('spacemolt_market', 'unsubscribe_market');\n if (baseId) this.marketCache.drop(baseId);\n }\n\n /** The cached order book for a base, if subscribed. */\n market(baseId: string): MarketBook | undefined {\n return this.marketCache.book(baseId);\n }\n\n /**\n * Subscribe to a change-feed of presence at your current POI: players, plus\n * the pirates, empire NPCs, wildlife, intact prizes and arena NPCs there —\n * all six of `get_nearby`'s classes. With a working ship scanner it also\n * carries the ship count at every charted POI in your system\n * (`shipCounts`); nothing else in it is system-wide.\n * Returns the baseline and seeds the observation cache; `observation_update`\n * pushes are merged automatically. Read with `account.observation()`. Also\n * bridges the POI-scoped classes into their matching `location` fields in the\n * base state cache (see `bridgeObservationToLocation`), so\n * `account.state.location` reflects live data too once subscribed, instead of\n * only refreshing on the next `get_status`/mutation delta.\n *\n * Scoped to your current POI the same way `subscribeMarket` is scoped to\n * your current dock — see the docked_at note there; the same silent\n * server-side drop on leaving the POI applies here\n * (`internal/game/observation_subscriptions.go`), and\n * `checkSubscriptionsAgainstLocation` guards against it the same way.\n */\n async subscribeObservation(activeScan = false): Promise<SubscribeObservationResponse> {\n const result = await this.commands.spacemolt.subscribe_observation(activeScan ? { active_scan: true } : undefined);\n const snapshot = requireStructuredContent(result, 'spacemolt/subscribe_observation');\n this.observationCache.seed(snapshot);\n this.bridgeObservationToLocation();\n this.observationSubscribedState = true;\n this.observationActiveScanState = activeScan;\n this.subscribedObservationPoiId = snapshot.poi_id;\n return snapshot;\n }\n\n /** Unsubscribe from the observation watch and clear its cache. */\n async unsubscribeObservation(): Promise<void> {\n this.observationSubscribedState = false;\n this.subscribedObservationPoiId = undefined;\n await this.query('spacemolt', 'unsubscribe_observation');\n this.observationCache.clear();\n }\n\n /**\n * Mirrors the observation watch's POI-scoped presence into the matching\n * `location` fields in the base state cache, so code reading\n * `account.state.location` (rather than `account.observation()`) sees live\n * data once subscribed: players, pirates, empire NPCs, intact prizes, their\n * counts, `offline_collapsed`, and the cloaked-signature hint. Wildlife and\n * arena NPCs have no `location` field — read them from\n * `account.observation()`. The feed carries no leviathans, so\n * `nearby_leviathans` keeps whatever the server last said.\n *\n * The player list matches `get_nearby` and `get_status`: the server already\n * applies the offline collapse above 10 players and the 50-player cap, and\n * the bridge restores the order (online first, then by username) that\n * delta merging loses. `nearby_player_count` is the listed count, as in\n * `get_status`.\n *\n * One way the bridged values differ from what `get_status` would return\n * for the same POI: the pirate, empire-NPC and prize arrays are uncapped.\n * `get_status` truncates them (20 each) while reporting the pre-cap total in\n * the count, so a bridged array can be longer than the server would ever\n * send. The counts mean the same thing either way.\n *\n * `unknown_signature` is written even when false, and `offline_collapsed`\n * even when 0, where `get_status` omits the key; the bridge has to write\n * them to clear a value that has gone.\n * No-ops if `location` hasn't been seeded yet or nothing is subscribed.\n */\n private bridgeObservationToLocation(): void {\n const view = this.observationCache.current();\n if (!view) return;\n // The feed and `location` share the NearbyPlayer, PirateInfo,\n // EmpireNpcInfo and PrizeInfo schemas, so entries pass through.\n // Plain string comparison, not localeCompare: the server sorts by bytes.\n const nearbyPlayers = [...view.nearby.values()].sort(\n (a, b) =>\n Number(a.offline ?? false) - Number(b.offline ?? false) ||\n (a.username < b.username ? -1 : a.username > b.username ? 1 : 0),\n );\n const changed = this.cache.patchSection('location', {\n nearby_players: nearbyPlayers,\n nearby_player_count: nearbyPlayers.length,\n nearby_pirates: [...view.pirates.values()],\n nearby_pirate_count: view.pirates.size,\n nearby_empire_npcs: [...view.empireNpcs.values()],\n nearby_empire_npc_count: view.empireNpcs.size,\n nearby_prizes: [...view.prizes.values()],\n nearby_prize_count: view.prizes.size,\n offline_collapsed: view.offlineCollapsed,\n unknown_signature: view.unknownSignature,\n });\n if (changed.length) this.stateRevision++;\n if (changed.length) this.emitStateChange(changed);\n }\n\n /** The current observation watch view, if subscribed. */\n observation(): ObservationView | null {\n return this.observationCache.current();\n }\n\n /**\n * Detects a docked/POI change away from an active market or observation\n * subscription and proactively drops the now-dead cache entry, mirroring\n * the server's own silent unsubscribe-on-move (see the notes on\n * `subscribeMarket`/`subscribeObservation`). Without this, `market()`/\n * `observation()` would keep serving whatever was last cached — frozen,\n * with nothing distinguishing it from a genuinely live book — for as long\n * as nothing else happens to touch that specific base/POI again. Called\n * after every state update that could carry a `location` change.\n */\n private checkSubscriptionsAgainstLocation(): void {\n if (\n this.marketSubscribedState &&\n this.subscribedMarketBaseId !== undefined &&\n this.location?.docked_at !== this.subscribedMarketBaseId\n ) {\n this.marketCache.drop(this.subscribedMarketBaseId);\n this.marketSubscribedState = false;\n this.subscribedMarketBaseId = undefined;\n }\n if (\n this.observationSubscribedState &&\n this.subscribedObservationPoiId !== undefined &&\n this.location?.poi_id !== this.subscribedObservationPoiId\n ) {\n this.observationCache.clear();\n this.observationSubscribedState = false;\n this.subscribedObservationPoiId = undefined;\n }\n }\n\n /**\n * Movement that the state delta does not cover arrives as a plain `ok` push.\n * Bridge its location data into the cache.\n *\n * Two kinds of movement land here. **Transit start** (`travel`/`jump`, and\n * their `fleet_` variants) is never delivered as a delta by design: the\n * server holds one `action_result` back for the arrival so it can settle the\n * mutation on the same `request_id`, and sends this push in the meantime.\n * Everything the departure changed is either on the push or implied by it,\n * so these patch and stop — the one field they cannot carry is `ship.fuel`,\n * which the arrival delta corrects a transit later. **Fleet follower\n * arrival** is the other kind: a follower never submitted the mutation, so\n * on a server that cannot tell their connection speaks v2 there is no delta\n * at all, and only then is a reconcile worth its round trip.\n *\n * These pushes carry only the few fields the movement itself changed, so\n * they go through `patchSection` — unlike a server delta, which always\n * carries a complete `location` and is applied with `applyDelta`.\n */\n private applyMovementPush(frame: RawFrame): void {\n if (frame.type !== 'ok' || !isRecord(frame.payload) || typeof frame.payload.action !== 'string') return;\n\n const payload = frame.payload;\n let changed: StateSection[] = [];\n let reconcile = false;\n switch (payload.action) {\n case 'jump':\n case 'fleet_jump': {\n if (typeof payload.destination !== 'string' || typeof payload.arrival_tick !== 'number') {\n this.warnMalformedFrame(frame);\n return;\n }\n changed = this.cache.patchSection('location', {\n ...DEPARTED_SYSTEM,\n in_transit: true,\n transit_arrival_tick: payload.arrival_tick,\n transit_dest_system_id: payload.destination,\n transit_type: 'jump',\n });\n break;\n }\n case 'jumped':\n case 'pathfinder_arrival': {\n if (typeof payload.system_id !== 'string' || typeof payload.system !== 'string') {\n this.warnMalformedFrame(frame);\n return;\n }\n changed = this.cache.patchSection('location', {\n ...ARRIVED_IN_NEW_SYSTEM,\n poi_id: typeof payload.poi === 'string' ? payload.poi : undefined,\n system_id: payload.system_id,\n system_name: payload.system,\n });\n reconcile = true;\n break;\n }\n case 'travel':\n case 'fleet_travel': {\n if (typeof payload.destination !== 'string' || typeof payload.arrival_tick !== 'number') {\n this.warnMalformedFrame(frame);\n return;\n }\n changed = this.cache.patchSection('location', {\n ...DEPARTED,\n in_transit: true,\n transit_arrival_tick: payload.arrival_tick,\n transit_dest_poi_id: payload.destination,\n transit_type: 'travel',\n });\n break;\n }\n case 'arrived': {\n if (typeof payload.poi_id !== 'string' || typeof payload.poi !== 'string') {\n this.warnMalformedFrame(frame);\n return;\n }\n changed = this.cache.patchSection('location', {\n ...ARRIVED,\n poi_id: payload.poi_id,\n poi_name: payload.poi,\n });\n reconcile = true;\n break;\n }\n case 'fleet_undock':\n changed = this.cache.patchSection('location', { docked_at: null });\n break;\n case 'fleet_dock':\n // Older servers send only the station's display name, which is not the\n // base ID `docked_at` holds — reconcile rather than cache the wrong one.\n if (typeof payload.base_id === 'string') {\n changed = this.cache.patchSection('location', { docked_at: payload.base_id });\n } else {\n reconcile = true;\n }\n break;\n default:\n return;\n }\n\n const revision = ++this.stateRevision;\n if (changed.includes('location')) this.checkSubscriptionsAgainstLocation();\n if (changed.length) this.emitStateChange(changed);\n if (reconcile) void this.reconcileFleetState(revision, payload.action);\n }\n\n /**\n * Refill a fleet follower's location from one authoritative snapshot.\n *\n * An arrival push carries the destination's name and little else, so the\n * system-, POI- and presence-scoped fields it invalidates have nothing to\n * refill them and no formula to derive them. This is the one movement gap a\n * round trip is the only answer to, and only on a server that does not send\n * followers a delta — a current one does, and these branches never run.\n *\n * A newer movement push invalidates an older in-flight query so a delayed\n * snapshot cannot move the cache backwards.\n */\n private async reconcileFleetState(revision: number, action: string): Promise<void> {\n try {\n const result = await this.commands.spacemolt.get_status();\n const snapshot = requireStructuredContent(result, 'spacemolt/get_status');\n if (revision !== this.stateRevision) return;\n const changed = this.cache.seed(snapshot);\n if (changed.length) this.stateRevision++;\n if (changed.includes('location')) this.checkSubscriptionsAgainstLocation();\n if (changed.length) this.emitStateChange(changed);\n } catch (err) {\n if (revision === this.stateRevision) {\n console.warn(`[spacemolt] failed to reconcile state after ${action}`, err);\n }\n }\n }\n\n /** Close the connection deliberately. Suppresses auto-reconnect. */\n close(): void {\n this.userClosing = true;\n this.socket.close();\n }\n\n /** Fired after a successful reconnect + re-auth. Returns an unsubscribe function. */\n onReconnected(listener: () => void): () => void {\n this.reconnectedListeners.add(listener);\n return () => {\n this.reconnectedListeners.delete(listener);\n };\n }\n /** Fired at the start of each reconnect attempt (1-based). Returns an unsubscribe function. */\n onReconnecting(listener: (attempt: number) => void): () => void {\n this.reconnectingListeners.add(listener);\n return () => {\n this.reconnectingListeners.delete(listener);\n };\n }\n /**\n * Fired before each rate-limit retry sleep (`query`/`mutate`/`authenticate`\n * auto-retrying a `rate_limited` error) — the delay includes jitter, so\n * accounts rate-limited together don't retry in lockstep; this is what a\n * caller sees per attempt. Returns an unsubscribe function.\n */\n onRateLimited(listener: (info: RateLimitedInfo) => void): () => void {\n this.rateLimitedListeners.add(listener);\n return () => {\n this.rateLimitedListeners.delete(listener);\n };\n }\n /**\n * Fired when the connection is gone for good (non-reconnectable or retries\n * exhausted). Returns an unsubscribe function.\n */\n onDisconnected(listener: (err: ConnectionClosedError) => void): () => void {\n this.disconnectedListeners.add(listener);\n return () => {\n this.disconnectedListeners.delete(listener);\n };\n }\n\n // --- internals ---\n\n private async authExchange(\n action: 'login' | 'login_token',\n payload: Record<string, unknown>,\n ): Promise<LoggedInPayload> {\n let authEntry: PendingAuth | undefined;\n const authPromise = new Promise<LoggedInPayload>((resolve, reject) => {\n const accepted = this.beginAuth(resolve, reject);\n // See the matching comment in `register()` — identity, not just\n // \"accepted\", so this call's catch can't clobber a newer exchange.\n if (accepted) authEntry = this.pendingAuth ?? undefined;\n if (accepted) this.sendFrame('spacemolt_auth', action, payload, this.nextRequestId());\n });\n let state: LoggedInPayload;\n try {\n state = await withTimeout(\n authPromise,\n this.connectTimeoutMs,\n `No auth response received within ${this.connectTimeoutMs}ms`,\n );\n } catch (err) {\n // Only clear `pendingAuth` if it's still the entry this call created —\n // a rejected `beginAuth` (another exchange already in flight) never\n // touched it, and a newer exchange may have replaced it since.\n if (authEntry && this.pendingAuth === authEntry) this.pendingAuth = null;\n throw err;\n }\n this._loginPayload = state;\n await this.maybeSeedState();\n return state;\n }\n\n /** Best-effort seed of the state cache after auth; failures are non-fatal. */\n private async maybeSeedState(): Promise<void> {\n if (!this.seedState) return;\n try {\n await this.refresh();\n } catch {\n // The connection is authenticated; a failed seed just leaves the cache\n // to fill from the first mutation delta. Don't fail auth over it.\n }\n }\n\n /** Returns whether the auth exchange was accepted — a caller must not send its frame when it wasn't. */\n private beginAuth(\n onLoggedIn: (state: LoggedInPayload, registered?: RegisteredFrame['payload']) => void,\n onError: (err: Error) => void,\n ): boolean {\n if (this.pendingAuth) {\n onError(new SpacemoltError('auth_in_progress', 'another auth exchange is already in flight'));\n return false;\n }\n if (this._authenticated) {\n onError(new SpacemoltError('already_authenticated', 'this connection is already authenticated'));\n return false;\n }\n this.pendingAuth = { onLoggedIn, onError };\n return true;\n }\n\n private sendFrame(\n tool: string,\n action: string,\n payload: Record<string, unknown> | undefined,\n requestId: string,\n ): void {\n // While `reconnectOnce` is mid-swap (old socket rejected, new one not yet\n // authenticated), block everything except the auth handshake itself —\n // otherwise a mutation freed by that rejection can land on the fresh,\n // not-yet-authenticated socket and hang until it times out instead of\n // failing immediately. Scoped to that window specifically (not a general\n // \"must be authenticated\" rule) so it doesn't reject a query/mutation\n // sent on a connection `reconnectOnce` never touched. Lifts as soon as the\n // new socket logs in, so the post-auth `get_status` seed still goes out.\n const isAuthHandshake = tool === 'spacemolt_auth' && action !== 'logout';\n if (this.reconnectsPending > 0 && !this._authenticated && !isAuthHandshake) {\n throw new ConnectionClosedError('cannot send: account is reconnecting');\n }\n const frame: InboundFrame = { tool, action, ...(payload ? { payload } : {}), request_id: requestId };\n this.callHook(this.onSend, 'onSend', redactForOnSend(frame));\n this.socket.send(frame);\n }\n\n /**\n * Calls an optional single-callback hook (`onSend`/`onReceive`), swallowing\n * a throw so a broken observer can't stop the frame being sent or routed —\n * same handling as `notifyListeners` for a `Set` of listeners.\n */\n private callHook<A extends unknown[]>(hook: ((...args: A) => void) | undefined, label: string, ...args: A): void {\n if (!hook) return;\n try {\n hook(...args);\n } catch (err) {\n console.warn(`[spacemolt] ${label} hook threw: ${err}`);\n }\n }\n\n private nextRequestId(): string {\n // Skip anything a caller already has in flight — a caller-supplied id is\n // free-form, so it can look exactly like one of ours.\n let id = `r${++this.requestSeq}`;\n while (this.correlator.has(id)) id = `r${++this.requestSeq}`;\n return id;\n }\n\n /**\n * Pick the `request_id` for one frame. A caller-supplied id is echoed by the\n * server unchanged, which is the point — it lets the caller correlate its own\n * in-flight requests. An empty id is treated as no id, because the server\n * drops falsy ids and the request would then hang until it timed out.\n *\n * A caller-supplied id must be unique for the life of the connection, not\n * only while it is in flight. Reusing a live id is refused here. Reusing an\n * id whose request timed out is not detected, and a late frame for the first\n * request then settles the second one with the wrong outcome.\n */\n private claimRequestId(requestId?: string): string {\n if (!requestId) return this.nextRequestId();\n if (this.correlator.has(requestId)) {\n throw new SpacemoltError('duplicate_request_id', `request_id \"${requestId}\" is already in flight`);\n }\n return requestId;\n }\n\n private routeFrame(frame: RawFrame): void {\n this.callHook(this.onReceive, 'onReceive', redactForOnReceive(frame));\n // Any frame carrying a numeric `tick` advances the observed game clock.\n if (isRecord(frame.payload)) this.observeTick(frame.payload.tick);\n switch (frame.type) {\n case 'welcome': {\n if (!isWelcomeFrame(frame)) return this.warnMalformedFrame(frame);\n const payload = frame.payload;\n this._welcome = payload;\n this.observeTick(payload.current_tick);\n this.welcomeWaiter?.resolve(payload);\n this.welcomeWaiter = null;\n return;\n }\n case 'registered':\n if (!isRegisteredFrame(frame)) return this.warnMalformedFrame(frame);\n if (this.pendingAuth) this.pendingAuth.registered = frame.payload;\n return;\n case 'logged_in': {\n if (!isLoggedInFrame(frame)) return this.warnMalformedFrame(frame);\n // The frame guard only checks for a payload object; the shape itself is\n // the server's published LoggedInPayload schema, which LoggedInFrame\n // now carries directly.\n const payload = frame.payload;\n const auth = this.pendingAuth;\n if (auth) {\n this.pendingAuth = null;\n this._authenticated = true;\n auth.onLoggedIn(payload, auth.registered);\n } else {\n this.emitter.emit(frame);\n }\n return;\n }\n case 'action_result': {\n if (!isActionResultFrame(frame)) {\n if (!this.correlator.handle(frame)) this.warnMalformedFrame(frame);\n return;\n }\n const delta = frame.payload.result;\n if (delta) {\n const changed = this.cache.applyDelta(delta);\n if (changed.length) this.stateRevision++;\n if (changed.includes('location')) this.checkSubscriptionsAgainstLocation();\n // A throwing consumer must never block mutation correlation below —\n // that would strand the awaiting mutate()/query() call until its\n // timeout, on a connection that stayed perfectly healthy.\n // emitStateChange guards each listener.\n if (changed.length) this.emitStateChange(changed);\n }\n if (!this.correlator.handle(frame)) {\n // The frame arrived and its delta was already applied to the cache\n // above — this only means the *caller* awaiting this specific\n // request_id is no longer listening, almost always because\n // awaitMutationWithTimeout's fastMutationTimeoutMs/mutationTimeoutMs\n // already fired and called correlator.cancel(). That's a real\n // outcome arriving late, not a truly dropped one — worth knowing\n // about explicitly rather than silently falling through to a\n // notification path nothing listens on.\n //\n // A frame with no request_id at all was never anybody's mutation: it\n // is an unsolicited delta, which is how a fleet follower's arrival\n // reaches them. Nothing timed out, so say nothing.\n if (frame.request_id) {\n console.warn(\n `[spacemolt] action_result for ${frame.request_id} arrived with no matching pending mutation (already timed out?)`,\n );\n }\n this.emitter.emit(frame);\n }\n return;\n }\n case 'result':\n case 'action_error':\n if (!this.correlator.handle(frame)) this.emitter.emit(frame);\n return;\n case 'error': {\n if (!isErrorFrame(frame)) {\n if (!this.correlator.handle(frame)) this.warnMalformedFrame(frame);\n return;\n }\n if (this.correlator.handle(frame)) return;\n const auth = this.pendingAuth;\n if (auth) {\n this.pendingAuth = null;\n auth.onError(errorFromFrame(frame));\n return;\n }\n this.emitter.emit(frame);\n return;\n }\n default:\n this.applyMovementPush(frame);\n this.emitter.emit(frame);\n }\n }\n\n private warnMalformedFrame(frame: RawFrame): void {\n console.warn(`[spacemolt] dropped malformed ${frame.type} frame`);\n }\n\n /**\n * Fails everything waiting on the current socket: in-flight correlator\n * entries (query/mutate), a pending `welcome` wait, and a pending auth\n * exchange (`login`/`register`/`loginToken`). Deliberately excludes\n * `emitter.closeStreams()`: `handleClose` (a real close) still ends the\n * player's event async iterators itself, but a `reconnectOnce` forced on a\n * live socket leaves them running. Shared by `handleClose` and\n * `reconnectOnce`, which both strand work on a socket that's going away.\n */\n private failPendingWork(err: ConnectionClosedError): void {\n this._authenticated = false;\n this.correlator.rejectAll(err);\n if (this.welcomeWaiter) {\n const waiter = this.welcomeWaiter;\n this.welcomeWaiter = null;\n waiter.reject(err);\n }\n if (this.pendingAuth) {\n const auth = this.pendingAuth;\n this.pendingAuth = null;\n auth.onError(err);\n }\n }\n\n private handleClose(err: ConnectionClosedError): void {\n // Reject with the original err (not a wrapped SpacemoltError) so its\n // code/reason survive — e.g. a 4003 connection_rate_limited close's\n // retry_after hint, which reconnectLoop/client.connect() honor.\n this.failPendingWork(err);\n this.emitter.closeStreams();\n // A reconnect loop is running: each of its attempts wires a fresh socket\n // back here, so an attempt's close lands in this handler. The loop owns\n // the terminal decision — reporting it here would fire `onDisconnected`\n // once per attempt while retries remain. Hand the close to the loop\n // instead; it decides whether to retry, give up, or discard a\n // \"successful\" attempt whose socket died on the way up.\n if (this.reconnecting) {\n this.attemptClose = err;\n return;\n }\n if (this.shouldReconnect(err)) {\n void this.reconnectLoop(err);\n } else if (!this.userClosing) {\n notifyListeners(this.disconnectedListeners, 'onDisconnected', err);\n }\n }\n\n private shouldReconnect(err: ConnectionClosedError): boolean {\n if (!this.reconnectConfig || this.userClosing || this.reconnecting) return false;\n if (!this.credentialsProvider) return false;\n return !isTerminalClose(err);\n }\n\n private async reconnectLoop(err: ConnectionClosedError): Promise<void> {\n if (this.reconnecting || !this.reconnectConfig || !this.credentialsProvider) return;\n this.reconnecting = true;\n const cfg = this.reconnectConfig;\n // A 4003 close carries an authoritative retry_after hint from the\n // server — honor it for the first attempt instead of guessing with\n // exponential backoff, which risks retrying before the server's window\n // has actually rolled over and tripping the same limit again.\n const retryAfterMs = retryAfterMsFromClose(err);\n for (let attempt = 1; attempt <= cfg.maxRetries; attempt++) {\n if (this.userClosing) {\n this.reconnecting = false;\n return;\n }\n notifyListeners(this.reconnectingListeners, 'onReconnecting', attempt);\n const backoff =\n attempt === 1 && retryAfterMs !== undefined\n ? retryAfterMs\n : Math.min(cfg.baseDelayMs * 2 ** (attempt - 1), cfg.maxDelayMs);\n await delay(backoff);\n if (this.userClosing) {\n this.reconnecting = false;\n return;\n }\n this.attemptClose = null;\n try {\n await this.reconnectOnce();\n // `reconnectOnce` can resolve over a socket that already died —\n // `resubscribe` is best-effort, so a close during it is not thrown.\n // A recorded close means the attempt did not actually hold.\n if (!this.attemptClose) {\n this.reconnecting = false;\n notifyListeners(this.reconnectedListeners, 'onReconnected');\n return;\n }\n } catch {\n // fall through: retry, or give up on a terminal close below\n }\n if (this.attemptClose && isTerminalClose(this.attemptClose)) break;\n }\n const finalErr = this.attemptClose && isTerminalClose(this.attemptClose) ? this.attemptClose : err;\n this.reconnecting = false;\n // A deliberate `close()` is terminal but silent — same as the\n // non-reconnecting path in `handleClose`.\n if (!this.userClosing) notifyListeners(this.disconnectedListeners, 'onDisconnected', finalErr);\n }\n\n /**\n * Reconnect this account's underlying connection in place: a fresh socket,\n * re-authenticated, subscriptions restored — while preserving this\n * instance's identity (cache, correlator, every wired listener). A single\n * attempt with no internal retry/backoff; the caller owns retry pacing\n * (this account's own `reconnectLoop`, or `SpacemoltClient`'s rate-limited\n * queue for a client-managed account — see `handleAccountDisconnected`).\n * Requires `credentials` (constructor option).\n *\n * Closes the current socket first — a no-op on the normal disconnect path\n * (already closed), but avoids orphaning a still-open one if this is ever\n * called outside that path (e.g. a future forced reconnect while a socket\n * is technically still alive but not receiving pushes).\n */\n async reconnectOnce(): Promise<void> {\n if (!this.credentialsProvider) throw new Error('reconnectOnce requires credentials');\n // A caller may run this long after it was scheduled (SpacemoltClient's\n // queue), and close() may land mid-way. A closed account must not log\n // back in: that session would replace any newer one for the player.\n const stopIfClosed = (): void => {\n if (!this.userClosing) return;\n this.socket.close();\n throw new ConnectionClosedError('account was closed');\n };\n stopIfClosed();\n this.socket.close();\n // The old socket's close event is ignored once makeSocket below replaces\n // `this.socket` (the identity guard in makeSocket), so handleClose never\n // runs for it and anything still in flight on it -- a query/mutation, a\n // stranded `welcome` wait, a stranded login/register -- would otherwise\n // hang until its own timeout. `failPendingWork` (shared with handleClose)\n // rejects all of it now, before the new socket exists, so nothing sent on\n // it is caught up in this and, critically, `pendingAuth` is free before\n // `authenticate` below tries to claim it -- otherwise that call finds\n // `beginAuth` already occupied by the stranded attempt and rejects with\n // `auth_in_progress` while the stranded promise resolves later off the\n // new socket's reply instead.\n //\n // `failPendingWork` clears `_authenticated` first: rejecting a mutation's\n // correlator entry frees `enqueueMutation`'s lane, so a queued mutation's\n // task can run on the very next microtask -- before `makeSocket`/\n // `authenticate` below have run. `sendFrame`'s guard (reconnectsPending &&\n // !_authenticated) is what stops it from reaching the new, not-yet-\n // authenticated socket instead of hanging on it; the guard lifts at\n // logged_in, so the post-auth seed runs.\n //\n // `reconnectsPending` is a narrower guard than \"not authenticated\" — it's\n // only true for this window, so it can't reject a query/mutation any\n // other caller (including tests that drive query/mutate directly,\n // without a full auth handshake) legitimately sends on a connection this\n // method never touched.\n this.reconnectsPending++;\n this.failPendingWork(new ConnectionClosedError('account is reconnecting'));\n try {\n this.makeSocket();\n await this.open();\n stopIfClosed();\n await this.authenticate(await this.credentialsProvider());\n stopIfClosed();\n } finally {\n this.reconnectsPending--;\n }\n await this.resubscribe();\n }\n\n private async resubscribe(): Promise<void> {\n if (this.marketSubscribedState) {\n try {\n await this.subscribeMarket();\n } catch {\n /* best-effort */\n }\n }\n if (this.observationSubscribedState) {\n try {\n await this.subscribeObservation(this.observationActiveScanState);\n } catch {\n /* best-effort */\n }\n }\n }\n\n /**\n * Runs `fn`, retrying on a `rate_limited` `SpacemoltError` up to\n * `maxRateLimitRetries` times. The wait is jittered (see `jitteredDelayMs`)\n * so accounts rate-limited together don't all retry in lockstep, and fires\n * `onRateLimited` before each sleep. `command` identifies the call for that\n * listener (`tool.action`, or `'authenticate'`).\n */\n private async withRateLimitRetry<T>(command: string, fn: () => Promise<T>): Promise<T> {\n for (let attempt = 0; ; attempt++) {\n try {\n return await fn();\n } catch (err) {\n if (err instanceof SpacemoltError && err.code === 'rate_limited' && attempt < this.maxRateLimitRetries) {\n const delayMs = jitteredDelayMs(retryAfterMs(err));\n notifyListeners(this.rateLimitedListeners, 'onRateLimited', { command, attempt: attempt + 1, delayMs });\n await delay(delayMs);\n continue;\n }\n throw err;\n }\n }\n }\n\n /** Serialize mutations: each runs only after the previous settles. */\n private enqueueMutation<T>(task: () => Promise<T>): Promise<T> {\n const run = this.mutationLane.then(task, task);\n this.mutationLane = run.then(\n () => undefined,\n () => undefined,\n );\n return run;\n }\n}\n",
|
|
20
|
+
"/**\n * Pluggable credential storage for multi-account use.\n *\n * The `CredentialStore` interface is the only persistence seam in the library;\n * swap the implementation to control where credentials live (memory, a file,\n * the browser, a secrets manager, …). The core never imports Node built-ins —\n * the file-backed store does, and lives here in `src/auth/` for that reason.\n */\n\nimport { isRecord } from '../validation.ts';\n\n/**\n * How an account authenticates. Raw credentials (login / login_token / register)\n * plus `clerk`: a Clerk API key + the owned player's id, from which the account\n * mints a fresh single-use WS token on each (re)connect (see `src/auth/clerk.ts`).\n */\nexport type AuthCredentials =\n | { kind: 'login'; username: string; password: string }\n | { kind: 'login_token'; token: string }\n | { kind: 'clerk'; apiKey: string; playerId: string; httpBaseUrl: string }\n | { kind: 'register'; username: string; empire: string; registration_code?: string };\n\nexport interface StoredAccount {\n /** Stable handle for this account within the client (e.g. the username). */\n id: string;\n credentials: AuthCredentials;\n /** Filled in after a successful auth. */\n playerId?: string;\n}\n\nexport interface CredentialStore {\n list(): Promise<StoredAccount[]>;\n get(id: string): Promise<StoredAccount | undefined>;\n put(account: StoredAccount): Promise<void>;\n remove(id: string): Promise<void>;\n}\n\nfunction hasString(value: Record<string, unknown>, key: string): boolean {\n return typeof value[key] === 'string';\n}\n\nexport function isStoredAccount(value: unknown): value is StoredAccount {\n if (!isRecord(value) || !hasString(value, 'id') || !isRecord(value.credentials)) return false;\n const credentials = value.credentials;\n switch (credentials.kind) {\n case 'login':\n return hasString(credentials, 'username') && hasString(credentials, 'password');\n case 'login_token':\n return hasString(credentials, 'token');\n case 'clerk':\n return (\n hasString(credentials, 'apiKey') && hasString(credentials, 'playerId') && hasString(credentials, 'httpBaseUrl')\n );\n case 'register':\n return (\n hasString(credentials, 'username') &&\n hasString(credentials, 'empire') &&\n (credentials.registration_code === undefined || typeof credentials.registration_code === 'string')\n );\n default:\n return false;\n }\n}\n\n/** In-memory store. The default; nothing is persisted across process restarts. */\nexport class MemoryCredentialStore implements CredentialStore {\n private readonly accounts = new Map<string, StoredAccount>();\n\n list(): Promise<StoredAccount[]> {\n return Promise.resolve([...this.accounts.values()]);\n }\n get(id: string): Promise<StoredAccount | undefined> {\n return Promise.resolve(this.accounts.get(id));\n }\n put(account: StoredAccount): Promise<void> {\n this.accounts.set(account.id, account);\n return Promise.resolve();\n }\n remove(id: string): Promise<void> {\n this.accounts.delete(id);\n return Promise.resolve();\n }\n}\n",
|
|
21
|
+
"import { HttpError } from '../errors.ts';\nimport { jitteredDelayMs } from '../jitter.ts';\n\n/**\n * Shared HTTP GET for the library's bulk/live data fetches (catalog, map,\n * stations, mobile-base). Bounds every request — including reading the\n * response body, not just its headers — with a timeout, retries a transient\n * `429`/`503` a few times (honoring `Retry-After` when the server sends one,\n * jittered the same way as the WebSocket side's rate-limit retry — see\n * `jitteredDelayMs`), and reports a retry-exhausted or otherwise non-ok\n * response as a typed `HttpError`. A timeout or network error is not an\n * `HttpError` — it throws the native `DOMException`/`TypeError` as-is.\n * `MAX_RETRY_WAIT_MS` caps the *total* base wait across every attempt, not\n * each attempt checked in isolation.\n */\n\nconst MAX_RETRIES = 3;\nconst BASE_BACKOFF_MS = 500;\nconst MAX_RETRY_WAIT_MS = 60_000;\n\nconst delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\n/** Parses `Retry-After` as delta-seconds or an HTTP-date. Returns ms to wait, or undefined if unparseable. */\nfunction parseRetryAfterMs(header: string | null): number | undefined {\n if (!header) return undefined;\n const seconds = Number(header);\n if (!Number.isNaN(seconds)) return Math.max(0, seconds * 1000);\n const dateMs = Date.parse(header);\n return Number.isNaN(dateMs) ? undefined : Math.max(0, dateMs - Date.now());\n}\n\n/** Options every public data fetcher accepts. */\nexport interface FetchOptions {\n /** Inject a `fetch` implementation (tests, observability). Defaults to global `fetch`. */\n fetchImpl?: typeof fetch;\n /** Abort each request after this many ms, body included. Default 30000. */\n timeoutMs?: number;\n}\n\nexport interface HttpGetOptions {\n headers?: Record<string, string>;\n /** Abort the request after this many ms (`AbortSignal.timeout`). Default 30000. */\n timeoutMs?: number;\n /**\n * Inject a `fetch` implementation — tests, custom runtimes, or an\n * observability wrapper (status/bytes/timing/retries) a consumer supplies\n * via `SpacemoltClientOptions.fetchImpl` / the per-call `fetchImpl` option.\n * Defaults to global `fetch`.\n */\n fetchImpl?: typeof fetch;\n /** Response statuses besides 2xx to return rather than treat as a failure (e.g. 304). */\n okStatuses?: readonly number[];\n /**\n * Total (un-jittered) base retry wait allowed across every attempt before\n * giving up — not re-checked per attempt in isolation. Default\n * `MAX_RETRY_WAIT_MS` (60000). Mainly for tests that need a small cap to\n * exercise this without waiting real seconds.\n */\n maxRetryWaitMs?: number;\n}\n\n/**\n * `GET url`, bounded by `timeoutMs` (headers and body both) and retried up to\n * `MAX_RETRIES` times on `429`/`503` (waiting `Retry-After` when present,\n * else a short backoff — either way, jittered). A timeout or network error is\n * not retried — it throws the native error as-is, not an `HttpError`. Any\n * other non-ok, non-`okStatuses` response throws an `HttpError`.\n */\nexport async function httpGet(url: string, opts: HttpGetOptions = {}): Promise<Response> {\n const { headers, timeoutMs = 30_000, fetchImpl = fetch, okStatuses = [], maxRetryWaitMs = MAX_RETRY_WAIT_MS } = opts;\n let totalBaseWaitMs = 0;\n for (let attempt = 1; ; attempt++) {\n const res = await fetchImpl(url, { headers, signal: AbortSignal.timeout(timeoutMs) });\n if (res.ok || okStatuses.includes(res.status)) return res;\n const retryAfterMs = parseRetryAfterMs(res.headers.get('retry-after'));\n const baseWaitMs = retryAfterMs ?? BASE_BACKOFF_MS * 2 ** (attempt - 1);\n // The cap is on the total (un-jittered) base wait across every attempt,\n // not each attempt in isolation — 3 retries of a 60s Retry-After would\n // otherwise sleep ~3x the cap in total. Checked against the un-jittered\n // base so jitter can't push a wait just under the limit over it (or vice\n // versa).\n const retryable = (res.status === 429 || res.status === 503) && totalBaseWaitMs + baseWaitMs <= maxRetryWaitMs;\n if (retryable && attempt <= MAX_RETRIES) {\n totalBaseWaitMs += baseWaitMs;\n await res.body?.cancel().catch(() => {});\n await delay(jitteredDelayMs(baseWaitMs));\n continue;\n }\n await res.body?.cancel().catch(() => {});\n throw new HttpError(`GET ${url} -> ${res.status} ${res.statusText}`, {\n status: res.status,\n url,\n attempts: attempt,\n retryAfterMs,\n });\n }\n}\n",
|
|
22
|
+
"import type {\n CatalogAchievement,\n CatalogDump,\n FacilityDefinition,\n Item,\n MiningConstants,\n Module,\n Recipe,\n ShipClass,\n SkillDefinition,\n} from '../generated/openapi/types.gen.ts';\nimport { type FetchOptions, httpGet } from './http.ts';\nimport { isRecord, requireRecord } from '../validation.ts';\n\n/**\n * Local copy of the bulk game catalog (`GET /api/catalog.json`).\n *\n * Reference data — ships, items, recipes, skills, facilities — that changes\n * only on a server release. Entry shapes come from the spec's published\n * `CatalogDump` component types (`ShipClass`, `Item`/`Module`, `Recipe`,\n * `SkillDefinition`, `FacilityDefinition`), so they track the server via the\n * spec sync. Entries are structurally validated as JSON objects and then\n * trusted to match the spec — the same trust model as state-cache deltas.\n *\n * The payload is large (multiple MB), so the server ships it `public,\n * max-age=3600` with a content-hash `ETag`. We keep that ETag on the cache and\n * revalidate conditionally (`If-None-Match`): an unchanged catalog comes back as\n * a ~0-byte `304 Not Modified`, so a long-lived client can cheaply pick up a new\n * catalog after a server release instead of holding the copy it fetched at\n * startup forever (see `SpacemoltClient.catalog`).\n */\n\n/** A ship entry — the spec's `ShipClass` (the dump omits live prices). */\nexport type CatalogShip = ShipClass;\n/** An item entry — regular items and modules share the merged `items` list. */\nexport type CatalogItem = Item | Module;\nexport type CatalogRecipe = Recipe;\nexport type CatalogSkill = SkillDefinition;\nexport type CatalogFacility = FacilityDefinition;\n/** An achievement entry — the same shape for player and faction achievements. */\nexport type { CatalogAchievement };\n\n/**\n * The normalized catalog. Derived from the spec's `CatalogDump` rather than\n * restated field by field, so a section the server adds breaks `typecheck`\n * here instead of being silently dropped by `normalizeCatalog` — which is how\n * the achievements sections went missing until v0.573.1.\n */\nexport type Catalog = Omit<CatalogDump, 'ships' | 'items' | 'recipes' | 'skills' | 'facilities'> & {\n ships: CatalogShip[];\n items: CatalogItem[];\n recipes: CatalogRecipe[];\n skills: CatalogSkill[];\n facilities: CatalogFacility[];\n};\n\n/** Result of a conditional catalog fetch. */\nexport interface CatalogFetchResult {\n /** True when the server answered `304 Not Modified` — `catalog` is absent. */\n notModified: boolean;\n /** The freshly fetched catalog (absent on a 304). */\n catalog?: Catalog;\n /** The server's `ETag` for the returned (or still-current) catalog, if any. */\n etag?: string;\n}\n\nfunction catalogEntries<T>(value: unknown): T[] {\n return Array.isArray(value) ? (value.filter(isRecord) as T[]) : [];\n}\n\nfunction normalizeCatalog(value: unknown): Catalog {\n const data = requireRecord(value, 'catalog response');\n return {\n version: typeof data.version === 'string' ? data.version : '',\n mining: (isRecord(data.mining) ? data.mining : {}) as MiningConstants,\n ships: catalogEntries<CatalogShip>(data.ships),\n items: catalogEntries<CatalogItem>(data.items),\n recipes: catalogEntries<CatalogRecipe>(data.recipes),\n skills: catalogEntries<CatalogSkill>(data.skills),\n facilities: catalogEntries<CatalogFacility>(data.facilities),\n achievements: catalogEntries<CatalogAchievement>(data.achievements),\n faction_achievements: catalogEntries<CatalogAchievement>(data.faction_achievements),\n hidden_achievement_count: typeof data.hidden_achievement_count === 'number' ? data.hidden_achievement_count : 0,\n hidden_faction_achievement_count:\n typeof data.hidden_faction_achievement_count === 'number' ? data.hidden_faction_achievement_count : 0,\n };\n}\n\n/**\n * Fetch the catalog, optionally conditional on a previously seen `ETag`. When\n * `etag` is passed and the server confirms the catalog is unchanged, this\n * returns `{ notModified: true }` after a ~0-byte `304` — no multi-MB download\n * or re-parse. Otherwise it returns the fresh catalog and its new `ETag`.\n *\n * Bounded by a request timeout and retried on a transient `429`/`503`; a\n * failure that isn't a 304 throws `HttpError`. Pass `fetchImpl` to inject a\n * `fetch` (tests, or an observability wrapper — see `httpGet`).\n */\nexport async function fetchCatalogConditional(\n httpBaseUrl: string,\n etag?: string,\n opts: FetchOptions = {},\n): Promise<CatalogFetchResult> {\n const url = `${httpBaseUrl.replace(/\\/$/, '')}/api/catalog.json`;\n const headers: Record<string, string> = { accept: 'application/json' };\n if (etag) headers['if-none-match'] = etag;\n const res = await httpGet(url, { headers, fetchImpl: opts.fetchImpl, timeoutMs: opts.timeoutMs, okStatuses: [304] });\n if (res.status === 304) return { notModified: true, etag };\n const data: unknown = await res.json();\n return {\n notModified: false,\n catalog: normalizeCatalog(data),\n etag: res.headers?.get?.('etag') ?? undefined,\n };\n}\n\n/** Unconditionally fetch and normalize the catalog. See `fetchCatalogConditional` for `fetchImpl`. */\nexport async function fetchCatalog(httpBaseUrl: string, opts: FetchOptions = {}): Promise<Catalog> {\n const { catalog } = await fetchCatalogConditional(httpBaseUrl, undefined, opts);\n if (!catalog) throw new Error('unconditional catalog fetch returned no catalog');\n return catalog;\n}\n\nexport class CatalogCache {\n private readonly shipsById: Map<string, CatalogShip>;\n private readonly itemsById: Map<string, CatalogItem>;\n private readonly recipesById: Map<string, CatalogRecipe>;\n private readonly skillsById: Map<string, CatalogSkill>;\n private readonly facilitiesById: Map<string, CatalogFacility>;\n private readonly achievementsById: Map<string, CatalogAchievement>;\n\n constructor(\n readonly catalog: Catalog,\n /** The server `ETag` this catalog was fetched with, for conditional reloads. */\n readonly etag?: string,\n ) {\n this.shipsById = index(catalog.ships);\n this.itemsById = index(catalog.items);\n this.recipesById = index(catalog.recipes);\n this.skillsById = index(catalog.skills);\n this.facilitiesById = index(catalog.facilities);\n this.achievementsById = index([...catalog.achievements, ...catalog.faction_achievements]);\n }\n\n /** Fetch the catalog and wrap it in a cache. */\n static async load(httpBaseUrl: string, opts: FetchOptions = {}): Promise<CatalogCache> {\n const { catalog, etag } = await fetchCatalogConditional(httpBaseUrl, undefined, opts);\n if (!catalog) throw new Error('unconditional catalog fetch returned no catalog');\n return new CatalogCache(catalog, etag);\n }\n\n /**\n * Conditionally refresh via `If-None-Match`. Returns `this` unchanged when the\n * server confirms the catalog is still current (a cheap `304`), or a new\n * `CatalogCache` when the catalog has changed.\n */\n async revalidate(httpBaseUrl: string, opts: FetchOptions = {}): Promise<CatalogCache> {\n const result = await fetchCatalogConditional(httpBaseUrl, this.etag, opts);\n if (result.notModified) return this;\n if (!result.catalog) throw new Error('modified catalog response returned no catalog');\n return new CatalogCache(result.catalog, result.etag);\n }\n\n /** Server release this catalog was built for; `''` if the response omitted it. */\n get version(): string {\n return this.catalog.version;\n }\n\n ship(id: string): CatalogShip | undefined {\n return this.shipsById.get(id);\n }\n item(id: string): CatalogItem | undefined {\n return this.itemsById.get(id);\n }\n recipe(id: string): CatalogRecipe | undefined {\n return this.recipesById.get(id);\n }\n skill(id: string): CatalogSkill | undefined {\n return this.skillsById.get(id);\n }\n facility(id: string): CatalogFacility | undefined {\n return this.facilitiesById.get(id);\n }\n /** Looks up player and faction achievements alike — the ids share one space. */\n achievement(id: string): CatalogAchievement | undefined {\n return this.achievementsById.get(id);\n }\n\n get ships(): readonly CatalogShip[] {\n return this.catalog.ships;\n }\n get items(): readonly CatalogItem[] {\n return this.catalog.items;\n }\n get recipes(): readonly CatalogRecipe[] {\n return this.catalog.recipes;\n }\n get skills(): readonly CatalogSkill[] {\n return this.catalog.skills;\n }\n get facilities(): readonly CatalogFacility[] {\n return this.catalog.facilities;\n }\n get achievements(): readonly CatalogAchievement[] {\n return this.catalog.achievements;\n }\n get factionAchievements(): readonly CatalogAchievement[] {\n return this.catalog.faction_achievements;\n }\n /**\n * Achievements the server withholds from the catalog until earned, reported\n * as a count so a client can show \"9 hidden\" rather than imply the list is\n * complete.\n */\n get hiddenAchievementCount(): number {\n return this.catalog.hidden_achievement_count;\n }\n get hiddenFactionAchievementCount(): number {\n return this.catalog.hidden_faction_achievement_count;\n }\n}\n\nfunction index<T>(entries: T[]): Map<string, T> {\n const map = new Map<string, T>();\n for (const entry of entries) {\n const id = isRecord(entry) && typeof entry.id === 'string' ? entry.id : undefined;\n if (id) map.set(id, entry);\n }\n return map;\n}\n",
|
|
23
|
+
"import type { MapData, MapDataSystem } from '../generated/openapi/types.gen.ts';\nimport { type FetchOptions, httpGet } from './http.ts';\nimport { isRecord, requireRecord } from '../validation.ts';\n\n/**\n * Local copy of the static galaxy map (`GET /api/map`).\n *\n * Returns `{ systems, empires }` where `empires` maps an empire id to a display\n * colour. Static per release; the separate `/api/map/activity` overlay (online\n * counts, battles) changes frequently and is not cached here.\n *\n * Both shapes come from the spec. `MapDataSystem` is the entry this endpoint\n * actually returns (`id` with flat `x`/`y`), published under its own name so it\n * no longer collides with the v2 map *command*'s `MapSystem` (`system_id`, a\n * nested `position`) — which used to win the name and make `MapData.systems`\n * document a shape this endpoint never sends.\n */\n\n/** A system entry from `GET /api/map`. */\nexport type MapSystem = MapDataSystem;\n\nexport type GalaxyMap = MapData;\n\nexport async function fetchMap(httpBaseUrl: string, opts: FetchOptions = {}): Promise<GalaxyMap> {\n const url = `${httpBaseUrl.replace(/\\/$/, '')}/api/map`;\n const res = await httpGet(url, {\n headers: { accept: 'application/json' },\n fetchImpl: opts.fetchImpl,\n timeoutMs: opts.timeoutMs,\n });\n const data = requireRecord(await res.json(), 'map response');\n const systems = Array.isArray(data.systems)\n ? data.systems.filter((system): system is MapSystem => isRecord(system))\n : [];\n const empires = isRecord(data.empires)\n ? Object.fromEntries(\n Object.entries(data.empires).filter((entry): entry is [string, string] => typeof entry[1] === 'string'),\n )\n : {};\n return { systems, empires };\n}\n\nexport class MapCache {\n private readonly bySystemId: Map<string, MapSystem>;\n\n constructor(readonly map: GalaxyMap) {\n this.bySystemId = new Map();\n for (const system of map.systems) {\n const id = typeof system.id === 'string' ? system.id : undefined;\n if (id) this.bySystemId.set(id, system);\n }\n }\n\n /** Fetch the galaxy map and wrap it in a cache. */\n static async load(httpBaseUrl: string, opts: FetchOptions = {}): Promise<MapCache> {\n return new MapCache(await fetchMap(httpBaseUrl, opts));\n }\n\n system(id: string): MapSystem | undefined {\n return this.bySystemId.get(id);\n }\n get systems(): readonly MapSystem[] {\n return this.map.systems;\n }\n /** Empire id -> display colour. */\n get empires(): Record<string, string> {\n return this.map.empires;\n }\n}\n\n/** Derive the HTTP origin from a WebSocket URL (wss://host/ws/v2 -> https://host). */\nexport function httpBaseFromWs(wsUrl: string): string {\n try {\n const u = new URL(wsUrl);\n const protocol = u.protocol === 'wss:' ? 'https:' : u.protocol === 'ws:' ? 'http:' : u.protocol;\n return `${protocol}//${u.host}`;\n } catch {\n return wsUrl;\n }\n}\n",
|
|
24
|
+
"import type { MobileBaseLocation } from '../generated/openapi/types.gen.ts';\nimport { type FetchOptions, httpGet } from './http.ts';\nimport { requireRecord } from '../validation.ts';\n\n/**\n * Where the galaxy's single moving capital currently is\n * (`GET /wheres-mobile-base`).\n *\n * The mobile base relocates as the game runs, so this is live data — fetch it\n * when you need it rather than caching it like the catalog or map. The response\n * is the spec's published `MobileBaseLocation` (`{ system }`), a system id that\n * indexes into the galaxy map.\n */\n\n/** Fetch the mobile base's current system id. Pass `fetchImpl` to inject a `fetch` (tests, observability). */\nexport async function fetchMobileBase(httpBaseUrl: string, opts: FetchOptions = {}): Promise<MobileBaseLocation> {\n const url = `${httpBaseUrl.replace(/\\/$/, '')}/wheres-mobile-base`;\n const res = await httpGet(url, {\n headers: { accept: 'application/json' },\n fetchImpl: opts.fetchImpl,\n timeoutMs: opts.timeoutMs,\n });\n const data = requireRecord(await res.json(), 'mobile base response');\n if (typeof data.system !== 'string') throw new Error('mobile base response is missing a system id');\n return { system: data.system };\n}\n\nexport type { MobileBaseLocation };\n",
|
|
25
|
+
"import { type FetchOptions, httpGet } from './http.ts';\nimport { isRecord, requireRecord } from '../validation.ts';\n\n/**\n * Station directory (`GET /api/stations`).\n *\n * A public summary of every station in the galaxy — identity, owning\n * empire/faction, system, offered services, condition, and defensive posture —\n * plus the empire display list the server sends alongside it. Live data (the\n * server caches it for ~10s), so fetch on demand rather than caching like the\n * catalog or map.\n *\n * These shapes mirror the server's station list response; they aren't\n * published in the OpenAPI spec yet (see docs/gameserver-todo.md), so they're\n * hand-typed here and kept tolerant of server-side additions via the index\n * signature.\n */\n\nexport interface StationSummary {\n id: string;\n /**\n * Base ID for this station — the identifier `location.docked_at` reports and\n * that base-scoped commands (market, storage, services) take, so this is the\n * join between the directory and live state. Distinct from `id`.\n */\n base_id: string;\n /** POI the station sits at — the identifier `travel` takes. */\n poi_id: string;\n name: string;\n description: string;\n /** Base type, e.g. `station` or `outpost`. */\n type: string;\n empire?: string;\n empire_name?: string;\n faction_id?: string;\n faction_name?: string;\n faction_tag?: string;\n faction_color?: string;\n system_id: string;\n system_name: string;\n services: string[];\n condition: string;\n condition_text: string;\n satisfaction_pct: number;\n facility_count: number;\n /** Damage per tick the station's armed guns can actually deliver — zero when its batteries are out of shells. */\n weapon_dps: number;\n wrecked: boolean;\n [key: string]: unknown;\n}\n\n/** An empire display entry from the station list (`{ id, name }`). */\nexport interface StationEmpire {\n id: string;\n name: string;\n}\n\nexport interface StationList {\n stations: StationSummary[];\n empires: StationEmpire[];\n}\n\n/** Fetch the public station directory. Pass `fetchImpl` to inject a `fetch` (tests, observability). */\nexport async function fetchStations(httpBaseUrl: string, opts: FetchOptions = {}): Promise<StationList> {\n const url = `${httpBaseUrl.replace(/\\/$/, '')}/api/stations`;\n const res = await httpGet(url, {\n headers: { accept: 'application/json' },\n fetchImpl: opts.fetchImpl,\n timeoutMs: opts.timeoutMs,\n });\n const data = requireRecord(await res.json(), 'stations response');\n const stations = Array.isArray(data.stations) ? (data.stations.filter(isRecord) as StationSummary[]) : [];\n const empires = Array.isArray(data.empires)\n ? data.empires.filter(\n (empire): empire is StationEmpire =>\n isRecord(empire) && typeof empire.id === 'string' && typeof empire.name === 'string',\n )\n : [];\n return { stations, empires };\n}\n",
|
|
26
|
+
"/**\n * Multi-account client.\n *\n * Manages N authenticated `Account` connections, persisting their credentials\n * through a pluggable `CredentialStore`. Connecting many accounts is staggered\n * to stay under the server's per-IP login/connection rate limits — the server\n * itself advises \"reuse one session per bot for its lifetime\", so the intended\n * pattern is: add accounts once, `connectAll()` at startup, keep them open.\n */\n\nimport { Account } from './account.ts';\nimport {\n type AuthCredentials,\n type CredentialStore,\n MemoryCredentialStore,\n type StoredAccount,\n} from './auth/credentials.ts';\nimport type { WebSocketFactory } from './transport/socket.ts';\nimport type { InboundFrame, RawFrame } from './protocol.ts';\nimport type { ReconnectOptions, RegisterParams, RegisterResult } from './account.ts';\nimport { CatalogCache } from './data/catalog.ts';\nimport type { FetchOptions } from './data/http.ts';\nimport { notifyListeners } from './events/emitter.ts';\nimport { MapCache, httpBaseFromWs } from './data/map.ts';\nimport { fetchMobileBase, type MobileBaseLocation } from './data/mobile-base.ts';\nimport { fetchStations, type StationList } from './data/stations.ts';\nimport { ClerkSource, type ClerkPlayer } from './auth/clerk.ts';\nimport { CLOSE_CODE, type ConnectionClosedError, retryAfterMsFromClose } from './errors.ts';\n\nconst DEFAULT_HTTP_BASE = 'https://game.spacemolt.com';\n\nexport interface SpacemoltClientOptions {\n /** WebSocket URL of the v2 endpoint. */\n url?: string;\n /** Where credentials live. Defaults to an in-memory store. */\n store?: CredentialStore;\n /** Inject a WebSocket implementation (tests, custom runtimes). */\n webSocketFactory?: WebSocketFactory;\n /** Observe every outbound frame on every managed account (see Account). */\n onSend?: (accountId: string, frame: InboundFrame) => void;\n /** Observe every inbound frame on every managed account (see Account). */\n onReceive?: (accountId: string, frame: RawFrame) => void;\n /** Seed each account's state cache after auth (see Account). Default true. */\n seedState?: boolean;\n /**\n * Delay between connecting accounts. Default is derived from\n * `connectBatchSize` (`60_000 / connectBatchSize` — 600ms for the default\n * batch size of 100), guaranteeing a batch can't finish in under a minute\n * regardless of how fast each connect() actually completes — a flat\n * 250ms doesn't guarantee that (see `connectIds`). Set explicitly to\n * override that computed default with your own value (trusted as-is, not\n * a floor) — e.g. for a smaller test fleet where finishing fast is fine.\n */\n connectStaggerMs?: number;\n /**\n * Max accounts to connect before pausing for `connectBatchWaitMs`, so a\n * fleet never actually trips the server's per-IP WS-connection rate limit\n * (hitting it risks an IP-level timeout/ban on repeat offense — better to\n * never ask). Matches the server's default connection cap (100/min), so a\n * fleet at or under this size behaves exactly like a single stagger pass,\n * same as before; a larger fleet connects in batches of this size instead.\n * Default 100.\n */\n connectBatchSize?: number;\n /**\n * Pause between batches once `connectBatchSize` is exceeded, letting the\n * server's per-IP rate-limit window (1 minute by default) fully roll over\n * before the next batch starts. Default 65000 (65s — a margin over the\n * server's 1-minute window).\n */\n connectBatchWaitMs?: number;\n /**\n * Reconnect an account after an unexpected disconnect (a dropped\n * WebSocket after it was already connected — see `connectRetry` for the\n * initial connect instead). Default `true`. Driven by the client itself\n * (not each `Account`'s own standalone reconnect logic), reconnecting the\n * *same* `Account` instance in place (`Account.reconnectOnce` — fresh\n * socket, re-authenticated, subscriptions restored) rather than replacing\n * it, so anything holding a direct reference (e.g. a running loop) keeps\n * working transparently. Paced through the same rate-limited queue used\n * for the initial connect — see `handleAccountDisconnected` — so a mass\n * disconnect (e.g. every account dropped at once by a game-server restart)\n * reconnects the fleet through the same `connectBatchSize`/\n * `connectStaggerMs`/`connectBatchWaitMs` pacing, instead of every account\n * racing an independent timer. Pass `false` to leave a dropped account\n * disconnected instead (see `onAccountDisconnected`). If you pass a\n * `ReconnectOptions` object, only its truthiness matters — reconnect\n * pacing comes from `connectRetry` (the same backoff config used for the\n * initial connect), not this option's own `maxRetries`/`baseDelayMs`/\n * `maxDelayMs`. Never reconnects after a deliberate `close()`/`remove()`,\n * a `session_replaced`, or an `auth_timeout`. Token-only accounts can't\n * reconnect (the token is single-use).\n */\n reconnect?: boolean | ReconnectOptions;\n /** HTTP origin for bulk data fetches. Defaults to the origin of `url`. */\n httpBaseUrl?: string;\n /**\n * How long `catalog()` serves its cached copy before revalidating against the\n * server. The catalog only changes on a server release, but a long-lived\n * client that fetched it once at startup would otherwise keep serving that\n * copy indefinitely — days stale across a release. Past this age the next\n * `catalog()` call revalidates conditionally (`If-None-Match`): an unchanged\n * catalog is a ~0-byte `304` (near-free), a changed one is re-downloaded.\n * Matches the server's own `max-age`. Default 3600000 (1h). Set `0` to\n * revalidate on every call, or `Infinity` to cache for the client's lifetime\n * (the old fetch-once behavior).\n */\n catalogMaxAgeMs?: number;\n /**\n * Clerk API key for `connectOwned()` / `listOwnedPlayers()` — connect every\n * game account the Clerk user owns without storing per-account passwords.\n * Generate one from the website; keep it secret.\n */\n clerkApiKey?: string;\n /**\n * Inject a `fetch` implementation (tests, custom runtimes). The per-call\n * timeout is delivered via `init.signal` (an `AbortSignal`), not a\n * separate argument — a wrapper must pass `init` through to the real\n * `fetch` unchanged or it silently loses the timeout.\n */\n fetchImpl?: typeof fetch;\n /**\n * Abort each HTTP data fetch (catalog, map, stations, mobile base) after this\n * many ms, body included. Default 30000. Raise it on a slow link: the catalog\n * is several MB.\n */\n httpTimeoutMs?: number;\n /**\n * How long to wait for the server's `welcome` frame (post-WS-upgrade) and\n * for a `logged_in`/error response to an auth attempt, before giving up.\n * Without this, a connection the server silently never completes (accepts\n * the WS upgrade but never responds) hangs forever with no error and no\n * retry — this can't be told apart from \"still connecting\" from the\n * outside. Default 15000 (15s — generous over the ~150-300ms a healthy\n * connect actually takes, per live measurement).\n */\n connectTimeoutMs?: number;\n /**\n * How long to wait for a query's response before giving up. Unlike a\n * mutation (which can legitimately take minutes, e.g. a travel/jump's\n * transit time), a query has no legitimate reason to take long — bounding\n * it turns a silently-dropped response into a clean error instead of a\n * permanent hang. Default 15000 (15s).\n */\n queryTimeoutMs?: number;\n /**\n * How long to wait, after a mutation's pending ack arrives, for its final\n * `action_result`/`action_error` outcome before giving up. Generous by\n * design — some mutations legitimately take many ticks (a jump/travel's\n * transit time is distance-based and can run minutes) — but not infinite:\n * without this, a single silently-dropped outcome frame hangs forever AND\n * wedges every subsequent mutation on that account behind it (mutations\n * are serialized per account). Default 600000 (10 minutes).\n */\n mutationTimeoutMs?: number;\n /**\n * Fallback safety net: retry a failed `connect()` (the raw WebSocket\n * handshake, before any auth frame) with backoff instead of dropping the\n * account. `connectBatchSize`/`connectBatchWaitMs` above are the primary\n * defense — they're sized to avoid ever tripping the server's per-IP\n * WS-connection rate limit in the first place — but this covers the\n * unexpected case anyway (e.g. other traffic sharing the IP eating into\n * the budget), since a 429 on the handshake surfaces as a plain\n * `ConnectionClosedError` — not a `SpacemoltError` with `code:\n * 'rate_limited'` — so it can't be told apart from a genuine connection\n * failure and isn't covered by `Account`'s targeted rate-limit retry.\n * Default `true` (enabled). Pass `false` to disable and fail fast instead.\n */\n connectRetry?: boolean | ReconnectOptions;\n}\n\nconst DEFAULT_CONNECT_RETRY: Required<ReconnectOptions> = { maxRetries: 8, baseDelayMs: 2000, maxDelayMs: 60_000 };\n\n/** Assumed length of the server's per-IP WS-connection rate-limit window. */\nconst CONNECT_RATE_WINDOW_MS = 60_000;\n\nconst delay = (ms: number): Promise<void> => new Promise((resolve) => setTimeout(resolve, ms));\n\nexport class SpacemoltClient {\n private readonly store: CredentialStore;\n private readonly connected = new Map<string, Account>();\n private catalogCache?: CatalogCache;\n private catalogFetchedAt = 0;\n private mapCache?: MapCache;\n private clerkSource?: ClerkSource;\n private readonly accountConnectedListeners = new Set<(account: Account) => void>();\n private readonly accountReconnectedListeners = new Set<(account: Account) => void>();\n private readonly accountDisconnectedListeners = new Set<(id: string, err: ConnectionClosedError) => void>();\n /** Paced by connectBatchSize/connectStaggerMs/connectBatchWaitMs — the same limiter drains both the initial fleet connect and later reconnects, see `enqueueRateLimited`. */\n private readonly rateLimitedQueue: Array<() => Promise<void>> = [];\n private rateLimitedQueueDraining = false;\n /**\n * Ids currently mid-reconnect. Guards against a socket dropping again\n * *during* `reconnectAccountInPlace` (e.g. another rate-limit close before\n * auth completes) re-firing `handleAccountDisconnected` and enqueuing a\n * second, parallel reconnect chain for the same id — the drop instead\n * surfaces as a failure inside the one already-running `withConnectRetry`\n * loop, which retries it itself.\n */\n private readonly reconnectingIds = new Set<string>();\n\n constructor(private readonly opts: SpacemoltClientOptions = {}) {\n this.store = opts.store ?? new MemoryCredentialStore();\n }\n\n /**\n * Fires the first time an id becomes a connected+authenticated `Account`\n * instance — the initial connect (`connect`/`connectAll`/`connectOwned`/\n * `register`). Does NOT fire again for a later reconnect after an\n * unexpected disconnect — that reuses the same instance in place (see\n * `Account.reconnectOnce`) rather than creating a new one, so there's\n * nothing new to index/re-wire; see `onAccountReconnected` for that event\n * instead. Unlike `connectAll`'s/`connectOwned`'s per-call `onConnect`\n * option (scoped to that one call), this is a persistent subscription.\n * Returns an unsubscribe function.\n */\n onAccountConnected(listener: (account: Account) => void): () => void {\n this.accountConnectedListeners.add(listener);\n return () => this.accountConnectedListeners.delete(listener);\n }\n\n /**\n * Fires after an already-connected account's connection is restored\n * following an unexpected disconnect — the same `Account` instance\n * throughout, reconnected in place. Purely informational (e.g. logging);\n * nothing needs re-indexing since the instance never changed. Returns an\n * unsubscribe function.\n */\n onAccountReconnected(listener: (account: Account) => void): () => void {\n this.accountReconnectedListeners.add(listener);\n return () => this.accountReconnectedListeners.delete(listener);\n }\n\n /**\n * Fires when an account is dropped for good: a terminal close (session\n * replaced by another connection, or an auth timeout) that this client\n * deliberately does not reconnect after, or a reconnect attempt that\n * exhausted its retries. Silent otherwise today — this is the only\n * visibility a caller has into that. Returns an unsubscribe function.\n */\n onAccountDisconnected(listener: (id: string, err: ConnectionClosedError) => void): () => void {\n this.accountDisconnectedListeners.add(listener);\n return () => this.accountDisconnectedListeners.delete(listener);\n }\n\n private notifyAccountConnected(account: Account): void {\n notifyListeners(this.accountConnectedListeners, 'onAccountConnected', account);\n }\n\n private notifyAccountReconnected(account: Account): void {\n notifyListeners(this.accountReconnectedListeners, 'onAccountReconnected', account);\n }\n\n private notifyAccountDisconnected(id: string, err: ConnectionClosedError): void {\n notifyListeners(this.accountDisconnectedListeners, 'onAccountDisconnected', id, err);\n }\n\n /** HTTP origin used for bulk data fetches (catalog, map). */\n get httpBaseUrl(): string {\n return this.opts.httpBaseUrl ?? (this.opts.url ? httpBaseFromWs(this.opts.url) : DEFAULT_HTTP_BASE);\n }\n\n private get httpOptions(): FetchOptions {\n return { fetchImpl: this.opts.fetchImpl, timeoutMs: this.opts.httpTimeoutMs };\n }\n\n /**\n * The bulk catalog. Fetched on first use and cached, then revalidated against\n * the server once the cache is older than `catalogMaxAgeMs` (default 1h) so a\n * long-lived client picks up a new catalog after a server release instead of\n * serving a days-stale copy. Revalidation is conditional (`If-None-Match`), so\n * an unchanged catalog costs a ~0-byte `304` and the cached instance is kept.\n * Pass `force` to refetch unconditionally now.\n */\n async catalog(force = false): Promise<CatalogCache> {\n const maxAgeMs = this.opts.catalogMaxAgeMs ?? 3_600_000;\n const cached = this.catalogCache;\n const fresh = cached && !force && Date.now() - this.catalogFetchedAt < maxAgeMs;\n if (fresh) return cached;\n\n this.catalogCache =\n !this.catalogCache || force\n ? await CatalogCache.load(this.httpBaseUrl, this.httpOptions)\n : await this.catalogCache.revalidate(this.httpBaseUrl, this.httpOptions);\n this.catalogFetchedAt = Date.now();\n return this.catalogCache;\n }\n\n /** The static galaxy map, fetched once and cached. Pass `force` to refetch. */\n async map(force = false): Promise<MapCache> {\n if (force || !this.mapCache) this.mapCache = await MapCache.load(this.httpBaseUrl, this.httpOptions);\n return this.mapCache;\n }\n\n /** The live station directory. Not cached — it changes as the game runs. */\n stations(): Promise<StationList> {\n return fetchStations(this.httpBaseUrl, this.httpOptions);\n }\n\n /** The mobile base's current system. Not cached — it moves. */\n mobileBase(): Promise<MobileBaseLocation> {\n return fetchMobileBase(this.httpBaseUrl, this.httpOptions);\n }\n\n /** The credential store backing this client. */\n get credentialStore(): CredentialStore {\n return this.store;\n }\n\n // --- credential management (persist; does not connect) ---\n\n /** Persist username/password credentials. Returns the account id (username). */\n async addLogin(username: string, password: string): Promise<string> {\n await this.store.put({ id: username, credentials: { kind: 'login', username, password } });\n return username;\n }\n\n /** Persist a login-token credential under an explicit id. */\n async addToken(id: string, token: string): Promise<string> {\n await this.store.put({ id, credentials: { kind: 'login_token', token } });\n return id;\n }\n\n // --- connecting ---\n\n /**\n * Register a brand-new account: connect, register, and persist the generated\n * password as login credentials (keyed by username) for future sessions.\n */\n async register(params: RegisterParams): Promise<{ account: Account; result: RegisterResult }> {\n const account = this.createAccount(params.username);\n this.connected.set(params.username, account);\n try {\n await account.connect();\n const result = await account.register(params);\n await this.store.put({\n id: params.username,\n credentials: { kind: 'login', username: params.username, password: result.password },\n playerId: result.player_id,\n });\n account.onDisconnected((err) => this.handleAccountDisconnected(params.username, account, err));\n this.notifyAccountConnected(account);\n return { account, result };\n } catch (error) {\n account.close();\n this.connected.delete(params.username);\n throw error;\n }\n }\n\n /** Resolves `connectRetry` into a concrete backoff config. */\n private connectRetryConfig(): Required<ReconnectOptions> {\n const retryOpt = this.opts.connectRetry ?? true;\n if (retryOpt === false) return { maxRetries: 0, baseDelayMs: 0, maxDelayMs: 0 };\n return { ...DEFAULT_CONNECT_RETRY, ...(retryOpt === true ? {} : retryOpt) };\n }\n\n /**\n * Retry `attempt` with the shared `connectRetry` backoff, honoring a 4003\n * `connection_rate_limited` close's `retry_after` hint over the\n * exponential fallback. Shared by the initial connect (`connect`) and an\n * in-place reconnect (`reconnectAccountInPlace`) so both back off\n * identically.\n */\n private async withConnectRetry<T>(attempt: () => Promise<T>): Promise<T> {\n const retry = this.connectRetryConfig();\n let lastErr: unknown;\n for (let i = 0; i <= retry.maxRetries; i++) {\n try {\n return await attempt();\n } catch (err) {\n lastErr = err;\n if (i < retry.maxRetries) {\n const retryAfterMs = retryAfterMsFromClose(err);\n await delay(retryAfterMs ?? Math.min(retry.baseDelayMs * 2 ** i, retry.maxDelayMs));\n }\n }\n }\n throw lastErr;\n }\n\n /**\n * Connect and authenticate one stored account. Idempotent per id.\n *\n * Retries the whole connect+authenticate sequence with backoff on failure\n * (see `connectRetry`) — a fleet large enough to exceed the per-IP\n * WS-connection rate limit sees some accounts rejected at the handshake,\n * which self-heals once the server's rate-limit window rolls over.\n */\n async connect(id: string): Promise<Account> {\n const existing = this.connected.get(id);\n if (existing) return existing;\n const stored = await this.store.get(id);\n if (!stored) throw new Error(`no stored credentials for account \"${id}\"`);\n\n return this.withConnectRetry(async () => {\n const account = this.createAccount(id);\n this.connected.set(id, account);\n try {\n await account.connect();\n await account.authenticate(stored.credentials);\n await this.capturePlayerId(stored);\n // Only start listening for a later drop once the account has\n // actually completed its first successful connect — a close\n // *during* this attempt is `connectRetry`'s job (the catch block\n // below), not a reconnect-after-established-connection event; wiring\n // this any earlier raced this same attempt's own retry loop with a\n // second, uncoordinated one triggered by the very close that just\n // failed it.\n account.onDisconnected((err) => this.handleAccountDisconnected(id, account, err));\n this.notifyAccountConnected(account);\n return account;\n } catch (err) {\n this.connected.delete(id);\n account.close();\n throw err;\n }\n });\n }\n\n /** Connect every stored account, staggered to respect rate limits. */\n async connectAll(opts: { onConnect?: (account: Account) => void } = {}): Promise<Account[]> {\n const stored = await this.store.list();\n return this.connectIds(\n stored.map((s) => s.id),\n opts.onConnect,\n );\n }\n\n // --- Clerk multi-account (connect every account you own) ---\n\n /** List the player accounts the Clerk user owns. Requires `clerkApiKey`. */\n async listOwnedPlayers(): Promise<ClerkPlayer[]> {\n return this.requireClerkAuth().source.listPlayers();\n }\n\n /**\n * Connect every account the Clerk user owns (optionally filtered), staggered\n * to respect rate limits. Stores a `clerk` credential per player — each\n * account mints a fresh single-use WS token on connect and reconnect, so no\n * passwords are persisted. Requires `clerkApiKey`.\n *\n * A fleet-wide call can legitimately take minutes (see `connectIds`'s\n * pacing) — `onConnect` fires as each account finishes, so a caller can\n * index/use accounts incrementally instead of only after the whole batch\n * settles (the returned promise still doesn't resolve until every account\n * has been attempted).\n */\n async connectOwned(\n opts: { filter?: (player: ClerkPlayer) => boolean; onConnect?: (account: Account) => void } = {},\n ): Promise<Account[]> {\n const { source, apiKey } = this.requireClerkAuth();\n const players = await source.listPlayers();\n const selected = opts.filter ? players.filter(opts.filter) : players;\n const ids: string[] = [];\n for (const player of selected) {\n await this.store.put({\n id: player.username,\n credentials: {\n kind: 'clerk',\n apiKey,\n playerId: player.id,\n httpBaseUrl: source.httpBaseUrl,\n },\n playerId: player.id,\n });\n ids.push(player.username);\n }\n return this.connectIds(ids, opts.onConnect);\n }\n\n private requireClerkAuth(): { source: ClerkSource; apiKey: string } {\n const apiKey = this.opts.clerkApiKey;\n if (!apiKey) {\n throw new Error('connectOwned/listOwnedPlayers require `clerkApiKey` in SpacemoltClientOptions');\n }\n this.clerkSource ??= new ClerkSource({\n apiKey,\n httpBaseUrl: this.httpBaseUrl,\n fetchImpl: this.opts.fetchImpl,\n });\n return { source: this.clerkSource, apiKey };\n }\n\n /**\n * Connect the given stored ids, staggered to respect rate limits. At or\n * under `connectBatchSize` accounts this is a single stagger pass — the\n * same behavior as before batching existed. Past that, it pauses for\n * `connectBatchWaitMs` between batches so the fleet never actually asks\n * for more connections than the server's per-IP window allows. A single\n * account failing to connect must not abort the rest of the batch — it's\n * logged and skipped so the caller still gets every account that succeeded.\n *\n * `onConnect` fires synchronously as each id finishes (success only) so a\n * caller managing many accounts (e.g. indexing them for lookup) doesn't\n * have to wait for the entire — potentially minutes-long — batch before\n * any single account becomes usable.\n *\n * Pacing itself is `enqueueRateLimited` — the same queue a later\n * reconnect (see `handleAccountDisconnected`) competes for a slot in, so a\n * reconnect landing mid-batch is paced fairly alongside the rest of the\n * fleet instead of racing it on a separate timer.\n */\n private async connectIds(ids: string[], onConnect?: (account: Account) => void): Promise<Account[]> {\n const accounts: Account[] = [];\n await Promise.all(\n ids.map((id) =>\n this.enqueueRateLimited(() => this.connect(id))\n .then((account) => {\n accounts.push(account);\n onConnect?.(account);\n })\n .catch((err: unknown) => {\n console.warn(`[spacemolt] failed to connect \"${id}\": ${err}`);\n }),\n ),\n );\n return accounts;\n }\n\n /**\n * Enqueues `task`, paced by `connectBatchSize`/`connectStaggerMs`/\n * `connectBatchWaitMs` — the single rate limiter shared by the initial\n * fleet connect (`connectIds`) and every later reconnect\n * (`handleAccountDisconnected`), so the server's per-IP WS-connection cap\n * is respected by one mechanism, not a parallel one for each case. Returns\n * a promise settling with `task`'s own outcome once its turn comes up.\n */\n private enqueueRateLimited<T>(task: () => Promise<T>): Promise<T> {\n return new Promise<T>((resolve, reject) => {\n this.rateLimitedQueue.push(async () => {\n try {\n resolve(await task());\n } catch (err) {\n reject(err);\n }\n });\n void this.drainRateLimitedQueue();\n });\n }\n\n private async drainRateLimitedQueue(): Promise<void> {\n if (this.rateLimitedQueueDraining) return;\n this.rateLimitedQueueDraining = true;\n // Default stagger is derived from batchSize so a full batch can never\n // finish in under a minute regardless of how fast each connect() call\n // actually completes. A flat 250ms alone doesn't guarantee this: 100\n // accounts at 250ms apart, plus a healthy ~150-300ms connect time each,\n // finishes in ~45s — silently exceeding the server's 100/min per-IP\n // WS-connection cap (verified live: connecting 100 accounts this fast\n // trips it, hanging accounts 101+ instead of a clean rejection). An\n // explicit connectStaggerMs is trusted as the caller's deliberate\n // override, same as connectBatchSize <= 0 already opts out of batching\n // protection entirely.\n const batchSize = this.opts.connectBatchSize ?? 100;\n const stagger = this.opts.connectStaggerMs ?? (batchSize > 0 ? Math.ceil(CONNECT_RATE_WINDOW_MS / batchSize) : 250);\n const batchWaitMs = this.opts.connectBatchWaitMs ?? 65_000;\n let ranInCurrentBatch = 0;\n let isFirst = true;\n while (this.rateLimitedQueue.length > 0) {\n if (!isFirst) {\n if (batchSize > 0 && ranInCurrentBatch >= batchSize) {\n await delay(batchWaitMs);\n ranInCurrentBatch = 0;\n } else if (stagger > 0) {\n await delay(stagger);\n }\n }\n isFirst = false;\n const task = this.rateLimitedQueue.shift();\n if (!task) break;\n ranInCurrentBatch++;\n await task();\n }\n this.rateLimitedQueueDraining = false;\n }\n\n // --- access ---\n\n /** The connected account for an id, if connected. */\n account(id: string): Account | undefined {\n return this.connected.get(id);\n }\n /** All currently-connected accounts. */\n accounts(): Account[] {\n return [...this.connected.values()];\n }\n /** Ids of all currently-connected accounts. */\n ids(): string[] {\n return [...this.connected.keys()];\n }\n\n /** Close and forget an account, and remove its stored credentials. */\n async remove(id: string): Promise<void> {\n this.connected.get(id)?.close();\n this.connected.delete(id);\n await this.store.remove(id);\n }\n\n /** Close every connection (credentials remain in the store). */\n closeAll(): void {\n for (const account of this.connected.values()) account.close();\n this.connected.clear();\n }\n\n // --- internals ---\n\n /**\n * Reconnection for a client-managed account is driven here, not by the\n * `Account`'s own (disabled — see `createAccount`) reconnect logic: an\n * unexpected disconnect closes every affected account at once (e.g. a\n * game-server restart), and reconnecting through the same rate-limited\n * queue used for the initial connect — instead of each account racing its\n * own independent timer — is what keeps a mass reconnect from re-tripping\n * the server's per-IP WS-connection rate limit right as it recovers.\n *\n * Reconnects in place (`Account.reconnectOnce`, same instance) rather than\n * replacing the account with a new one: anything holding a direct\n * reference to this `Account` (e.g. a running loop, which captures it once\n * at start) keeps working transparently once the connection is restored,\n * instead of being welded to a now-dead instance nobody is driving.\n */\n private handleAccountDisconnected(id: string, account: Account, err: ConnectionClosedError): void {\n // A newer instance (the account was removed) has already superseded\n // this one, or a reconnect is already in flight for it — a socket\n // dropping again *during* reconnectAccountInPlace (e.g. another\n // rate-limit close before auth completes) re-fires this same listener\n // on the same persistent instance; without this check it would enqueue\n // a second, parallel reconnect chain instead of letting the one already\n // running retry it.\n if (this.connected.get(id) !== account || this.reconnectingIds.has(id)) {\n return;\n }\n\n // session_replaced: another connection took our slot — reconnecting\n // would just fight it. auth_timeout: we failed to auth in time. Neither\n // is worth retrying (mirrors Account.shouldReconnect's old per-account\n // logic, now made here instead since the client owns this decision).\n const terminal = err.code === CLOSE_CODE.SESSION_REPLACED || err.code === CLOSE_CODE.AUTH_TIMEOUT;\n if (terminal || this.opts.reconnect === false) {\n this.connected.delete(id);\n this.notifyAccountDisconnected(id, err);\n return;\n }\n\n this.reconnectingIds.add(id);\n // remove()/closeAll() can drop the account while this waits in the queue\n // or retries; from then on there is nothing to reconnect or report.\n const wanted = (): boolean => this.connected.get(id) === account;\n void this.enqueueRateLimited(() =>\n this.withConnectRetry(async () => (wanted() ? account.reconnectOnce() : undefined)),\n )\n .then(() => {\n if (wanted()) this.notifyAccountReconnected(account);\n })\n .catch((reconnectErr: unknown) => {\n if (!wanted()) return;\n console.warn(`[spacemolt] failed to reconnect \"${id}\": ${reconnectErr}`);\n this.connected.delete(id);\n this.notifyAccountDisconnected(id, err);\n })\n .finally(() => this.reconnectingIds.delete(id));\n }\n\n private createAccount(id: string): Account {\n const account = new Account({\n id,\n url: this.opts.url,\n webSocketFactory: this.opts.webSocketFactory,\n onSend: this.opts.onSend && ((f) => this.opts.onSend?.(id, f)),\n onReceive: this.opts.onReceive && ((f) => this.opts.onReceive?.(id, f)),\n seedState: this.opts.seedState,\n // The client owns reconnection for its managed accounts (see\n // handleAccountDisconnected) instead of each Account reconnecting\n // independently — always false here regardless of\n // SpacemoltClientOptions.reconnect, which now only controls whether\n // the *client* reconnects a dropped account, not how the Account\n // itself would.\n reconnect: false,\n fetchImpl: this.opts.fetchImpl,\n connectTimeoutMs: this.opts.connectTimeoutMs,\n queryTimeoutMs: this.opts.queryTimeoutMs,\n mutationTimeoutMs: this.opts.mutationTimeoutMs,\n credentials: async () => {\n const stored = await this.store.get(id);\n if (!stored) throw new Error(`no stored credentials for account \"${id}\"`);\n return stored.credentials;\n },\n });\n return account;\n }\n\n private async capturePlayerId(stored: StoredAccount): Promise<void> {\n const playerId = this.connected.get(stored.id)?.player?.id;\n if (playerId && playerId !== stored.playerId) {\n await this.store.put({ ...stored, playerId });\n }\n }\n}\n\nexport type { AuthCredentials, CredentialStore, StoredAccount };\n",
|
|
27
|
+
"// AUTO-GENERATED by scripts/generate.ts from openapi.json. DO NOT EDIT.\n// Server push frames carry a `type` (msg_type) and a `payload`. The server\n// publishes a typed schema for some of them as `Notification_<msg_type>`;\n// those are imported below. Push frames without a published schema fall back\n// to `Record<string, unknown>` until the server types them (incremental work).\n\nimport type {\n NotificationAchievementUnlocked,\n NotificationActionError,\n NotificationActionResult,\n NotificationArenaChallenge,\n NotificationArenaObjective,\n NotificationBaseDestroyed,\n NotificationBaseRaidUpdate,\n NotificationBattleAlert,\n NotificationBattleDamage,\n NotificationBattleEnded,\n NotificationBattleJoined,\n NotificationBattleLeft,\n NotificationBattleStarted,\n NotificationBattleUpdate,\n NotificationChatMessage,\n NotificationCloak,\n NotificationCompleteMission,\n NotificationCraftingUpdate,\n NotificationDroneAdrift,\n NotificationDroneDestroyed,\n NotificationDroneScan,\n NotificationDroneSurvey,\n NotificationDroneUpdate,\n NotificationError,\n NotificationFacilityReclaimed,\n NotificationFacilityRentWarning,\n NotificationFactionAllianceBroken,\n NotificationFactionAllianceFormed,\n NotificationFactionAllianceProposal,\n NotificationFactionMobileBaseUpdate,\n NotificationFactionPeaceAccepted,\n NotificationFactionPeaceProposal,\n NotificationFactionWarDeclared,\n NotificationFleet,\n NotificationGiftReceived,\n NotificationMarketUpdate,\n NotificationMiningYield,\n NotificationObservationUpdate,\n NotificationOk,\n NotificationPersonnelUpdate,\n NotificationPilotlessShip,\n NotificationPirateDestroyed,\n NotificationPirateRadio,\n NotificationPlayerDied,\n NotificationPlayerKill,\n NotificationPrizeUpdate,\n NotificationRanchPoached,\n NotificationReconnected,\n NotificationRefueledBy,\n NotificationRepairedBy,\n NotificationScanDetected,\n NotificationServerRestartWarning,\n NotificationShipCaptured,\n NotificationShipCommissionComplete,\n NotificationSkillLevelUp,\n NotificationStationRepaired,\n NotificationTradeCancelled,\n NotificationTradeComplete,\n NotificationTradeDeclined,\n NotificationTradeOfferReceived,\n} from './openapi/types.gen.ts';\n\n/** msg_type values that have a published payload schema. */\nexport type TypedNotificationType =\n | \"achievement_unlocked\"\n | \"action_error\"\n | \"action_result\"\n | \"arena_challenge\"\n | \"arena_objective\"\n | \"base_destroyed\"\n | \"base_raid_update\"\n | \"battle_alert\"\n | \"battle_damage\"\n | \"battle_ended\"\n | \"battle_joined\"\n | \"battle_left\"\n | \"battle_started\"\n | \"battle_update\"\n | \"chat_message\"\n | \"cloak\"\n | \"complete_mission\"\n | \"crafting_update\"\n | \"drone_adrift\"\n | \"drone_destroyed\"\n | \"drone_scan\"\n | \"drone_survey\"\n | \"drone_update\"\n | \"error\"\n | \"facility_reclaimed\"\n | \"facility_rent_warning\"\n | \"faction_alliance_broken\"\n | \"faction_alliance_formed\"\n | \"faction_alliance_proposal\"\n | \"faction_mobile_base_update\"\n | \"faction_peace_accepted\"\n | \"faction_peace_proposal\"\n | \"faction_war_declared\"\n | \"fleet\"\n | \"gift_received\"\n | \"market_update\"\n | \"mining_yield\"\n | \"observation_update\"\n | \"ok\"\n | \"personnel_update\"\n | \"pilotless_ship\"\n | \"pirate_destroyed\"\n | \"pirate_radio\"\n | \"player_died\"\n | \"player_kill\"\n | \"prize_update\"\n | \"ranch_poached\"\n | \"reconnected\"\n | \"refueled_by\"\n | \"repaired_by\"\n | \"scan_detected\"\n | \"server_restart_warning\"\n | \"ship_captured\"\n | \"ship_commission_complete\"\n | \"skill_level_up\"\n | \"station_repaired\"\n | \"trade_cancelled\"\n | \"trade_complete\"\n | \"trade_declined\"\n | \"trade_offer_received\";\n\n/** Maps a typed push msg_type to its payload type. */\nexport interface NotificationPayloads {\n \"achievement_unlocked\": NotificationAchievementUnlocked;\n \"action_error\": NotificationActionError;\n \"action_result\": NotificationActionResult;\n \"arena_challenge\": NotificationArenaChallenge;\n \"arena_objective\": NotificationArenaObjective;\n \"base_destroyed\": NotificationBaseDestroyed;\n \"base_raid_update\": NotificationBaseRaidUpdate;\n \"battle_alert\": NotificationBattleAlert;\n \"battle_damage\": NotificationBattleDamage;\n \"battle_ended\": NotificationBattleEnded;\n \"battle_joined\": NotificationBattleJoined;\n \"battle_left\": NotificationBattleLeft;\n \"battle_started\": NotificationBattleStarted;\n \"battle_update\": NotificationBattleUpdate;\n \"chat_message\": NotificationChatMessage;\n \"cloak\": NotificationCloak;\n \"complete_mission\": NotificationCompleteMission;\n \"crafting_update\": NotificationCraftingUpdate;\n \"drone_adrift\": NotificationDroneAdrift;\n \"drone_destroyed\": NotificationDroneDestroyed;\n \"drone_scan\": NotificationDroneScan;\n \"drone_survey\": NotificationDroneSurvey;\n \"drone_update\": NotificationDroneUpdate;\n \"error\": NotificationError;\n \"facility_reclaimed\": NotificationFacilityReclaimed;\n \"facility_rent_warning\": NotificationFacilityRentWarning;\n \"faction_alliance_broken\": NotificationFactionAllianceBroken;\n \"faction_alliance_formed\": NotificationFactionAllianceFormed;\n \"faction_alliance_proposal\": NotificationFactionAllianceProposal;\n \"faction_mobile_base_update\": NotificationFactionMobileBaseUpdate;\n \"faction_peace_accepted\": NotificationFactionPeaceAccepted;\n \"faction_peace_proposal\": NotificationFactionPeaceProposal;\n \"faction_war_declared\": NotificationFactionWarDeclared;\n \"fleet\": NotificationFleet;\n \"gift_received\": NotificationGiftReceived;\n \"market_update\": NotificationMarketUpdate;\n \"mining_yield\": NotificationMiningYield;\n \"observation_update\": NotificationObservationUpdate;\n \"ok\": NotificationOk;\n \"personnel_update\": NotificationPersonnelUpdate;\n \"pilotless_ship\": NotificationPilotlessShip;\n \"pirate_destroyed\": NotificationPirateDestroyed;\n \"pirate_radio\": NotificationPirateRadio;\n \"player_died\": NotificationPlayerDied;\n \"player_kill\": NotificationPlayerKill;\n \"prize_update\": NotificationPrizeUpdate;\n \"ranch_poached\": NotificationRanchPoached;\n \"reconnected\": NotificationReconnected;\n \"refueled_by\": NotificationRefueledBy;\n \"repaired_by\": NotificationRepairedBy;\n \"scan_detected\": NotificationScanDetected;\n \"server_restart_warning\": NotificationServerRestartWarning;\n \"ship_captured\": NotificationShipCaptured;\n \"ship_commission_complete\": NotificationShipCommissionComplete;\n \"skill_level_up\": NotificationSkillLevelUp;\n \"station_repaired\": NotificationStationRepaired;\n \"trade_cancelled\": NotificationTradeCancelled;\n \"trade_complete\": NotificationTradeComplete;\n \"trade_declined\": NotificationTradeDeclined;\n \"trade_offer_received\": NotificationTradeOfferReceived;\n}\n\n/** Names of every push msg_type with a published schema, for runtime checks. */\nexport const TYPED_NOTIFICATION_TYPES = [\n \"achievement_unlocked\",\n \"action_error\",\n \"action_result\",\n \"arena_challenge\",\n \"arena_objective\",\n \"base_destroyed\",\n \"base_raid_update\",\n \"battle_alert\",\n \"battle_damage\",\n \"battle_ended\",\n \"battle_joined\",\n \"battle_left\",\n \"battle_started\",\n \"battle_update\",\n \"chat_message\",\n \"cloak\",\n \"complete_mission\",\n \"crafting_update\",\n \"drone_adrift\",\n \"drone_destroyed\",\n \"drone_scan\",\n \"drone_survey\",\n \"drone_update\",\n \"error\",\n \"facility_reclaimed\",\n \"facility_rent_warning\",\n \"faction_alliance_broken\",\n \"faction_alliance_formed\",\n \"faction_alliance_proposal\",\n \"faction_mobile_base_update\",\n \"faction_peace_accepted\",\n \"faction_peace_proposal\",\n \"faction_war_declared\",\n \"fleet\",\n \"gift_received\",\n \"market_update\",\n \"mining_yield\",\n \"observation_update\",\n \"ok\",\n \"personnel_update\",\n \"pilotless_ship\",\n \"pirate_destroyed\",\n \"pirate_radio\",\n \"player_died\",\n \"player_kill\",\n \"prize_update\",\n \"ranch_poached\",\n \"reconnected\",\n \"refueled_by\",\n \"repaired_by\",\n \"scan_detected\",\n \"server_restart_warning\",\n \"ship_captured\",\n \"ship_commission_complete\",\n \"skill_level_up\",\n \"station_repaired\",\n \"trade_cancelled\",\n \"trade_complete\",\n \"trade_declined\",\n \"trade_offer_received\",\n] as const;\n",
|
|
28
|
+
"/**\n * Hand-written payload types for the `ok` and `fleet` push frames.\n *\n * Every other push frame is typed from the server's published\n * `Notification_<msg_type>` schema, and the generated `NotificationPayloads`\n * map carries it. These two families publish only a single flat object each —\n * optional fields and a free-form `action` string, covering a few variants — so\n * the generated type cannot narrow to a variant's fields.\n *\n * They are hand-written rather than published because splitting them into\n * distinct `msg_type`s is the fix, and that breaks any v1 client switching on\n * `type === \"ok\"`. Until v1 is retired the shapes live here.\n * `tests/push-frames.test.ts` fails the moment the server publishes either\n * schema as a union, which is the signal to delete this file and let codegen\n * take over.\n *\n * **Two discriminators.** Most `ok` variants key on `action`; seven key on\n * `type` instead. That split is the server's, not ours, so a bare `p.action`\n * does not compile on `OkPush` — guard with `'action' in p` first, or narrow to\n * `OkActionPush` / `OkTypePush`. `FleetPush` has a single key and needs no guard.\n *\n * **The unions are closed**, derived from gameserver v0.596.2. A member typed\n * `{ action: string }` to absorb later frames would join every literal's\n * narrowing and make all of them useless. The cost is that a variant the server\n * adds after that build still arrives at your `on('ok')` handler — nothing\n * validates the payload against these types — as a value matching no member. An\n * exhaustive `switch` with a `never` default therefore compiles but is unsafe at\n * runtime; give it a real default branch.\n */\n\nimport type {\n AttackNpcResponse,\n AttackPlayerResponse,\n DockResponse,\n EspionageResponse,\n JumpResponse,\n PathfinderJumpResponse,\n TravelResponse,\n} from './generated/openapi/types.gen.ts';\n\n/** Human-readable summary, carried by the hand-written variants below. */\ninterface PushBase {\n message?: string;\n}\n\n// --- `ok` pushes discriminated by `action` -----------------------------------\n\n/** Your own transit started. `applyMovementPush` applies this to the cache. */\nexport interface OkTravelStarted extends PushBase {\n action: 'travel';\n /** POI ID being travelled to. */\n destination: string;\n /** Engine tick the arrival lands on. */\n arrival_tick: number;\n}\n\n/** Your own jump started. `applyMovementPush` applies this to the cache. */\nexport interface OkJumpStarted extends PushBase {\n action: 'jump';\n /** System ID being jumped to. */\n destination: string;\n arrival_tick: number;\n /** True when the jump routes through a wormhole rather than a lane. */\n is_wormhole: boolean;\n}\n\n/** Your fleet leader started an in-system travel and pulled you along. */\nexport interface OkFleetTravelStarted extends PushBase {\n action: 'fleet_travel';\n destination: string;\n arrival_tick: number;\n}\n\n/** Your fleet leader started a jump and pulled you along. */\nexport interface OkFleetJumpStarted extends PushBase {\n action: 'fleet_jump';\n destination: string;\n arrival_tick: number;\n}\n\n/** Your fleet leader docked and took the fleet with them. */\nexport interface OkFleetDocked extends PushBase {\n action: 'fleet_dock';\n /** Station display name. */\n base: string;\n /** Canonical base ID — this is what `location.docked_at` holds, not `base`. */\n base_id: string;\n}\n\n/** Your fleet leader undocked and took the fleet with them. */\nexport interface OkFleetUndocked extends PushBase {\n action: 'fleet_undock';\n}\n\n/**\n * The ship you were riding was destroyed or captured. You are at your home\n * station with no ship. A state delta follows on a v2 socket; `riding` is not a\n * state section, so clear any cached value yourself.\n */\nexport interface OkPassengerStranded extends PushBase {\n action: 'passenger_stranded';\n}\n\n/** The Mobile Capital jumped while you were docked at it, taking you along. */\nexport interface OkMobileCapitalTransit extends PushBase {\n action: 'mobile_capital_transit';\n /** System ID the station arrived in. */\n system: string;\n}\n\n/**\n * An espionage operation you launched is under way (start) or resolved\n * (outcome). The two shapes differ: the start carries `arrival_tick`, the\n * resolution carries `outcome` and `story`. Only the start reaches a v2 socket\n * — the resolution ships as a delta-carrying `action_result` — but both are\n * here because a v1 transport sees both.\n */\nexport type OkEspionage =\n | (PushBase & { action: 'espionage'; arrival_tick: number })\n | (EspionageResponse & { action: 'espionage' });\n\n/**\n * In-system travel completed.\n *\n * v1 transports only. Over `/ws/v2` an arrival is a delta-carrying\n * `action_result`; this plain broadcast is the fallback taken when no delta\n * sections are set. A v2 consumer's `arrived` handler never fires — read\n * `account.location` instead.\n */\nexport type OkArrived = TravelResponse & { action: 'arrived' };\n\n/**\n * A jump or Pathfinder drift completed. `pathfinder_arrival` is the off-network\n * variant. v1 transports only, for the same reason as `OkArrived`.\n */\nexport type OkJumped = JumpResponse;\n\n/** Docking completed. */\nexport type OkDocked = DockResponse & { action: 'dock' };\n\n/**\n * An attack resolved. Two shapes share the action and are separated by `kind`:\n * `npc` covers pirates, wildlife, stations and prize hulls; `player` is PvP.\n */\nexport type OkAttack = AttackNpcResponse | AttackPlayerResponse;\n\n/** A Pathfinder off-network jump was plotted, or an in-flight drift replotted. */\nexport type OkPathfinderPlot = PathfinderJumpResponse;\n\n// --- `ok` pushes discriminated by `type` -------------------------------------\n// The server uses `type` rather than `action` for these. A payload carrying\n// `action` never carries `type`, and vice versa.\n\n/** The server docked you so a dock-required command could run. */\nexport interface OkAutoDock extends PushBase {\n type: 'auto_dock';\n}\n\n/** The server undocked you so a command needing open space could run. */\nexport interface OkAutoUndock extends PushBase {\n type: 'auto_undock';\n}\n\n/** An Emergency Warp Stabilizer fired at critical hull and warped you home. */\nexport interface OkEmergencyWarpStabilizer extends PushBase {\n type: 'emergency_warp_stabilizer_activated';\n /** Home station display name — not a base ID. */\n home_base: string;\n hull: number;\n max_hull: number;\n}\n\n/** Passengers you were carrying reached their destination. */\nexport interface OkPassengerArrivals extends PushBase {\n type: 'passenger_arrivals';\n station: string;\n delivered: number;\n stranded: number;\n fare_collected: number;\n /**\n * Reputation change per counterparty, keyed by empire or stronghold ID. The\n * key is always present, but the value is `null` when the delivery moved no\n * reputation — the common case. Check before iterating.\n */\n reputation_changes: Record<string, number> | null;\n}\n\n/** Another player moved connecting passengers onto one of your ships. */\nexport interface OkPassengersTransferred extends PushBase {\n type: 'passengers_transferred';\n /** ID of your ship the passengers were moved onto. */\n ship_id: string;\n count: number;\n /** Station display name. */\n station: string;\n}\n\n/** A ship-processing job at a station finished. */\nexport interface OkShipProcessing extends PushBase {\n type: 'ship_processing';\n}\n\n/** Passengers are waiting in a transit lounge you can pick up from. */\nexport interface OkTransitLoungeDepartures extends PushBase {\n type: 'transit_lounge_departures';\n station: string;\n base_id: string;\n passengers: number;\n /** Ticks until the soonest departure. */\n soonest_ticks: number;\n}\n\n/** A shipment you contracted for is past its delivery window. */\nexport interface OkShipmentOverdue extends PushBase {\n type: 'shipment_overdue';\n shipment_id: string;\n package_id: string;\n /** Base ID the shipment is bound for. */\n destination: string;\n /** Ticks left before the shipment is recovered. */\n recovery_ticks: number;\n late_fee: number;\n}\n\n/** A new forum thread was posted. Broadcast to every connected player. */\nexport interface OkNewForumPost extends PushBase {\n type: 'new_forum_post';\n thread_id: string;\n title: string;\n author: string;\n category: string;\n /** RFC3339 timestamp. */\n timestamp: string;\n is_dev_team: boolean;\n}\n\n/**\n * A wildlife kill notice, sent when a hunt lands. Carries neither `action` nor\n * `type` — the optional-undefined keys are what let the other members stay\n * narrowable alongside it.\n */\nexport interface OkMessageOnly {\n action?: undefined;\n type?: undefined;\n message: string;\n}\n\n// --- `fleet` pushes ----------------------------------------------------------\n\n/** You were invited to a fleet. */\nexport interface FleetInvite extends PushBase {\n action: 'fleet_invite';\n fleet_id: string;\n leader_name: string;\n leader_id: string;\n /** True for a fleet auto-created to carry an arena challenge. */\n arena_only: boolean;\n}\n\n/** Someone joined the fleet. Sent to every other member. */\nexport interface FleetMemberJoined {\n action: 'fleet_member_joined';\n player_id: string;\n player_name: string;\n}\n\n/** Someone left the fleet. Sent to every other member. */\nexport interface FleetMemberLeft {\n action: 'fleet_member_left';\n player_id: string;\n player_name: string;\n}\n\n/** The leader removed someone. Sent to the remaining members, not the target. */\nexport interface FleetMemberKicked {\n action: 'fleet_member_kicked';\n player_id: string;\n player_name: string;\n}\n\n/** The leader removed *you* from the fleet. */\nexport interface FleetKicked extends PushBase {\n action: 'fleet_kicked';\n}\n\n/** The fleet was disbanded. */\nexport interface FleetDisbanded extends PushBase {\n action: 'fleet_disbanded';\n}\n\n/** Fleet leadership passed to another member. */\nexport interface FleetLeaderPromoted extends PushBase {\n action: 'fleet_leader_promoted';\n new_leader: string;\n}\n\n/** A fleet member died. */\nexport interface FleetMemberDied extends PushBase {\n action: 'fleet_member_died';\n player_name: string;\n}\n\n/** A passenger boarded a fleet ship. */\nexport interface FleetPassengerBoarded extends PushBase {\n action: 'fleet_passenger_boarded';\n player_id: string;\n player_name: string;\n}\n\n/** A passenger stopped riding and left the fleet. */\nexport interface FleetPassengerDisembarked extends PushBase {\n action: 'fleet_passenger_disembarked';\n player_id: string;\n player_name: string;\n}\n\n// --- unions ------------------------------------------------------------------\n\n/** Every `ok` push known as of gameserver v0.596.2. */\nexport type OkPush =\n | OkTravelStarted\n | OkJumpStarted\n | OkFleetTravelStarted\n | OkFleetJumpStarted\n | OkFleetDocked\n | OkFleetUndocked\n | OkPassengerStranded\n | OkMobileCapitalTransit\n | OkEspionage\n | OkArrived\n | OkJumped\n | OkDocked\n | OkAttack\n | OkPathfinderPlot\n | OkAutoDock\n | OkAutoUndock\n | OkEmergencyWarpStabilizer\n | OkPassengerArrivals\n | OkPassengersTransferred\n | OkShipProcessing\n | OkTransitLoungeDepartures\n | OkShipmentOverdue\n | OkNewForumPost\n | OkMessageOnly;\n\n/** The `ok` variants keyed on `action`. `Extract`ed for an exhaustive switch. */\nexport type OkActionPush = Extract<OkPush, { action: string }>;\n\n/** The `ok` variants keyed on `type`. `Extract`ed for an exhaustive switch. */\nexport type OkTypePush = Extract<OkPush, { type: string }>;\n\n/** Every `fleet` push known as of gameserver v0.596.2, all keyed on `action`. */\nexport type FleetPush =\n | FleetInvite\n | FleetMemberJoined\n | FleetMemberLeft\n | FleetMemberKicked\n | FleetKicked\n | FleetDisbanded\n | FleetLeaderPromoted\n | FleetMemberDied\n | FleetPassengerBoarded\n | FleetPassengerDisembarked;\n\n/** `action` values carried by an `ok` push. */\nexport const OK_PUSH_ACTIONS = [\n 'travel',\n 'jump',\n 'fleet_travel',\n 'fleet_jump',\n 'fleet_dock',\n 'fleet_undock',\n 'passenger_stranded',\n 'mobile_capital_transit',\n 'espionage',\n 'arrived',\n 'jumped',\n 'pathfinder_arrival',\n 'dock',\n 'attack',\n 'pathfinder_jump',\n 'pathfinder_redirect',\n] as const;\nexport type OkPushAction = (typeof OK_PUSH_ACTIONS)[number];\n\n/** `type` values carried by an `ok` push, for the frames that use that key. */\nexport const OK_PUSH_TYPES = [\n 'auto_dock',\n 'auto_undock',\n 'emergency_warp_stabilizer_activated',\n 'passenger_arrivals',\n 'passengers_transferred',\n 'ship_processing',\n 'transit_lounge_departures',\n 'shipment_overdue',\n 'new_forum_post',\n] as const;\nexport type OkPushType = (typeof OK_PUSH_TYPES)[number];\n\n/** `action` values carried by a `fleet` push. */\nexport const FLEET_PUSH_ACTIONS = [\n 'fleet_invite',\n 'fleet_member_joined',\n 'fleet_member_left',\n 'fleet_member_kicked',\n 'fleet_kicked',\n 'fleet_disbanded',\n 'fleet_leader_promoted',\n 'fleet_member_died',\n 'fleet_passenger_boarded',\n 'fleet_passenger_disembarked',\n] as const;\nexport type FleetPushAction = (typeof FLEET_PUSH_ACTIONS)[number];\n"
|
|
29
|
+
],
|
|
30
|
+
"mappings": "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",
|
|
31
|
+
"debugId": "AAB4EA14A4AA073D64756E2164756E21",
|
|
32
|
+
"names": []
|
|
33
|
+
}
|