Skip to content

[AIDE-124] Tailscale Serve Management - #97

Merged
chandlerhuff merged 4 commits into
mainfrom
feature/AIDE-124-tailscale-serve-management
Aug 29, 2026
Merged

[AIDE-124] Tailscale Serve Management#97
chandlerhuff merged 4 commits into
mainfrom
feature/AIDE-124-tailscale-serve-management

Conversation

@chandlerhuff

Copy link
Copy Markdown
Member

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/funnel CLI commands (never a shell, only loopback 127.0.0.1 destinations), report back normalized snapshots, and the control plane persists templates, per-agent assignments, and durable fleet operations.

Changes

  • Agent contract (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.
  • Control agent handlers: inspect/upsert/remove typed jobs that run the Tailscale CLI without a shell, normalize tailscale status --json + serve status --json into 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 at CONTROL_AGENT_TAILSCALE_EXECUTABLE.
  • TailscaleServeService: fleet templates with optimistic-concurrency revisions, listener-conflict detection across assignments, automatic import of inspected routes into IMPORTED templates, per-agent enable/disable toggles that retain desired state, retryable deletes (template purged only after every agent confirms), and durable operations with QUEUED/RUNNING/SUCCEEDED/FAILED/PARTIAL_FAILED/UNSUPPORTED aggregation.
  • Persistence: new Prisma migration adding TailscaleServeTemplate, TailscaleServeAssignment, TailscaleAgentState, and TailscaleServeOperation(+Agent) tables with indexes on lifecycle, status, and job linkage.
  • GraphQL: full schema in schemas/tailscale.graphql — overview query, four typed mutations, and two subscriptions (overviewChanged, operationChanged); resolvers reject agent credentials for control-plane operations.
  • UI: new /tailscale dashboard 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.
  • MCP tools: builtin:tailscale group with 5 tools; zod-validated typed inputs that reject raw command fields and out-of-range ports before service invocation, with read-only/write/destructive-open-world annotations.
  • Workflows: four new polled step kinds (TAILSCALE_SERVE_INSPECT/UPSERT_TEMPLATE/SET_AGENT_ENABLED/DELETE_TEMPLATE) with config descriptors, agent resource selectors, session tailscale.* namespace fields, and wait pollers that fail on partial fleet results.
  • Tooling: mock-data seeding for templates/assignments/identities, a Playwright route, and nav/aliases wiring (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

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
@chandlerhuff chandlerhuff self-assigned this Aug 29, 2026
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.
@chandlerhuff
chandlerhuff merged commit 6d872e4 into main Aug 29, 2026
3 checks passed
@chandlerhuff
chandlerhuff deleted the feature/AIDE-124-tailscale-serve-management branch August 29, 2026 17:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant