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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@agrimsingh/apiary

v0.1.1

Published

Repo-local autonomous swarm conductor for Codex app-server

Readme

Apiary

Repo-local swarm conductor for autonomous, role-based software execution.

Apiary runs a loop of specialized roles (queen, worker, auditor, medic) against your repository, verifies progress through configurable gates, and persists full run state/events in local SQLite.


What Apiary does

At a high level, apiary run:

  1. Validates project config (apiary.md, apiary.gates.yml, apiary.promptpacks.yml)
  2. Requires a clean git tree
  3. Creates a new branch (apiary/<timestamp>-swarm)
  4. Starts (or connects to) a local daemon
  5. Executes iterative role turns:
    • Queen plans a bounded next slice
    • Worker implements it
    • Auditor verifies it
    • Medic repairs failures
  6. Runs required gates (tests/typecheck/smoke/etc.)
  7. Commits successful output and optionally pushes
  8. Stores full timeline, artifacts, and summaries in .apiary/state.sqlite

Architecture

┌──────────────┐   JSON lines over unix socket   ┌─────────────────────┐
│ apiary CLI   │ ───────────────────────────────▶ │ local daemon         │
│ (commands/*) │                                  │ (daemon/server.ts)   │
└──────┬───────┘                                  └──────┬───────────────┘
       │                                                 │
       │                                                 │ JSON-RPC over stdio
       │                                                 ▼
       │                                        ┌─────────────────────┐
       │                                        │ codex app-server    │
       │                                        │ (role threads/turns)│
       │                                        └─────────────────────┘
       │
       ▼
┌─────────────────────┐
│ .apiary/state.sqlite│
│ runs, events, gates,│
│ approvals, snapshots│
└─────────────────────┘

Main modules

  • src/cli.ts - command surface (init, up, run, stop, status, replay, auth, cleanup, stats)
  • src/daemon/server.ts - daemon RPC server, subscriptions, approval handling, app-server lifecycle/restart
  • src/daemon/ipc.ts - newline-delimited JSON IPC protocol helpers
  • src/orchestrator/loopEngine.ts - core queen/worker/auditor/medic loop and budgets
  • src/orchestrator/gateRunner.ts - gate execution with timeout/env requirements/log capture
  • src/orchestrator/approvalPolicy.ts - command/file-change approval decisions per profile
  • src/orchestrator/gitOps.ts - branch creation, commit, push, remote detection
  • src/codex/appServerSession.ts - role thread management + turn dispatch to app-server
  • src/codex/stdioRpcClient.ts - JSON-RPC client over child process stdio
  • src/config/loaders.ts - YAML/frontmatter config loading with Zod validation
  • src/storage/db.ts - persistence, summaries, event queries, cleanup
  • src/utils/env.ts - shared .env loading, upserting, and validation
  • src/utils/helpers.ts - shared pickString utility for nested key extraction
  • src/utils/tokenUsage.ts - shared token usage estimation from heterogeneous payloads
  • src/utils/shellTokenizer.ts - shared POSIX-style shell command tokenizer
  • src/tui/* - Ink terminal UI for live run status and interaction

Prerequisites

  • Git repository (run Apiary from repo root)
  • Node.js + npm (recent LTS)
  • codex CLI available in PATH (used for codex app-server and codex login)

Install / run

npm package (fastest path)

npx @agrimsingh/apiary init
npx @agrimsingh/apiary up
npx @agrimsingh/apiary run --profile fast

Optional global install:

npm i -g @agrimsingh/apiary
apiary status

Dev mode

npm install
npm run dev -- init
npm run dev -- up
npm run dev -- run --profile fast

Built binary

npm install
npm run build
node dist/cli.js init
node dist/cli.js run --profile safe

Publish to npm (@agrimsingh)

npm login
npm publish --access public

Command reference

apiary init

Creates default project config (if missing):

  • apiary.md
  • apiary.gates.yml
  • apiary.promptpacks.yml

Also ensures .gitignore contains:

  • .apiary/
  • .env

apiary up

Ensures daemon is running and waits for app-server readiness (appServer=online).

  • Timeout default: 90s
  • Override with APIARY_UP_TIMEOUT_SEC (seconds)

apiary run

apiary run \
  --profile fast \
  --iterations 25 \
  --max-minutes 180 \
  --max-tokens 3000000 \
  --turn-timeout-sec 300 \
  --steer "focus on P0 regressions" \
  --push

Options:

  • --profile <fast|safe> (if omitted, uses defaults.profile from apiary.gates.yml; fallback is fast)
  • --iterations <n>
  • --max-minutes <n>
  • --max-tokens <n>
  • --turn-timeout-sec <n>
  • --steer <text> (initial steering text)
  • --push (force push on success; redundant when effective profile is fast)

Notes:

  • Numeric options must be positive integers.
  • Run fails early if working tree is dirty.
  • Run always creates a new branch before execution.

apiary status

apiary status
apiary status --summary
apiary status --summary --compact
apiary status --health
apiary status --summary --run-id <runId>

Shows daemon/app-server status; optional run summary and health probes.

apiary replay

apiary replay --run-id <runId>
apiary replay --run-id <runId> --follow

Replays timeline events from SQLite; --follow tails in near-real-time.

apiary stop

Requests active run interruption and daemon shutdown, then removes local pid/socket artifacts.

apiary auth

apiary auth --status
apiary auth --device-auth
apiary auth --with-api-key

Delegates to codex login flow.

apiary cleanup

apiary cleanup --days 30

Prunes old completed/failed/interrupted runs and associated artifacts from SQLite.

Default days:

  • CLI default: 30
  • Env override: APIARY_CLEANUP_DAYS

apiary stats

apiary stats
apiary stats --days 7
apiary stats --compact

Shows aggregate analytics from local SQLite run history.

Options:

  • --days <n> include only runs started in the last N days
  • --compact print single-line key=value output

Default JSON output shape:

{
  "totalRuns": 12,
  "byStatus": { "completed": 8, "failed": 3, "interrupted": 1 },
  "passRate": "66.7%",
  "iterations": { "avg": 4.2, "max": 15 },
  "completionReasons": [
    { "reason": "objective_done", "count": 5 },
    { "reason": "no_edit_gates_passed", "count": 3 }
  ],
  "mostFailedGates": [
    { "gateId": "tests", "failures": 5 },
    { "gateId": "typecheck", "failures": 2 }
  ],
  "timeSpan": {
    "firstRun": "2026-02-18T10:00:00.000Z",
    "latestRun": "2026-02-20T15:30:00.000Z"
  }
}

Compact output example:

totalRuns=12 completed=8 failed=3 interrupted=1 passRate=66.7% avgIterations=4.2 maxIterations=15 topCompletionReason=objective_done:5 topFailedGate=tests:5

Run lifecycle (state machine)

Loop phases from LoopEngine:

  1. bootstrap - initialize run, load config/prompts
  2. plan - queen produces JSON dispatch (decision, prompts, success criteria)
  3. implement - worker applies bounded code changes
  4. verify - run gates + auditor review
  5. repair - medic applies minimal fixes using failure packet
  6. repeat until done / budget exhausted / failure

Termination conditions include:

  • Objective completed (queen says done and gates are clean)
  • Max iterations reached
  • Wall-clock deadline exceeded
  • Token budget exceeded
  • Worker no-edit limit hit (auto-completes if all required gates pass; fails otherwise)
  • No-progress limit hit
  • Explicit stop/interruption
  • Internal error (unexpected exception in run loop)

Interactive TUI (apiary run in TTY)

Hotkeys:

  • a accept approval
  • s accept approval for session
  • d decline approval
  • c cancel approval
  • i interrupt run
  • q quit view
  • : command mode

Command mode:

  • :status
  • :steer <text>
  • :secret KEY VALUE
  • :quit

Secret handling

:secret KEY VALUE writes/updates .env with secure validation:

  • key must match ^[A-Z_][A-Z0-9_]*$
  • value cannot contain newline / CR / null byte
  • .env permissions are forced to 0600 (best-effort)
  • .env loader ignores invalid key lines from manual edits

Config files

apiary.md (frontmatter contract)

Required frontmatter fields:

  • title: string
  • objective: string
  • constraints: string[]
  • acceptance_criteria: string[]
  • out_of_scope: string[]

apiary.gates.yml

Schema highlights:

  • version: 1
  • defaults.profile: fast|safe
  • defaults.timeoutSec: positive integer
  • gates[]:
    • id (alphanumeric/_/-)
    • required: boolean
    • command: string
    • timeoutSec: positive integer
    • envRequired?: string[]
    • pass.exitCode

Gate logs are written to:

  • .apiary/gate-<sanitized-id>.log

Profile resolution:

  • CLI --profile overrides config
  • if --profile is omitted, daemon uses defaults.profile
  • if config cannot be loaded, daemon falls back to fast

Timeout resolution:

  • if a gate omits timeoutSec, loader applies defaults.timeoutSec
  • if a gate explicitly sets timeoutSec, that explicit value wins

apiary.promptpacks.yml

Per-role prompt contracts:

  • queen.system, queen.firstTurn
  • worker.system, worker.firstTurn
  • auditor.system, auditor.firstTurn
  • medic.system, medic.firstTurn

Safety / approval model

Execution profile affects both sandboxing and approvals.

Profile behavior

| Profile | App-server approvalPolicy | Network access | Typical auto-approval behavior | |---|---|---|---| | fast | never | enabled | aggressive auto-approval (accepted_session) when path/command checks pass | | safe | untrusted | disabled | stricter; many actions require explicit approval |

Role write boundaries

  • Writable roles: worker, medic
  • Read-only roles: queen, auditor

All file/command approvals are path-checked against repo root. Out-of-root actions are not auto-approved. Shell control operators (&&, ||, ;, pipes, backticks, $(...), $VAR, ${VAR}) always require approval in both profiles to prevent command chaining attacks.


Git semantics during run

apiary run performs opinionated git automation:

  • requires clean working tree up front
  • creates new branch: apiary/<timestamp>-swarm
  • on successful run:
    • stages everything (git add -A)
    • commits (apiary: successful run <runId>)
    • pushes current branch when effective profile is fast (or when --push is set), only if a commit was created

If no remote exists, push is skipped with a clear message.


Local data layout (.apiary/)

Typical contents:

  • daemon.sock - local IPC socket
  • daemon.pid - daemon process id file
  • state.sqlite - run/event/state database
  • gate-*.log - per-gate execution output

SQLite includes:

  • runs, threads, turns, items, item_deltas
  • events
  • gate_results
  • failure_packets
  • approvals
  • snapshots

Environment variables

  • APIARY_UP_TIMEOUT_SEC - up readiness timeout (seconds, default: 90)
  • APIARY_CLEANUP_DAYS - default retention window for cleanup
  • APIARY_MODEL - force model selection if available server-side
  • APIARY_REASONING_EFFORT - low|medium|high|xhigh
  • APIARY_RPC_TIMEOUT_MS - app-server RPC timeout per request
  • APIARY_LOG_LEVEL - debug|info|warn|error

Also common gate env:

  • OPENAI_API_KEY (required by sample api_smoke gate)

Troubleshooting

status shows daemon offline

  • Run apiary up
  • If stale artifacts exist, run apiary stop then apiary up

run fails with dirty tree

  • Commit/stash before running; Apiary enforces clean start.

run.start says app-server not ready

  • Wait for apiary up readiness or inspect apiary status --health.

Gate blocked on missing env

  • Provide with :secret KEY VALUE in TUI or add to .env.

Only one run allowed

  • If run already in progress, finish/stop current run first.

Frequent RPC timeouts

  • Raise APIARY_RPC_TIMEOUT_MS.
  • Inspect app-server health via apiary status --health.

Development

npm run typecheck
npm test
npm run build

Default smoke gate:

npm run api:smoke

Dogfooding

Apiary builds itself. The apiary stats command was implemented entirely by an apiary run session:

  1. A sprint objective was defined in apiary.md specifying the stats command, its flags (--days, --compact), output shape, and acceptance criteria.
  2. apiary run --profile fast --iterations 10 was executed against the repo.
  3. The worker created src/commands/stats.ts, src/commands/stats.test.ts, added getAggregateStats() to src/storage/db.ts, registered the CLI subcommand, and updated the README.
  4. All required gates (typecheck + tests) passed on every iteration.
  5. The run completed with 7 new tests, all passing, typecheck clean.

This validated the full loop: queen planning, worker implementation, gate verification, and autonomous convergence on a real feature.


Current maturity

Project is intentionally local-first and stateful. The daemon, approval flow, and loop guards are test-covered across 124 tests in 19 files spanning command helpers, daemon behavior, policy checks, gate parsing/execution, DB constraints, session routing, and shared utility modules.