/** * Versioned, machine-readable agent contract. `tools[]` describes every CLI * entry point precisely enough for an agent to call it safely without reading * the implementation, including the credential it resolves, the scopes and * privileges it requires, its side effects, and its exit/error contract. */ export declare const manifest: { readonly manifestVersion: 2; readonly name: "tailsacle-cli"; readonly bins: readonly ["tailsacle-cli", "tscli", "tailscale-cli-opencode"]; readonly envelope: { readonly fields: readonly ["ok", "command", "durationMs", "resolved", "warnings", "requiredPrivileges", "sideEffects", "retryable", "error"]; readonly errorCodes: { readonly retryable: 75; readonly credential: 3; readonly policy: 8; readonly binary: 5; readonly localTailscale: 6; readonly funnelService: 7; readonly privilege: 9; readonly general: 1; }; readonly errorMap: { readonly CREDENTIAL_NOT_FOUND: 3; readonly CREDENTIAL_AMBIGUOUS: 3; readonly CREDENTIAL_FORMAT_UNSUPPORTED: 3; readonly AUTH_KEY_FORMAT_INVALID: 3; readonly AUTH_KEY_NOT_CONFIGURED: 3; readonly POLICY_FILE_NOT_FOUND: 8; readonly POLICY_VERIFY_FAILED: 8; readonly POLICY_CONFIRMATION_REQUIRED: 8; readonly POLICY_PROVISION_CONFIRMATION_REQUIRED: 8; readonly POLICY_HUJSON_MERGE_FAILED: 8; readonly TAILSCALE_BINARY_NOT_FOUND: 5; readonly BIN_DOWNLOAD_HTTP_400: 5; readonly BIN_CHECKSUM_MISMATCH: 5; readonly BIN_SHA256_INVALID: 5; readonly BIN_EXTRACT_FAILED: 5; readonly BIN_INDEX_INCOMPLETE: 5; readonly BIN_TRACK_UNSUPPORTED: 5; readonly TAILSCALE_NOT_RUNNING: 6; readonly FUNNEL_PORT_UNSUPPORTED: 7; readonly FUNNEL_TARGET_REQUIRED: 7; readonly FUNNEL_TCP_INVALID: 7; readonly FUNNEL_ATTR_REQUIRED: 7; readonly FUNNEL_EPHEMERAL: 7; readonly FUNNEL_DNS_NOT_PUBLISHED: 7; readonly FUNNEL_ENDPOINT_UNREACHABLE: 7; readonly PRIVILEGE_REQUIRED: 9; }; readonly privilegeMap: { readonly TAILSCALE_BINARY_NOT_FOUND: "install Tailscale or run as root/Administrator for auto-download"; readonly TAILSCALE_NOT_RUNNING: "start tailscaled (systemctl/enable or run as root/Administrator)"; readonly BIN_WINDOWS_MANUAL: "install the Tailscale MSI as Administrator or set TS_TAILSCALE_BIN"; }; readonly warningCodes: readonly ["PROVISIONED_TAGS", "PROVISIONED_FUNNEL", "ENABLED_HTTPS", "KEY_EXPIRY_DEFAULT", "KEY_EXPIRY_MAX", "KEY_EXPIRY_UNLIMITED", "KEY_EXPIRY_CLAMPED", "AUTO_TAG", "REUSABLE_KEY_DEFAULTED", "TAILNET_DEFAULTED", "TAILNET_DOMAIN_UNUSUAL", "NO_TAGS_CONFIGURED", "CREDENTIAL_AMBIGUOUS", "CREDENTIAL_NOT_FOUND", "API_CREDENTIAL_NOT_CONFIGURED", "SIDE_EFFECT_PLAN", "FUNNEL_TARGET_DEFAULTED", "CLEANUP_SKIPPED", "CONFIG_FILE_LOADED"]; }; readonly resolve_credentials: { readonly precedence: readonly ["TS_AUTH_KEY", "TS_CREDENTIAL_ENV-selected env var (or --credential-env)", "TS_CLIENT_SECRET", "OAuth trust credential in any tskey-client- env var", "TS_OAUTH_CLIENT_ID + TS_OAUTH_CLIENT_SECRET", "TS_ACCESS_TOKEN", "TS_API_KEY"]; readonly override: "--credential-env (or TS_CREDENTIAL_ENV / config file credentialEnv) to select one specific env var holding the trust credential (required when detection is ambiguous); --client-secret/--client-id override TS_CLIENT_SECRET/TS_CLIENT_ID for one run (visible in process listings)"; readonly auto_detect: { readonly source: "any env var whose value starts with tskey-client-"; }; }; readonly tools: readonly [{ readonly name: "doctor"; readonly summary: "Resolve credentials, runtime, local binary and API capability with no remote side effects."; readonly command: readonly ["doctor", readonly ["--detect-credentials"], readonly ["--show-resolution"]]; readonly consumes: { readonly inputs: readonly ["env.tskey-client-*", "env.TS_API_KEY", "env.TS_ACCESS_TOKEN", "env.TS_OAUTH_*"]; readonly inputsSchema: "no positional args; flags optional"; }; readonly outputs: { readonly json: "CommandResult(envelope) > resolved { config, credential {found,source,masked}, apiCredential, binary, runtime }"; }; readonly scopes: readonly ["none (local only)"]; readonly privileges: readonly ["read files", "read env"]; readonly sideEffects: readonly ["none"]; readonly retryable: false; readonly confirmation: "never"; }, { readonly name: "deploy"; readonly summary: "Join the tailnet with auth-key or resolved credential, optionally configure Serve/Funnel, and auto-cleanup matching offline devices."; readonly command: readonly ["deploy", "--yes", readonly ["--dry-run"], readonly ["--expose "], readonly ["--funnel"], readonly ["--apply-policy"], readonly ["--enable-https"], readonly ["--cleanup"], readonly ["--bin "], readonly ["--ssh | --no-ssh"], readonly ["--state-dir "], readonly ["--backup-dir "]]; readonly consumes: { readonly inputs: readonly ["TS_AUTH_KEY or API credential", "TS_TAGS", "TS_HOSTNAME", "TS_PROFILE", "TS_EPHEMERAL", "TS_KEY_EXPIRY"]; readonly inputsSchema: "env-driven; --expose targets \"PORT#path=target\""; }; readonly outputs: { readonly json: "resolved { binary, device, authKeySource, exposures, warnings, cleanup? }"; }; readonly scopes: readonly ["auth_keys", "devices:core:read", "devices:core:write", "policy_file (provisioning)", "all (HTTPS enable)"]; readonly privileges: readonly ["tailscaled needs root/admin unless userspace is pre-configured"]; readonly sideEffects: readonly ["authenticate node", "write Tailscale state", "create auth-key", "configure Serve/Funnel", "provision tailnet policy (--apply-policy)", "enable tailnet HTTPS (--enable-https)", "delete offline devices (--cleanup)"]; readonly retryable: true; readonly confirmation: "--yes or TTY for every provisioning/cleanup side effect"; }, { readonly name: "up"; readonly summary: "Deploy alias without exposure configuration."; readonly command: readonly ["up", readonly ["--dry-run"], readonly ["--yes"], readonly ["--apply-policy"], readonly ["--cleanup"], readonly ["--ssh | --no-ssh"], readonly ["--state-dir "], readonly ["--backup-dir "]]; readonly consumes: { readonly inputs: readonly ["same as deploy", "TS_NO_CLEANUP=1 disables auto-cleanup"]; }; readonly outputs: { readonly json: "same as deploy"; }; readonly scopes: readonly ["auth_keys", "devices:core:*"]; readonly privileges: readonly ["tailscaled needs root/admin unless userspace is pre-configured"]; readonly sideEffects: readonly ["authenticate node", "write Tailscale state", "create auth-key", "delete offline devices (--cleanup)"]; readonly retryable: true; readonly confirmation: "--yes or TTY"; }, { readonly name: "funnel"; readonly summary: "Expose a local service publicly via Tailscale Funnel and verify public DNS propagation plus the live TLS/TCP endpoint."; readonly command: readonly ["funnel", "[target]", readonly ["--https "], readonly ["--tcp "], readonly ["--path "], readonly ["--expose ..."], readonly ["--yes"], readonly ["--apply-policy"], readonly ["--enable-https"], readonly ["--verify-timeout "], readonly ["--ssh | --no-ssh"], readonly ["--state-dir "]]; readonly consumes: { readonly inputs: readonly ["target or $PORT", "config tags (funnel node attribute)", "HTTPS enablement"]; }; readonly outputs: { readonly json: "resolved { target, public, https, path, url?, dnsPropagated, dnsAttempts, verified, tlsVerified?, tlsVerifiedPorts?, tcpVerified?, verifyAttempts }"; }; readonly scopes: readonly ["policy_file (provisioning)", "all (HTTPS enable)"]; readonly privileges: readonly ["tailscaled running", "funnel node attribute or --apply-policy", "non-ephemeral node"]; readonly sideEffects: readonly ["configure Funnel config", "provision nodeAttrs (--apply-policy)", "enable tailnet HTTPS (--enable-https)"]; readonly retryable: true; readonly confirmation: "--yes or TTY for provisioning; DNS and live-endpoint verification retry up to --verify-timeout"; }, { readonly name: "serve"; readonly summary: "Share a local service on the tailnet (not public)."; readonly command: readonly ["serve", "", readonly ["--https "], readonly ["--http "], readonly ["--tcp "], readonly ["--path "]]; readonly consumes: { readonly inputs: readonly ["target"]; }; readonly outputs: { readonly json: "resolved { target, public, path, https? }"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["tailscaled running"]; readonly sideEffects: readonly ["configure Serve config"]; readonly retryable: false; readonly confirmation: "never"; }, { readonly name: "relay"; readonly summary: "Run a TCP relay proxy to forward connections to another machine (single or multi-port, or via config file), optionally exposing via Serve/Funnel."; readonly command: readonly ["relay", readonly ["-l, --listen "], readonly ["-t, --target "], readonly ["-m, --map "], readonly ["-f, --file "], readonly ["--host
"], readonly ["--target-host
"], readonly ["--serve"], readonly ["--funnel"]]; readonly consumes: { readonly inputs: readonly ["listen/target port", "mapping array", "JSON config file"]; }; readonly outputs: { readonly json: "resolved { status, count, mappings, tailscaleServe, tailscaleFunnel }"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["none (or tailscaled running if --serve/--funnel)"]; readonly sideEffects: readonly ["run local TCP proxy", "optional Serve/Funnel configure"]; readonly retryable: true; readonly confirmation: "never"; }, { readonly name: "relay-mcp-postgres"; readonly summary: "Run TCP relays to PostgreSQL and serve a nexql-mcp HTTP MCP endpoint exposing all databases on the relayed instance (agent-driven connection via setup_connection)."; readonly command: readonly ["relay-mcp-postgres", readonly ["-l, --listen "], readonly ["-t, --target "], readonly ["-m, --map "], readonly ["-f, --file "], readonly ["--host
"], readonly ["--target-host
"], readonly ["--mcp-port "], readonly ["--mcp-bind
"], readonly ["--token "], readonly ["--user "], readonly ["--password "], readonly ["--database "], readonly ["--db-retry-interval "], readonly ["--mcp-ready-timeout "], readonly ["--log "], readonly ["--serve"], readonly ["--funnel"]]; readonly consumes: { readonly inputs: readonly ["listen/target port", "mapping array", "JSON config file", "PostgreSQL user/password/database (password via --password or PGPASSWORD/TS_PGPASSWORD env)"]; }; readonly outputs: { readonly json: "resolved { status, relayCount, mappings, primaryDatabase, mcpHttpUrl, mcpToken, connectionString (masked), nexqlMcpPid, runnerVersion, tailscaleServe, tailscaleFunnel }"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["none (or tailscaled running if --serve/--funnel)"]; readonly sideEffects: readonly ["run local TCP proxy", "spawn nexql-mcp HTTP MCP server (supervisor respawns until the DB is reachable)", "optional Serve/Funnel configure"]; readonly retryable: true; readonly confirmation: "never"; }, { readonly name: "dns"; readonly summary: "Read tailnet DNS settings; optionally enable MagicDNS."; readonly command: readonly ["dns", readonly ["--enable-magicdns"], readonly ["--dry-run"], readonly ["--yes"]]; readonly consumes: { readonly inputs: readonly ["API credential"]; }; readonly outputs: { readonly json: "resolved { nameservers, preferences, searchpaths } or { magicDNSEnabled: true, dryRun?: boolean }"; }; readonly scopes: readonly ["dns:read", "dns (MagicDNS enable)"]; readonly privileges: readonly ["tailnet admin for DNS writes"]; readonly sideEffects: readonly ["enable MagicDNS (--enable-magicdns, confirmation)"]; readonly retryable: false; readonly confirmation: "--yes or TTY for --enable-magicdns"; }, { readonly name: "policy"; readonly summary: "Diff, validate and guarded-sync a HuJSON policy file; use policy-sync for writes."; readonly command: readonly ["policy", readonly ["--file "], readonly ["--dry-run"], readonly ["--sync"], readonly ["--yes"], readonly ["--backup-dir "]]; readonly consumes: { readonly inputs: readonly ["TS_POLICY_FILE or --file path"]; }; readonly outputs: { readonly json: "resolved { changed, validated, written, etag?, backup?, diff }"; }; readonly scopes: readonly ["policy_file:read", "policy_file"]; readonly privileges: readonly ["tailnet admin for policy writes"]; readonly sideEffects: readonly ["policy write + local backup (--sync + confirmation)"]; readonly retryable: false; readonly confirmation: "--yes or TTY before writing"; }, { readonly name: "status"; readonly summary: "Show local Tailscale status."; readonly command: readonly ["status", readonly ["--show-resolution"]]; readonly consumes: { readonly inputs: readonly []; }; readonly outputs: { readonly json: "resolved = tailscale status JSON (optionally with credential resolution)"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["tailscaled running"]; readonly sideEffects: readonly ["none"]; readonly retryable: false; readonly confirmation: "never"; }, { readonly name: "cleanup"; readonly summary: "Find and safely remove matching offline devices (exact hostname/tag match)."; readonly command: readonly ["cleanup", readonly ["--dry-run"], readonly ["--yes"]]; readonly consumes: { readonly inputs: readonly ["TS_CLEANUP_OFFLINE_AFTER seconds", "TS_PROTECTED_DEVICES comma list"]; }; readonly outputs: { readonly json: "resolved { candidates: [{ id, hostname, name, dnsName, tags, lastSeen, offlineSinceSeconds }], deleted: string[] }"; }; readonly scopes: readonly ["devices:core:read", "devices:core:write"]; readonly privileges: readonly ["tailnet admin"]; readonly sideEffects: readonly ["delete offline devices (--yes/confirmation)"]; readonly retryable: false; readonly confirmation: "--yes or TTY"; }, { readonly name: "update-bin"; readonly summary: "Download the latest stable Tailscale build into the package cache (never overwrites package-managed binaries) or fall back to the native updater on Windows. Also reachable as the global flag --update-bin (e.g. `tailsacle-cli --update-bin`)."; readonly command: readonly ["update-bin", readonly ["--force"], readonly ["--skip-checksum"], readonly ["--track "], readonly ["--yes"], readonly ["--dry-run"]]; readonly consumes: { readonly inputs: readonly ["TS_BIN_DIR cache override", "TS_BIN_VERSION optional pinned version", "network access to pkgs.tailscale.com"]; }; readonly outputs: { readonly json: "resolved { cached, before?, after?, info? }"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["write to the cache directory"]; readonly sideEffects: readonly ["download + verify + atomic-install stable binary"]; readonly retryable: true; readonly confirmation: "never (explicit command)"; }, { readonly name: "service"; readonly summary: "Install, manage and remove a relay/script as a background service: systemd (Linux system/user unit), Windows SCM (WinSW via node-windows), or Windows Task Scheduler (--scheduler, no admin)."; readonly command: readonly ["service", "", readonly ["init --name --out "], readonly ["install --file [--user] [--scheduler] [--yes]"], readonly ["uninstall --name [--yes]"], readonly ["status --name "], readonly ["logs --name [--lines ] [--follow]"], readonly ["start|stop|restart --name "], readonly ["list"]]; readonly consumes: { readonly inputs: readonly ["service config file (.tailsacle-service.jsonc, JSONC supported)", "node-windows (optional, Windows SCM path only)"]; }; readonly outputs: { readonly json: "resolved per subcommand: init { file, name }; install { installed, name, platform, scope, unitPath, status, pid, portsListening }; status { name, status, pid?, uptimeSeconds?, restartCount? }; list ServiceInfo[]"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["root/sudo for Linux system units (--user avoids sudo)", "Administrator for Windows SCM (--scheduler avoids admin)"]; readonly sideEffects: readonly ["write systemd unit or Windows service/task definition", "enable and start the service", "remove service definition on uninstall"]; readonly retryable: false; readonly confirmation: "--yes or TTY for install/uninstall"; }, { readonly name: "agent-manifest"; readonly summary: "Emit this versioned contract."; readonly command: readonly ["agent-manifest", readonly ["--json"]]; readonly consumes: { readonly inputs: readonly []; }; readonly outputs: { readonly json: "manifest envelope"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["none"]; readonly sideEffects: readonly ["none"]; readonly retryable: false; readonly confirmation: "never"; }, { readonly name: "daemon"; readonly summary: "Inspect or stop the local tailscaled daemon."; readonly command: readonly ["daemon", ""]; readonly consumes: { readonly inputs: readonly []; }; readonly outputs: { readonly json: "resolved { running, tracked, trackedAlive }"; }; readonly scopes: readonly ["none"]; readonly privileges: readonly ["none"]; readonly sideEffects: readonly ["stop tracked userspace tailscaled (stop action)"]; readonly retryable: false; readonly confirmation: "never"; }, { readonly name: "opencode"; readonly summary: "Separate bin tailscale-cli-opencode: resolve/install opencode (npx -y opencode-ai when missing), grant headless full permissions (permission: allow, the --auto equivalent), start opencode serve in the background, join the tailnet and publish it through a Tailscale Funnel, then verify public DNS + live TLS before printing the public URL. --stop tears the tracked serve and userspace tailscaled down."; readonly command: readonly ["opencode", readonly ["--port "], readonly ["--opencode-config "], readonly ["--install"], readonly ["--no-verify"], readonly ["--verify-timeout "], readonly ["--dry-run"], readonly ["--stop"], readonly ["--yes"], readonly ["--apply-policy"], readonly ["--enable-https"], readonly ["--state-dir "], readonly ["--backup-dir "], readonly ["--tag-owner "], readonly ["--credential-env "], readonly ["--profile "], readonly ["--config "], readonly ["--json"]]; readonly consumes: { readonly inputs: readonly ["env.TS_AUTH_KEY / OAuth trust credential / TS_API_KEY (for join + funnel provisioning)", "npx (Node.js 22+) for opencode-ai resolution", "network access to npmjs + Tailscale control plane"]; }; readonly outputs: { readonly json: "resolved { opencode { runner, pid, command, port, configPath, permissionConfig, permissionWritten, permissionExisting, logPath }, deployment, dnsName?, urls[], verified, verifyAttempts? }"; }; readonly scopes: readonly ["none (local opencode + tailscale funnel)"]; readonly privileges: readonly ["write ~/.config/opencode and ./opencode.json", "npm/npx access for opencode-ai", "tailscaled running (userspace auto-started)"]; readonly sideEffects: readonly ["install/resolve opencode-ai via npx (when missing or --install)", "start opencode serve (background, tracked in the cache pidfile)", "join tailnet and configure Funnel (auto-provision with --apply-policy/--enable-https)", "verify public DNS + live TLS endpoint"]; readonly retryable: false; readonly confirmation: "--yes or TTY"; }]; readonly policy_writes: { readonly flow: readonly ["fetch policy + etag", "diff/merge (HuJSON-preserving)", "validate (POST /acl/validate)", "local backup", "write with If-Match", "verify"]; readonly hujson: "comments and trailing commas preserved for tagOwners/nodeAttrs provisioning; policy command writes the file verbatim"; }; readonly cleanup_candidates: { readonly schema: { readonly id: "string"; readonly hostname: "string"; readonly name: "string"; readonly dnsName: "string"; readonly tags: "string[]"; readonly lastSeen: "string?"; readonly offlineSinceSeconds: "number"; }; readonly match: "exact normalized hostname (device.hostname/dnsName/name) AND every wanted tag; never substring; devices without lastSeen are never treated as offline"; }; }; //# sourceMappingURL=manifest.d.ts.map