platform

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2026 License: GPL-3.0 Imports: 15 Imported by: 0

Documentation

Overview

Package platform defines the extension boundary AgentRoute uses to wire up coding agent tools (Claude Code in v1; Codex, Gemini CLI, and others later via manifest-driven or in-tree adapters). See the architecture plan §6.

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrUnknownWire             = errors.New("manifest: unknown wire protocol")
	ErrUnsupportedConfigTarget = errors.New("manifest: unsupported config_target.type in this version of AgentRoute")
	ErrMissingWiring           = errors.New("manifest: config_target.type has no matching [wiring] block")
	ErrUnknownTemplateVar      = errors.New("manifest: unknown template variable")
)

Sentinel errors ParseManifest and Validate return, so callers (notably the registry, which must skip rather than fail hard on an as-yet-unsupported manifest) can distinguish "malformed manifest" from "well-formed manifest this version of AgentRoute can't wire up yet".

Functions

This section is empty.

Types

type Detection

type Detection struct {
	Installed  bool
	ConfigPath string
	Version    string
}

Detection reports what Detect found about whether a tool is installed and how it's configured.

type LinkInput

type LinkInput struct {
	// GatewayURL is the local gateway's base URL, e.g. "http://127.0.0.1:4505".
	GatewayURL string
	// AuthToken is the bearer credential the tool must send; the gateway
	// validates it against the same value.
	AuthToken string
	// RoleAliases maps tier ID (profile.TierHeavy etc.) to the AgentRoute
	// alias (profile.Alias(tier)) the tool should be configured to request
	// for that role.
	RoleAliases map[string]string
}

LinkInput carries everything Link needs to point a tool at AgentRoute's gateway.

type LinkResult

type LinkResult struct {
	ConfigPath string
	KeysSet    []string
}

LinkResult reports what Link actually changed.

type LinkStatus

type LinkStatus struct {
	Linked     bool
	GatewayURL string
	ConfigPath string
}

LinkStatus reports a platform's current wiring state.

type Logf

type Logf func(format string, args ...any)

Logf is the shape of a logging callback the registry uses to report manifests it skipped, mirroring orchestrator.Logf so callers can wire both into the same printer/TUI toast sink.

type Manifest

type Manifest struct {
	ID           string               `toml:"id"`
	DisplayName  string               `toml:"display_name"`
	Wire         string               `toml:"wire"`
	Detect       ManifestDetect       `toml:"detect"`
	ConfigTarget ManifestConfigTarget `toml:"config_target"`
	Roles        map[string]string    `toml:"roles"`
	Wiring       ManifestWiring       `toml:"wiring"`
}

Manifest is AgentRoute's declarative platform-adapter format (plan §6.3): most tools need no Go code, just a TOML file describing how to detect the tool and how to point it at the gateway.

func ParseManifest

func ParseManifest(data []byte) (Manifest, error)

ParseManifest decodes raw TOML into a Manifest and validates it. It does not touch the filesystem beyond what the caller already read.

func (Manifest) Validate

func (m Manifest) Validate() error

Validate checks that m is well-formed and that its config_target/wiring combination is one AgentRoute can actually interpret.

type ManifestAdapter

type ManifestAdapter struct {
	// contains filtered or unexported fields
}

ManifestAdapter implements Platform by interpreting a Manifest. Most tools need nothing beyond this — see registry.go for how manifests are discovered and turned into these.

func NewManifestAdapter

func NewManifestAdapter(m Manifest) *ManifestAdapter

NewManifestAdapter returns a Platform backed by m, using m's own config_target.path. Manifest must have already passed Validate (as ParseManifest guarantees) — NewManifestAdapter does not re-validate.

func (*ManifestAdapter) Detect

func (a *ManifestAdapter) Detect(_ context.Context) (Detection, error)

Detect implements Platform: Installed reports whether [detect].binary is on PATH (true if no binary is declared); ConfigPath is always returned.

func (*ManifestAdapter) DisplayName

func (a *ManifestAdapter) DisplayName() string

DisplayName implements Platform.

func (*ManifestAdapter) ID

func (a *ManifestAdapter) ID() string

ID implements Platform.

Link implements Platform.

For config_target.type=="toml", it merges the manifest's [wiring.toml] dotted keys (rendered against in) into the target TOML file, taking a backup on first link exactly like the claudecode adapter.

For config_target.type=="shell-env", it does NOT write any file: per manifests/examples/gemini-cli.toml.example's comment, the UX for shell_env wiring (env file vs. direct export vs. wrapper script) is an open design question deferred past v1. Link instead returns the rendered variables in LinkResult so a caller can show them to the user, with a nil error — guessing silently here would be worse than doing nothing.

func (*ManifestAdapter) Roles

func (a *ManifestAdapter) Roles() []Role

Roles implements Platform, deriving the role list from the manifest's [roles] table (sorted by ID for deterministic output).

func (*ManifestAdapter) Status

