Skip to content

Repository files navigation

mini-agent

A small Node.js coding agent that calls Claude directly and implements the core Agent Skills lifecycle: discover, disclose, activate, and follow.

The central constraint is progressive disclosure. Claude initially receives only each skill's name and description. Full instructions enter the conversation only after Claude selects the skill, and supporting files are read separately when the active skill needs them.

Quick start

Requirements: Node.js 20.11 or newer and an Anthropic API key.

npm install
export ANTHROPIC_API_KEY="your-key"
npm run dev -- "I'm new to this project, what should I do?"

The onboarding prompt activates welcome-me and follows the bundled skill. The linked upstream skill currently requires this first line:

> Welcome to our Command Code assignment agent!

An unrelated prompt must not load those instructions:

npm run dev -- "What's the weather?"

To prove the selection path without spending API credits, run the deterministic demo:

npm run demo:mock

The mock is deliberately narrow. It proves discovery, activation, and tool-loop plumbing; normal questions require a configured model provider.

What to test

Prompt Expected skill
I'm new to this project, what should I do? welcome-me
Turn the recent commits into release notes. changelog-generator
What's the weather? None

Use --debug to print activations to stderr or --json for structured output:

npm run dev -- --debug "I'm new to this project"
npm run dev -- --json "Turn the recent commits into release notes"

How skill loading works

sequenceDiagram
    participant U as User
    participant C as CLI
    participant D as Skill catalog
    participant M as Claude
    participant S as Selected skill

    C->>D: Discover SKILL.md files
    D-->>C: Names and descriptions only
    U->>C: Submit a prompt
    C->>M: Prompt and skill catalog
    alt A skill matches
        M->>C: activate_skill(name)
        C->>S: Read full instructions
        S-->>C: Instructions and resource list
        C->>M: Activated skill as tool result
        opt A referenced file is needed
            M->>C: read_skill_resource(skill, path)
            C->>S: Read the bounded resource
            S-->>M: Resource content
        end
    else No skill matches
        M-->>C: Answer without activation
    end
    M-->>U: Final response
Loading

This follows the specification's three context levels:

  1. Catalog: load every skill's name and description.
  2. Instructions: load one complete SKILL.md body after activation.
  3. Resources: load referenced files only when they are needed.

The activate_skill schema contains an enum of discovered names, so the model cannot request an unknown skill. /welcome-me ... and other skill slash commands also support explicit user activation.

Architecture

flowchart LR
    Input[Prompt or Ink UI] --> Agent[Agent loop]
    Agent --> Provider{Provider adapter}
    Provider --> Anthropic[Claude Messages API]
    Provider --> OpenRouter[OpenRouter]
    Provider --> Vercel[Vercel AI Gateway]
    Agent --> Skills[Skill catalog]
    Skills --> Activate[activate_skill]
    Skills --> Resource[read_skill_resource]
    Agent --> Tools[Workspace tools]
    Agent --> Delegate[Bounded subagent]
    Agent --> Events[Activity and token events]
    Events --> Session[Session history]
Loading

The provider boundary normalizes text, tool calls, stop reasons, request IDs, and token usage. Anthropic is implemented with Node's native fetch against the Claude Messages API; there is no Anthropic SDK dependency.

Interactive terminal

Run without a prompt to open the React/Ink interface:

npm run dev

If a provider has no saved key, use /key. Choose a provider, confirm or edit its model ID, and enter the key in the masked input. Keys are stored outside session files with owner-only permissions. Environment variables take precedence over saved credentials.

Useful controls:

Control Action
/ Search commands and installed skills
Ctrl+P Search OpenRouter models
Ctrl+R or /rewind Rewind conversation context
Escape Stop the active run
Ctrl+C Exit

The conversation displays streamed response text, model turns, skill activation, tool and subagent activity, stop reasons, and token usage. The viewport stays within the current terminal height instead of pushing live activity below the composer.

Sessions are saved locally. /history lists them, /resume opens an earlier session, and /redo reapplies a rewound turn. Rewind changes conversation context only; it does not claim to reverse file changes.

Providers and models

Anthropic is the default provider and claude-sonnet-5 is the default model.

Provider Key Example model
Anthropic ANTHROPIC_API_KEY claude-sonnet-5
OpenRouter OPENROUTER_API_KEY deepseek/deepseek-v4-flash
Vercel AI Gateway AI_GATEWAY_API_KEY anthropic/claude-sonnet-4.6

Select a provider or model from the command line:

