npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

markdown-agent

v2.16.0

Published

```bash review.claude.md # Run with Claude commit.gemini.md "fix auth bug" # Run with Gemini git diff | explain.claude.md # Pipe through any command ```

Readme

markdown-agent

review.claude.md                 # Run with Claude
commit.gemini.md "fix auth bug"  # Run with Gemini
git diff | explain.claude.md     # Pipe through any command

Your markdown files are now executable AI agents.


What Is This?

Markdown files become first-class CLI commands. Write a prompt in markdown, run it like a script. The command is inferred from the filename.

# review.claude.md
---
model: opus
---
Review this code for bugs and suggest improvements.

@./src/**/*.ts
review.claude.md                 # Runs: claude --model opus <prompt>
review.claude.md --verbose       # Pass extra flags

How It Works

1. Filename → Command

Name your file task.COMMAND.md and the command is inferred:

task.claude.md    # Runs claude
task.gemini.md    # Runs gemini
task.codex.md     # Runs codex
task.copilot.md   # Runs copilot (print mode by default)

2. Frontmatter → CLI Flags

Every YAML key becomes a CLI flag passed to the command:

---
model: opus              # → --model opus
dangerously-skip-permissions: true  # → --dangerously-skip-permissions
mcp-config: ./mcp.json   # → --mcp-config ./mcp.json
add-dir:                 # → --add-dir ./src --add-dir ./tests
  - ./src
  - ./tests
---

3. Body → Prompt

The markdown body is passed as the final argument to the command.


Unix Philosophy

markdown-agent embraces the Unix philosophy:

  • No magic mapping - Frontmatter keys pass directly to the command
  • Stdin/stdout - Pipe data in and out
  • Composable - Chain agents together
  • Transparent - See what runs in logs
# Pipe input
git diff | ma review.claude.md

# Chain agents
ma plan.claude.md | ma implement.codex.md

Installation

npm install -g markdown-agent
# or
bun install && bun link

Quick Start

# Run with filename-inferred command
ma task.claude.md
ma task.gemini.md

# Override command via --command flag
ma task.md --command claude
ma task.md -c gemini

# Pass additional flags to the command
ma task.claude.md --verbose --debug

Note: Both ma and markdown-agent commands are available.


Command Resolution

Commands are resolved in this priority order:

  1. CLI flag: --command claude or -c claude
  2. Filename pattern: task.claude.mdclaude

If no command can be resolved, you'll get an error with instructions.


Flag Hijacking

Some CLI flags are "hijacked" by markdown-agent—they're consumed and never passed to the underlying command. This allows generic markdown files without command names to be executed.

--command / -c

Override the command for any markdown file:

# Run a generic .md file with any command
ma task.md --command claude
ma task.md -c gemini

# Override the filename-inferred command
ma task.claude.md --command gemini  # Runs gemini, not claude

$varname Fields

Frontmatter fields starting with $ (except $1, $2...) hijack their corresponding CLI flags:

---
$feature_name: Authentication   # Default value
$target_dir: src/features       # Default value
---
Build {{ feature_name }} in {{ target_dir }}.
# Use defaults
ma create.claude.md

# Override with CLI flags (hijacked, not passed to command)
ma create.claude.md --feature_name "Payments" --target_dir "src/billing"

The --feature_name and --target_dir flags are consumed by markdown-agent for template substitution—they won't be passed to the command.


Frontmatter Reference

System Keys (handled by markdown-agent)

| Field | Type | Description | |-------|------|-------------| | args | string[] | Named positional arguments for template variables | | env | object | Set process environment variables | | env | string[] | Pass as --env flags to command | | $1, $2... | string | Map positional args to flags (e.g., $1: prompt) | | _interactive / _i | boolean | Enable interactive mode (overrides print-mode defaults) | | _subcommand | string/string[] | Prepend subcommand(s) to CLI args |

All Other Keys → CLI Flags

