Skip to content

Latest commit

 

History

History
288 lines (215 loc) · 15.8 KB

File metadata and controls

288 lines (215 loc) · 15.8 KB

Agent Development Notes

This repo is an installable agent registry. Treat registry/<agent>/... as the source of truth and treat generated JSON as build output.

Start Here

  1. Read README.md for the current repository workflow.
  2. Read registry/<agent>/atom.json for catalog metadata, supported targets, env vars, and connections.
  3. Read registry/<agent>/README.md for human setup and usage.
  4. Edit the agent under registry/<agent>/agent/ — a real eve agent folder copied verbatim on install.

Do not edit files in public/r/ or public/index.json. They are generated by pnpm generate and ignored by git. The root registry.json is generated too, but it is tracked as a small path-only shadcn/GitHub registry index.

Repository Conventions

  • No legacy / backward-compatibility code. This project is not live yet. When you change a structure or convention, change it everywhere to the new form directly. Do not add dual-path detection, migration shims, or "old way" fallbacks — just update all call sites.
  • Code is self-documenting; do not add noise comments. No comments that restate the code or narrate a refactor (e.g. "migrating from X to Y" — it reads as false a year later). Only comment a genuinely non-obvious why. Prefer clear names and structure over prose.

How eve and flue actually work (read the real docs)

Build against the real frameworks — never from memory, from the existing agents, or from stub types. Both ship their docs and TypeScript types inside their npm packages; read them before changing any framework-facing code.

  • eve — npm eve (filesystem-first durable agents). An agent lives in a single agent/ folder, and everything is filesystem-discoveredagent/agent.ts is optional and tiny when present (defineAgent({ model }) only, no instructions/tools/channels passed in); omit it to take eve's default model. agent/instructions.md (system prompt), agent/tools/*.ts (defineTool from eve/tools, inputSchema accepts Zod / any Standard Schema / plain JSON Schema, execute(input, ctx); filename = tool name), agent/channels/*.ts (slackChannel is bidirectional — handles inbound mentions and posts replies; creds via Vercel Connect), agent/sandbox/sandbox.ts (defineSandbox), agent/schedules/*.tsdefineSchedule is one-of { cron, markdown } or { cron, run }: use markdown (task mode) for a report agent with no external channel (eve runs the agent on the prompt at the cron tick and the report is the session output); use run only to hand the result to a channel via receive(channel, …). Peer deps: ai, zod. Docs: node_modules/eve/docs/.
  • flue — npm @flue/runtime. Source under src/: agents are flat files src/agents/<name>.ts (defineAgent(({ id }) => ({ model, instructions, tools, sandbox, skills })) — a factory, capabilities inline). Tools use defineTool from @flue/runtime with Valibot input/output
    • run, passed as tools: [...]. Instructions: import instructions from './x.md' with { type: 'markdown' } (attribute required; inlined at build; *.md → string decl ships in the package). Skills: with { type: 'skill' }. Sandbox: local() from @flue/runtime/node. Slack is inbound-only — outbound posting is an application tool (chat.postMessage). Scheduling is platform cron — Cloudflare wrangler.jsonc + src/cloudflare.ts invoke(workflow,…), or Node via Croner in app.ts; there is no defineSchedule. Docs: node_modules/@flue/runtime/docs/guide/.
  • Schemas do NOT cross targets. eve takes Zod (or any Standard Schema); flue hard-requires Valibot specifically — it checks schema["~standard"].vendor === "valibot" at runtime and rejects Zod, so Standard Schema conformance does not help. A tool's schema must be authored per target (Zod for eve, Valibot for flue); only the framework-neutral run() logic, name, description, and types are shared.

Giving an agent capability

An agent must do work only an LLM can do. If removing the model leaves ~the same output, it's a script, not an agent. Never bake judgment or copy into tool code — no recommend* / draft* / classify* / score* functions that map an input to a hardcoded output string. Tools, CLIs, and connections return raw facts; the model does the reasoning and writing.

Give the agent a real capability, in this priority:

  1. CLI in the sandbox + a usage skill. When the service has a good CLI (posthog-cli, stripe, gh, …), run it via the agent's sandbox and document the workflow in instructions.md or a skill. CLIs give progressive disclosure (<cli> search → info → call) — the model pulls only the schema it needs, so the full API surface is reachable at near-zero prompt cost.
  2. eve connection (MCP or OpenAPI) (agent/connections/*.ts). When the service exposes an MCP server or an OpenAPI document but no good CLI, wire a connection instead of hand-rolling an HTTP client. eve brokers auth and the model discovers tools on demand via the built-in connection_search, so a connection is progressive-disclosure too, not a preloaded catalog. Narrow the surface with tools.allow (MCP) or operations.allow (OpenAPI), and gate writes with an approval policy. Example: registry/backlink-prospector/agent/connections/dataforseo.ts.
  3. Custom defineTool (the focused exception). Only when there is no CLI and no usable contract, or for a single validated write you want the model laser-focused on, or to wrap non-HTTP logic. Returns raw facts / performs one action. Do not hand-roll an HTTP client for an API the service already exposes via MCP/OpenAPI — that is a connection.

So the ordering is CLI > connection > custom tool. Reach for a custom tool when no contract exists, not as the default wrapper for a hosted API.

Credentials: CLIs read restricted/read-only keys from the sandbox env (the agent never echoes them). Connections take env-sourced static creds via headers / auth.getToken (eve resolves them per step, so they never reach the model), or Vercel Connect (connect() from @vercel/connect/eve) for OAuth. flue takes credentials from env/secrets in trusted app code.

Source Layout

Each agent lives in its own folder. The folder holds only atom.json, README.md, and agent/. The agent/ directory is a real eve agent folder, copied verbatim on install to ~/agent/.

registry/<agent>/
  atom.json
  README.md
  agent/
    instructions.md
    agent.ts            (optional) defineAgent({ model: ... }) to pin a non-default model
    tools/  channels/  sandbox/  schedules/  skills/  connections/  lib/  evals/   (all optional)

This structure is enforced by the generator (validateAgentStructure):

  • The agent root may contain only atom.json, README.md, and agent/.
  • agent/ requires instructions.md, and otherwise allows only agent.ts and the directories tools/ channels/ sandbox/ schedules/ skills/ connections/ lib/ evals/.

Custom files inside an allowed directory (e.g. extra lib/ or tools/ modules) are fine, but unexpected folders or stray files will fail pnpm check. Sandbox setup scripts live flat at agent/sandbox/workspace/<setup>.sh (no scripts/ nesting).

Keep atom.json small. It is catalog metadata, not runtime config. Put behavior in source files. Cron timing belongs in agent/schedules/*, not in atom.json.

Write atom.json titles, descriptions, and the opening of each agent README for users browsing the catalog: lead with the outcome the agent helps with, not implementation details such as storage backends, files written, or framework internals. Do not append "Agent" to catalog titles or README H1s unless it is part of a proper name.

Agent READMEs

Before writing or editing any registry/<agent>/README.md, use the agent-readme skill (.claude/skills/agent-readme/). It owns the README shape and rules; this file does not repeat them.

Installed Agents Are Local Templates

Users install these files into their own repo and then edit them. Write installed instructions for the user's project, not as generic marketing copy.

instructions.md is addressed to the agent, in the second person. Never refer to the agent in the third person — write "You are…", "Use…", "Do not…", not "This agent is…" or "The agent reflects…". (Third-person references to a tool are fine: "The X tool only reads data; it does not send email.")

Keep instructions.md purely for runtime behavior. Do not include user-facing setup notes, maintainer guidance, or instructions to edit the file after install. Put customization guidance in the agent README's ## Setup section, and let the CLI point users to the README plus generic next steps after install. The installed prompt may refer to configured project resources, but it should not explain how a human should configure those resources.

Prefer wording like:

  • "You are a SEO audit agent." (state the role directly; don't prefix it with "this project's")
  • "Audit this project's configured site..." (keep "this project's" for the user's real resources — site, repo, Stripe account, open PRs — where it carries meaning)
  • "If no site, URL, or sitemap is configured, stop and say what needs to be configured..."

Avoid wording like:

  • "You are this project's SEO audit agent." (drop "this project's" from the role; it adds nothing)
  • "You are a pragmatic agent for growth teams." (marketing tone)
  • "This agent is read-only." (third person — write "You are read-only.")
  • "This file is intended to be edited after install so you reflect the project's real..."
  • "After installing, edit agent/instructions.md..." inside instructions.md.
  • "Replace this placeholder with the production URL before enabling the workflow."
  • Hard-coded example.com or project-specific domains in executable prompts.

README examples may use generic sample domains, but runtime instructions, schedules, and workflows should refer to configured URLs/context and block cleanly if required setup is missing.

Runtime instructions, prompts, schedules, workflows, and installed helper defaults should not refer to Atom Eve as the user's runtime environment. These files are copied into the user's own repo. Use project-local names such as reports/<agent>/..., <agent>/..., or configured host paths instead of registry-branded paths like atom-eve/<agent>/.... Registry branding belongs in this repo's catalog docs and install docs, not in installed agent behavior.

Avoid Prompt Duplication

Instructions live once in agent/instructions.md. A schedule's trigger prompt lives inline in its defineSchedule({ markdown }) — do not copy long behavior text into schedules.

Skills: Owned And Remote

Agents reference two kinds of skills. Both end up as local files the framework discovers; the difference is where the source of truth lives.

Owned skills are authored in this repo under registry/<agent>/skills/ and copied on install (Eve → agent/skills/, Flue → src/skills/<agent>-<name>/SKILL.md). Use these for an agent's own operational loop. We may also publish an owned skill to skills.sh for reach.

Remote skills are cross-cutting expertise (e.g. a marketing playbook) shared across many agents. Do not copy a third-party skill into this repo. Declare it in atom.json:

"skills": [{ "ref": "coreyhaines31/marketingskills@copywriting" }]

When an agent's capability is a CLI with a published usage skill (e.g. vercel-labs/agent-browser@agent-browser), declare that skill in atom.json skills and let the model load it on demand. Do not inline the CLI's command reference into instructions.md — keep a brief pointer to the skill plus the agent-specific caveats (re-snapshot, screenshot paths).

The ref is the skills.sh install id: owner/repo, optionally @skill to pick one skill from a multi-skill repo (the same value npx skills add <ref> accepts). At install time the CLI delegates to the skills CLI (npx skills add <repo> -s <skill> -a <target> --copy -y), which owns auth and placement: -a eve lands skills in agent/skills/<skill>/, and every other target uses -a universal (the shared .agents/skills/<skill>/ location). A shared skill therefore lives once at its source and is referenced by many agents.

Notes:

  • The skills.sh REST API requires a Vercel OIDC token, so we never call it directly — the skills CLI handles auth. flue is not a skills-CLI target, hence the universal fallback.
  • Remote-skill install is best-effort: if it fails it warns and prints the npx skills add <ref> fallback rather than failing the whole install. A skills-lock.json is written in the user's project so they can npx skills update later.
  • Set ATOM_EVE_SKIP_REMOTE_SKILLS=1 to skip remote installs (the fixture checks set this so pnpm check stays hermetic).
  • Neither Eve nor Flue support runtime-remote skills, so the files must land locally — but the authored source stays remote and DRY across the registry.

Eve Target Rules

The agent installs as a root agent (not a subagent): agent/** is copied verbatim to ~/agent/**. See "How eve and flue actually work" for the framework API; the points below are the registry-specific rules.

agent/agent.ts is optional: omit it to use eve's default model. Include it only to pin a different model, ideally with an environment override:

import { defineAgent } from "eve";

export default defineAgent({
  model: process.env.AGENT_MODEL ?? "anthropic/claude-sonnet-4.6"
});

Schedules use Eve's current public shape:

import { defineSchedule } from "eve/schedules";

export default defineSchedule({
  cron: "0 9 * * *",
  markdown: "Run the configured weekly audit."
});

Do not use unsupported schedule fields such as timezone or prompt.

Flue Target Rules

Flue is a planned generated artifact, not authored by hand; see "How eve and flue actually work".

Browser And Sandbox Capabilities

For browser-driven agents, use the framework's native sandbox or command capability to run browser tooling. Do not create a custom wrapper tool when the framework can run the CLI directly.

Sandbox setup scripts live flat at agent/sandbox/workspace/<setup>.sh (no scripts/ nesting); eve mirrors agent/sandbox/workspace/** to /workspace, so the script lands at /workspace/<setup>.sh and the bootstrap runs it with bash <setup>.sh. The bootstrap is template-scoped, so every session inherits the installed CLI — instructions.md must NOT also tell the agent to run the setup script "before the first command". The agent uses the CLI directly.

Generated Registry Files

The generator emits two registry shapes:

  • registry.json: tracked, path-only GitHub/shadcn registry index.
  • public/r/**: ignored, resolved static payloads with file content for the website endpoint.

Future PRs should mostly review:

  • registry/<agent>/...
  • atom.json
  • README.md
  • small path-only registry.json changes

If a PR contains huge JSON content blobs, fix the generator workflow or rebase after the registry-artifact cleanup.

Verification

Run targeted checks while iterating. Run the full check once before final handoff when the change affects code, generated outputs, install behavior, or agent runtime behavior:

pnpm check

For install-sensitive changes, also run a clean install flow:

mkdir -p /tmp/atom-eve-install-test
cd /tmp/atom-eve-install-test
node /path/to/atom-eve/packages/cli/dist/index.js init --target eve --runtime vercel
node /path/to/atom-eve/packages/cli/dist/index.js add /path/to/atom-eve/registry/<agent> --target eve
pnpm install
pnpm typecheck
pnpm build

Git Hygiene

  • Do not revert unrelated local changes.
  • Do not hand-edit generated artifacts unless debugging the generator.
  • Keep commits focused: source changes, generated path-only registry changes, and docs updates should be easy to review.