CLI

evlog agents

Agent Skills
Teach the AI agents working in your repository how to use evlog — a short block of conventions in AGENTS.md, plus the published agent skills installed through npx skills.

Wiring evlog into an app is half the job. The other half is the assistant writing the handlers, which keeps reaching for console.log and throw new Error(...) until something in the repository tells it not to.

evlog agents writes that something.

Terminal
evlog agents
Output
nuxt

✓ created AGENTS.md
✓ created CLAUDE.md
✓ installed the evlog skills
  ran      npx --yes skills add https://www.evlog.dev

What it writes

FileWhat happens
AGENTS.mdCreated if missing. Otherwise the evlog block is replaced in place, between <!-- evlog:start --> and <!-- evlog:end --> — everything outside those markers is left exactly as it was.
CLAUDE.mdCreated as a one-line @AGENTS.md if missing. If it exists and already mentions AGENTS.md, it is left alone.

The block is short on purpose — it is loaded into every agent turn. It states the rules (one wide event per operation, grouped context, structured errors, audit on sensitive actions, what never gets logged) and points at the skills for the depth. The logger accessor named in it follows your framework: useLogger(event) on Nuxt and Nitro, useLogger() from your lib/evlog.ts on Next.js, req.context.log on TanStack Start. When no framework is detected the block is still written with a generic accessor — the conventions apply just as well on Express or Hono.

The skills are not ours to install

The agent skills come from npx skills, which evlog agents shells out to — the same way evlog init runs your package manager instead of unpacking a tarball itself.

That is deliberate. Every agent reads a different directory (.claude/skills, .agents/skills, .codex/skills, …), and the skills CLI already resolves them per agent, symlinks a canonical copy, and supports a global scope. It also keeps no manifest, so any copy we wrote behind its back would be a second one it could never update. Delegating means one copy, and npx skills update / remove / list keep working on it.

Before running anything, evlog agents looks for evlog skills already installed — any agent, project-local or global — and leaves them alone if it finds them:

Output
· AGENTS.md is up to date
· CLAUDE.md already points at AGENTS.md
✓ skills already installed · .agents/skills, .claude/skills
   npx skills update to refresh them
Interactively, the skills CLI asks its own questions — which agents to install for, project or global. That question is its to ask, so evlog agents hands over the terminal rather than answering on your behalf. Non-interactive runs (--json, --yes, CI, no TTY) pass --yes so nothing blocks on a prompt nobody will answer.

What you are trusting

Delegating means running third-party code, so it is worth being explicit about the trust model.

  • What runs. Exactly one command, never assembled from anything you did not pass: npx --yes skills add <source>, plus a trailing --yes when the run is non-interactive and --skill / --global when you asked for them. Interactively it is shown twice — in the plan you confirm, and again as the step starts. Non-interactively (--json, --yes, CI, no TTY) it appears in the report the run prints afterward. Either way the string is the command argument for argument, so re-typing it reproduces the run exactly; --dry-run shows it without running anything.
  • Not pinned. npx resolves the latest skills at run time. That is the point — skills guidance tracks the docs site, not a CLI release — but it does mean the version you get today is not the one you got last month. If your policy needs a fixed version, use --no-skills and run your own pinned npx skills@<version> add https://www.evlog.dev.
  • --source is validated. It must be a plain http: / https: origin — letters, digits, and . _ ~ : / - only, so no query string and no shell metacharacters — and --skills entries must be lowercase dashed names. On Windows the spawn needs a shell to resolve npx (Node refuses to run a .cmd without one), so both are checked before anything is spawned rather than trusted down the chain.
  • Nothing is spawned without a decision. --no-skills skips it entirely, and the interactive flow will not reach the command until you confirm the plan.

If none of that fits your policy, evlog agents --no-skills still writes AGENTS.md and CLAUDE.md — those never touch the network — and you can install the skills however you prefer.

Safe to re-run

Running it again refreshes the block against the current CLI. Anything already identical is reported rather than rewritten, so a second run leaves the working tree clean. Run it after upgrading @evlog/cli.

Flags

FlagWhat it does
--skills <list>Comma-separated skill names, passed to npx skills add --skill (default: all of them)
--no-skillsStill write AGENTS.md and CLAUDE.md; skip only the skill installation — nothing is spawned
--global, -gInstall the skills for every project instead of just this one
--source <url>Where the skills are published — a plain http(s) origin (default: https://www.evlog.dev)
--dry-runShow the plan without writing or running anything
--yes, -yApply without confirming
Terminal
evlog agents --skills review-logging-patterns
evlog agents --global
evlog agents --no-skills
evlog agents --dry-run

If the skills CLI fails — no network, no npx — the block is still on disk and the command reports the failure and exits 1. The AGENTS.md block never needs the network.

As part of evlog init

evlog init offers this as its last question. The AGENTS.md and CLAUDE.md writes land in the same plan as the evlog wiring — one list, one confirmation — and the skills run alongside the package-manager install. Skip it with --no-agents:

Terminal
evlog init --no-agents

Next Steps