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

@nemesis-oss/devagent-ts

v1.0.0

Published

Autonomous, developer-focused AI coding assistant runtime and terminal UI powered by local & cloud Ollama models with capability routing, Docker sandbox, and LSP code intelligence.

Downloads

116

Readme

DevAgent TS

A TypeScript developer agent runtime built on Ollama (local + cloud), with capability-based model routing, LSP-backed code intelligence, a Rails semantic index, a checkpoint/resume-able orchestrator, and a tool-first architecture (35+ tools).

Architecture

src/
├── provider/       Ollama REST client (local + cloud), model catalog, capability router
├── benchmark/      Model scoring harness (JSON validity, tool-calling, latency, tok/s)
├── orchestrator/   Plan steps, parallel dependency-aware execution, checkpoint/resume
├── runtime/        Checkpoint store, config constants, event bus, state store, task machine
├── tools/          35+ tools: filesystem, git, docker, github, sqlite, shell, rspec, rubocop...
├── lsp/            Language server pool/manager — 14 languages configured
├── intelligence/   LSP-backed code intelligence router + Rails semantic index (12 scanners)
├── memory/         SQLite-backed conversation memory + summarizer
├── docs/           DevDocs-backed documentation index (ingest, FTS5 store, workspace detection)
├── learning/       Episode recording, grading, reflection, skill synthesis
├── skills/         Skill loader/registry/resolver (Markdown skill packages)
├── mcp/            MCP client + tool adapter (external MCP servers as tools)
├── cli/            Agent orchestration glue (Agent class, conversation, config)
└── tui/            Ink terminal UI (see docs/SPEC.md — frozen product spec)

