Documentation
¶
Overview ¶
Package generic implements a data-driven "breadth-tier" adapter: one Go implementation that supports many agents from a table of Specs, rather than a hand-written package per agent. It is for the long tail of agents whose agentsync surface is a rules/memory file plus (optionally) an `mcpServers` JSON and/or an Agent-Skills (SKILL.md) directory — the same shapes the deep adapters (Windsurf/Cline/Continue/Codex) already take.
The DEEP adapters (claude, codex, cursor, gemini, opencode, continuedev, windsurf, roo, cline) are NOT generic — they have richer, agent-specific component support (subagents, commands, hooks, …) and bidirectional nuances that don't fit a table. The generic tier deliberately covers memory, MCP, and Agent Skills (the open SKILL.md spec, where the agent natively scans a skills directory), and reports every other component as a skip, so its coverage is never overstated. Skills fit the table because their on-disk format is uniform across agents — only the scanned directory varies, with no dialect to model. Breadth-tier agents still flow through agentsync's normal apply/import pipeline, so they inherit drift detection, secret resolution, and capture — which a one-way "rules dump" (ruler/rulesync) does not provide.
Each agent is one verified Spec (see specs.go); adding an agent is a data entry, not a package. Every path in a Spec MUST be verified against the agent's upstream docs (and corroborated by prior-art tools) before being added — the count stays honest because each row reflects the agent's real coverage.
Index ¶
- type Adapter
- func (a *Adapter) Apply(ops []adapter.FileOp, w adapter.DestWriter) error
- func (a *Adapter) Capabilities() adapter.Capability
- func (a *Adapter) Detect() (bool, error)
- func (a *Adapter) Ingest(scope adapter.Scope, project string) (source.Canonical, error)
- func (a *Adapter) KeyMergeStrategy() string
- func (a *Adapter) Name() string
- func (a *Adapter) Render(r secrets.Resolved, scope adapter.Scope, project string) ([]adapter.FileOp, []adapter.Skip, error)
- type FileTarget
- type MCPTarget
- type Options
- type Spec
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Adapter ¶
type Adapter struct {
// contains filtered or unexported fields
}
Adapter implements adapter.Adapter for one Spec.
func (*Adapter) Apply ¶
Apply routes every destination write through the supplied DestWriter rather than calling iox.AtomicWrite directly. The DestWriter owns the foreign-collision backup invariant — see the doc on adapter.DestWriter.
func (*Adapter) Capabilities ¶
func (a *Adapter) Capabilities() adapter.Capability
func (*Adapter) Ingest ¶
Ingest reads this breadth-tier agent's memory, MCP, and skills back into a partial canonical. Inverse of Render (memory + MCP + skills; the components the tier never projects are simply not read).
func (*Adapter) KeyMergeStrategy ¶
KeyMergeStrategy is merge-jsonc-keys when the spec has an MCP file (the only key-merge surface); otherwise "" (memory is a whole-file write). The breadth tier always uses the JSONC-tolerant merge so a commented settings file (Zed, Copilot's .vscode/mcp.json, Amp) is parsed rather than clobbered — hujson reads plain JSON identically, so dedicated *.json MCP files are unaffected.
func (*Adapter) Render ¶
func (a *Adapter) Render(r secrets.Resolved, scope adapter.Scope, project string) ([]adapter.FileOp, []adapter.Skip, error)
Render projects the canonical model into this breadth-tier agent's memory (rules) file, its mcpServers JSON, and its Agent-Skills directory — each when the spec declares a target for it. Every other component (subagents, commands, hooks, LSP), and skills/MCP for a spec that declares no target, is reported as a skip: the generic tier deliberately covers memory + MCP + skills only. A component the spec does not support at the requested scope (e.g. user-scope memory for a project-only agent) is likewise reported as a skip rather than written somewhere wrong.
type FileTarget ¶
type FileTarget struct {
User string // file path or directory root under the user home (targetRoot)
Project string // file path or directory root under the project root
}
FileTarget is a per-scope path (relative to the scope root) for a file component (Memory: a single markdown file) or a directory component (Skills: the Agent-Skills root directory under which each skill is a <name>/SKILL.md subtree). An empty path means the component is unsupported at that scope.
type MCPTarget ¶
type MCPTarget struct {
User string
Project string
RootKey string
TransportKey string
StdioValue string
RemoteValue string
RemoteURLKey string
SSEURLKey string
}
MCPTarget describes an agent's MCP servers JSON file and its on-disk dialect. The breadth tier only handles JSON `<rootKey>` server-map files; agents whose MCP is TOML, app-storage, or otherwise unmodeled simply leave User/Project empty (MCP unsupported) and are reported as a skip.
The dialect knobs capture the variance the prior-art research surfaced across the tail (all with Claude-compatible defaults):
- RootKey: the top-level object key. Default "mcpServers"; e.g. "servers" (VS Code Copilot), "mcp" (Crush).
- TransportKey: the per-server field naming the transport. "" = inferred from command-vs-url (no field). Else e.g. "type" or "transport".
- StdioValue / RemoteValue: the TransportKey values for stdio vs remote (defaults "stdio"/"http"; Copilot CLI uses "local" for stdio). Ignored when TransportKey == "".
- RemoteURLKey: the per-server field holding a remote server's URL. Default "url"; some agents use "httpUrl" (Qwen) or "serverUrl" (Antigravity).
- SSEURLKey: for Gemini-lineage agents that split remote transports across TWO url fields (Qwen: `httpUrl` = streamable HTTP, `url` = SSE), the field holding an SSE server's URL. "" = no split (SSE shares RemoteURLKey). When set, ingest reads both fields (RemoteURLKey wins when both are present, mirroring the upstream precedence) and render routes a canonical `sse` server to this key.
type Spec ¶
type Spec struct {
Name string // agent name (Adapter.Name())
DetectBin string // binary on PATH (best-effort); "" to skip
DetectDir string // dir under targetRoot whose existence implies installed; "" to skip
Memory FileTarget // rules/instructions FILE path (plain markdown)
MCP MCPTarget // mcpServers JSON
Skills FileTarget // Agent-Skills DIRECTORY root (holds <name>/SKILL.md subtrees); empty = unsupported
}
Spec is the verified, data-driven description of one breadth-tier agent.
func Specs ¶
func Specs() []Spec
Specs returns the verified breadth-tier agent table. Each entry's paths were cross-referenced against the agent's upstream docs AND prior-art config-sync tools (ruler, rulesync) before inclusion — see docs/capability-matrix.md (§ "Breadth tier") for the per-agent basis and the deliberate exclusions.
Rules of the table:
- MEMORY is the universal axis: every entry projects the canonical memory to the agent's verified rules/instructions file (the AGENTS.md standard where the agent reads it, else its agent-specific file). Plain markdown body.
- MCP is enabled ONLY where the agent reads a JSON server-map file whose dialect the engine can express faithfully (root key + transport field + url key). Agents whose MCP is an array, YAML, TOML, app-storage, or otherwise unmodeled leave MCP empty — the engine reports it as a skip rather than write a shape the agent can't read.
- SKILLS is enabled where the agent natively scans Agent-Skills (SKILL.md) directories (the open agentskills.io spec). The on-disk skill format is uniform across agents, so there is no dialect to model — only the scanned directory varies. Most agents read the cross-vendor `.agents/skills` convention (shared with Codex, so the render pipeline dedupes the byte-identical ops); a few scan only their own `.<agent>/skills`. Agents that don't natively scan a SKILL.md directory — Jules/Firebase (publish skills FOR other agents), Amazon Q (skills only via an MCP server, a different component), OpenHands (programmatic load, no auto-scanned dir) — leave Skills empty and report it as a skip.
- A scope with no verified target is left empty (reported as a skip), never guessed. Low-confidence user-scope paths from the research are omitted.
Deep, agent-specific adapters (claude, codex, cursor, gemini, opencode, continuedev, windsurf, roo, cline) are NOT here — they live in their own packages with richer component support.