This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
This is an unofficial, MIT-licensed Swift 6 package providing async/await access to the Tailscale LocalAPI for Apple platforms. It's designed for building monitoring tools, status widgets, dashboards, and developer utilities that work with an existing Tailscale installation.
Important: This is NOT an official Tailscale product and has no affiliation with Tailscale Inc. Maintain this disclaimer in README, DocC, and source headers. This is NOT an embedded Tailscale implementation—use official TailscaleKit for that.
# Build the package
swift build
# Format code
swift format --in-place --recursive Sources/ Tests/
# Lint code (CI uses swift format lint only)
swift format lint --recursive Sources/ Tests/
# Run all tests (unit tests with mocked transport only)
swift test
# Run integration tests (requires local tailscaled instance)
TAILSCALE_INTEGRATION=1 swift test --filter TailscaleClientIntegrationTests
# Run a single test
swift test --filter StatusAPITests
# Build documentation
swift package --allow-writing-to-directory ./docs \
generate-documentation --target TailscaleClient \
--output-path ./docs
# Enable LocalAPI discovery debug logging
TAILSCALE_DISCOVERY_DEBUG=1 swift test
# Run the development CLI tool
swift run tailscale-swift status-
Transport Layer (
Transport/)TailscaleTransportprotocol: Pluggable transport abstractionURLSessionTailscaleTransport: Production implementation supporting both Unix domain sockets and loopback TCPUnixSocketTransport: Low-level Unix socket communication usingCFSocketandconnect(2)- Handles header injection (
Tailscale-Cap,Authorization), request building, and network error mapping
-
Configuration & Discovery (
Configuration/)TailscaleClientConfiguration: Connection settings (endpoint, auth token, capability version, transport)LocalAPIDiscovery: Environment variable and platform-specific discovery of LocalAPI endpoint.defaultconfiguration auto-discovers via env vars, then platform-specific methods, then fallback socket paths- On macOS, uses
MacClientInfoto locate App Store GUI's loopback API
-
macOS Platform Discovery (
Platform/MacClientInfo.swift)- IMPORTANT: App Store discovery is disabled by default to avoid TCC popups
- Must explicitly opt-in:
TailscaleClientConfiguration.default(allowMacOSAppStoreDiscovery: true) - Discovery order (when socket discovery fails and App Store discovery is enabled):
- libproc (PRIMARY): Uses
proc_pidinfoto find IPNExtension's open files (~5ms) - Filesystem fallback: Enumerates Group Containers directories (~50-200ms)
- libproc (PRIMARY): Uses
- Respects
TAILSCALE_SAMEUSER_PATH,TAILSCALE_SAMEUSER_DIR,TAILSCALE_SKIP_LIBPROC - Use
TAILSCALE_DISCOVERY_DEBUG=1for verbose logging to stderr
-
Models (
Models/)StatusResponse: Strongly-typed Codable models mirroring LocalAPI JSON responsesStatusQuery: Query parameters for status endpoint (e.g.,includePeers)- All models are
Sendablefor Swift 6 strict concurrency
-
Client API (
TailscaleClient.swift)- Public
actor TailscaleClientproviding thread-safe async access - Exposes:
status(query:),whois(address:),prefs(),ping(ip:type:size:),metrics() - Maps transport errors to
TailscaleClientError(.transport,.unexpectedStatus,.decoding)
- Public
-
Network Interface Discovery (
Platform/NetworkInterfaceDiscovery.swift)- Uses BSD
getifaddrsto enumerate system interfaces - Matches Tailscale IPs to find the TUN interface (e.g.,
utun16) - Exposed via
StatusResponse.interfaceNameandStatusResponse.interfaceInfo
- Uses BSD
- Swift 6 Strict Concurrency: All public types are
Sendable; useactorfor state isolation - Async/await throughout: No callbacks or completion handlers
- Protocol-oriented transport: Inject
MockTransportin tests, use real transports in production - Graceful discovery fallback: LocalAPI discovery degrades gracefully through multiple strategies
- Unix socket support: Custom CFSocket-based implementation for Unix domain socket communication
- Unit tests: Use
MockTransportwith fixture JSON files fromTests/TailscaleClientTests/Fixtures/ - Integration tests: Gated behind
TAILSCALE_INTEGRATION=1environment variable; talk to real tailscaled - XCTest patterns: Use
XCTAssertThrowsErrorAsynchelper (defined inTestSupport.swift) for async error assertions - Request recording: Use
RequestRecorderactor pattern (seeStatusAPITests.swift) to verify requests in tests - CI is hermetic: GitHub Actions runs only mock-backed unit tests; no real tailscaled dependency
- Never manually edit Xcode project files: Have the human user perform XCode modifications
- Swift 6 features required: Use async/await and actors throughout; avoid legacy concurrency patterns
- Platform-specific code: Use
#if os(macOS)for macOS-specific discovery logic - Error handling: Provide detailed error context (transport errors include underlying errors, decoding errors include body)
- Documentation: Add DocC doc comments to all public APIs; include usage examples
- Environment variable overrides: Support them for all configuration (see README table); useful for testing and CI
- Directory structure:
Documentation/- Project documentation (markdown files, analysis docs, man pages). Committed to git.docs/- Generated DocC output. Gitignored. Never put project docs here.
Current version: v0.3.1 - Unix socket priority, opt-in App Store discovery
Primary use case: Network Weather (NWX) macOS app for network diagnostics.
Recent releases:
- v0.3.1: Unix socket priority (avoids TCC popups), opt-in App Store discovery, chunked HTTP support
- v0.3.0: IPN bus streaming (
watchIPNBus()) for real-time state updates - v0.2.1: Network interface discovery (
StatusResponse.interfaceName,StatusResponse.interfaceInfo)
CLI commands available: status, whois, prefs, ping, health, metrics, watch
Roadmap (see ROADMAP.md):
- v0.4.0: DERP map, exit node suggestions, native STUN probing (netcheck equivalent)
- v0.5.0: DNS diagnostics
- v0.6.0: Configuration management
LocalAPI Coverage: See Documentation/LOCALAPI-COVERAGE.md for comprehensive analysis of all available endpoints, CLI-only features, and implementation strategies.
Sources/TailscaleClient/
TailscaleClient.swift # Main client actor and error types
Configuration/ # Endpoint discovery and configuration
TailscaleClientConfiguration.swift
LocalAPIDiscovery.swift
Transport/ # HTTP/socket communication layer
TailscaleTransport.swift
UnixSocketTransport.swift
Models/ # Codable response models
StatusResponse.swift
StatusQuery.swift
WhoIsResponse.swift
PrefsResponse.swift
PingResult.swift
IPNNotify.swift # IPN bus streaming models
Platform/ # Platform-specific helpers
MacClientInfo.swift # macOS loopback discovery (libproc)
NetworkInterfaceDiscovery.swift # TUN interface detection
Support/ # Utilities
DecodingSupport.swift # JSONDecoder extensions
TailscaleClient.docc/ # DocC documentation catalog
Sources/tailscale-swift/ # Development CLI tool
TailscaleSwift.swift # Main entry point
Status.swift, WhoIs.swift, Prefs.swift, Ping.swift, Health.swift, Metrics.swift
Tests/TailscaleClientTests/
*DecodingTests.swift # JSON decoding tests per model
StatusAPITests.swift # Transport and API tests with mocks
NewEndpointAPITests.swift # Tests for whois/prefs/ping/metrics
ErrorHandlingTests.swift # Error type and recovery tests
NetworkInterfaceDiscoveryTests.swift
TailscaleClientIntegrationTests.swift # Gated by TAILSCALE_INTEGRATION=1
TestSupport.swift # XCTest helpers (XCTAssertThrowsErrorAsync)
Fixtures/ # Sample JSON responses