Key Features

  • Capability-based model routing, local-first with self-escalationModelCatalog discovers installed local + Ollama Cloud models and tags them (coding/vision/reasoning/quick/tools) by name heuristic; Router picks a local-first candidate per capability and falls back through the rest on rate-limit/timeout/network errors. Every turn attempts the quick model (an always-resident small local model, e.g. minicpm5-1b, pinned by name via quickModel/DEVAGENT_QUICK_MODEL) first — there is no content-based pre-filter. The model itself decides when it's out of its depth by calling the escalate_task tool; once called, the rest of that turn routes to a stronger model (a vision/reasoning-tagged one if the original message hinted at it, otherwise the primary/cloud model), reusing the exact same conversation history so nothing done so far is lost. There's also a heuristic backstop for when a small model doesn't self-escalate: if a tool call errors and the very next turn answers with plain text instead of retrying or calling escalate_task, that answer is discarded (never shown) and the turn is silently re-run on the primary model. Escalation is scoped to a single turn — the next user message starts back on the quick model.
  • Checkpoint/resume — the orchestrator persists plan state (CheckpointStore, atomic JSON) after every step transition; Agent.resumePlannedTask() picks a crashed run back up, resetting only non-terminal step statuses so completed work is never re-run. Separately, SessionStore persists the full LLM conversation transcript after every turn; Agent.resumeSession() / the /resume slash command restore it in a fresh process, verified to correctly re-send prior context to the model.
  • Browser toolsrc/browser/manager.ts wraps a lazily-launched headless Chromium (Playwright) with one reused page; browser_navigate/click/fill/get_text/screenshot/evaluate/close tools expose it to the agent.
  • Parallel step execution — independent plan steps (no dependency between them) run concurrently via Promise.all each round; dependents still wait for their dependency's batch to finish.
  • Tool-first architecture — the LLM never searches files, greps, or runs git/docker/gh by itself; every such action is a deterministic Tool with a JSON-schema signature. DynamicToolSelector prunes which tool schemas are exposed per turn instead of dumping the full registry.
  • LSP intelligence — 14 languages configured (TypeScript, Ruby, Python, Go, Rust, Java, C#, C/C++, PHP, Swift, Kotlin, Dart, YAML, Docker), with definition/references/hover/diagnostics/rename/completion/etc. exposed as tools.
  • Rails semantic index — 12 scanners (controller, model, job, mailer, policy, concern, migration, schema, view, rspec, routes, gem) feeding a graph store and query engine, exposed as find_model/find_route/find_controller/etc. tools.
  • Benchmark harnessnpm run benchmark runs built-in cases against every discovered local + cloud model (or one, via --model <substring>; a category, via --category <name>), reporting pass rate, latency, and tokens/sec per model plus a pass-rate breakdown per category. Prints a running/done progress line per case ([3/14] local/model — case-id ...) and enforces a per-case timeout (--timeout <ms>, default 2 minutes) so a stalled local Ollama server — which has no built-in request timeout — reports as a failed case instead of hanging the whole run forever. Cases span 8 categories: output-format/tool-calling (JSON validity, correct tool selection among distractors, typed arguments, not over-calling tools), reasoning/thinking (multi-step word problems, logic deduction, chain-of-thought), agentic-looping (multi-turn ReAct-style tool chains), error-recovery (retrying after a scripted tool failure instead of giving up), escalation (the real escalate_task tool: does the model self-escalate on a genuinely hard task, and does it avoid escalating an easy one), and execution (real end-to-end tool calls — actual filesystem reads and ripgrep-backed search against a throwaway workspace, not mocked). Single-turn cases (src/benchmark/cases.ts) hit the model once; agentic cases (src/benchmark/cases-agentic.ts, cases-execution.ts) run a standalone bounded ReAct loop (runner.ts) mirroring Agent.runUserMessage's tool-turn loop, independent of the real agent/conversation/routing machinery.
  • Learning + memory — episode recording, grading, reflection, and skill synthesis (src/learning/) backed by a SQLite conversation store (src/memory/).
  • Offline documentation searchnpm run docs:ingest -- <id...> fetches DevDocs's pre-built per-library JSON bundles (no scraping at runtime) and indexes them into a local SQLite FTS5 store (.devagent/docs.db). search_docs/get_doc/list_doc_sources tools expose it to the agent; search_docs auto-scopes to doc sources relevant to the current workspace (detected from package.json/tsconfig.json/Gemfile/go.mod/etc. — Rails, React, Node, TypeScript, Python, Go, Rust, ...) unless a source is given explicitly.
  • Docker-sandboxed shell--network=none, --pids-limit=128, memory/CPU capped; buffer-overflow SIGKILL, hard timeout with kill escalation.
  • Path-contained filesystem tools — every path resolved and checked against workspace root before I/O; atomic writes via temp+rename.
  • Loop detection — flags repeated (tool, args, error) signatures to prevent infinite retry cycles.

Tools

Filesystem/edit: read_file, write_file, patch, append, list_directory, delete_file, make_directory, copy_file, move_file, snapshot_backup, watch, search_code. VCS/infra: git, docker (build/run/stop/logs/exec/compose; --privileged blocked), github (gh pr/issue/release/repo/run/api; merge/delete/close blocked), sqlite_query (read-only: SELECT/PRAGMA/EXPLAIN only). Market data: binance_public_api (GET-only, no API key — spot/USD-M/COIN-M public endpoints incl. /futures/data/* OI history & long-short ratio), binance_technical_indicators (SMA/EMA/RSI/MACD/Bollinger from klines), binance_order_book (bid/ask imbalance), binance_futures_stats (funding rate + open interest), binance_screener (multi-symbol RSI scan), binance_watch_price/binance_unwatch_price (live WebSocket ticker), binance_price_alert (WS-backed price threshold alerts), binance_liquidations (live futures liquidation feed). Quant research: binance_backtest (rule-based strategy vs real history — win rate/expectancy/profit factor/drawdown), binance_walk_forward (edge stability across time windows), binance_monte_carlo (bootstrap resampling of the trade sequence), binance_param_sweep (grid search over parameters, ranked by expectancy), binance_paper_trade (simulated positions marked-to-market against live prices — no real exchange, no keys). Project: run_tests, run_lint, run_format, run_build, rubocop, rspec, shell (Docker-sandboxed). Code intelligence (LSP-backed): get_definition, find_references, rename_symbol, workspace_symbols, document_symbols, hover, diagnostics, code_actions, format_document, signature_help, completion, semantic_tokens. Rails semantic: find_model, find_route, find_controller, find_service, find_spec, find_association, find_callback, rails_context, and more. Documentation: search_docs (workspace-scoped full-text search over ingested DevDocs sources), get_doc (fetch one section by source+path), list_doc_sources (ingested sources + workspace defaults). Plus anything registered via MCP servers (agent.registerMcpServer(command, args)).

Installation & CLI Usage

Global CLI

Install globally via npm:

npm install -g @nemesis-oss/devagent-ts

# Launch the terminal UI
devagent
# or
devagent-ts

Programmatic Usage

import { Provider } from "@nemesis-oss/devagent-ts/provider";
import { ModelCatalog } from "@nemesis-oss/devagent-ts/catalog";
import { Router } from "@nemesis-oss/devagent-ts/router";

const local = new Provider({ tier: "local", model: "qwen3.5:4b" });
const cloud = new Provider({ tier: "cloud", model: "qwen3.5:4b", apiKey: process.env.OLLAMA_API_KEY });

const catalog = new ModelCatalog(local, cloud);
await catalog.refresh(); // discovers installed models on both tiers

const router = new Router({ local, cloud, catalog });
const response = await router.route("reasoning", [{ role: "user", content: "..." }]);

Or use the Agent class directly — it wires provider/catalog/router, tools, LSP, Rails index, memory, learning, and checkpointing together:

import { Agent } from "@nemesis-oss/devagent-ts/agent";

const agent = new Agent({ config: { workspaceRoot: "/path/to/project" } });
const reply = await agent.runUserMessage("Add a null check to the parser");

Requirements

  • Node.js >= 20
  • Ollama running locally, or OLLAMA_API_KEY set for cloud tier
  • Docker (for the sandboxed shell tool and the docker tool)
  • gh CLI on PATH (for the github tool)
  • Language servers on PATH for any LSP-backed tools you want (typescript-language-server, ruby-lsp, pyright, gopls, rust-analyzer, etc.) — missing servers degrade gracefully to a text fallback, not a crash

Environment Variables

| Variable | Default | Description | |----------|---------|-------------| | OLLAMA_HOST | http://localhost:11434 | Ollama server URL (local tier) | | OLLAMA_API_KEY | — | Primary API key for cloud tier — first in the key pool | | OLLAMA_API_KEYS | — | Comma-separated extra Ollama Cloud keys (e.g. separate accounts). On a 429 Provider rotates to the next key and retries before giving up — this is for availability across your own accounts, not multi-vendor routing to other providers | | DEVAGENT_MODEL | qwen3.5:4b | Default model tag | | DEVAGENT_TIER | local | local or cloud | | DEVAGENT_WORKSPACE | auto-detected | Workspace root override. Auto-detection walks up from cwd to the nearest .git (matching how most editor/CLI tooling resolves a project root), then falls back to the nearest existing .devagent/, then cwd itself. All workspace-scoped state (.devagent/history.json, memory.db, checkpoint.json, workspace config.json) lives under whatever this resolves to — set it explicitly if you run devagent from outside the project tree | | DEVAGENT_TIMEOUT_MS | — | Request timeout in milliseconds (cloud tier only — local never times out mid-generation) | | DEVAGENT_SYSTEM_PROMPT | (built-in) | Custom system prompt | | DEVAGENT_SHELL_IMAGE | devagent-sandbox:latest | Docker image for sandbox | | DEVAGENT_SHELL_TIMEOUT_SEC | 30 | Shell command timeout in seconds | | DEVAGENT_TOOL_SELECTION_MODE | heuristic | heuristic | llm | hybrid — how DynamicToolSelector prunes exposed tools | | DEVAGENT_MAX_ACTIVE_TOOLS | — | Cap on tools exposed per turn | | DEVAGENT_MAX_LOGS / DEVAGENT_MAX_CONVERSATION / DEVAGENT_MAX_TOOL_CALLS / DEVAGENT_MAX_NOTIFICATIONS | 500/500/200/20 | Bounded buffer sizes (src/runtime/config.ts) |

Development

npm install
npm test          # jest — 702 tests across 96 suites
npm run build     # TypeScript → dist/
npm run benchmark # score installed models on JSON validity + tool-calling

Documentation Index

Ingest one or more DevDocs sources (MPL-2.0 — generated docs retain DevDocs attribution) into the local FTS5 index at .devagent/docs.db:

npm run docs:ingest -- node typescript react rails

Re-running for the same id atomically replaces its sections (safe to re-run to pick up upstream updates — DevDocs rebuilds monthly). See src/docs/catalog.ts for the full list of supported ids. Ingestion is a one-off/periodic step — the search_docs/get_doc tools never hit the network at inference time, only the local index.

Docker Sandbox

docker build -t devagent-sandbox:latest docker/devagent-sandbox/