Every other frontmatter key is passed directly to the command:

---
model: opus                           # → --model opus
dangerously-skip-permissions: true    # → --dangerously-skip-permissions
mcp-config: ./mcp.json                # → --mcp-config ./mcp.json
p: true                               # → -p (single char = short flag)
---

Value conversion:

  • key: "value"--key value
  • key: true--key
  • key: false → (omitted)
  • key: [a, b]--key a --key b

Print vs Interactive Mode

All commands run in print mode by default (non-interactive, exit after completion). Use the .i. filename marker, _interactive frontmatter, or CLI flags to enable interactive mode.

Print Mode (Default)

task.claude.md      # Runs: claude --print "..."
task.copilot.md     # Runs: copilot --silent --prompt "..."
task.codex.md       # Runs: codex exec "..."
task.gemini.md      # Runs: gemini "..." (one-shot)

Interactive Mode

Add .i. before the command name in the filename:

task.i.claude.md    # Runs: claude "..." (interactive session)
task.i.copilot.md   # Runs: copilot --silent --interactive "..."
task.i.codex.md     # Runs: codex "..." (interactive session)
task.i.gemini.md    # Runs: gemini --prompt-interactive "..."

Or use _interactive (or _i) in frontmatter:

---
_interactive: true   # or _interactive: (empty), or _i:
model: opus
---
Review this code with me interactively.

Or use CLI flags:

ma task.claude.md --_interactive  # Enable interactive mode
ma task.claude.md -_i             # Short form

Global Configuration

Set default frontmatter per command in ~/.markdown-agent/config.yaml:

commands:
  claude:
    model: sonnet # Default model for claude
  copilot:
    silent: true  # Always use --silent for copilot

Built-in defaults: All commands default to print mode with appropriate flags per CLI tool.


Examples

Claude with MCP Server

# db.claude.md
---
model: opus
mcp-config: ./postgres-mcp.json
dangerously-skip-permissions: true
---
Analyze the database schema and suggest optimizations.

Gemini YOLO Mode

# refactor.gemini.md
---
model: gemini-3-pro-preview
yolo: true
---
Refactor the authentication module to use async/await.

Codex with Sandbox

# analyze.codex.md
---
model: o3
sandbox: workspace-write
full-auto: true
---
Analyze this codebase and suggest improvements.

Copilot (no frontmatter needed!)

# task.copilot.md
Explain this code.

This runs: copilot --silent --prompt "Explain this code." (print mode)

For interactive mode, use .i. in the filename:

# task.i.copilot.md
Explain this code.

This runs: copilot --silent --interactive "Explain this code."

Template Variables with Args

# create-feature.claude.md
---
args: [feature_name, target_dir]
model: sonnet
---
Create a new feature called "{{ feature_name }}" in {{ target_dir }}.
ma create-feature.claude.md "Auth" "src/features"

Environment Variables

# api-test.claude.md
---
env:
  API_URL: https://api.example.com
  DEBUG: "true"
---
Test the API at !`echo $API_URL`

Imports & Command Inlines

Inline content from other files or command output directly in your prompts.

File Imports

Use @ followed by a path to inline file contents:

---
model: claude
---
Follow these coding standards:
@~/.config/coding-standards.md

Now review this code:
@./src/api.ts
  • @~/path - Expands ~ to home directory
  • @./path - Relative to current markdown file
  • @/path - Absolute path

Imports are recursive—imported files can have their own @ imports.

Glob Imports

Use glob patterns to include multiple files at once:

Review all TypeScript files in src:
@./src/**/*.ts

Glob imports:

  • Respect .gitignore automatically
  • Include common exclusions (node_modules, .git, etc.)
  • Are limited to ~100,000 tokens by default
  • Set MA_FORCE_CONTEXT=1 to override the token limit

Files are formatted as XML with path attributes:

<api path="src/api.ts">
...file content...
</api>

<utils path="src/utils.ts">
...file content...
</utils>

Line Range Imports

Extract specific lines from a file:

@./src/api.ts:10-50

This imports only lines 10-50 from the file.

Symbol Extraction

Extract specific TypeScript/JavaScript symbols (interfaces, types, functions, classes, etc.):

@./src/types.ts#UserInterface
@./src/api.ts#fetchUser

Supported symbols:

  • interface Name { ... }
  • type Name = ...
  • function Name(...) { ... }
  • class Name { ... }
  • const/let/var Name = ...
  • enum Name { ... }

Command Inlines

Use !`command` to execute a shell command and inline its output:

Current branch: !`git branch --show-current`
Recent commits:
!`git log --oneline -5`

Based on the above, suggest what to work on next.

URL Imports

Fetch content from URLs (markdown and JSON only):

@https://raw.githubusercontent.com/user/repo/main/README.md

Environment Variables

markdown-agent automatically loads .env files from the markdown file's directory.

Loading Order

Files are loaded in order (later files override earlier):

  1. .env - Base environment
  2. .env.local - Local overrides (not committed)
  3. .env.development / .env.production - Environment-specific
  4. .env.development.local / .env.production.local - Environment-specific local

Example

my-agents/
├── .env                    # API_KEY=default
├── .env.local              # API_KEY=my-secret (gitignored)
└── review.claude.md

Environment variables are available:

  • In command inlines: !`echo $API_KEY`
  • In the spawned command's environment

CLI Options

Usage: ma <file.md> [any flags for the command]
       ma <file.md> --command <cmd>
       ma --setup
       ma --logs
       ma --help

Command resolution:
  1. --command flag (e.g., ma task.md --command claude)
  2. Filename pattern (e.g., task.claude.md → claude)

All frontmatter keys are passed as CLI flags to the command.
Global defaults can be set in ~/.markdown-agent/config.yaml

ma-specific flags (consumed, not passed to command):
  --command, -c       Specify command to run
  --dry-run           Preview without executing
  --_interactive, -_i Enable interactive mode

Examples:
  ma task.claude.md -p "print mode"
  ma task.claude.md --model opus --verbose
  ma commit.gemini.md
  ma task.md --command claude
  ma task.md -c gemini
  ma task.claude.md -_i  # Run in interactive mode

Without a file:
  ma --setup    Configure shell to run .md files directly
  ma --logs     Show log directory
  ma --help     Show this help

Environment Variables

| Variable | Description | |----------|-------------| | MA_FORCE_CONTEXT | Set to 1 to disable the 100k token limit for glob imports | | NODE_ENV | Controls which .env.[NODE_ENV] file is loaded (default: development) |


Shell Setup

Make .md files directly executable:

ma --setup   # One-time setup

Then run agents directly:

task.claude.md                   # Just type the filename
task.claude.md --verbose         # With passthrough args

Manual Setup (zsh)

Add to ~/.zshrc:

alias -s md='ma'
export PATH="$HOME/agents:$PATH"  # Your agent library

Building Your Agent Library

Create a directory of agents and add it to PATH:

~/agents/
├── review.claude.md     # Code review
├── commit.gemini.md     # Commit messages
├── explain.claude.md    # Code explainer
├── test.codex.md        # Test generator
└── debug.claude.md      # Debugging helper
export PATH="$HOME/agents:$PATH"

Now use them from anywhere:

review.claude.md                 # Review current directory
commit.gemini.md "add auth"      # Generate commit message
git diff | review.claude.md      # Review staged changes

Notes

  • If no frontmatter is present, the file is printed as-is (unless command inferred from filename)
  • Template system uses LiquidJS - supports conditionals, loops, and filters
  • Logs are always written to ~/.markdown-agent/logs/<agent-name>/ for debugging
  • Use --logs to show the log directory
  • Stdin is wrapped in <stdin> tags and prepended to the prompt