Reference
Complete reference for the Abbyfile framework: options, subcommands, flags, and types.
agent.Option Functions
All options are in pkg/agent/options.go.
WithName(name string) Option
Required. Sets the agent name. Used for the CLI binary name, memory directory (~/.abbyfile/<name>/), override path, and MCP server identity.
WithVersion(version string) Option
Required. Sets the semantic version. Surfaces via --version, --describe, and MCP handshake.
WithDescription(desc string) Option
Sets a short description. Shows in --describe JSON, MCP server metadata, and the Cobra help text.
WithPromptFS(fs embed.FS, path string) Option
Required. Sets the embedded filesystem and the path within it for the system prompt. This is set automatically by abby build — you do not need to call it directly.
WithTools(defs ...*tools.Definition) Option
Registers tool definitions. Variadic – accepts multiple definitions. Can be called multiple times; definitions accumulate.
agent.WithTools(
tools.CLI("date", "date", "Get the current date"),
myBuiltinTool(),
)
WithToolTimeout(d time.Duration) Option
Sets the timeout for tool execution. Default: 30 * time.Second. Applies to both CLI and builtin tools.
WithMemory(enabled bool) Option
Enables or disables persistent memory. Default: false. When enabled, creates a FileStore at ~/.abbyfile/<name>/memory/ and registers five memory tools (memory_read, memory_write, memory_list, memory_delete, memory_search).
WithMemoryLimits(limits memory.Limits) Option
Sets capacity limits for the memory store. Only meaningful when memory is enabled.
WithModel(model string) Option
Sets the agent’s model hint. This is informational metadata — the runtime (Claude Code, etc.) picks its own model. The value is surfaced in --describe JSON and as a “Model Preference” hint in MCP server instructions.
WithLazyToolLoading(enabled bool) Option
Deprecated (v0.10.0), no effect. Lazy loading via a search_tools meta-tool was removed: it advertised tools it never registered, and MCP 2026-07-28 requires a fixed tools/list. Clients such as Claude Code already defer MCP tool definitions through their own tool search. Passing true logs a warning. The option will be removed in a future release.
WithConfigPath(path string) Option
Overrides the default config.yaml location (~/.abbyfile/<name>/config.yaml). Primarily useful for testing.
WithLogger(logger *slog.Logger) Option
Sets the structured logger. Default: slog.NewTextHandler(os.Stderr, nil). Logs go to stderr so they do not interfere with MCP protocol on stdout.
WithSandbox(cfg sandbox.Config) Option
WithSandbox sets the compiled-in sandbox for built-in tools. Without it the agent uses sandbox.Default(): file tools confined to the working directory and run_command refusing every call.
CLI Subcommands and Flags
Root Command
Usage:
<agent-name> [flags]
<agent-name> [command]
Flags:
--version Print version and exit
--describe Print agent manifest as JSON and exit
--custom-instructions Print the system prompt and exit
-h, --help Help for the agent
run-tool <name>
Execute a registered tool by name.
Usage:
<agent-name> run-tool <name> [flags]
Flags:
--input string Tool input as JSON object
Examples:
./my-agent run-tool date
./my-agent run-tool read_file --input '{"path": "go.mod"}'
./my-agent run-tool go_test --input '{"package": "./pkg/tools/..."}'
memory
Manage persistent memory. Only available when memory is enabled.
Usage:
<agent-name> memory [command]
Commands:
read <key> Read a value from memory
write <key> <value> Write a value to memory (overwrites existing)
append <key> <value> Append content to an existing memory key
list List all memory keys
delete <key> Delete a key from memory
gc Remove expired memory keys
config
Inspect and modify runtime configuration overrides stored at ~/.abbyfile/<name>/config.yaml.
Usage:
<agent-name> config [command]
Commands:
get [field] Show configuration (compiled defaults + overrides)
set <field> <value> Set a config override
reset <field> Remove an override, reverting to compiled default
path Print the config file path
Examples:
./my-agent config get # show all fields with source
./my-agent config get model # show just model
./my-agent config set model opus # set override
./my-agent config set tool_timeout 120s # set timeout override
./my-agent config reset model # revert to compiled default
./my-agent config path # ~/.abbyfile/my-agent/config.yaml
Output format for get:
model: opus (override)
tool_timeout: 30s (compiled)
Supported fields for set: model, tool_timeout, context_budget.max_output_lines, context_budget.max_output_bytes, context_budget.on_overflow, context_budget.head_lines, context_budget.tail_lines, context_budget.summary_lines, context_budget.eager_instructions, sandbox.allowed_dirs, sandbox.bash, sandbox.allow_commands, sandbox.max_command_timeout. Complex fields (memory_limits, command_policy) can be set by editing the YAML directly.
reset supports model and tool_timeout individually, the complex fields memory_limits and command_policy (each cleared as a whole), and the whole-block names context_budget and sandbox, which clear every override in that block at once (e.g. config reset sandbox reverts all four sandbox.* fields to their compiled defaults). There is no per-field reset for an individual context_budget.* or sandbox.* key — reset the whole block instead.
Setting any sandbox.* field validates the merged sandbox as a whole, not just the field being set, and refuses to write an override that would be invalid. set prints a restart hint for every sandbox.* field (a running MCP session already loaded the old sandbox), plus a stderr warning for sandbox.bash unrestricted or a sandbox.allowed_dirs containing /.
When reset removes the last field, the config file is deleted.
serve-mcp
Start an MCP-over-stdio server.
Usage:
<agent-name> serve-mcp
No flags. The server runs until the stdin stream closes or the process is killed. Logs go to stderr.
validate
Check that the agent is configured correctly.
Usage:
<agent-name> validate
Checks performed:
- Prompt: loads the system prompt (embedded or override)
- Tools: for CLI tools, verifies the command exists in PATH; for builtin tools, verifies the handler is non-nil
- Memory: if enabled, verifies the memory directory is writable
- Override: reports whether an override file is active
- Version: verifies the version string is set
Output format:
[PASS] Prompt: loaded (245 bytes)
[PASS] Tool "date": command "date" found at /bin/date
[PASS] Tool "read_file": builtin handler registered
[PASS] Memory: directory /Users/you/.abbyfile/my-agent/memory is writable
[INFO] Override: not active (using embedded prompt)
[PASS] Version: 0.1.0
----------------------------------------
Validation PASSED
--describe JSON Schema
{
"name": "string",
"version": "string",
"description": "string",
"model": "string",
"toolTimeout": "30s",
"tools": [
{
"name": "string",
"description": "string",
"builtin": false,
"inputSchema": { },
"annotations": {
"ReadOnlyHint": false,
"DestructiveHint": null,
"IdempotentHint": false,
"OpenWorldHint": null,
"Title": ""
}
}
],
"memory": true,
"memoryLimits": {
"maxKeys": 0,
"maxValueBytes": 0,
"maxTotalBytes": 0
},
"sandbox": {
"allowedDirs": ["/"],
"bash": "restricted",
"allowCommands": ["echo *"],
"maxCommandTimeout": "2m0s",
"warnings": ["sandbox.allowed_dirs entry \"/\" resolves to / — file tools can reach the whole filesystem"]
}
}
Notes:
modelis only present if set (compiled default or config override)toolTimeoutis only present if non-defaulttoolsincludes both user-registered tools and memory tools (if enabled)memoryLimitsis only present when memory is enabled and limits are setannotationsis only present when set on the tool definitionbuiltinistruefor builtin tools and memory tools,falsefor CLI toolssandboxreflects the effective, resolved sandbox (compiled defaults plus anyconfig.yamloverride) —allowedDirsis the resolved absolute path(s), not the raw frontmatter value (soallowed_dirs: ["."]renders as the working directory’s absolute path), andmaxCommandTimeoutis a Gotime.Durationstring (e.g."2m0s"for the 120s default, not"120s");warningsisomitemptyand only appears when there is at least one (e.g.allowed_dirsincluding/, orbash: unrestricted)
tools.CLI
func CLI(name, command, description string) *Definition
Creates a Definition for a CLI tool that runs command as a subprocess.
Generated input schema:
{
"type": "object",
"properties": {
"args": {
"type": "string",
"description": "Command-line arguments to pass to the tool"
}
}
}
The returned Definition can be further configured:
def.Args = []string{...}– set default argumentsdef.WithAnnotations(&tools.Annotations{...})– set MCP hints
tools.BuiltinTool
func BuiltinTool(name, description string, schema any, handler func(input map[string]any) (string, error)) *Definition
Creates a Definition for a builtin tool that runs the handler function in-process.
Parameters:
name– unique tool namedescription– shown to the LLM for tool selectionschema– JSON Schema asmap[string]any(ornilfor no input)handler– function that receives parsed JSON input and returns a string result
tools.BuiltinToolCtx
func BuiltinToolCtx(name, description string, schema any, handler func(ctx context.Context, input map[string]any) (string, error)) *Definition
Creates a Definition for a builtin tool with a context-aware handler. The executor passes the sandbox, the effective timeout, and cancellation through ctx (see sandbox.FromContext). It also sets Handler to a wrapper that calls handler with context.Background(), so callers that invoke Handler directly keep working, under the default sandbox and with no deadline.
All shipped builtins (read_file, write_file, edit_file, glob_files, grep_search, run_command) are registered with BuiltinToolCtx.
tools.Definition
type Definition struct {
Name string
Description string
InputSchema any
Annotations *Annotations
Builtin bool
Command string // CLI tools only
Args []string // CLI tools only, default arguments
Handler func(input map[string]any) (string, error) // builtin tools only
HandlerCtx func(ctx context.Context, input map[string]any) (string, error) // builtin tools only; the executor prefers this over Handler
UsesCommandTimeout bool // run_command only: the handler enforces sandbox.max_command_timeout itself, so the executor's outer limit becomes max(executor timeout, max_command_timeout)
}
Methods:
def.WithAnnotations(a *Annotations) *Definition
Sets MCP annotation hints. Returns the definition for chaining.
def.ValidateInput(input map[string]any) error
Validates input against the InputSchema. Checks required fields and property types. Returns nil if valid or if schema is nil.
tools.Annotations
type Annotations struct {
ReadOnlyHint bool // tool does not modify state
DestructiveHint *bool // nil = MCP default (true)
IdempotentHint bool // safe to call multiple times
OpenWorldHint *bool // nil = MCP default (true)
Title string // human-readable name
}
Use tools.BoolPtr(b bool) *bool to set pointer fields:
DestructiveHint: tools.BoolPtr(false),
OpenWorldHint: tools.BoolPtr(false),
tools.Executor
func NewExecutor(timeout time.Duration, logger *slog.Logger) *Executor
Creates an executor with the given timeout and logger. Zero timeout defaults to 30 seconds. Nil logger disables logging.
func (e *Executor) Run(ctx context.Context, def *Definition, input map[string]any) (string, error)
Runs a tool. For CLI tools, executes the command as a subprocess. For builtin tools, calls the handler. Returns trimmed stdout (or stderr if stdout is empty) for CLI tools.
tools.Registry
func NewRegistry() *Registry
func (r *Registry) Register(def *Definition) error // add a tool (error if name empty or duplicate)
func (r *Registry) Get(name string) *Definition // get by name (nil if not found)
func (r *Registry) All() []*Definition // all registered tools
memory.Limits
type Limits struct {
MaxKeys int `json:"maxKeys,omitempty"` // max number of keys (0 = unlimited)
MaxValueBytes int64 `json:"maxValueBytes,omitempty"` // max bytes per value (0 = unlimited)
MaxTotalBytes int64 `json:"maxTotalBytes,omitempty"` // max total bytes (0 = unlimited)
}
Zero values mean unlimited. Pass the zero value memory.Limits{} for no limits.
memory.FileStore
func NewFileStore(agentName string, limits Limits) (*FileStore, error)
Creates a file store at ~/.abbyfile/<agentName>/memory/. Creates the directory if it does not exist.
func NewFileStoreAt(dir string, limits Limits) (*FileStore, error)
Creates a file store at a specific directory. Used for testing.
func (s *FileStore) Read(key string) (string, error)
func (s *FileStore) Write(key, content string) error
func (s *FileStore) Append(key, content string) error
func (s *FileStore) Delete(key string) error
func (s *FileStore) Keys() ([]string, error)
Keys must not be empty or contain path separators. Each key is stored as <dir>/<key>.md.
memory.Manager
func NewManager(store *FileStore) *Manager
Wraps a FileStore with a sync.RWMutex for concurrent access.
func (m *Manager) Get(key string) (string, error)
func (m *Manager) Set(key, value string) error
func (m *Manager) Append(key, value string) error
func (m *Manager) Delete(key string) error
func (m *Manager) Keys() ([]string, error)
func (m *Manager) Tools() []*tools.Definition
func (m *Manager) FormatKeysAsContext() string
Tools() returns five builtin tool definitions: memory_read, memory_write, memory_list, memory_delete, memory_search.
FormatKeysAsContext() returns a string like "Available memory keys: notes, config" or empty string if no keys.
prompt.Loader
func NewLoader(agentName string, fs embed.FS, path string) *Loader
Created automatically by generated binaries. The embed.FS is populated by abby build.
func (l *Loader) Load() (string, error) // load prompt (override or embedded)
func (l *Loader) IsOverridden() bool // true if override file exists
func (l *Loader) OverridePath() string // ~/.abbyfile/<name>/override.md
mcp.Bridge
func NewBridge(cfg BridgeConfig) *Bridge
type BridgeConfig struct {
Name string
Version string
Description string
Model string // model hint, appended to instructions
Registry *tools.Registry
Executor *tools.Executor
Loader *prompt.Loader
Memory *memory.Manager // nil if memory disabled
Logger *slog.Logger // nil disables logging
LazyToolLoading bool // Deprecated: ignored (logs a warning)
EagerInstructions bool // true: full prompt in handshake, no get_instructions tool
}
func (b *Bridge) Serve(ctx context.Context) error // stdio transport
func (b *Bridge) ServeTransport(ctx context.Context, transport gomcp.Transport) error // any transport
abby build
Usage:
abby build [flags]
Flags:
--agent string Build a single agent by name
--config-method string auto (default; env ABBY_CONFIG_METHOD), cli, or file
--dry-run Show planned changes without building or writing anything
-f, --file string Path to Abbyfile
-h, --help help for build
--module-dir string Use local module path instead of published version (dev/CI only)
-o, --output string Output directory for binaries (default "./build")
--parallelism int Max concurrent agent builds (0 = sequential)
--plugin Also generate a Claude Code plugin directory
--runtime string Target runtime: auto, all, claude-code, codex, gemini (default "auto")
--subagent Also emit a Claude Code sub-agent (.claude/agents/<name>.md)
Parses the Abbyfile, generates Go source from each agent’s .md file, and compiles standalone binaries. Also generates/updates MCP config for the target runtime(s).
The --runtime flag controls which runtimes receive MCP config:
auto(default) — detects a runtime whose CLI is onPATHor whose config directory exists (never by checking whether$HOMEexists), falls back to Claude Codeall— generates config for all supported runtimes (Claude Code, Codex, Gemini CLI)claude-code/codex/gemini— targets a specific runtime
| Runtime | Local Config | Global Config |
|---|---|---|
| Claude Code | .mcp.json |
$CLAUDE_CONFIG_DIR/.claude.json if set, else ~/.claude.json |
| Codex | .codex/config.toml |
$CODEX_HOME/config.toml if set, else ~/.codex/config.toml |
| Gemini CLI | .gemini/settings.json |
~/.gemini/settings.json |
(~/.claude/mcp.json, written by abby ≤ v0.11, is legacy — Claude Code never read it; see Migrating from v0.11.)
When --plugin is passed, each agent also gets a <name>.claude-plugin/ directory in the output folder containing the binary, an MCP config, and any declared skills. See Plugins guide.
--subagent (or --plugin) also writes <output>/.claude/agents/<name>.md, whose tools: line grants the agent’s own MCP tools as mcp__<name>__<tool> alongside its native tools (see Context Budget guide → --subagent). An agent marked binary: false in the Abbyfile always gets this file and nothing else: no compile, no MCP config entry (see Agents without a binary). Every emitted file ends with a provenance marker line, <!-- abbyfile: <name> v<version> -->, which abby install and abby doctor read.
abby install
Usage:
abby install [flags] <ref>...
Flags:
--all Install all agents from a repo (remote) or ./build/ (local)
--config-method string auto (default; env ABBY_CONFIG_METHOD), cli, or file
--dry-run Show planned changes without installing anything
--env stringArray Set an environment variable for the MCP server (KEY=VALUE, repeatable)
--force Replace an existing .claude/agents/<name>.md that abby did not install or that was edited since
-g, --global Install globally to /usr/local/bin
-h, --help help for install
--insecure-skip-checksum Skip release checksum verification (use with care)
--model string Override the agent's model in ~/.abbyfile/<name>/config.yaml
--runtime string Target runtime: auto, all, claude-code, codex, gemini (default "auto")
Installs agent binaries and wires them into the MCP config for detected (or specified) runtimes.
Local install (from ./build/):
abby install my-agent
abby install -g my-agent
Remote install (from GitHub Releases):
abby install github.com/owner/repo/agent
abby install github.com/owner/repo/[email protected]
Bulk install (multiple agents at once):
abby install --all github.com/owner/repo # all agents from a repo
abby install --all # all agents from ./build/
abby install github.com/o/r/a1 github.com/o/r/a2 # specific agents
abby install github.com/org1/r1/a1 github.com/org2/r2/a2 # cross-repo
Remote --all discovers agents by scanning release tags (<agent>/v<version> format) and installs the latest version of each. Multiple positional arguments can reference agents from different repos.
Bulk installs use best-effort error handling: failures are reported but don’t stop remaining installs. A summary is printed at the end.
The --model flag cannot be combined with --all or multiple agents (it is agent-specific).
Remote install downloads the binary for the current platform (<agent>-<GOOS>-<GOARCH>), verifies its checksum against the release’s <agent>-sha256sums.txt/SHA256SUMS/checksums.txt asset (fails without one, unless --insecure-skip-checksum), verifies it’s a valid agent with --describe, installs it, wires MCP, and tracks it in the registry. Set GITHUB_TOKEN for private repos.
Both local and remote installs are tracked in ~/.abbyfile/registry.json.
Installing sub-agent files
A local install also installs the agent’s sub-agent file when abby build emitted one (build/.claude/agents/<name>.md, from --subagent or binary: false). It goes where Claude Code discovers sub-agents: <project>/.claude/agents/<name>.md, or ~/.claude/agents/<name>.md with --global. A binary: false agent installs only this file: no binary and no MCP config entry. --all picks these agents up alongside the binaries.
- Overwrite protection. If the destination already exists, install replaces it only when it is identical, or is the file abby installed earlier and nobody has edited since (checked against the digest kept in the registry). Anything else, such as a hand-maintained agent file, is refused with an error naming
--force, and nothing is installed. The check runs before the binary is copied. - Version check. For a compiled agent, a built file whose marker version differs from the binary’s version is stale, so it is skipped with a note; rebuild with
--subagentto refresh it. - Source check. A built file without a matching provenance marker is refused; rebuild it with
abby build.
Remote installs don’t install sub-agent files, since releases don’t carry them.
Limitations, because the registry holds one entry per agent name across all projects: installing the same agent in a second project moves its tracking there, so reinstalling in the first project refuses that project’s untouched file until you pass --force. A remote install over a local entry replaces it and drops the file’s tracking; the file stays on disk, untracked.
--dry-run copies no binary, writes no MCP config, and changes no registry entry (a remote install still downloads and checksum-verifies into a temp file, so the printed preview reflects a binary abby actually checked). --env KEY=VALUE (repeatable) sets the MCP server’s env; without it, an existing entry’s env is preserved. See the Distribution Guide for the full method-selection rule, entry fields, and checksum behavior.
abby publish
Usage:
abby publish [flags]
Flags:
--agent string Publish a single agent by name
--dry-run Cross-compile only, skip GitHub Release creation
-f, --file string Path to Abbyfile
-h, --help help for publish
--module-dir string Use local module path instead of published version (dev/CI only)
Cross-compiles agent binaries for 4 platforms (darwin/amd64, darwin/arm64, linux/amd64, linux/arm64) and creates a GitHub Release via the gh CLI.
Release tag format: <agent>/v<version>. Binary asset naming: <agent>-<os>-<arch>.
Requires the gh CLI to be installed and authenticated.
abby list
Usage:
abby list [flags]
Flags:
-h, --help help for list
--json Output as JSON
Shows all installed agents from the registry (~/.abbyfile/registry.json). Displays name, version, source, scope, and path in a table.
abby update
Usage:
abby update [agent-name]
Checks GitHub Releases for newer versions of installed agents and downloads updates. Only agents installed from a remote source can be updated.
If no agent name is given, checks all remote-installed agents. If any agent fails to update (including a release without a checksum asset), the others still run and the command exits non-zero.
abby uninstall
Usage:
abby uninstall <agent-name> [flags]
Flags:
--config-method string auto (default; env ABBY_CONFIG_METHOD), cli, or file
--dry-run Show planned changes without removing anything
-h, --help help for uninstall
--runtime string Target runtime: auto, all, claude-code, codex, gemini (default "auto")
Removes an installed agent: deletes the binary, removes the MCP entry from all detected (or specified) runtime configs, deletes its installed sub-agent file, and removes the entry from the registry. A sub-agent file edited since install is left in place, with a note. A binary: false agent has only the file to remove. Every runtime’s removal is planned before anything is deleted: a planning failure (e.g. an unparsable config file) leaves the binary, the configs and the registry entry untouched and exits non-zero. Once planned, every removal is attempted regardless of an earlier one’s apply failure; if any fails, the registry entry is kept (so uninstall can be re-run) and the command exits non-zero.
abby doctor
Usage:
abby doctor [agent]... [flags]
Flags:
--config-method string Accepted for symmetry; doctor only reads config
-h, --help help for doctor
--runtime string Runtimes to check: auto, all, claude-code, codex, gemini (default "auto")
Diagnoses one or more installed agents (all of them, if none are named) against their registry entries: the binary’s presence and executable bit; --describe and the MCP handshake (both the 2026-07-28 server/discover and legacy 2025-11-25 initialize protocol eras), run in the agent’s own project root; each targeted runtime’s config entry (existence, binary path, and whether its timeout is stale versus the current binary, including a Codex entry with no tool_timeout_sec, which gets Codex’s 60s default); a reminder for Codex project-scope entries about project trust; any entries left in the legacy ~/.claude/mcp.json (written by abby ≤ v0.11, never read by Claude Code); and, for an agent whose sub-agent file was installed, whether that file is missing (a failure), edited since install, or at a different version from the agent (both warnings). A binary: false agent gets only the sub-agent file checks. doctor never writes, backs up, or modifies any config file. It exits non-zero if any check failed. See the Distribution Guide for sample output.
ABBY_CONFIG_METHOD
Environment variable read by abby build, abby install, abby uninstall and abby doctor when their --config-method flag isn’t given, and by abby update, which has no --config-method flag of its own — ABBY_CONFIG_METHOD is its only way to change the method. One of auto (default — CLI when it can express the entry, else a file edit), cli (require the CLI; error if a change can’t use it), or file (always edit the config file directly). See Where abby registers agents for the full method-selection rule.
registry.Entry
type Entry struct {
Name string `json:"name"`
Source string `json:"source"` // "local" or "github.com/owner/repo/agent"
Version string `json:"version"`
Path string `json:"path"` // absolute path to installed binary; "" for a binary: false agent
Scope string `json:"scope"` // "local" or "global"
InstalledAt string `json:"installedAt"` // RFC3339 timestamp
AgentFile string `json:"agentFile,omitempty"` // installed .claude/agents/<name>.md
AgentFileSHA256 string `json:"agentFileSha256,omitempty"` // its digest when abby wrote it
}
registry.Registry
func DefaultPath() (string, error) // ~/.abbyfile/registry.json
func Load(path string) (*Registry, error) // load from disk (empty if not exists)
func (r *Registry) Save() error // atomic save (write temp + rename)
func (r *Registry) Set(e Entry) // add or update entry
func (r *Registry) Get(name string) (Entry, bool)
func (r *Registry) Remove(name string)
func (r *Registry) List() []Entry
github.ReleaseRef
type ReleaseRef struct {
Owner string // repository owner
Repo string // repository name
Agent string // agent name (defaults to repo name)
Version string // specific version or "" for latest
}
github.Client
func NewClient() *Client // reads GITHUB_TOKEN from env
func ParseRef(ref string) (ReleaseRef, error)
func IsRemoteRef(ref string) bool
func ResolveAssetName(agentName string) string // <name>-<GOOS>-<GOARCH>
func FindAsset(release *Release, agentName string) (*Asset, error)
func VersionFromTag(tag string) string
func CompareVersions(a, b string) (int, error) // -1, 0, or 1
func (c *Client) LatestRelease(ctx context.Context, ref ReleaseRef) (*Release, error)
func (c *Client) GetRelease(ctx context.Context, ref ReleaseRef) (*Release, error)
func (c *Client) DownloadAsset(ctx context.Context, asset Asset, w io.Writer) error
builder.BuildConfig
type BuildConfig struct {
OutputDir string // directory for compiled binaries
ModuleDir string // local abbyfile module path (for replace directive)
TargetOS string // GOOS for cross-compilation (empty = native)
TargetArch string // GOARCH for cross-compilation (empty = native)
}
When TargetOS and TargetArch are set, the binary name becomes <agent>-<os>-<arch> and CGO_ENABLED=0 is set for static cross-compilation.
definition.SkillDef
type SkillDef struct {
Name string `yaml:"name"`
Description string `yaml:"description"`
Path string `yaml:"path"` // relative to agent .md file
}
Declared in block 2 of agent .md files under skills:. Used by --plugin to generate skill files in the plugin directory. All three fields are required.
plugin.GenerateConfig
type GenerateConfig struct {
OutputDir string // parent directory (e.g., "build")
BinaryPath string // path to the compiled binary
}
plugin.SkillFile
type SkillFile struct {
Name string
Description string
Content string // markdown body
}
plugin.Generate
func Generate(def *definition.AgentDef, skills []SkillFile, cfg GenerateConfig) error
Creates a <outputDir>/<name>.claude-plugin/ directory containing:
.claude-plugin/plugin.json— name, version, description,"abbyfile": true.mcp.json— onemcpServers.<name>entry withcommand: "./<name>"andargs: ["serve-mcp"](notypeortimeout; the plugin runs the bundled binary)<name>— copy of the compiled binary (executable)skills/<skill-name>/SKILL.md— for each skill, with frontmatter (name, description) + content