npm run dev -- -p openrouter -m deepseek/deepseek-v4-flash "Review this project"
npm run dev -- -p vercel -m anthropic/claude-sonnet-4.6 "Write release notes"

Model IDs are passed through to the provider. OpenRouter's Ctrl+P picker fetches tool-capable models, supports search, and accepts a complete custom model ID.

Workspace tools

The agent can inspect and edit one workspace through explicit tools:

  • list files;
  • search with rg without invoking a shell;
  • read bounded files;
  • inspect bounded git history;
  • write files;
  • apply precise text edits.

Every requested path and resolved symlink target must stay inside the workspace. Use --workspace <path> to select a different root or --read-only to remove write and edit tools.

An offline tool-loop demo creates a small page in a temporary workspace:

npm run dev -- --mock --workspace /tmp/mini-agent-demo "Create an HTML page"

Native workflow

The optional workflow separates planning, execution, and verification:

/plan Add validation to the config loader
/start-work
/loop 6

/plan stores a decision-complete plan using read-only tools. /start-work gives one step to super-executor and asks super-verifier to inspect the result. /loop repeats that bounded cycle until every step passes or the iteration limit is reached.

Set VERIFY_CMD when the project has a canonical local check:

VERIFY_CMD="npm test" npm run dev

Five focused role definitions live in agents/: super-planner, super-executor, super-verifier, super-explorer, and super-oracle. The main agent can also delegate a small number of tool-free analysis tasks. Set --subagents 0 to disable that capability.

Project structure

.skills/          three bundled assessment skills
agents/           native workflow role definitions
src/agent/        model and tool loop
src/providers/    Anthropic and compatible provider adapters
src/session/      session history, resume, rewind, and redo
src/skills/       discovery, validation, activation, and resources
src/tools/        bounded workspace tools
src/ui/           React/Ink terminal interface
src/workflow/     plan, execute, and verify workflow
tests/            behavior tests at public seams
scripts/          build, size, and release checks

Skill discovery checks the bundled .skills directory, ~/.agents/skills, .agents/skills, and a project .skills directory. Project skills take precedence. Malformed or invalid skills appear in skills doctor instead of crashing startup.

npm run dev -- skills list
npm run dev -- skills doctor

Verification and packaging

Run the complete local gate:

npm run check

It runs the type checker, sixty behavior tests, full and lite builds, and byte-budget checks. Build the installable release archive with:

npm run pack:release

Current arm64 macOS measurements:

Artifact Size
Lite headless CLI 154,345 bytes
Full CLI, UI, skills, roles, and notices 905,099 bytes
Compressed release archive < 350 KB

Both builds require an installed Node.js runtime. The size measurements do not hide an embedded standalone runtime. The release contains bundled, minified application code and no production dependency declarations.

To install the generated archive as a command available from any directory:

npm install -g ./artifacts/mini-agent-0.1.0.tgz
mini-agent

Submission notes

Time spent: about six hours across specification review, implementation, tests, terminal QA, and packaging.

Challenges faced: the TUI took the most iteration. My first version put live model activity in a footer. Long replies made streamed text and tool calls appear beside the input or outside the visible terminal. I changed the partial reply into a normal conversation turn, moved activity into its own rows, and calculated the line budget from the terminal width. The UI now favors recent activity instead of trying to keep unlimited scrollback on screen.

The agent loop had a less visible failure: every run stopped after six model turns. A prompt that delegated work or retried a broken tool call could end before it had an answer. The turn budget now grows with the configured subagent limit. Invalid tool arguments receive the expected schema and one repair attempt. If the same bad call repeats, the tool is disabled for that run. The loop remains bounded, so a long tool chain can still stop and must be continued in another prompt.

changelog-generator selected correctly, then failed because it could not inspect the repository. I added a bounded git_history tool that calls git directly without exposing a general shell. This requires a real git checkout; a downloaded source archive without .git cannot provide commit history.

Persistence looked correct until the next restart, when the UI asked for the key again and could forget the selected provider. Provider and model selection now live with the session. Credentials use a separate owner-readable state file, and environment variables take precedence over both.

Subagents are intentionally small: they run sequentially, have no workspace tools, and are limited to focused analysis. The mock provider is similarly narrow and only covers known demo paths. A live Sonnet smoke test remains manual because the automated gate does not use secrets or spend API credits.

The bundled skills are pinned to their source commit with their license files. See THIRD_PARTY_NOTICES.md.

About

mini-agent harness with agent skills, bounded subagents, streaming tui, workspace tools, git integration, session persistence, and multi-provider model support - all under 1 mb.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages