coddy-agent: Instructions file for Claude Code

AGENTS.md

coddy-agent AGENTS.md is an instructions file for Claude Code, Codex, OpenCode from coddy-project/coddy-agent. It costs 19,699 tokens per session, scanned B, original, MIT.

A set of repository instructions for Coddy, a coding assistant with a command-line interface, remote mode, tools, plugins, and background tasks. It maps the codebase’s main areas and their responsibilities.

In plain words
What is it for?
Use it when changing Coddy’s CLI, agent orchestration, tool connections, remote server support, MCP integration, session handling, or detached shell commands.
Why use it?
It helps an agent find the right code and follow project rules for builds, pre-commit checks, documentation, remote control, and background commands.

Instructions file for Claude CodeCodexOpenCode

Written for Claude Code and Codex and OpenCode: PreToolUse hook event, but also the file is AGENTS.md. Also seen: reads .claude/ paths; mentions CLAUDE.md; mentions subagents.

This is coddy-project/coddy-agent's own configuration. It tells Claude Code, Codex and OpenCode how to work on coddy-agent itself, so it is not a mod to install elsewhere. Copy it as a starting point and replace the rules that are about this project. Everything coddy-agent configures →

Reuse

Borrowing it

Nothing to install: this file belongs to coddy-project/coddy-agent. Take a copy, put it at the same path in your own repository, and replace the rules that are about this project with yours.

Copy the file
curl -O https://raw.githubusercontent.com/coddy-project/coddy-agent/main/AGENTS.md
Clone the repo
git clone --depth 1 https://github.com/coddy-project/coddy-agent

Made for: Claude Code, Codex, OpenCode.

Wrote this? Show the measurements

A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.

agentmods badge for coddy-agent AGENTS.md