Status implements Platform. For toml wiring it reports linked if the target file currently contains the dotted keys this adapter would set (regardless of value, since the value is profile-specific). For shell-env wiring, since Link never writes anything, Status always reports not-linked — there is nothing on disk to check.

func (a *ManifestAdapter) Unlink(_ context.Context) error

Unlink implements Platform. For shell-env wiring (nothing was written by Link) it is a no-op. For toml wiring it restores the backup taken on Link, falling back to removing exactly the recorded dotted keys if the backup is missing — mirroring claudecode.Adapter.Unlink.

func (*ManifestAdapter) Wire

func (a *ManifestAdapter) Wire() gateway.Wire

Wire implements Platform.

type ManifestConfigTarget

type ManifestConfigTarget struct {
	Type string `toml:"type"`
	Path string `toml:"path"`
}

ManifestConfigTarget is a manifest's [config_target] table: which file (if any) Link/Unlink edit, and how.

v1 implements two of the three documented types — "toml" (a TOML file, edited via dotted-key wiring.toml entries) and "shell-env" (no file; Link reports the variables the tool needs without writing anything, see ManifestAdapter.Link). "json-env" (Claude Code's settings.json) is recognized but deliberately unsupported here: it needs backup/restore semantics the in-tree claudecode adapter already provides, and the generic interpreter doesn't yet replicate them (see manifests/claude-code.toml's comment). ParseManifest/Validate report ErrUnsupportedConfigTarget for it so the registry can skip it cleanly instead of failing to load every manifest in the directory.

type ManifestDetect

type ManifestDetect struct {
	Binary      string   `toml:"binary"`
	ConfigPaths []string `toml:"config_paths"`
}

ManifestDetect is a manifest's [detect] table: how to tell whether the described tool is installed.

type ManifestWiring

type ManifestWiring struct {
	ShellEnv map[string]string `toml:"shell_env"`
	TOML     map[string]string `toml:"toml"`
}

ManifestWiring is a manifest's [wiring.*] tables: the literal (template) values to write into the target config once rendered against a platform.LinkInput. Exactly one of these is populated, matching ConfigTarget.Type.

type Platform

type Platform interface {
	ID() string
	DisplayName() string
	// Wire identifies which gateway Translator must be running for this
	// platform's requests to be served.
	Wire() gateway.Wire
	Roles() []Role
	Detect(ctx context.Context) (Detection, error)
	Link(ctx context.Context, in LinkInput) (LinkResult, error)
	Unlink(ctx context.Context) error
	Status(ctx context.Context) (LinkStatus, error)
}

Platform adapts one coding agent tool to AgentRoute's gateway. Link and Unlink must be exact inverses: Unlink after Link must restore the tool's config to byte-identical its pre-Link state.

func LoadManifestAdapters

func LoadManifestAdapters(dir string, logf Logf) ([]Platform, error)

LoadManifestAdapters reads every "*.toml" file directly inside dir (manifests/ in production) and returns the ones whose config_target type AgentRoute currently knows how to wire up, as Platform adapters.

Files under a nested "examples/" directory, or any file ending in ".example", are reference material rather than adapters to load — the manifest authoring docs (plan §6.3) point at them as schema examples for tools not enabled in v1, and manifests/examples/*.toml.example exist purely to be read by a person, never by this loader. A manifest with a currently-unsupported config_target (json-env, in v1) is skipped with a log line rather than failing the whole load, since Claude Code's own manifests/claude-code.toml is exactly such a file: it documents the schema but is deliberately served by the in-tree claudecode adapter instead (see manifest.go's ManifestConfigTarget doc).

A manifest that fails to parse, or is well-formed but invalid in any other way, is reported as an error rather than silently skipped — those indicate either a typo in a manifest meant to be loaded, or a bug, and both deserve to be loud.

type Registry

type Registry struct {
	// contains filtered or unexported fields
}

Registry holds every Platform AgentRoute can wire a profile to: the in-tree adapters plus whatever manifests LoadManifestAdapters found.

func NewRegistry

func NewRegistry(manifestsDir string, logf Logf, inTree ...Platform) (*Registry, error)

NewRegistry builds a Registry from inTree (e.g. claudecode.New()) plus any manifest adapters loaded from manifestsDir. inTree adapters take precedence on ID collision — a manifest can never shadow an in-tree adapter, since the in-tree one is the one AgentRoute actually ships and tests.

func (*Registry) All

func (r *Registry) All() []Platform

All returns every registered platform, in registration order (deterministic: manifests in directory-listing order, then in-tree adapters in the order passed to NewRegistry).

func (*Registry) Get

func (r *Registry) Get(id string) (Platform, bool)

Get returns the platform registered under id, if any.

type Role

type Role struct {
	ID          string
	DisplayName string
}

Role is one generic tier ("heavy"/"balanced"/"fast", see internal/profile) that a platform exposes a native concept for. A platform may use a subset of AgentRoute's tiers.

Directories

Path Synopsis
Package claudecode is AgentRoute's v1 in-tree Platform adapter for Claude Code.
Package claudecode is AgentRoute's v1 in-tree Platform adapter for Claude Code.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL