Documentation
¶
Overview ¶
Package launch provides the launcher for AI coding agents under Aileron's daemon. Per ADR-0015, the launcher's job is to:
- Resolve the daemon and register a session.
- Route the agent's LLM traffic through the daemon's gateway (when the agent exposes an env-controllable base URL).
- Register aileron-mcp with the agent so Aileron's tools are callable as mcp__aileron__*.
The launcher does not replace $SHELL, install wrapper scripts, write policy files, or audit shell commands the agent runs locally. The audit boundary is "actions Aileron executes" (ADR-0010 audit store), not "every command the agent runs."
Index ¶
- Constants
- Variables
- func EnsureVault(path string, prompter PassphrasePrompter, w io.Writer, maxRetries int) (vault.Vault, error)
- func IsVaultRef(value string) bool
- func OpenLocalVault(vaultPath, passphrase string) (vault.Vault, error)
- func ParseLogLevel(s string) slog.Level
- func ResolveBinary(names []string) (string, error)
- func ResolveTokens(tokens []string, v vault.Vault) ([]string, error)
- func ResolveVaultRef(value string, v vault.Vault) (string, error)
- func SessionLogPath(dir string) string
- func ValidateTokenRef(field, value string) error
- type Agent
- type LaunchConfig
- type LaunchResult
- type PassphrasePrompter
- type Registry
Constants ¶
const LevelTrace = slog.Level(-8)
LevelTrace is a custom slog level below Debug, reserved for high-volume tracing output.
const MCPServerName = "aileron"
MCPServerName is the name Aileron registers itself under in agents' MCP-server configs. The agent surfaces Aileron's tools as `mcp__<MCPServerName>__<tool-name>`. Agent definitions reference this when they wire host-level allowlists (e.g. Claude Code's `--allowedTools mcp__aileron`) so the host CLI does not double-prompt for tools the daemon already gates (ADR-0009 / ADR-0010).
Variables ¶
var DefaultVaultPath = func() string { home, err := os.UserHomeDir() if err != nil { return filepath.Join(".aileron", "secrets.json") } return filepath.Join(home, ".aileron", "secrets.json") }
DefaultVaultPath returns the default vault file path (~/.aileron/secrets.json). Replaceable in tests.
var OpenVaultFunc = promptAndOpenVault
OpenVaultFunc is the function used to open the vault when vault references are found in token fields. Defaults to prompting for a passphrase on /dev/tty. Replaceable in tests.
Functions ¶
func EnsureVault ¶
func EnsureVault(path string, prompter PassphrasePrompter, w io.Writer, maxRetries int) (vault.Vault, error)
EnsureVault returns an unlocked vault.Vault for the local vault at path, prompting the user for a passphrase. On first launch (file missing), the user is prompted twice — passphrase and confirmation — before the vault is created. On subsequent launches the user is prompted once, with retry on wrong passphrase up to `maxRetries` times. A tampered vault never retries: the function returns immediately.
The KEK derived from the passphrase is held inside the returned vault for the lifetime of the process; nothing is logged or written to disk beyond what the existing FileVault already persists.
Per ADR-0011, this is the v1 entry point that `aileron launch` calls before any agent runs. The runtime will not accept chat completion requests until vault.Vault is unlocked (the gate is enforced inside the gateway server when constructed via [app.NewHandlerWithConfig]).
func IsVaultRef ¶
IsVaultRef returns true if the value is a vault reference (starts with "vault:").
func OpenLocalVault ¶
OpenLocalVault opens the local encrypted vault, deriving a KEK from the passphrase and the salt stored in the vault file. If the vault file doesn't exist yet, it is created with a fresh salt.
func ParseLogLevel ¶
ParseLogLevel converts a string level name to an slog.Level. Accepted values: "trace", "debug", "info", "warn", "error". Returns slog.LevelWarn for unrecognized input.
func ResolveBinary ¶
ResolveBinary searches PATH for the first matching binary name from the given candidates. Returns the absolute path or an error.
func ResolveTokens ¶
ResolveTokens resolves a slice of token values that may contain vault references. Returns the resolved values in the same order. If any token is a vault reference, the provided vault is used for lookups. If v is nil and vault references exist, an error is returned.
func ResolveVaultRef ¶
ResolveVaultRef resolves a value that may be a vault reference. If it starts with "vault:", the remainder is looked up in the vault. Otherwise the value is returned as-is.
func SessionLogPath ¶
SessionLogPath returns `<dir>/.aileron/session.log`. The session log captures the launched agent's stdio and is per-project. Distinct from the daemon's user-scoped audit store (ADR-0010), which records actions Aileron executes — not the agent's local stdio.
Exported so `aileron sessions watch <id>` can resolve the same path the launcher writes to.
func ValidateTokenRef ¶
ValidateTokenRef checks that a token value is either empty or a vault reference. Plaintext tokens are rejected to prevent secrets from being committed to version control alongside source.
Types ¶
type Agent ¶
type Agent interface {
// Name returns the agent identifier used in CLI args (e.g. "claude").
Name() string
// BinaryNames returns candidate binary names to search on PATH, in
// preference order. For example, ["claude"] or ["codex", "openai-codex"].
BinaryNames() []string
// Args returns CLI arguments the agent requires. These are prepended
// before any user-supplied arguments.
Args() []string
// Env returns additional environment variables to set for the agent
// process. Returns nil if no extra env is needed.
Env() map[string]string
// LLMEndpointEnv returns the name of the environment variable the
// agent's LLM client honours to override its default API endpoint
// (e.g. "ANTHROPIC_BASE_URL" for Claude Code, "OPENAI_BASE_URL" for
// Codex CLI). Returns "" when the agent does not support endpoint
// override via env (some agents resolve the endpoint from a settings
// file; gateway routing is not available for those agents under launch).
LLMEndpointEnv() string
// ConfigureMCP arranges for the agent to discover Aileron's MCP
// server. Agents that accept MCP wiring on the CLI (Claude Code's
// --mcp-config) return extra args; agents that read MCP server
// configuration from a config file (Codex's ~/.codex/config.toml,
// Goose's ~/.config/goose/config.yaml, OpenCode's opencode.json)
// write the file and return nil args.
//
// mcpBin is the absolute path to the aileron-mcp binary.
// mcpEnv is the environment the MCP server needs (AILERON_URL,
// AILERON_SESSION_ID, etc.) — agents that write the config file
// must persist these in the file's env block; agents that pass via
// CLI must serialize them into their flag value.
// dir is the launch working directory (project root for agents that
// write per-project config like OpenCode); empty means "use cwd".
ConfigureMCP(mcpBin string, mcpEnv map[string]string, dir string) ([]string, error)
}
Agent describes a launchable AI coding agent.
type LaunchConfig ¶
type LaunchConfig struct {
// Agent is the agent to launch.
Agent Agent
// Args are extra arguments to pass to the agent binary.
Args []string
// Dir is the working directory for the agent. If empty, the current
// directory is used.
Dir string
// LogLevel sets the session log verbosity (e.g. slog.LevelDebug).
LogLevel slog.Level
}
LaunchConfig holds the configuration for launching an agent.
type LaunchResult ¶
type LaunchResult struct {
ExitCode int
}
LaunchResult holds the outcome of a launched agent process.
func Launch ¶
func Launch(ctx context.Context, config LaunchConfig) (LaunchResult, error)
Launch starts the agent as a child process under Aileron's daemon.
Per ADR-0015 the launcher is the daemon-connection + MCP-registration + gateway-routing step. It does not replace $SHELL, install wrapper scripts, or audit shell commands the agent runs locally.
Per ADR-0012 launch is a thin client of the user-scoped local daemon. It resolves (and auto-spawns) the daemon URL, registers the session, asks the agent to wire up aileron-mcp (Claude/Pi pass `--mcp-config`; Codex/Goose/OpenCode write config files), points the agent's LLM-endpoint env at the daemon if applicable, then execs the agent.
type PassphrasePrompter ¶
PassphrasePrompter reads a passphrase from the user. The default implementation hides input on the controlling tty; tests inject a scripted prompter.