/** * Robot config R/W for the AgenticROS CLI. * * Lives in the CLI so the multi-robot persistence path does NOT pull * `@agenticros/core` (and its transport deps) into the published * `agenticros` tarball. The shape we read/write is intentionally a * subset of `@agenticros/core`'s `AgenticROSConfig.robots`: * * robots: Array<{ * id: string; * name?: string; * namespace?: string; * cameraTopic?: string; * default?: boolean; * }> * * Backwards compat with the legacy single-robot config: * - If `config.robots` is absent/empty AND `config.robot` is set, we * "promote" `config.robot` into `robots[0]` on the next write. The * legacy `config.robot` field is LEFT in place (harmlessly — the * core resolver prefers the explicit array when non-empty) so older * adapters that only read `config.robot` keep working. * - When the file is missing or empty we treat it as `{}`. Writes * create both the file and its directory. * * All paths route through the CLI's own paths helper so workspace / * installed / bundle modes pick up the same `~/.agenticros/config.json`. */ import type { RobotProfile } from "./robot-profile.js"; /** Sensor/hardware tags on a robot — mirrors @agenticros/core's RobotSensors. */ export interface RobotSensors { has_realsense?: boolean; has_lidar?: boolean; has_arm?: boolean; } /** What the CLI persists per robot. Matches the core config schema. */ export interface RobotEntry { id: string; name?: string; namespace?: string; cameraTopic?: string; default?: boolean; /** * Phase 1.e robot kind ("amr" | "arm" | "drone" | "rover" | …). * Free-form string; core defaults to "amr" when unset. */ kind?: string; /** * Phase 1.e sensor/hardware tags. Same all-false default semantics * as core — only the keys the user sets are written through. */ sensors?: RobotSensors; /** * Phase 1.e optional per-robot capability allowlist. When set, the * `ros2_find_robots_for` filter uses this list instead of the * gateway's global capability registry. Stored verbatim — the CLI * doesn't import the registry to validate against. */ capabilities?: string[]; /** * Hardware profile (features + ROS bindings). Optional. When unset, * advertised verbs stay gateway-wide. */ profile?: RobotProfile; /** * Optional per-robot safety overlay (velocity / workspace). Unset * fields inherit gateway `config.safety`. */ safety?: { maxLinearVelocity?: number; maxAngularVelocity?: number; workspaceLimits?: { xMin: number; xMax: number; yMin: number; yMax: number; }; }; /** * Optional per-robot transport override. Opaque JSON — the core's * `RobotTransportOverrideSchema` is the schema-of-truth and will Zod- * validate this at config-load time. The CLI doesn't import core, so * we only carry the field through as a plain object. */ transport?: Record; } export declare function robotConfigPath(): string; /** Parse `~/.agenticros/config.json` to a plain object, or `{}` when absent/bad. */ export declare function readConfigObject(path?: string): Record; /** Write the config object back, creating directories as needed. */ export declare function writeConfigObject(obj: Record, path?: string): void; /** * Return the robots[] view the agent would see (explicit array when * non-empty, otherwise a one-entry array synthesised from legacy * `config.robot`). Read-only — the CLI uses this to render `robots list` * without ever needing to import @agenticros/core. */ export declare function readRobots(obj?: Record): { robots: RobotEntry[]; from: "explicit" | "legacy" | "none"; }; /** * Compute the active robot id using the same precedence the core * resolver does: * 1. explicit robots[] entry with `default: true` * 2. first entry in robots[] (with legacy fallback) * 3. undefined when there are no robots at all */ export declare function getActiveRobotId(obj?: Record): string | undefined; export interface AddRobotResult { /** Whether the entry was actually written (false = a duplicate id was already present). */ added: boolean; /** True when this write promoted the legacy `config.robot` into `robots[]`. */ promotedLegacy: boolean; /** The final robots[] array after the write. */ robots: RobotEntry[]; } /** * Add a robot to `config.robots[]`. * * Promotes the legacy single-robot config on first multi-robot write — * `config.robot` is copied as the first entry in the array, and any * `default: true` flag we'd set on the new entry is held against that * promoted incumbent (it stays the default unless the caller explicitly * asks otherwise). * * Idempotent: re-adding an existing id updates name/namespace/cameraTopic * in place but returns `added: false` so the CLI can render the right * "already present" message. */ export declare function addRobot(entry: RobotEntry, opts?: { setDefault?: boolean; obj?: Record; }): AddRobotResult; /** * Remove a robot from `config.robots[]` by id. * * Returns `removed: false` when the id isn't present. Removing the last * entry leaves `robots: []` (which the core resolver then ignores in * favour of the legacy `config.robot` fallback — so the deployment * keeps working). * * Idempotent across re-runs. */ export declare function removeRobot(id: string, obj?: Record): { removed: boolean; robots: RobotEntry[]; }; /** * Set `default: true` on exactly one robot in `config.robots[]`. * * Auto-promotes the legacy single-robot config first if needed (so * marking the first new robot as default doesn't lose the previous * incumbent). Throws when the id isn't present after promotion. */ export declare function setDefaultRobot(id: string, obj?: Record): { robots: RobotEntry[]; promotedLegacy: boolean; }; /** * Apply a per-robot transport override to an existing robot. * * Auto-promotes legacy `config.robot` into `config.robots[]` so the * caller can target the historical single-robot config by its derived * id. Throws when the id can't be found after promotion — matching the * UX of `setDefaultRobot`. * * The `override` argument is the plain JSON shape the core's * `RobotTransportOverrideSchema` will validate at config-load time. The * CLI doesn't validate field shapes — that lives in `@agenticros/core`. */ export declare function setTransportForRobot(id: string, override: Record, obj?: Record): { robots: RobotEntry[]; promotedLegacy: boolean; }; /** * Remove a per-robot transport override (so the robot inherits the * global transport config). Idempotent — returns `cleared: false` when * the robot didn't have an override to begin with. Throws on unknown id * (we'd rather complain loudly than silently no-op against a typo). */ export declare function clearTransportForRobot(id: string, obj?: Record): { cleared: boolean; robots: RobotEntry[]; promotedLegacy: boolean; }; /** * Write (or replace) a hardware profile on an existing robot. * Auto-promotes legacy `config.robot` into `robots[]` when needed. */ export declare function setProfileForRobot(id: string, profile: RobotProfile, obj?: Record): { robots: RobotEntry[]; promotedLegacy: boolean; }; //# sourceMappingURL=robot-config.d.ts.map