@elizaos/plugin-tailscale 2.0.0-beta.1 → 2.0.11-beta.7

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/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/index.ts","../src/services/CloudTailscaleService.ts","../src/accounts.ts","../src/environment.ts","../src/services/LocalTailscaleService.ts","../src/__tests__/TailscaleTestSuite.ts","../src/connector-account-provider.ts","../src/types.ts","../src/providers/tailscale-status.ts","../src/services/TunnelBackendSelector.ts"],"sourcesContent":["import {\n elizaLogger,\n getConnectorAccountManager,\n type Plugin,\n} from \"@elizaos/core\";\nimport { tunnelSlotIsFree } from \"@elizaos/plugin-tunnel\";\nimport { TailscaleTestSuite } from \"./__tests__/TailscaleTestSuite\";\nimport { createTailscaleConnectorAccountProvider } from \"./connector-account-provider\";\nimport { tailscaleStatusProvider } from \"./providers/tailscale-status\";\nimport { selectTunnelBackend } from \"./services/TunnelBackendSelector\";\n\n/**\n * Plugin doesn't list any services upfront. The selector runs in `init()` and\n * registers exactly one Tailscale backend (local or cloud) under the canonical\n * `serviceType=\"tunnel\"` slot from `@elizaos/plugin-tunnel`. Coordination with\n * other tunnel providers (ngrok, plugin-tunnel's local CLI, plugin-elizacloud's\n * cloud tunnel) is first-active-wins via `tunnelSlotIsFree(runtime)`.\n *\n * Consumers should stay backend-agnostic via `getTunnelService(runtime)` from\n * `@elizaos/plugin-tunnel`.\n *\n * The canonical TUNNEL action from `@elizaos/plugin-tunnel` handles start,\n * stop, and status. This plugin only contributes a provider/backend.\n */\nexport const tailscalePlugin: Plugin = {\n name: \"tailscale\",\n description:\n \"Tunnel plugin with local Tailscale serve/funnel and cloud-proxy backends.\",\n actions: [],\n providers: [tailscaleStatusProvider],\n tests: [new TailscaleTestSuite()],\n init: async (_config, runtime) => {\n try {\n const manager = getConnectorAccountManager(runtime);\n manager.registerProvider(\n createTailscaleConnectorAccountProvider(runtime),\n );\n } catch (err) {\n elizaLogger.warn(\n `[plugin-tailscale] failed to register ConnectorAccountManager provider: ${\n err instanceof Error ? err.message : String(err)\n }`,\n );\n }\n\n if (!tunnelSlotIsFree(runtime)) {\n elizaLogger.info(\n \"[plugin-tailscale] another tunnel service already registered — skipping Tailscale backend\",\n );\n return;\n }\n\n const decision = selectTunnelBackend(runtime);\n elizaLogger.info(\n `[plugin-tailscale] tunnel backend: ${decision.backend.name} (${decision.reason})`,\n );\n await runtime.registerService(decision.backend);\n },\n};\n\nexport default tailscalePlugin;\n\nexport * from \"./accounts\";\nexport { createTailscaleConnectorAccountProvider } from \"./connector-account-provider\";\nexport { CloudTailscaleService } from \"./services/CloudTailscaleService\";\nexport { LocalTailscaleService } from \"./services/LocalTailscaleService\";\nexport type { BackendDecision } from \"./services/TunnelBackendSelector\";\nexport {\n readBackendMode,\n selectTunnelBackend,\n} from \"./services/TunnelBackendSelector\";\nexport type {\n ITunnelService,\n TailscaleBackendMode,\n TunnelProvider,\n TunnelStatus,\n} from \"./types\";\n","import { spawn } from \"node:child_process\";\nimport { elizaLogger, type IAgentRuntime, Service } from \"@elizaos/core\";\nimport { z } from \"zod\";\nimport { readTailscaleAccounts, resolveTailscaleAccount } from \"../accounts\";\nimport { validateTailscaleConfig } from \"../environment\";\nimport type { ITunnelService, TunnelStatus } from \"../types\";\n\nconst CLOUD_BASE_FALLBACK = \"https://api.elizacloud.ai/api/v1\";\n\nconst authKeyResponseSchema = z.object({\n authKey: z.string(),\n tailnet: z.string(),\n loginServer: z.string().optional(),\n hostname: z.string().optional(),\n magicDnsName: z.string(),\n});\n\ntype AuthKeyResponse = z.infer<typeof authKeyResponseSchema>;\n\ninterface CloudFetchInit {\n method: \"POST\";\n headers: Record<string, string>;\n body: string;\n}\n\ninterface CloudFetchResponse {\n ok: boolean;\n status: number;\n statusText: string;\n json(): Promise<unknown>;\n text(): Promise<string>;\n}\n\ntype CloudFetch = (\n url: string,\n init: CloudFetchInit,\n) => Promise<CloudFetchResponse>;\n\ninterface CloudTailscaleServiceOptions {\n /** Override fetch impl for tests. */\n fetch?: CloudFetch;\n /** Override CLI runner for tests. */\n cliRunner?: (\n cmd: string,\n args: string[],\n ) => Promise<{ code: number | null; stdout: string; stderr: string }>;\n}\n\ninterface SpawnResult {\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nfunction defaultCliRunner(cmd: string, args: string[]): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const out: Buffer[] = [];\n const err: Buffer[] = [];\n child.stdout?.on(\"data\", (chunk: Buffer) => out.push(chunk));\n child.stderr?.on(\"data\", (chunk: Buffer) => err.push(chunk));\n child.on(\"error\", reject);\n child.on(\"exit\", (code) =>\n resolve({\n code,\n stdout: Buffer.concat(out).toString(\"utf8\"),\n stderr: Buffer.concat(err).toString(\"utf8\"),\n }),\n );\n });\n}\n\nasync function defaultFetch(\n url: string,\n init: CloudFetchInit,\n): Promise<CloudFetchResponse> {\n return normalizeFetchResponse(await fetch(url, init));\n}\n\nexport class CloudTailscaleService extends Service implements ITunnelService {\n static override serviceType = \"tunnel\";\n readonly capabilityDescription =\n \"Provides Tailscale tunnel functionality via Eliza Cloud — auth keys are minted server-side and the local CLI joins the tailnet.\";\n\n private readonly fetchImpl: CloudFetch;\n private readonly cliRunner: (\n cmd: string,\n args: string[],\n ) => Promise<SpawnResult>;\n\n private tunnelUrl: string | null = null;\n private tunnelPort: number | null = null;\n private startedAt: Date | null = null;\n private isShuttingDown = false;\n private joinedTailnet = false;\n\n constructor(\n runtime?: IAgentRuntime,\n options: CloudTailscaleServiceOptions = {},\n ) {\n super(runtime);\n this.fetchImpl = options.fetch ?? defaultFetch;\n this.cliRunner = options.cliRunner ?? defaultCliRunner;\n }\n\n static override async start(runtime: IAgentRuntime): Promise<Service> {\n const service = new CloudTailscaleService(runtime);\n await service.start();\n return service;\n }\n\n async start(): Promise<void> {\n elizaLogger.info(\"[CloudTailscaleService] started\");\n }\n\n async stop(): Promise<void> {\n await this.stopTunnel();\n }\n\n async startTunnel(\n port?: number,\n options: { accountId?: string } = {},\n ): Promise<string | undefined> {\n if (this.isActive()) {\n elizaLogger.warn(\"[CloudTailscaleService] tunnel already running\");\n return this.tunnelUrl ?? undefined;\n }\n\n if (port === undefined || port === null) {\n elizaLogger.warn(\n \"[CloudTailscaleService] startTunnel called without a port — service active but no tunnel started\",\n );\n return;\n }\n\n if (port < 1 || port > 65535) {\n throw new Error(\"Invalid port number\");\n }\n\n const config = await validateTailscaleConfig(\n this.runtime,\n options.accountId,\n );\n const { baseUrl, apiKey } = this.resolveCloudCredentials(options.accountId);\n\n const response = await this.fetchImpl(\n `${baseUrl}/apis/tunnels/tailscale/auth-key`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${apiKey}`,\n },\n body: JSON.stringify({\n tags: config.TAILSCALE_TAGS,\n expirySeconds: config.TAILSCALE_AUTH_KEY_EXPIRY_SECONDS,\n }),\n },\n );\n\n if (!response.ok) {\n const text = await safeReadText(response);\n throw new Error(\n `Cloud Tailscale auth-key mint failed (${response.status} ${response.statusText}): ${text}`,\n );\n }\n\n const rawJson: unknown = await response.json();\n const parsed = authKeyResponseSchema.safeParse(rawJson);\n if (!parsed.success) {\n throw new Error(\n `Cloud Tailscale response malformed: ${parsed.error.issues.map((i) => i.message).join(\"; \")}`,\n );\n }\n\n await this.joinTailnet(parsed.data);\n await this.runServe(port, config.TAILSCALE_FUNNEL);\n\n this.tunnelUrl = `https://${parsed.data.magicDnsName}`;\n this.tunnelPort = port;\n this.startedAt = new Date();\n this.joinedTailnet = true;\n elizaLogger.info(\n `[CloudTailscaleService] tunnel started: ${this.tunnelUrl}`,\n );\n return this.tunnelUrl;\n }\n\n async stopTunnel(_options: { accountId?: string } = {}): Promise<void> {\n if (!this.isActive() && !this.joinedTailnet) {\n elizaLogger.warn(\"[CloudTailscaleService] no active tunnel to stop\");\n return;\n }\n this.isShuttingDown = true;\n elizaLogger.info(\"[CloudTailscaleService] stopping tunnel\");\n\n if (this.tunnelPort !== null) {\n await this.cliRunner(\"tailscale\", [\"serve\", \"reset\"]);\n await this.cliRunner(\"tailscale\", [\"funnel\", \"reset\"]);\n }\n\n if (this.joinedTailnet) {\n await this.cliRunner(\"tailscale\", [\"logout\"]);\n }\n\n this.cleanup();\n this.isShuttingDown = false;\n elizaLogger.info(\"[CloudTailscaleService] tunnel stopped\");\n }\n\n getUrl(): string | null {\n return this.tunnelUrl;\n }\n\n isActive(): boolean {\n return this.tunnelUrl !== null && !this.isShuttingDown;\n }\n\n getStatus(): TunnelStatus {\n return {\n active: this.isActive(),\n url: this.tunnelUrl,\n port: this.tunnelPort,\n startedAt: this.startedAt,\n provider: \"tailscale\",\n };\n }\n\n private async joinTailnet(payload: AuthKeyResponse): Promise<void> {\n const args = [\"up\", `--auth-key=${payload.authKey}`];\n const loginServer =\n payload.loginServer ??\n (payload.tailnet.startsWith(\"http\") ? payload.tailnet : null);\n if (loginServer) {\n args.push(`--login-server=${loginServer}`);\n }\n if (payload.hostname) {\n args.push(`--hostname=${payload.hostname}`);\n }\n\n const result = await this.cliRunner(\"tailscale\", args);\n if (result.code !== 0) {\n throw new Error(\n `tailscale up failed (code ${result.code}): ${result.stderr.trim()}`,\n );\n }\n }\n\n private async runServe(port: number, funnel: boolean): Promise<void> {\n const args = funnel\n ? [\"funnel\", String(port)]\n : [\"serve\", \"--bg\", \"--https=443\", `localhost:${port}`];\n const result = await this.cliRunner(\"tailscale\", args);\n if (result.code !== 0) {\n throw new Error(\n `tailscale ${args[0]} failed (code ${result.code}): ${result.stderr.trim()}`,\n );\n }\n }\n\n private resolveCloudCredentials(accountId?: string): {\n baseUrl: string;\n apiKey: string;\n } {\n const account = accountId\n ? resolveTailscaleAccount(readTailscaleAccounts(this.runtime), accountId)\n : null;\n const apiKey =\n readNonEmptyString(account?.cloudApiKey) ??\n readNonEmptyString(this.runtime.getSetting(\"ELIZAOS_CLOUD_API_KEY\"));\n if (!apiKey) {\n throw new Error(\n \"CloudTailscaleService requires ELIZAOS_CLOUD_API_KEY. Set it or use the local backend.\",\n );\n }\n const baseRaw =\n readNonEmptyString(account?.cloudBaseUrl) ??\n readNonEmptyString(this.runtime.getSetting(\"ELIZAOS_CLOUD_BASE_URL\")) ??\n CLOUD_BASE_FALLBACK;\n return { baseUrl: stripTrailingSlash(baseRaw), apiKey };\n }\n\n private cleanup(): void {\n this.tunnelUrl = null;\n this.tunnelPort = null;\n this.startedAt = null;\n this.joinedTailnet = false;\n }\n}\n\nfunction readNonEmptyString(value: unknown): string | null {\n if (value === null || value === undefined) return null;\n const trimmed = String(value).trim();\n return trimmed.length > 0 ? trimmed : null;\n}\n\nfunction stripTrailingSlash(url: string): string {\n return url.replace(/\\/+$/, \"\");\n}\n\nasync function safeReadText(response: CloudFetchResponse): Promise<string> {\n const text = await response.text().catch(() => \"\");\n return text.slice(0, 500);\n}\n\nfunction normalizeFetchResponse(value: unknown): CloudFetchResponse {\n if (!isRecord(value)) {\n throw new Error(\"Cloud Tailscale fetch returned a non-object response\");\n }\n\n const { ok, status, statusText, json, text } = value;\n if (\n typeof ok !== \"boolean\" ||\n typeof status !== \"number\" ||\n typeof statusText !== \"string\" ||\n typeof json !== \"function\" ||\n typeof text !== \"function\"\n ) {\n throw new Error(\n \"Cloud Tailscale fetch response is missing required fields\",\n );\n }\n\n return {\n ok,\n status,\n statusText,\n json: async () => json.call(value),\n text: async () => String(await text.call(value)),\n };\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null;\n}\n","import type { IAgentRuntime } from \"@elizaos/core\";\n\nexport const DEFAULT_TAILSCALE_ACCOUNT_ID = \"default\";\n\nexport interface TailscaleAccountConfig {\n accountId: string;\n authKey?: string;\n tags?: string | string[];\n funnel?: string | boolean;\n defaultPort?: string | number;\n backend?: \"local\" | \"cloud\" | \"auto\";\n authKeyExpirySeconds?: string | number;\n cloudApiKey?: string;\n cloudBaseUrl?: string;\n label?: string;\n}\n\ntype RawAccountRecord = Record<string, unknown>;\n\nfunction nonEmptyString(value: unknown): string | undefined {\n return typeof value === \"string\" && value.trim().length > 0\n ? value.trim()\n : undefined;\n}\n\nfunction readSetting(runtime: IAgentRuntime, key: string): string | undefined {\n return nonEmptyString(runtime.getSetting(key));\n}\n\nexport function normalizeTailscaleAccountId(value: unknown): string {\n return nonEmptyString(value) ?? DEFAULT_TAILSCALE_ACCOUNT_ID;\n}\n\nexport function resolveTailscaleAccountId(\n runtime: IAgentRuntime,\n options?: Record<string, unknown>,\n): string {\n return normalizeTailscaleAccountId(\n options?.accountId ??\n options?.tailscaleAccountId ??\n readSetting(runtime, \"TAILSCALE_DEFAULT_ACCOUNT_ID\") ??\n readSetting(runtime, \"TAILSCALE_ACCOUNT_ID\"),\n );\n}\n\nfunction parseAccountsJson(raw: string | undefined): RawAccountRecord[] {\n if (!raw) return [];\n try {\n const parsed = JSON.parse(raw) as unknown;\n if (Array.isArray(parsed)) {\n return parsed.filter(\n (item): item is RawAccountRecord =>\n Boolean(item) && typeof item === \"object\" && !Array.isArray(item),\n );\n }\n if (parsed && typeof parsed === \"object\") {\n return Object.entries(parsed as Record<string, unknown>)\n .filter(([, value]) => value && typeof value === \"object\")\n .map(([id, value]) => ({\n ...(value as RawAccountRecord),\n accountId: (value as RawAccountRecord).accountId ?? id,\n }));\n }\n } catch {\n return [];\n }\n return [];\n}\n\nfunction readRawField(\n record: RawAccountRecord,\n keys: readonly string[],\n): unknown {\n const credentials =\n record.credentials && typeof record.credentials === \"object\"\n ? (record.credentials as RawAccountRecord)\n : {};\n const metadata =\n record.metadata && typeof record.metadata === \"object\"\n ? (record.metadata as RawAccountRecord)\n : {};\n const settings =\n record.settings && typeof record.settings === \"object\"\n ? (record.settings as RawAccountRecord)\n : {};\n\n for (const source of [record, credentials, metadata, settings]) {\n for (const key of keys) {\n const value = source[key];\n if (value !== undefined && value !== null && value !== \"\") return value;\n }\n }\n return undefined;\n}\n\nfunction normalizeBackend(\n value: unknown,\n): \"local\" | \"cloud\" | \"auto\" | undefined {\n return value === \"local\" || value === \"cloud\" || value === \"auto\"\n ? value\n : undefined;\n}\n\nfunction accountFromRecord(\n record: RawAccountRecord,\n): TailscaleAccountConfig | null {\n const accountId = normalizeTailscaleAccountId(\n record.accountId ?? record.id ?? record.name,\n );\n const account: TailscaleAccountConfig = {\n accountId,\n authKey: nonEmptyString(\n readRawField(record, [\n \"TAILSCALE_AUTH_KEY\",\n \"authKey\",\n \"accessToken\",\n \"access\",\n ]),\n ),\n tags: readRawField(record, [\"TAILSCALE_TAGS\", \"tags\"]) as\n | string\n | string[]\n | undefined,\n funnel: readRawField(record, [\"TAILSCALE_FUNNEL\", \"funnel\"]) as\n | string\n | boolean\n | undefined,\n defaultPort: readRawField(record, [\n \"TAILSCALE_DEFAULT_PORT\",\n \"defaultPort\",\n ]) as string | number | undefined,\n backend: normalizeBackend(\n readRawField(record, [\"TAILSCALE_BACKEND\", \"backend\"]),\n ),\n authKeyExpirySeconds: readRawField(record, [\n \"TAILSCALE_AUTH_KEY_EXPIRY_SECONDS\",\n \"authKeyExpirySeconds\",\n ]) as string | number | undefined,\n cloudApiKey: nonEmptyString(\n readRawField(record, [\"ELIZAOS_CLOUD_API_KEY\", \"cloudApiKey\"]),\n ),\n cloudBaseUrl: nonEmptyString(\n readRawField(record, [\"ELIZAOS_CLOUD_BASE_URL\", \"cloudBaseUrl\"]),\n ),\n label: nonEmptyString(record.label ?? record.displayName),\n };\n return account;\n}\n\nfunction addAccount(\n accounts: Map<string, TailscaleAccountConfig>,\n account: TailscaleAccountConfig | null,\n): void {\n if (account) {\n accounts.set(account.accountId, account);\n }\n}\n\nexport function readTailscaleAccounts(\n runtime: IAgentRuntime,\n): TailscaleAccountConfig[] {\n const accounts = new Map<string, TailscaleAccountConfig>();\n const characterConfig = runtime.character?.settings?.tailscale as\n | { accounts?: unknown }\n | undefined;\n const characterAccounts = characterConfig?.accounts;\n\n if (Array.isArray(characterAccounts)) {\n for (const item of characterAccounts) {\n if (item && typeof item === \"object\") {\n addAccount(accounts, accountFromRecord(item as RawAccountRecord));\n }\n }\n } else if (characterAccounts && typeof characterAccounts === \"object\") {\n for (const [id, value] of Object.entries(\n characterAccounts as Record<string, unknown>,\n )) {\n if (value && typeof value === \"object\") {\n addAccount(\n accounts,\n accountFromRecord({\n ...(value as RawAccountRecord),\n accountId: (value as RawAccountRecord).accountId ?? id,\n }),\n );\n }\n }\n }\n\n for (const record of parseAccountsJson(\n readSetting(runtime, \"TAILSCALE_ACCOUNTS\"),\n )) {\n addAccount(accounts, accountFromRecord(record));\n }\n\n addAccount(accounts, {\n accountId: normalizeTailscaleAccountId(\n readSetting(runtime, \"TAILSCALE_ACCOUNT_ID\") ??\n readSetting(runtime, \"TAILSCALE_DEFAULT_ACCOUNT_ID\"),\n ),\n authKey: readSetting(runtime, \"TAILSCALE_AUTH_KEY\"),\n tags: readSetting(runtime, \"TAILSCALE_TAGS\"),\n funnel: readSetting(runtime, \"TAILSCALE_FUNNEL\"),\n defaultPort: readSetting(runtime, \"TAILSCALE_DEFAULT_PORT\"),\n backend: normalizeBackend(readSetting(runtime, \"TAILSCALE_BACKEND\")),\n authKeyExpirySeconds: readSetting(\n runtime,\n \"TAILSCALE_AUTH_KEY_EXPIRY_SECONDS\",\n ),\n cloudApiKey: readSetting(runtime, \"ELIZAOS_CLOUD_API_KEY\"),\n cloudBaseUrl: readSetting(runtime, \"ELIZAOS_CLOUD_BASE_URL\"),\n });\n\n return Array.from(accounts.values());\n}\n\nexport function resolveTailscaleAccount(\n accounts: readonly TailscaleAccountConfig[],\n accountId: string,\n): TailscaleAccountConfig | null {\n return (\n accounts.find((account) => account.accountId === accountId) ??\n accounts.find(\n (account) => account.accountId === DEFAULT_TAILSCALE_ACCOUNT_ID,\n ) ??\n accounts[0] ??\n null\n );\n}\n","import type { IAgentRuntime } from \"@elizaos/core\";\nimport { z } from \"zod\";\nimport {\n readTailscaleAccounts,\n resolveTailscaleAccount,\n resolveTailscaleAccountId,\n} from \"./accounts\";\n\nconst tailscaleEnvSchema = z.object({\n TAILSCALE_AUTH_KEY: z.string().optional(),\n TAILSCALE_TAGS: z\n .union([z.string(), z.array(z.string())])\n .optional()\n .transform((value) => {\n if (Array.isArray(value)) return value.filter((tag) => tag.length > 0);\n if (typeof value === \"string\" && value.length > 0)\n return value\n .split(\",\")\n .map((tag) => tag.trim())\n .filter((tag) => tag.length > 0);\n return [\"tag:eliza-tunnel\"];\n })\n .default([\"tag:eliza-tunnel\"]),\n TAILSCALE_FUNNEL: z\n .union([z.string(), z.boolean()])\n .optional()\n .transform((value) => value === true || value === \"true\" || value === \"1\")\n .default(false),\n TAILSCALE_DEFAULT_PORT: z\n .union([z.string(), z.number()])\n .optional()\n .transform((value) => {\n if (value === undefined || value === \"\") return 3000;\n const num =\n typeof value === \"string\" ? Number.parseInt(value, 10) : value;\n if (Number.isNaN(num) || num <= 0 || num > 65535) return 3000;\n return num;\n })\n .default(3000),\n TAILSCALE_BACKEND: z\n .enum([\"local\", \"cloud\", \"auto\"])\n .optional()\n .default(\"auto\"),\n TAILSCALE_AUTH_KEY_EXPIRY_SECONDS: z\n .union([z.string(), z.number()])\n .optional()\n .transform((value) => {\n if (value === undefined || value === \"\") return 3600;\n const num =\n typeof value === \"string\" ? Number.parseInt(value, 10) : value;\n if (Number.isNaN(num) || num <= 0) return 3600;\n return num;\n })\n .default(3600),\n});\n\ntype TailscaleConfig = z.infer<typeof tailscaleEnvSchema>;\n\nfunction readSetting(runtime: IAgentRuntime, key: string): string | undefined {\n const value = runtime.getSetting(key);\n if (value === null || value === undefined) return undefined;\n return String(value);\n}\n\nexport async function validateTailscaleConfig(\n runtime: IAgentRuntime,\n accountId?: string,\n): Promise<TailscaleConfig> {\n const resolvedAccountId = accountId ?? resolveTailscaleAccountId(runtime);\n const account = resolveTailscaleAccount(\n readTailscaleAccounts(runtime),\n resolvedAccountId,\n );\n const config = {\n TAILSCALE_AUTH_KEY:\n account?.authKey ??\n readSetting(runtime, \"TAILSCALE_AUTH_KEY\") ??\n process.env.TAILSCALE_AUTH_KEY,\n TAILSCALE_TAGS:\n account?.tags ??\n readSetting(runtime, \"TAILSCALE_TAGS\") ??\n process.env.TAILSCALE_TAGS,\n TAILSCALE_FUNNEL:\n account?.funnel ??\n readSetting(runtime, \"TAILSCALE_FUNNEL\") ??\n process.env.TAILSCALE_FUNNEL,\n TAILSCALE_DEFAULT_PORT:\n account?.defaultPort ??\n readSetting(runtime, \"TAILSCALE_DEFAULT_PORT\") ??\n process.env.TAILSCALE_DEFAULT_PORT,\n TAILSCALE_BACKEND:\n account?.backend ??\n readSetting(runtime, \"TAILSCALE_BACKEND\") ??\n process.env.TAILSCALE_BACKEND,\n TAILSCALE_AUTH_KEY_EXPIRY_SECONDS:\n account?.authKeyExpirySeconds ??\n readSetting(runtime, \"TAILSCALE_AUTH_KEY_EXPIRY_SECONDS\") ??\n process.env.TAILSCALE_AUTH_KEY_EXPIRY_SECONDS,\n };\n return tailscaleEnvSchema.parse(config);\n}\n","import { spawn } from \"node:child_process\";\nimport { elizaLogger, type IAgentRuntime, Service } from \"@elizaos/core\";\nimport { z } from \"zod\";\nimport { validateTailscaleConfig } from \"../environment\";\nimport type { ITunnelService, TunnelStatus } from \"../types\";\n\nconst tailscaleStatusPeerSchema = z.object({\n DNSName: z.string().optional(),\n Online: z.boolean().optional(),\n});\n\nconst tailscaleStatusSchema = z.object({\n Self: z\n .object({\n DNSName: z.string().optional(),\n })\n .optional(),\n MagicDNSSuffix: z.string().optional(),\n Peer: z.record(z.string(), tailscaleStatusPeerSchema).optional(),\n});\n\ntype TailscaleStatus = z.infer<typeof tailscaleStatusSchema>;\n\ninterface SpawnResult {\n code: number | null;\n stdout: string;\n stderr: string;\n}\n\nfunction runCommand(cmd: string, args: string[]): Promise<SpawnResult> {\n return new Promise((resolve, reject) => {\n const child = spawn(cmd, args, { stdio: [\"ignore\", \"pipe\", \"pipe\"] });\n const out: Buffer[] = [];\n const err: Buffer[] = [];\n child.stdout?.on(\"data\", (chunk: Buffer) => out.push(chunk));\n child.stderr?.on(\"data\", (chunk: Buffer) => err.push(chunk));\n child.on(\"error\", reject);\n child.on(\"exit\", (code) =>\n resolve({\n code,\n stdout: Buffer.concat(out).toString(\"utf8\"),\n stderr: Buffer.concat(err).toString(\"utf8\"),\n }),\n );\n });\n}\n\nfunction checkTailscaleInstalled(): Promise<boolean> {\n return new Promise((resolve) => {\n const proc = spawn(\"which\", [\"tailscale\"]);\n proc.on(\"exit\", (code) => resolve(code === 0));\n proc.on(\"error\", () => resolve(false));\n });\n}\n\nfunction parseTailscaleStatus(stdout: string): TailscaleStatus | null {\n let raw: unknown;\n try {\n raw = JSON.parse(stdout);\n } catch {\n return null;\n }\n const result = tailscaleStatusSchema.safeParse(raw);\n return result.success ? result.data : null;\n}\n\nexport class LocalTailscaleService extends Service implements ITunnelService {\n static override serviceType = \"tunnel\";\n readonly capabilityDescription =\n \"Provides secure tunnel functionality via the locally-installed `tailscale` CLI (serve / funnel).\";\n\n private tunnelUrl: string | null = null;\n private tunnelPort: number | null = null;\n private startedAt: Date | null = null;\n private isShuttingDown = false;\n private useFunnel = false;\n\n static override async start(runtime: IAgentRuntime): Promise<Service> {\n const service = new LocalTailscaleService(runtime);\n await service.start();\n return service;\n }\n\n async start(): Promise<void> {\n elizaLogger.info(\"[LocalTailscaleService] starting\");\n const installed = await checkTailscaleInstalled();\n if (!installed) {\n throw new Error(\n \"tailscale is not installed. Install from https://tailscale.com/download or run: brew install tailscale\",\n );\n }\n }\n\n async stop(): Promise<void> {\n await this.stopTunnel();\n }\n\n async startTunnel(\n port?: number,\n options: { accountId?: string } = {},\n ): Promise<string | undefined> {\n if (this.isActive()) {\n elizaLogger.warn(\"[LocalTailscaleService] tunnel already running\");\n return this.tunnelUrl ?? undefined;\n }\n\n if (port === undefined || port === null) {\n elizaLogger.warn(\n \"[LocalTailscaleService] startTunnel called without a port — service active but no tunnel started\",\n );\n return;\n }\n\n if (port < 1 || port > 65535) {\n throw new Error(\"Invalid port number\");\n }\n\n const config = await validateTailscaleConfig(\n this.runtime,\n options.accountId,\n );\n this.useFunnel = config.TAILSCALE_FUNNEL;\n\n elizaLogger.info(\n `[LocalTailscaleService] starting tunnel on port ${port} (funnel=${this.useFunnel})`,\n );\n\n if (this.useFunnel) {\n const result = await runCommand(\"tailscale\", [\"funnel\", String(port)]);\n if (result.code !== 0) {\n throw new Error(\n `tailscale funnel exited with code ${result.code}: ${result.stderr.trim()}`,\n );\n }\n } else {\n const result = await runCommand(\"tailscale\", [\n \"serve\",\n \"--bg\",\n \"--https=443\",\n `localhost:${port}`,\n ]);\n if (result.code !== 0) {\n throw new Error(\n `tailscale serve exited with code ${result.code}: ${result.stderr.trim()}`,\n );\n }\n }\n\n const dnsName = await this.fetchSelfDnsName();\n if (!dnsName) {\n throw new Error(\n \"tailscale serve started but no DNSName resolved from `tailscale status --json`\",\n );\n }\n this.tunnelUrl = this.useFunnel\n ? `https://${dnsName}`\n : `https://${dnsName}`;\n this.tunnelPort = port;\n this.startedAt = new Date();\n elizaLogger.info(\n `[LocalTailscaleService] tunnel started: ${this.tunnelUrl}`,\n );\n return this.tunnelUrl;\n }\n\n async stopTunnel(_options: { accountId?: string } = {}): Promise<void> {\n if (!this.isActive()) {\n elizaLogger.warn(\"[LocalTailscaleService] no active tunnel to stop\");\n return;\n }\n this.isShuttingDown = true;\n elizaLogger.info(\"[LocalTailscaleService] stopping tunnel\");\n\n if (this.useFunnel) {\n await runCommand(\"tailscale\", [\"funnel\", \"reset\"]);\n } else {\n await runCommand(\"tailscale\", [\"serve\", \"reset\"]);\n }\n\n this.cleanup();\n this.isShuttingDown = false;\n elizaLogger.info(\"[LocalTailscaleService] tunnel stopped\");\n }\n\n getUrl(): string | null {\n return this.tunnelUrl;\n }\n\n isActive(): boolean {\n return this.tunnelUrl !== null && !this.isShuttingDown;\n }\n\n getStatus(): TunnelStatus {\n return {\n active: this.isActive(),\n url: this.tunnelUrl,\n port: this.tunnelPort,\n startedAt: this.startedAt,\n provider: \"tailscale\",\n };\n }\n\n private async fetchSelfDnsName(): Promise<string | null> {\n const result = await runCommand(\"tailscale\", [\"status\", \"--json\"]);\n if (result.code !== 0) {\n elizaLogger.error(\n `[LocalTailscaleService] tailscale status failed: ${result.stderr.trim()}`,\n );\n return null;\n }\n const status = parseTailscaleStatus(result.stdout);\n if (!status) {\n elizaLogger.error(\n \"[LocalTailscaleService] tailscale status returned malformed JSON\",\n );\n return null;\n }\n const raw = status.Self?.DNSName;\n if (!raw) return null;\n return raw.replace(/\\.$/, \"\");\n }\n\n private cleanup(): void {\n this.tunnelUrl = null;\n this.tunnelPort = null;\n this.startedAt = null;\n this.useFunnel = false;\n }\n}\n","import type { IAgentRuntime, TestCase, TestSuite } from \"@elizaos/core\";\nimport { CloudTailscaleService } from \"../services/CloudTailscaleService\";\nimport { LocalTailscaleService } from \"../services/LocalTailscaleService\";\n\nconst CANONICAL_TUNNEL_SERVICE_TYPE = \"tunnel\";\n\nexport class TailscaleTestSuite implements TestSuite {\n name = \"tailscale\";\n tests: TestCase[] = [\n {\n name: \"LocalTailscaleService claims canonical tunnel service-type\",\n fn: (_runtime: IAgentRuntime) => {\n if (\n LocalTailscaleService.serviceType !== CANONICAL_TUNNEL_SERVICE_TYPE\n ) {\n throw new Error(\n `LocalTailscaleService.serviceType must be \"${CANONICAL_TUNNEL_SERVICE_TYPE}\"`,\n );\n }\n },\n },\n {\n name: \"CloudTailscaleService claims canonical tunnel service-type\",\n fn: (_runtime: IAgentRuntime) => {\n if (\n CloudTailscaleService.serviceType !== CANONICAL_TUNNEL_SERVICE_TYPE\n ) {\n throw new Error(\n `CloudTailscaleService.serviceType must be \"${CANONICAL_TUNNEL_SERVICE_TYPE}\"`,\n );\n }\n },\n },\n ];\n}\n","/**\n * Tailscale ConnectorAccountManager provider.\n *\n * Adapts the existing multi-account resolver in `accounts.ts` to the\n * ConnectorAccountManager CRUD surface. Legacy single-account env/settings\n * are surfaced as the default OWNER account; additional accounts can be\n * declared through character.settings.tailscale.accounts or TAILSCALE_ACCOUNTS.\n *\n * Tailscale does not use an OAuth redirect flow here. Local CLI login and\n * cloud auth-key/API-key provisioning remain owned by the backend services.\n */\n\nimport type {\n ConnectorAccount,\n ConnectorAccountManager,\n ConnectorAccountPatch,\n ConnectorAccountProvider,\n ConnectorAccountPurpose,\n IAgentRuntime,\n} from \"@elizaos/core\";\nimport {\n normalizeTailscaleAccountId,\n readTailscaleAccounts,\n resolveTailscaleAccountId,\n type TailscaleAccountConfig,\n} from \"./accounts\";\n\nexport const TAILSCALE_PROVIDER_ID = \"tailscale\";\n\nconst DEFAULT_PURPOSES: ConnectorAccountPurpose[] = [\n \"admin\" as ConnectorAccountPurpose,\n \"automation\" as ConnectorAccountPurpose,\n];\n\nfunction hasExplicitConfig(account: TailscaleAccountConfig): boolean {\n return Boolean(\n account.authKey ||\n account.tags !== undefined ||\n account.funnel !== undefined ||\n account.defaultPort !== undefined ||\n account.backend !== undefined ||\n account.authKeyExpirySeconds !== undefined ||\n account.cloudApiKey ||\n account.cloudBaseUrl,\n );\n}\n\nfunction authMethodForAccount(account: TailscaleAccountConfig): string {\n if (account.cloudApiKey) return \"cloud_api_key\";\n if (account.authKey) return \"auth_key\";\n if (account.backend === \"local\") return \"local_cli\";\n return \"runtime\";\n}\n\nfunction toConnectorAccount(\n account: TailscaleAccountConfig,\n defaultAccountId: string,\n): ConnectorAccount {\n const now = Date.now();\n const accountId = normalizeTailscaleAccountId(account.accountId);\n const configured = hasExplicitConfig(account);\n return {\n id: accountId,\n provider: TAILSCALE_PROVIDER_ID,\n label: account.label ?? `Tailscale (${accountId})`,\n role: \"OWNER\",\n purpose: DEFAULT_PURPOSES,\n accessGate: \"open\",\n status: configured ? \"connected\" : \"disabled\",\n displayHandle: account.label ?? accountId,\n createdAt: now,\n updatedAt: now,\n metadata: {\n authMethod: authMethodForAccount(account),\n source: \"legacy\",\n isDefault: accountId === defaultAccountId,\n backend: account.backend ?? \"auto\",\n funnel: account.funnel ?? null,\n defaultPort: account.defaultPort ?? null,\n tags: account.tags ?? null,\n authKeyExpirySeconds: account.authKeyExpirySeconds ?? null,\n hasAuthKey: Boolean(account.authKey),\n hasCloudApiKey: Boolean(account.cloudApiKey),\n cloudBaseUrl: account.cloudBaseUrl ?? null,\n },\n };\n}\n\nfunction normalizePurposes(\n purpose: ConnectorAccountPatch[\"purpose\"] | undefined,\n fallback: ConnectorAccountPurpose[],\n): ConnectorAccountPurpose[] {\n if (Array.isArray(purpose)) return purpose;\n if (typeof purpose === \"string\" && purpose.trim()) return [purpose];\n return fallback;\n}\n\nfunction mergeStoredAccountPatch(\n account: ConnectorAccount,\n patch: ConnectorAccountPatch,\n): ConnectorAccount {\n return {\n ...account,\n ...patch,\n provider: TAILSCALE_PROVIDER_ID,\n id: account.id,\n purpose: normalizePurposes(patch.purpose, account.purpose),\n externalId:\n patch.externalId === undefined\n ? account.externalId\n : (patch.externalId ?? undefined),\n displayHandle:\n patch.displayHandle === undefined\n ? account.displayHandle\n : (patch.displayHandle ?? undefined),\n ownerBindingId:\n patch.ownerBindingId === undefined\n ? account.ownerBindingId\n : (patch.ownerBindingId ?? undefined),\n ownerIdentityId:\n patch.ownerIdentityId === undefined\n ? account.ownerIdentityId\n : (patch.ownerIdentityId ?? undefined),\n metadata: patch.metadata ?? account.metadata,\n createdAt: account.createdAt,\n };\n}\n\nexport function createTailscaleConnectorAccountProvider(\n runtime: IAgentRuntime,\n): ConnectorAccountProvider {\n return {\n provider: TAILSCALE_PROVIDER_ID,\n label: \"Tailscale\",\n\n listAccounts: async (\n manager: ConnectorAccountManager,\n ): Promise<ConnectorAccount[]> => {\n const stored = await manager\n .getStorage()\n .listAccounts(TAILSCALE_PROVIDER_ID);\n const storedById = new Set(stored.map((account) => account.id));\n const defaultAccountId = resolveTailscaleAccountId(runtime);\n const synthesized = readTailscaleAccounts(runtime)\n .map((account) => toConnectorAccount(account, defaultAccountId))\n .filter((account) => !storedById.has(account.id));\n return [...stored, ...synthesized];\n },\n\n createAccount: async (\n input: ConnectorAccountPatch,\n _manager: ConnectorAccountManager,\n ) => {\n return {\n ...input,\n provider: TAILSCALE_PROVIDER_ID,\n role: input.role ?? \"OWNER\",\n purpose: input.purpose ?? DEFAULT_PURPOSES,\n accessGate: input.accessGate ?? \"open\",\n status: input.status ?? \"pending\",\n };\n },\n\n patchAccount: async (\n accountId: string,\n patch: ConnectorAccountPatch,\n manager: ConnectorAccountManager,\n ) => {\n const existing = await manager\n .getStorage()\n .getAccount(TAILSCALE_PROVIDER_ID, accountId);\n if (existing) {\n return mergeStoredAccountPatch(existing, patch);\n }\n return { ...patch, provider: TAILSCALE_PROVIDER_ID };\n },\n\n deleteAccount: async (\n _accountId: string,\n _manager: ConnectorAccountManager,\n ): Promise<void> => {\n // Runtime credentials live in env/character settings or the selected\n // backend; the manager removes only its account row.\n },\n };\n}\n","/**\n * Tailscale plugin re-exports the canonical tunnel-service contract from\n * `@elizaos/plugin-tunnel`. Both backends (local CLI, cloud auth-key minter)\n * register under `serviceType=\"tunnel\"`. Consumers should call\n * `getTunnelService(runtime)` from `@elizaos/plugin-tunnel` to stay\n * backend-agnostic.\n */\n\nexport {\n getTunnelService,\n type ITunnelService,\n type TunnelProvider,\n type TunnelStatus,\n} from \"@elizaos/plugin-tunnel\";\n\nexport type TailscaleBackendMode = \"local\" | \"cloud\" | \"auto\";\n","/**\n * tailscaleStatus provider — injects the current tunnel status into the LLM\n * context as compact JSON.\n *\n * Replaces the previous GET_TAILSCALE_STATUS action: status is now passively\n * available every turn so the planner does not need to dispatch a dedicated\n * action just to read tunnel state.\n */\n\nimport type { IAgentRuntime, Memory, Provider, State } from \"@elizaos/core\";\nimport { getTunnelService } from \"../types\";\n\nfunction formatUptime(startedAt: Date): string {\n const ms = Date.now() - startedAt.getTime();\n const minutes = Math.floor(ms / 60_000);\n const hours = Math.floor(minutes / 60);\n if (hours > 0) {\n return `${hours} hour${hours === 1 ? \"\" : \"s\"}, ${minutes % 60} minute${minutes % 60 === 1 ? \"\" : \"s\"}`;\n }\n return `${minutes} minute${minutes === 1 ? \"\" : \"s\"}`;\n}\n\nexport const tailscaleStatusProvider: Provider = {\n name: \"tailscaleStatus\",\n description:\n \"Current Tailscale tunnel status: active flag, public URL, local port, uptime, backend provider.\",\n descriptionCompressed: \"Tailscale tunnel status: active, url, port, uptime.\",\n dynamic: true,\n contexts: [\"settings\", \"connectors\"],\n contextGate: { anyOf: [\"settings\", \"connectors\"] },\n cacheStable: false,\n cacheScope: \"turn\",\n get: async (runtime: IAgentRuntime, _message: Memory, _state: State) => {\n const tunnelService = getTunnelService(runtime);\n if (!tunnelService) {\n return { text: \"\" };\n }\n\n const status = tunnelService.getStatus();\n const uptime = status.startedAt ? formatUptime(status.startedAt) : null;\n\n const text = JSON.stringify({\n tailscale: {\n active: status.active,\n url: status.url,\n port: status.port,\n uptime,\n provider: status.provider,\n },\n });\n\n return {\n text,\n values: {\n active: status.active,\n url: status.url ?? \"\",\n port: status.port ?? 0,\n provider: status.provider,\n },\n data: { status, uptime },\n };\n },\n};\n","import { isCloudConnected } from \"@elizaos/cloud-routing\";\nimport { elizaLogger, type IAgentRuntime } from \"@elizaos/core\";\nimport {\n readTailscaleAccounts,\n resolveTailscaleAccount,\n resolveTailscaleAccountId,\n} from \"../accounts\";\nimport type { TailscaleBackendMode } from \"../types\";\nimport { CloudTailscaleService } from \"./CloudTailscaleService\";\nimport { LocalTailscaleService } from \"./LocalTailscaleService\";\n\ntype TunnelBackendCtor =\n | typeof LocalTailscaleService\n | typeof CloudTailscaleService;\n\nexport interface BackendDecision {\n backend: TunnelBackendCtor;\n mode: TailscaleBackendMode;\n reason: string;\n}\n\nconst ALLOWED_MODES: ReadonlySet<TailscaleBackendMode> = new Set([\n \"local\",\n \"cloud\",\n \"auto\",\n]);\n\nexport function readBackendMode(runtime: IAgentRuntime): TailscaleBackendMode {\n const account = resolveTailscaleAccount(\n readTailscaleAccounts(runtime),\n resolveTailscaleAccountId(runtime),\n );\n const raw = account?.backend ?? runtime.getSetting(\"TAILSCALE_BACKEND\");\n if (raw === null || raw === undefined) return \"auto\";\n const normalized = String(raw).trim().toLowerCase();\n if (ALLOWED_MODES.has(normalized as TailscaleBackendMode)) {\n return normalized as TailscaleBackendMode;\n }\n elizaLogger.warn(\n `[TunnelBackendSelector] invalid TAILSCALE_BACKEND=\"${raw}\" — falling back to \"auto\"`,\n );\n return \"auto\";\n}\n\nexport function selectTunnelBackend(runtime: IAgentRuntime): BackendDecision {\n const mode = readBackendMode(runtime);\n\n switch (mode) {\n case \"local\":\n return {\n backend: LocalTailscaleService,\n mode,\n reason: \"TAILSCALE_BACKEND=local\",\n };\n case \"cloud\":\n return {\n backend: CloudTailscaleService,\n mode,\n reason: \"TAILSCALE_BACKEND=cloud\",\n };\n case \"auto\": {\n if (isCloudConnected(runtime)) {\n return {\n backend: CloudTailscaleService,\n mode,\n reason: \"auto: cloud connected\",\n };\n }\n return {\n backend: LocalTailscaleService,\n mode,\n reason: \"auto: cloud not connected\",\n };\n }\n }\n}\n"],"mappings":"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","names":["elizaLogger","z","readSetting","z","spawn","elizaLogger","Service","z","z","spawn","Service","elizaLogger","elizaLogger","elizaLogger","elizaLogger"]}