[AIDE-124] Tailscale Serve Management - #97
Merged
Conversation
Add end-to-end Tailscale Serve management across the stack: - New tailscale service (src/services/tailscale) for managing serve configs - GraphQL schema, resolvers, and agent-contract types for tailscale operations - Control-agent handlers and agent inventory integration - Builtin tool exposing tailscale serve controls to agents - Workflow adapters, config descriptors, and session schema support - Dashboard UI page for tailscale serve management - Prisma migration and updated schema for tailscale state - Localization strings and mock-data seeding
Replace native selects and checkboxes with shadcn Select and Switch components, and add a dropdown menu for opening routes via DNS hostname, IPv4, or IPv6. Inspect agents on page appearance while keeping a manual refresh, and show relative inspection timestamps with refined status badges. Add a Tailscale breadcrumb and update translations.
…-safe Return the existing operation when a request is retried, use optimistic concurrency (expectedRevision) for template updates, persist dispatch state (UNSUPPORTED/FAILED/job) atomically with assignments, and guard against stale inspection projections. Also fix the app capability field name (AppCapabilities -> AcceptAppCaps) when normalizing serve config.
…ywright captures TailscaleServePage inspects the fleet on load, and all Playwright projects share one mock database, so each page load enqueued live QUEUED jobs while Polling screenshots were captured, making pendingJobs output timing-dependent. Seed a completed PARTIAL_FAILED inspection and pin crypto.randomUUID in the route's init script to reuse that request id.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds fleet-wide Tailscale Serve management: shared, typed Serve routes that the control plane applies to control agents with independent desired vs. observed state. Agents run safe
tailscale serve/funnelCLI commands (never a shell, only loopback127.0.0.1destinations), report back normalized snapshots, and the control plane persists templates, per-agent assignments, and durable fleet operations.Changes
agent-contract/tailscale): typed Serve route/payload parsers that validate protocols, ports (1–65535), mount paths, app capabilities (domain/name), Funnel port rules, and PROXY protocol constraints; SHA-256 route fingerprints and stable listener keys.inspect/upsert/removetyped jobs that run the Tailscale CLI without a shell, normalizetailscale status --json+serve status --jsoninto snapshots (only managed 127.0.0.1 targets; file/remote handlers stay unmanaged), remove moved listeners before re-applying, and serialize mutations per agent. Missing CLI produces an actionable error pointing atCONTROL_AGENT_TAILSCALE_EXECUTABLE.IMPORTEDtemplates, per-agent enable/disable toggles that retain desired state, retryable deletes (template purged only after every agent confirms), and durable operations withQUEUED/RUNNING/SUCCEEDED/FAILED/PARTIAL_FAILED/UNSUPPORTEDaggregation.TailscaleServeTemplate,TailscaleServeAssignment,TailscaleAgentState, andTailscaleServeOperation(+Agent)tables with indexes on lifecycle, status, and job linkage.schemas/tailscale.graphql— overview query, four typed mutations, and two subscriptions (overviewChanged,operationChanged); resolvers reject agent credentials for control-plane operations./tailscaledashboard page (System section) showing agent identity (MagicDNS hostname, IPv4/IPv6, backend state), supported/unsupported badges, fleet template cards with observed vs. desired status and retry, a typed template editor with a Funnel public-exposure confirmation, and delete confirmation. Localized in en, de, es, fr.builtin:tailscalegroup with 5 tools; zod-validated typed inputs that reject rawcommandfields and out-of-range ports before service invocation, with read-only/write/destructive-open-world annotations.TAILSCALE_SERVE_INSPECT/UPSERT_TEMPLATE/SET_AGENT_ENABLED/DELETE_TEMPLATE) with config descriptors, agent resource selectors, sessiontailscale.*namespace fields, and wait pollers that fail on partial fleet results.tailscale serve,funnel,tailnet).Tests
Unit tests across the agent contract, handlers, service (real SQLite + migrations, covering imports, drift, stale-revision replacement, partial failures, and retried deletes), GraphQL resolvers, UI page, MCP tools, and workflow adapters. Mock CI agent intentionally lacks Tailscale capabilities to exercise the unsupported path.
Ticket: AIDE-124