README.md
[![agentmods](https://agentmods.dev/badge/instructions/coddy-project/coddy-agent/agents-md/github.svg)](https://agentmods.dev/instructions/coddy-project/coddy-agent/agents-md)
Your own site
<a href="https://agentmods.dev/instructions/coddy-project/coddy-agent/agents-md"><img src="https://agentmods.dev/badge/instructions/coddy-project/coddy-agent/agents-md/github.svg" alt="Measured on agentmods" height="20"></a>

Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.

agentmods 80×15 button for coddy-agent AGENTS.md

Your own site · 80×15
<a href="https://agentmods.dev/instructions/coddy-project/coddy-agent/agents-md"><img src="https://agentmods.dev/badge/instructions/coddy-project/coddy-agent/agents-md.svg" alt="Reviewed on agentmods" width="80" height="20"></a>
Per session 19,699 This file is loaded in full into every session.
When invoked 19,699 The same file — it is already loaded in full.
Security scan B 1 finding. A grade says what 26 rules found in the file — not that it is safe.
Origin original No closer match found in the catalogue.
Token cost

What it costs to keep this loaded

Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.

ModelPer sessionOnce invoked
Fable 5.1 $0.19699 $0.19699
Opus 5.5 $0.07880 $0.07880
Sonnet 5.5 $0.03940 $0.03940
Haiku 4.5 $0.01970 $0.01970

Measured yesterday against content hash b5daa3c03570, method: parsed. Prices are Anthropic first-party input rates as of 2026-10-07, from the pricing page.

Security

Grade B, and why

coddy-agent AGENTS.md scanned grade B with 1 finding against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured yesterday.

A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.

Reads MCP configurationmediumAgent snooping

mcp.json carries server URLs and auth tokens; reading it lets a mod discover and abuse other integrations.

| `internal/mcp` | MCP transports, merged server list (**`<home>/mcp.json`** and the project's **`.coddy/mcp.json`** only: **`config.yaml`** declares no server, and **`internal/config/legacy_keys.go`** moves an old **`mc
AGENTS.md · 205 lines

How it starts

The opening of the file, as written. The whole thing — 205 lines — stays where its author put it; the contents beside it link to each section on GitHub.

Agent Notes for Coddy

Short map for automation-friendly contributors.

Repository navigation

Area Responsibility
cmd/coddy CLI entry (bare coddy console, cli, acp, serve, sessions, skills, plugin, mcp, providers login, rules list, update), plus -t / --test-config on the console, acp and serve: the config check in internal/config/check.go (schema stage in schema.go over the embedded config.schema.json, then the loader's rules), reported as file:line:col with a fix line, exit 1 on errors, nothing written; and --dry-run on the same three, which runs that check and then internal/dryrun.
internal/dryrun The --dry-run probes over a loaded config: Prepare (the static check, then config.LoadReadOnly and a config.Locator so every finding carries its line), Run (paths in paths.go, LLM providers through llm.ListModels with the configured models checked against the list in providers.go, listen addresses (the exporter's too, with a warning when it would be bound off loopback with no token), the Telegram token, remote MCP servers, configured remotes and the --remote target, swarm joins and upstreams in network.go), and the checklist Report (ok / warning / error / skipped per config path, exit 1 on errors; alone the flag prints problems and the status line, with --test-config the config report and every probe). The servers of <home>/mcp.json only: project-local .coddy/mcp.json stays behind the trust gate. coddy serve hands it the subsystems serve.Resolve enabled and their addresses (cmd/coddy/dryrun.go).
internal/serve What coddy serve is: the Runtime every subsystem shares (paths, logger, one session store and one session.Manager, the turn-mirror slot, and the surfaces that offered to show a detached subagent's permission prompt - the HTTP server, a Telegram bot - which are all asked at once, the first answer winning, and the process background waker (wake.go: a finished notify_on_finish task's turn goes to the surface that offered it first by rank - the Telegram chat bound to the session, then the HTTP server - or runs through the manager when neither is up), the Supervisor that runs them (subsystem.go: a Subsystem descriptor per surface with its enable key, its build tag and its Available flag, so an enabled surface the binary cannot run is refused by name, plus Fingerprint for what can be rebuilt in place and RestartKey for what only a fresh process can adopt, Auxiliary for a subsystem that serves beside the surfaces and is never the only one (KindMetrics, the exporter: it does not count as enabled and may always stop); supervisor.go: one goroutine per surface with panic recovery, a diff applied on every config reload - start, stop or rebuild only what moved - ErrRestartRequested when a RestartKey moves under a Restartable process, shutdown in reverse declaration order so intake stops before the API, and Supervisor.Status, the live table Runtime.Status reads), the status snapshot (status.go: the Snapshot a running process reads off itself - its build, the subsystem rows with their state, running, starting, stopped or retained, RestartRequired derived when read and never recorded, the turns running and the oldest one's start, the unfinished background tasks of the model by kind and status, the disk of the session store, the prompts that wait for a person, the provider quota windows and the swarm state - each part read on its own from Supervisor.Status, bgtask.Pool.CountUnfinished, session.Manager.OldestTurnStartedAt, platform.DiskFree, agent.PendingPrompts, session.Manager.CachedProviderUsage (the usage cache only, never a request) and swarm.Joins / swarm.RelayNodes, a part with no source left out; the exporter reads one per scrape), the status document (status_page.go: Runtime.StatusDocument / RenderStatus, what GET /coddy/status answers and Settings → System draws - the build, how the process started, the subsystems with their addresses, the disk, the activity and the attention list decided in Go, with the exporter's last hour through SetMetricsSource in a binary built with metrics), and the background dispatcher (dispatcher.go: the restart policy and the Record at <home>/serve.json; daemon.go: StartDetached, RunDispatcher, the worker process and the CODDY_SERVE_ROLE split, exit status ExitRestart = 75), and the systemd user service (systemd.go: UserService behind coddy serve install / uninstall, the unit renderer shared with the package, the PATH drop-in, the role service the unit sets so a listen-address change exits 75 under systemd too). Untagged: it names no tagged package, and the surfaces reach it through Available consts and stubs. Guide: docs/operate/serve.md.
internal/agent ReAct orchestration, MCP/tool wiring, and the opt-in wait for a hit usage limit (limit_wait.go: a llm.QuotaResetError from the resilient wrapper makes a top-level turn wait for the reset under agent.wait_for_limit_reset, sending provider_usage updates with resuming every 20 s, then re-issue the same call).
internal/mcp MCP transports, merged server list (<home>/mcp.json and the project's .coddy/mcp.json only: config.yaml declares no server, and internal/config/legacy_keys.go moves an old mcp_servers key into the home file on load), and the workspace trust gate for project-local .coddy/mcp.json (trust.go, gate.go; policy mcp.project_trust, approvals in <home>/mcp-trust.json keyed by the project (mcp.TrustWorkspace: a linked git worktree shares its main checkout's), ReadsEnvironment naming on every approval surface the variables a declaration's ${NAME} values read). A server's command and args run exactly as written, their ${CWD} and ${NAME} resolved by config.ExpandMCPValue the same way in every file: nothing here knows npx or any other package runner. The session manager watches <home>/mcp.json (StartGlobalMCPServers starts the watcher, ReloadMCPDeclarations reconciles only the servers whose declaration or switch moved). Client.CallToolResult returns what a result carries: its text (text blocks, the text of embedded resources, resource links), its pictures (ToolImage) and its files (ToolFile: audio, binary resources), which internal/agent keeps with the session's assets. mcptest serves test MCP servers of every kind a user configures - the test binary re-executed on stdio, a local npm package started by the real npx, streamable HTTP answering with JSON (NewHTTPServer) or with event streams (NewEventStreamServer) and SSE - each answering one tool with its token, and all but the npx one a screenshot tool too (ScreenshotTool: the token and Picture, LargePicture over 4 MiB as base64, or several, Pictures). The server pool (pool.go: Pool, PoolKey, WorkspaceBound) shares the configured servers between sessions: a session holds a lease (Client is a handle on a shared conn), a global server is one process for the whole process, a project server that does not name ${CWD} one per project (a linked git worktree shares the one of its main checkout) and any server naming ${CWD} one per workspace, a connection nothing holds stops after DefaultStopDelay unless the pool keeps it (Keep: the global servers session.Manager.StartGlobalMCPServers starts with coddy serve, the console and coddy acp, ended by CloseMCP), and a stdio server runs in its own process group, stopped by stdin EOF and then the group (client.go). The dial itself lives in internal/session/mcp_dial.go (every configured server through TrustGate.Acquire under its own 20 s bound, one more try at the next turn for one that did not answer), the manager's side of the pool in internal/session/mcp_pool.go (a server whose connection ended is parked and started again at the next turn) and the console's background connect in internal/session/mcp_background.go. Guide: docs/features/mcp.md (Shared servers).
internal/remote Go client for a remote coddy serve server: SSE frames back into ACP updates, /coddy REST, permission/question answers, and the permission prompts of background subagents the server announces on its events stream (detached_prompts.go). Powers --remote on the console and coddy acp. Guide: docs/surfaces/console.md (Remote mode), docs/plans/remote-control.md.
internal/providerlogin Signing a provider in without a key: Run (the device flows of NeuralDeep, Codex and OpenCode, Devin's browser sign-in, every request through the row's proxy, then the catalog llm.Apply*LoginToConfig adds to config.yaml), the resolution and endpoint rules coddy providers login shares (Resolve, NeuralDeepAPIBase, OpenCodeAPIBase, SummarizeAdded), and Ready, whether a provider row can answer, decided without a request or a credential helper. The console's /login (external/cli/login.go) runs it and installs the config it wrote through the manager's InstallConfig; the header points a console with no ready provider at it. Guide: docs/surfaces/console.md (Signing in to a provider).
internal/bgtask Background task pool for detached shell commands (run_command background: true plus the background_* tools, the Tasks panel, and /coddy/sessions/{id}/background-tasks), for subagent runs started by spawn_agent (Pool.Launch, kind agent, Agent {name, session_id} on the row), and for in-process servers the preview_server tool starts (Pool.Launch, kind server, Spec.URL / Snapshot.URL, Spec.NoTimeout - no hard limit unless the call names one). Pool.Adopt takes over a foreground command that outlived its timeout instead of killing it. Pool.CanWake says whether this process subscribed a waker (WakeWatcherKey), so run_command and spawn_agent promise a notify_on_finish wake only where one will happen, and Pool.MarkWokeAgent records on the row (woke_agent, persisted) that a task's end did start a turn, which is what keeps the bell on a finished card in the Tasks panel and woke the agent in /tasks. Guide: docs/features/background-tasks.md.
internal/canvas, internal/tools/canvas The canvas of the web UI (tools.canvas): every board is a .canvas file of the workspace (JSON Canvas 1.0, Obsidian's format) whose file nodes naming HTML pages run as live frames, shown as a tab of the Files window. board.go: Ref (the chat's bundle, its workspace, the file), Load, Show (on the named file, the chat's current one or a new canvas/<page folder>.canvas), Open, UpdateNodes, Rotate, Remove, and the chat's bookkeeping in its bundle (canvas.json, State: the current file, the generations of frame addresses and the roots wider than a page's folder, keyed by NodeKey file and node, applying only in the workspace they were written in), a subagent's pages on the canvas of the top session of its spawn tree and refused from a worktree of its own; file.go: reading a file into frames, items and edges, writing back only what changed under a per-file lock that makes one file's read-modify-write one turn across chats, FrameOf for the one frame a file request needs, FileStamp; jsoncanvas.go and obsidian_json.go: an ordered codec that keeps unknown keys and writes byte for byte as Obsidian does. The stamp of a frame's files (stamp.go), the frame capability (capability.go: an HMAC in the path naming the session, the file, the frame, its root, workspace and generation, the key derived for the canvas from the secret behind media tokens), serving a frame (serve.go: os.Root under the workspace, no links, no dot-names, the sandbox CSP, the bridge script bridge.js injected), the browser's reports in memory (reports.go, by session and NodeKey). internal/tools/canvas holds canvas_show and canvas_inspect; the routes are external/httpserver/canvas_http.go (every route names its file with ?file=), the relay's exception external/swarm (isCanvasFramePath), the board external/ui/src/ui/canvas/. A request whose Origin is null is refused with 403 on every API route but a frame's address (external/httpserver/auth.go, the relay's gate). Guide: docs/features/canvas.md, design: docs/plans/canvas.md.
internal/subagents Subagent definitions (markdown + YAML frontmatter from four default folders - ~/.agents/agents, .agents/agents, ${CODDY_HOME}/agents, .coddy/agents, always read, the later winning a name - and then the extra subagents.dirs, through config.Subagents.SearchDirs; built-ins general, explore and the hidden orchestrator crossreview), canonical scopes, the trust receipts for project-scope files (trust.go; policy subagents.project_trust, receipts in <home>/subagents-trust.json), the process-wide Limiter, and the catalog (coddy agents list, GET /coddy/subagents with the bounds each definition declares, the prompt block; the web UI lists it under Settings → Subagents, where a project definition under ask carries the MCP shield that approves it, bound to the digest it showed). A definition's spawns allowlist (builtin/user scope only) admits exactly the named children exactly one level past subagents.max_depth - the mechanism a coordinator uses to fan out. The runtime that spawns a child is internal/agent/subagent.go; it also continues a finished run in its own child session when the parent passes spawn_agent resume, instead of a second child starting over (issue #389). Child sessions are owned by internal/session, which stores each one inside the bundle of the session that spawned it (<parent>/subagents/<child>/) under an ordinary sess_ id and reopens it from that bundle for a resumed run (SubagentSpec.Resume). Guide: docs/features/subagents.md.
internal/hooks Operator lifecycle hooks: definition files in Claude Code's shape (definition.go, matcher.go with tool-name aliases), the loader with canonical scopes (loader.go; policy hooks.project_trust), the trust receipts for project-scope files (trust.go; <home>/hooks-trust.json, keyed by the project (mcp.TrustWorkspace), file and digest; surfaces **`coddy hooks list
internal/session Session manager, Filesystem persistence, Acp hooks, rules catalog, the paged reads of a history (message_window.go: PageMessages step-aligned pages and the counts a client numbers them from, MessagePage.UILog; behind GET /coddy/sessions/{id}/messages?limit=&before=&from=, issue #338), and the provider usage cache and schedule (provider_usage.go: the account quota behind a session's model, published as provider_usage at session ready and from every turn's release, served over GET /coddy/providers/{name}/usage and the events stream; provider_usage_sources.go picks the reader per provider type - internal/llm/neuraldeep_usage.go for the hub's GET /v1/limits, codex_usage.go for the Codex backend's usage endpoint, devin_usage.go for the seat-management status RPC), and the tool-call pairing guard (tool_pairing.go: ValidateToolPairing checks assistant batches against their contiguous tool results, RepairMissingToolResults inserts stable synthetic results for unambiguous missing calls on the outbound projection only - the stored transcript is never rewritten; the agent refuses a still-malformed history at the send boundary). Design: docs/plans/neuraldeep-usage.md.
internal/mention The one grammar of @ mentions (grammar.go: relative, absolute, ~ and ../ paths, quoted paths, :N-M / #L ranges, folders, @session: / @rule: (also @rule:<folder>/<name>) / @agent: / @coddy:, web pages; every reading of an ambiguous token, the one that exists winning), path resolution (paths.go), the workspace index for completion (index.go: git ls-files or a walk, cached per root, rebuilt when a mention starts), fuzzy ranking (fuzzy.go) and the <coddy_attachment> element plus its display twin ForDisplay (attachment.go). internal/session/mentions.go resolves a prompt's mentions once, into that user message; mention_search.go answers completion (GET /coddy/mentions, the console in-process); mention_check.go runs the resolver dry for the web composer's highlight (POST /coddy/mentions/check), so only a mention sending would attach is marked; internal/agent/mentions.go adds the rules a mentioned path activates to the same message, so a mention never moves the system prompt. The SPA twin is external/ui/src/ui/skills/draftAt.ts, held to internal/mention/testdata/grammar_cases.json like the Go side. Guide: docs/features/mentions.md.
internal/docs, docs/embed.go The documentation built into the binary: docs/embed.go (package docs, the only place the embed pattern reaches the tree from) carries nav.yaml and the pages of its groups, and the Russian translation under ru/ (its nav.yaml and the same pages), never plans/ or assets/; internal/docs reads them into a Library per language (library.go: Default (English), LoadLang, Resolve for every spelling of a page, Prev / Next; lang.go: For(lang), Lang for any spelling of a locale, LangFromEnv (CODDY_LANG, LC_ALL, LC_MESSAGES, LANG), LangOfText; a translated heading answers to the anchor of the English heading at the same position, so an address names a section in both languages), splits pages at headings with GitHub's anchors (markdown.go: Anchor and HeadingAnchors, which internal/docsgen's link check uses too, and the link rewriting to coddy:<slug>#<anchor> and to GitHub at the release tag), ranks sections with BM25F (search.go, index built once on first use per language; Russian words stemmed by Snowball, stem_ru.go) and reads a page or a section under a budget of characters (read.go). Consumers: coddy_docs_search / coddy_docs_read (internal/tools), @coddy: (internal/session/mentions.go, mention_search.go), GET /coddy/docs* (external/httpserver/docs_http.go), the web reader (external/ui/src/ui/docs/), the console's F1 help (external/cli/docs_modal.go), coddy docs (cmd/coddy/docs.go). A new group folder under docs/ goes into the embed pattern; TestDefaultCarriesEveryPageOfTheMap fails otherwise. Guide: docs/features/built-in-docs.md.
internal/rules Rules: discovery (factory.go) reads one project folder, the first of .coddy/rules, the shared .agents/rules as system agents-dir, .cursor/rules, .claude/rules and .codex/rules that holds a rule file - so another agent's mirror of the same rules is never loaded next to it - plus the operator's own ${CODDY_HOME}/rules as system user, which applies in every workspace and loses to the project a rule at the same path inside the rule folder, extension included; the same chain under every subfolder on the way down to a file a tool or a mention reaches, read on demand (Factory.Nested, issue #557), each such rule anchored at its own subfolder (Root and ScopeDir) and matched there only (MatchScoped needs the scope and the globs both), and under the one subfolder @rule:<folder>/<name> names, its .coddy/rules only (Factory.Folder, session.SubfolderRules); a rule is named by its file's path inside its rule folder (frontend/style) and @rule: addresses one tree of those names, a subproject's with the subproject in front (internal/session/rule_refs.go: the catalog first, then the deepest subproject; its completion steps down one level per query through Factory.FoldersWithRules); links in a rule folder are followed everywhere; nested AGENTS.md and DESIGN.md files read on demand for the folders a tool enters and never walked for (agents.go, AgentsForPaths), the dialect chosen by extension in markdown.go (.mdc Cursor: description / globs / alwaysApply, default manual; .md Claude Code: paths, unconditional without them) with a lenient reader for Cursor's YAML-invalid globs: **/*.go headers, doublestar glob matching anchored at the session cwd (MatchGlob), activation from mentioned paths (@path, an editor's file:// attachment) and filesystem tool paths (select.go, scope.go): only the always-on rules (AlwaysOnRules) are in {{.Rules}}, a rule a tool call activates rides in that call's result (llm.Message.Rules, internal/agent/rules_activation.go) and one a mention brings in that user message, each once until a compaction folds it away, and the catalog behind coddy rules list, which names the folder read and the ones skipped. The AGENTS.md and DESIGN.md documents come in three layers, always and in this order, whatever rules.auto_discover, rules.systems or the prompt template say (issue #425): the agent home's pair, then the workspace's (project_docs.go, LoadStanding), both in the system prompt, then the pair of every folder on the way down to a file a tool or a mention reaches (AgentsForPaths), attached to that result or message; no config key names them - the file existing is the switch. instructions.files (empty by default) only adds files after them, each under a ### <path> heading like the documents, its entries resolved by internal/session/instructions_load.go, which also reports the entries whose file a session cannot read (UnreadInstructionFiles: a log warning per rules generation, the console header, --dry-run) - one naming the same file in every workspace (absolute, ~, ${CODDY_HOME}) whenever it is unreadable, a relative or ${CWD} one only when its file is there and unreadable - since LoadStanding skips such a file without a word. Every file reaches the model once per rules generation, known by its real path (dockey.go, DocKey: links resolved, case folded on Windows and macOS), the first occurrence winning, so a nested document the system prompt already carries is not attached again. The standing parts are rendered once per rules generation of the session (session.RulesPrompt, internal/agent/rules_prompt.go) and placed in whatever template a turn runs on by internal/agent/system_prompt.go (renderWithDocuments: documents a template did not print are appended), so an AGENTS.md edited mid-session does not move the cached system prompt; a compaction, a config reload or a workspace switch starts the next generation. Guide: docs/features/rules.md.
external/httpserver The HTTP surface coddy serve runs under httpserver.enable, built with tags=http (SSE bridge, Swagger statics, /coddy REST, ServeMux wiring). Serve(ctx, Options) takes an already-built manager; turn_mirror.go implements session.TurnMirror, publishing a turn another surface started into that session's composer relay so a browser can watch it - session updates fan out, permission and question requests stay with the surface that has a human. status_http.go serves GET /coddy/status (registered only when Options.Status is set, so a server without it answers 404 like an older one) and merges its OpenAPI schemas. subagent_permission_hub.go is this server's offer to serve.Runtime for detached permission prompts: a subagent whose spawning turn has ended publishes its prompt on the agent task row (pending_permission, shown in the parent chat) and on GET /coddy/events (subagent_permission), answered through the ordinary POST /coddy/sessions/{child}/permission.
external/ui Embedded SPA (go:embed) when built with tags=http,ui. Settings → System (src/ui/settings/SystemSection.tsx, a lazy chunk, with systemStatus.ts and Sparkline.tsx; the reads and the badge in systemStatusApi.ts) draws GET /coddy/status of the server the page talks to (DESIGN.md, System tab). It installs as an app and shows system notifications from the background: the manifest, icons and service worker in public/, the notifications in src/ui/pwa/ (DESIGN.md, Installable app and notifications). Everything Telegram-specific is src/ui/telegram/ (the Mini App: its own bridge to the client, no script from telegram.org; DESIGN.md, Telegram Mini App). A long conversation is a sliding window: the newest page first, older pages as the reader scrolls up, a bounded slice of rows in the DOM (chat/TranscriptList.tsx, useTranscriptWindow; DESIGN.md, Transcript window); npm run check:transcript measures it in a real browser against the binary. The views of a chat are buttons in the chat header: Files as its icon alone at every width (the name in the tooltip), Background tasks at the right edge with its dot and counts; the dock shows the background tasks without a tab strip, the edits open in a window of their own (git's report of the folder, opened from git's count at the right edge of the plate joined to the top of the composer card, chat/WorkspaceBar.tsx), and so do the files, each with nothing over it: source coloured as one text with the chat's grammars, pictures, sound and film, a PDF in the browser's own viewer, an SVG as a picture and an HTML page in a sandboxed frame through Preview in the window's menu (src/ui/files/FilesView.tsx; DESIGN.md, Views of a chat, Workspace files window); npm run check:files drives them through an authenticated swarm relay.
external/memory Long-term memory (-tags memory): the memory subagent's prompt template, task and tool set (agent.go), the note storage and the six coddy_memory_* tools. The run itself is launched by internal/agent/memory_hooks.go as a system child in the task pool (bookkeeping in memory_run.go, untagged): one run per user turn, a bounded wait for its report, delivery in the turn context block after the history (never the system message, so the provider's prompt cache holds), retention of finished runs. See README there and docs/features/memory.md.
external/cli Interactive console TUI (-tags cli): bare coddy on a terminal, pi-style rendering in external/cli/tui. Guide: docs/surfaces/console.md.
external/swarm The relay coddy serve runs under swarm.enable, built with tags=swarm (part of FULL_TAGS, so the release binaries, image and packages carry it): the stateless relay - lease registry, per-node mount, aggregated sessions, ring-aware topology, and the reverse HTTP/2 tunnel for nodes that can only dial out - plus the relay's own settings (settings.go: /coddy/config* over internal/configapi with the relay's form, config.RelayUISchemaJSON, the document scoped to swarm and logger so a relay client neither reads nor writes the rest of the host's configuration, and a write through a mount refused when the node behind it is itself a relay). It serves nothing else of an agent: no /v1, no sessions, no documentation. Server.Close ends the tunnels, so a relay rebuilt on a config reload is dialled again. While it runs, Serve publishes its registry (swarm.PublishRelay) for the status snapshot. Shared vocabulary and the join client live untagged in internal/swarm, so coddy serve can join a relay without the tag; every running join set registers itself (internal/swarm/status.go: swarm.Joins, the relay host, kind, transport and online state of each registration, never a name or credential), and an agent registration yields to the relay of its own process (Client.yieldsToRelay): a process that runs both its API and a relay starts two join sets from one swarm.join that share the lease of one name, so the relay registers it, once, and the agent stays quiet until that relay stops. Guide: docs/operate/swarm.md.
external/metrics The Prometheus exporter coddy serve runs under metrics.enable, built with tags=metrics (in FULL_TAGS, so release binaries, image and packages carry it) and an auxiliary subsystem (serve.Subsystem.Auxiliary: never the only one, always free to stop; serve.Resolve refuses a config that enables only it). The package has no stub and cmd/coddy/metrics.go is its only importer; metrics_stub.go (no tag) keeps the descriptor, so a binary without the tag refuses metrics.enable naming the tag. collector.go: one private metrics.Set per family of github.com/VictoriaMetrics/metrics (expose.go writes HELP and TYPE in front of each, escapes label values in the series names and adds the library's Go and process families under a generic HELP), built by metricsWiring.Start right after rt.Init whenever the binary has the tag (collection spans the process; metrics.enable only opens the listener), fed by llm.AddCallObserver (internal/llm/call_observer.go: one event per provider attempt, its outcome one of llm.CallOutcomes, whether it is a retry, and the time to its first chunk with content, which Stream notes only for a caller's callback while someone observes, since a nil callback decides whether a failed stream may be retried), agent.AddToolCallObserver (internal/agent/tool_observer.go: one event per tool call, named by the built-in tool, mcp or other and never by an MCP server or tool, its outcome ok, error, refused or denied), session.Manager.AddTurnObserver (the turn edges and the duration between them) and Runtime.AddConfigObserver (a reload that leaves an exporter off loopback without a token is warned about), with the label budget of the llm families (16 providers and 64 named provider and model pairs for the life of the process, everything else other, decided when the attempt is observed, so labels are closed enums and configured names only; every admitted pair is seeded at zero); expose.go also writes the gauges from one serve.Snapshot per scrape, so a scrape asks no provider or server anything; every 15 s the Collector samples its own instrument sets the way a scrape writes them into a one-hour ring (Metrics: the providers and seven series of the status document), with no counter of its own and no scrape slot; serve.go serves GET /metrics behind the live bearer token (404 elsewhere, at most two scrapes at once across every listener of the collector), and since the Collector outlives Serve and the fingerprint is the listen address (no RestartKey), a new address rebuilds the listener in place with the counters kept. The Metrics tab of Settings is hidden without the tag (config.UISchemaJSONHiding, fed by httpserver.Options.UnbuiltSections). The alert rules and their promtool cases are examples/prometheus/, the Grafana dashboard and a Prometheus and Grafana compose stand examples/grafana/ (TestTheDashboardAndTheRulesReadOnlyExportedSeries holds both to what a scrape holds). A relay process runs an exporter of its own and does not carry its nodes'. Guide: docs/operate/monitoring.md.
internal/configapi The settings editor's four routes (GET /coddy/config/schema, GET / PUT /coddy/config, POST /coddy/config/validate) over a Backend - the live configuration, how a new one is installed, which schema and document decoration go with it - so the HTTP server and the swarm relay share one PUT transaction under config.WithConfigFileLock, Sections to serve and take only some top-level sections (the relay's), and Revisions, the last 32 configurations a process served, which a PUT is measured against. Untagged.
external/gateway Messenger gateway (-tags gateway.telegram, -tags gateway.pachca or -tags gateway for both), each bot a subsystem of coddy serve of its own: the Telegram bot under gateways.telegram.enable (a photo, a document or an album a person sends it reaches the session as the web UI's attachments do, downloaded through the Bot API with the caption as the prompt: telegram/media.go, issue #509), and the Pachca integration bot under gateways.pachca.enable (external/gateway/pachca: reads the bot's events history - newest first down to a (created_at, id) watermark in gateway_pachca_state.json, dispatched oldest first, deleted after handling - answers every message of a direct chat and, in a group, only a mention or a reply to the bot (Telegram follows the same group rule), streams into one edited message, answers a message with no text (a file on its own) that it reads text only; a reply reaches the session with the replied-to message quoted in front (external/gateway/replyquote, both adapters); its offline fake is the untagged internal/pachcafake, guide docs/surfaces/pachca.md); session store, proxy support, the ACL over access.Policy shared by both, and the web UI as the Telegram bot's Mini App (telegram/miniapp.go: the menu button and /app under gateways.telegram.mini_app, advertised only behind a credential through gateway.Options.WebUI, which cmd/coddy/serve.go decides, and opened only by the bot's admins, whom the launch data signs in (POST /coddy/auth/telegram, external/httpserver/auth_telegram.go); a sender who is not in a bot's admins only chats: the turn carries access.NonAdminTurn() (session.TurnRestriction: config, model, subagent, worktree and scheduler tools refused, approvals always asked and refused by the bot); gateway.Fingerprint and gateway.PachcaFingerprint in the untagged serve.go hash each bot's whole block). Chat turns run through the shared manager and are mirrored into the HTTP relay, so a conversation is live in the web UI; what the messenger needs is said twice and kept out of the transcript both times - a system prompt block for the turn (prompt.go, carried by session.PromptRunOpts.SurfaceSystemPrompt) and the outbound rendering of the answer (markdown.go); the poller stops intake before generation on shutdown, so a restart from a settings change does not truncate an answer. Full guide: docs/surfaces/gateway.md, rules: .cursor/rules/gateway.mdc.
tgfake (external module) The offline stand for the Telegram gateway lives in its own repository, github.com/EvilFreelancer/tgfake ("tgfake server"): a fake Bot API (every method the adapter calls, long-polled getUpdates, the /sim/* simulation API, a chat page that also plays Telegram for a Mini App) plus a scripted OpenAI-compatible model behind --llm. go.mod pins one version and everything here uses that one: the gateway's Go tests import pkg/server (as tgfake, through external/gateway/telegram/fakeapi_test.go) and pkg/botapi, several suites import pkg/llmstub (with StripTags: ["turn_context"]), the scripts build github.com/EvilFreelancer/tgfake/cmd/tgfake (a tool of go.mod) unless CODDY_TGFAKE_BIN names a prebuilt binary, and CI's Telegram stand (tgfake) job installs the release of that version with tgfake's own action. coddy serve is pointed at it with CODDY_TELEGRAM_API_BASE (config.TelegramAPIBaseEnv, honoured by the bot and the --dry-run probe alike). A change Telegram's behaviour needs is made in tgfake, released, and bumped here. Runner: examples/gateway/tg_e2e_offline.sh. Guides: docs/contributing/tgfake.md (running and bumping it), docs/surfaces/gateway.md (Debugging against a fake Bot API).
packaging Distribution package sources: the nfpm recipe (nfpm.yaml) for the Linux .deb and .rpm, the systemd user unit (systemd/coddy.service, installed and not enabled, rendered by serve.PackagedUnitFile() and held to it by a test), the Homebrew cask template (homebrew/coddy.rb.tmpl, prebuilt macOS archives; every release commits the rendered cask to the tap coddy-project/homebrew-coddy-agent with scripts/publish-homebrew-tap.sh, and the Homebrew tap workflow, .github/workflows/homebrew.yaml, installs it with a real brew on macOS through scripts/check-homebrew-cask.sh) and formula template (homebrew/coddy-formula.rb.tmpl, built from source - the artefact homebrew/core takes), the man page (man/coddy.1), bash and zsh completions, and the maintainer scripts (scripts/postinstall.sh, scripts/preremove.sh: what the user has to do next, the unit not enabled included). The package enables nothing and creates no system service, system account or /etc files; Coddy's state lives in the invoking user's ~/.coddy, and coddy serve install (internal/serve/systemd.go) enables the unit for one account, or writes one under ~/.config/systemd/user for a binary the install script put in place. Built by scripts/build-packages.sh, scripts/build-homebrew-cask.sh and scripts/build-homebrew-formula.sh (make deb, make rpm, make brew, make brew-formula; make brew-publish and make brew-cask-check for the tap); scripts/check-homebrew-submission.sh (make brew-check) is the preflight for the homebrew/core submission. Guides: docs/getting-started/install.md, docs/getting-started/homebrew.md (which Homebrew repository takes what, and the submission path), docs/contributing/build.md (Distribution packages), docs/getting-started/update.md (installations owned by a package manager).
internal/docsgen, cmd/docsgen The documentation generator and checker behind make docs / make docs-check / make docs-stamp: the hub and the llms files from docs/nav.yaml (and the Russian ones from docs/ru/nav.yaml), the translation checks and the stamp of docs/ru/ (translate.go), the link localization of a translated page (localize.go), the config field tables from the schema and config.DocDefaults, the CLI reference from the --help screens, the assets inventory, the relative-link and anchor check. Every tree walk asks git what it excludes and skips it (gitignore.go), so local scratch under docs/ is never reported as a page missing from the map; without git nothing is filtered.

Read the full file on GitHub · 205 lines

Changes

What this file has done since we first saw it

Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.

  1. yesterday Changed · +1 lines · +209 tokens per session b5daa3c03570
  2. 3d ago Changed · +332 tokens per session 90b843ad28c7
  3. 4d ago Changed · +25 tokens per session bc7a885a7028
  4. 5d ago Changed · +1 lines · +451 tokens per session 0a37fdf51836
  5. 6d ago Changed · +1 lines · +900 tokens per session 78ce9216adb7
  6. 9d ago Changed · +2 lines · +1,594 tokens per session 69541a5e7fdf
  7. 10d ago Changed · +27 lines · +638 tokens per session f684ec6d48d0
  8. 11d ago Changed · +69 tokens per session f7863d1e1bc9
  9. 12d ago Changed · +66 tokens per session ff311c4783f6
  10. 14d ago First seen · 173 lines · 15,415 tokens per session scan B 4c9320d3a772

Subscribe to this mod's changes

coddy-agent AGENTS.md is an instructions file published in the GitHub repository coddy-project/coddy-agent (185 stars, last pushed today), licensed MIT. It adds 19,699 tokens to every session, about $0.0788 per session on Opus 5.5. A static security scan graded it B with 1 finding (reads mcp configuration). No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.

Related

Other instructions, from other repositories

vscode buildNext.instructions.md

Working notes and architecture documentation for the new esbuild-based build system in build/next. Use when making changes to the new build pipeline (transpile/bundle commands, NLS plugin, source-map handling, resource copying, or self-hosting watch tasks).

microsoft/vscode · 9,715 tokens

next.js AGENTS.md

AGENTS.md instructions for vercel/next.js, covering next.js development guide, codebase structure, monorepo overview, core package: packages/next and other important packages.

vercel/next.js · 7,581 tokens

vscode oss-third-party-notices.instructions.md

Instructions for microsoft/vscode, covering vs code oss third-party-notices pipeline, architecture, pipeline flow in ci, cache eligibility and rollout and applying the notice (cutover).

microsoft/vscode · 5,262 tokens

langchain AGENTS.md

AGENTS.md instructions for langchain-ai/langchain, covering global development guidelines for the langchain monorepo, corridor security analysis, project architecture and context, monorepo structure and development tools & commands.

langchain-ai/langchain · 4,680 tokens

deepseek-harness AGENTS.md

AGENTS.md instructions for deepseek-ai/deepseek-harness, covering agents.md, pre-stable apis and released session data, repository layout, commands and host sandbox failures.

deepseek-ai/deepseek-harness · 4,261 tokens

vscode copilot-instructions.md

Copilot instructions for microsoft/vscode, covering vs code copilot instructions, project overview, root folders, core architecture (src/ folder) and built-in extensions (extensions/ folder).

microsoft/vscode · 2,731 tokens