made by Mayank Bhaskar ·
🩺 New tool — repo-pulse: instant git pulse (28-day heat bars, hot files, contributors). Run: node tools/repo-pulse.mjs
Give every task the right capability at the right time — with context, intent, reliability, cost, latency, trust, and controlled recovery in the loop.
Quick start · How it works · What's built · Roadmap
SkillRouter is an adaptive capability routing engine that selects the best available skill, plugin, tool, or MCP capability using capability fit, project context, intent, reliability, strategy, cost, latency, trust, and fallback behavior.
SkillRouter is currently a local-first TypeScript CLI and routing engine. It discovers capabilities, validates manifests, analyzes the task and repository, ranks candidates deterministically, creates an activation plan, applies lifecycle changes through adapters, records audit history, and exposes the decision for inspection. The long-term direction is a broader orchestration layer; the claims below distinguish what is implemented now from what is planned next.
Most capability systems make a static choice: map a task to a hard-coded tool, activate it, and hope it works. That leaves useful evidence on the table. A repository has language, framework, dependency, filesystem, Git, runtime, and risk signals; a capability has triggers, compatibility, requirements, permissions, trust, cost, latency, and declared metadata. SkillRouter turns those signals into an explicit, inspectable routing decision instead of hiding selection inside a pile of ad-hoc conditionals.
| Static selection | SkillRouter |
|---|---|
| One hard-coded tool | A catalog of candidate capabilities |
| Task text only | Task, project, Git, context, intent, and constraints |
| Opaque choice | Per-factor score breakdown and explanation |
| Retry the same failure | Ordered fallback chains with loop protection |
| Declared reliability forever | Fresh outcome metrics take precedence |
| Immediate activation | Plan, risk evaluation, permission policy, consent, and audit |
The current pipeline is deliberately modular. The CLI bootstraps local state, refreshes the catalog, analyzes the task and project, collects normalized context, scores every candidate, resolves conflicts and dependencies, creates a plan, and lets the runtime apply that plan through connected adapters. Routing itself does not require an LLM; optional semantic and LLM interfaces can be configured without making the deterministic path dependent on them.1
Task + project + Git context
│
▼
Candidate discovery
│
▼
Intent + context + constraints
│
▼
Strategy-aware scoring engine
│
▼
Conflict + dependency resolution
│
▼
Activation / fallback plan
│
▼
Runtime adapters + consent policy
│
▼
Audit history + outcome
│
└──────────► future score
The repository is in early development, but the current implementation is substantially beyond a prototype router. The implementation tracker is the source for phase status; this summary intentionally avoids presenting roadmap items as shipped functionality.2
| Area | Current implementation |
|---|---|
| Capability model | Canonical Capability model with skillrouter/v1 manifest parsing, validation, normalization, metadata, dependencies, conflicts, relationships, fallbacks, permissions, risk, trust, and compatibility. |
| Catalog and lifecycle | Local and Git discovery, indexed search, install, uninstall, update, lockfile support, enable/disable, activate/deactivate, and explicit lifecycle transitions. |
| Routing engine | Deterministic matching, project analysis, Git signals, modular scoring factors, conflict resolution, dependency ordering, activation planning, dry runs, manual overrides, and explanations. |
| Context and intent | Fault-tolerant normalized context providers plus deterministic intent classification, hard constraints, permission boundaries, and soft language/framework preferences. |
| Strategies | balanced, quality, speed, cheap, minimal, and safe, with declared cost and latency metadata available to the scorer. |
| Reliability and recovery | Bounded skill_metrics, historical scoring, stats, learn, declared fallback chains, attempted-set loop prevention, maximum step limits, fallback events, and learned suggestions. |
| Security | Risk levels, permission declarations, untrusted-by-default policy, secret detection, trust levels, audit logging, key/signature tooling, and consent gating. |
| Adapters | OpenCode, Claude, Codex CLI, Gemini CLI, Cline, Cursor, GitHub Copilot, Windsurf, Aider, MCP configuration, generic Agent Skills, config-driven custom CLI agents, and environment detection through doctor. |
| Reporting | Human-readable CLI output, JSON mode, explain, verify, self-test, structured logs, audit history, and static HTML dashboard export. |
SkillRouter connects to every major coding agent — natively through adapters, or through config for anything else. Capability payloads are exposed as managed, marked markdown files (or MCP registrations) that each agent picks up on its own terms.
| Agent | Type | SkillRouter exposes capabilities via |
|---|---|---|
| OpenCode | built-in | .opencode/skills/ (native skill format) |
| Claude Code | built-in | .claude/skills/ (native skill format) |
| Gemini CLI | built-in | ~/.gemini/extensions/ (extension + skills) |
| OpenAI Codex CLI | built-in | .codex/prompts/ + ~/.codex/prompts/ |
| Cline | built-in | .clinerules/ + ~/.cline/rules/ |
| Cursor | built-in | .cursor/rules/*.mdc (MDC frontmatter) |
| GitHub Copilot | built-in | .github/instructions/*.instructions.md (applyTo) |
| Windsurf | built-in | .windsurf/rules/ + global Codeium rules |
| Aider | built-in | .aider/skills/ (with --read hint) |
| MCP clients | built-in | serve-mcp tools (route_task, search_capabilities, router_stats) |
| Anything else | config | skillrouter agents add <name> --cmd <binary> --rules <dir> |
skillrouter agents add myagent --cmd mycli --rules .myagent/rules --label "My Agent"
skillrouter agents # list every connected agent + detection evidence
skillrouter agents remove myagentCustom agents are stored in skillrouter.yaml under customAgents. Exposed capability files carry a <!-- skillrouter:managed capability="…" --> marker, so uninstall, disable, and discovery stay clean.
Any MCP-capable client (Claude Desktop, Cline, Cursor, Codex, …) can ask SkillRouter which capability fits a task, mid-session:
claude mcp add skillrouter -- skillrouter serve-mcp{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"route_task","arguments":{"task":"audit authentication changes","strategy":"safe"}}}The server speaks newline-delimited JSON-RPC 2.0 on stdio with zero extra dependencies.
Strategies change the trade-off, not the underlying architecture. The scoring system combines matching signals with project and context evidence, trust and risk penalties, historical reliability, declared cost and latency, and the selected preset.3
| Strategy | Optimizes for |
|---|---|
balanced |
The default general-purpose trade-off across routing signals. |
quality |
Stronger quality, historical, reliability, and trust signals. |
speed |
Lower declared latency and tighter context-cost penalties. |
cheap |
Lower declared cost and tighter context-cost penalties. |
minimal |
Lower matching overhead and lighter quality/history weighting. |
safe |
Stronger permission and trust penalties for risk-aware selection. |
Select a strategy per route or in skillrouter.yaml:
skillrouter route "migrate the database" --strategy safeSkillRouter records outcomes in local skill_metrics. Fresh observed success rates take precedence over a capability's declared success rate; declared reliability is the final fallback when no fresher evidence exists. The observation window is bounded: once it exceeds 1,000 tasks, counters are halved so old evidence gradually matters less without allowing a small number of executions to dominate ranking.4
The feedback loop is visible from the CLI:
# Record a successful or failed outcome.
skillrouter learn dependency-vulnerability-scanner --success --task "audit dependencies"
skillrouter learn dependency-vulnerability-scanner --failure --task "audit dependencies"
# Inspect observed reliability.
skillrouter stats
skillrouter stats --jsonA capability can declare an ordered fallbacks list. When a primary path fails, the resolver walks the declared chain, skips attempted or unavailable candidates, and stops at a bounded number of steps. Failures emit events and learn can suggest the next declared fallback. The result is recovery behavior that is explicit in the manifest and inspectable in the decision history.5
Manifests are YAML or JSON documents using the skillrouter/v1 schema. The example below is adapted from the repository's checked-in security-auditor manifest and keeps the schema's required fields, trigger structure, compatibility, permissions, risk, context, and metadata intact.6
schema: skillrouter/v1
id: dependency-vulnerability-scanner
name: Dependency Vulnerability Scanner
version: 1.0.0
description: Scans project dependencies and lockfiles for known vulnerabilities.
type: skill
capabilities:
- scan-lockfiles-for-cves
- check-osv-advisories
triggers:
keywords:
- vulnerability
- cve
- dependency
- lockfile
intents:
- "scan dependencies for vulnerabilities"
- "check for known CVEs"
technologies:
- npm
- python
compatibility:
opencode: native
claude: native
gemini: adaptable
generic: compatible
permissions:
filesystem:
read: true
write: false
network:
allowed:
- nvd.nist.gov
- api.osv.dev
risk:
level: medium
score: 42
context:
estimatedTokens: 2800
activationLevel: 1
fallbacks:
- report-writer
trust: unknown
metadata:
author: SkillRouter Examples
license: MIT
categories:
- security
- supply-chainThe complete reference lives in docs/manifests/manifest-reference.md, and the authoritative JSON Schema is schemas/skillrouter-v1.schema.json.
The shortest useful path is a dry-run route. It refreshes the catalog, analyzes the task and project, ranks candidates, and prints the plan without changing active capabilities.
skillrouter route "write unit tests for the CLI" --dry-runFor machine-readable output:
skillrouter route "scan dependencies" \
--strategy safe \
--constraints '{"network":"forbidden"}' \
--dry-run --jsonThe JSON route payload includes the verified decision concepts exposed by the CLI: task, decisionId, mode, strategy, latencyMs, intent, context, analysis, activate, deactivate, contextUsage, dependencies, and dryRun. Each activation can include id, score, confidence, reasons, and a normalized breakdown.7
A representative shape looks like this; values are illustrative, while the field names match the current implementation:
{
"task": "write unit tests for the CLI",
"decisionId": "decision-id",
"strategy": "balanced",
"activate": [
{
"id": "testing-capability",
"score": 84,
"confidence": "high",
"reasons": ["matched technology term(s): typescript"],
"breakdown": {
"keyword": 12,
"technology": 14,
"historical": 8,
"permissionCost": -2
}
}
],
"dryRun": true
}To understand why the latest decision was made:
skillrouter explain
skillrouter explain --jsonSkillRouter is shipped as a single CLI. Use skillrouter --help for the complete command-specific options; the grouped surface below mirrors the command registry in src/cli/index.ts.8
| Group | Commands |
|---|---|
| Setup | init, doctor, status, config |
| Connect | agents, serve-mcp |
| Catalog | search, find, info, install, uninstall, update, source |
| Lifecycle | enable, disable, force-enable, force-disable, activate, deactivate, active |
| Routing | route, explain, context, classify |
| Security | scan, permissions, trust, trust-check, keys, sign, signatures |
| Observability | logs, audit, stats, learn, verify, self-test, export |
SkillRouter currently installs from source. Node.js 22.5 or newer is required because the project uses node:sqlite, the built-in test runner, and native TypeScript execution; Node 24 or Node 22.18+ is recommended for stable type stripping.9
git clone https://github.com/qtjg/skillrouter.git
cd skillrouter
npm install
npm run typecheck
npm run buildInitialize and inspect a project:
# Create project configuration and local state.
node --experimental-transform-types src/cli/index.ts init
node --experimental-transform-types src/cli/index.ts doctor
node --experimental-transform-types src/cli/index.ts statusAfter building, the package exposes the skillrouter binary through bin/skillrouter.js. Run the first route in dry-run mode before allowing activation:
npm run build
./bin/skillrouter route "write unit tests for the CLI" --dry-run
./bin/skillrouter explainOn Node.js 22.18+ or Node 24, plain execution is supported. On older 22.x releases, use --experimental-transform-types for direct source execution.10
The source tree is divided by domain so routing policy, capability lifecycle, adapters, storage, and security remain replaceable boundaries rather than one monolithic command implementation.
src/
├── adapters/ agent integrations and environment detection
├── cli/ command registry and command handlers
├── config/ global/project configuration
├── constraints/ hard constraints and soft preferences
├── context/ normalized context collection
├── core/ types, lifecycle, ids, and events
├── graph/ capability relationships and traversal
├── intent/ deterministic task intent classification
├── learning/ bounded outcome metrics
├── manifest/ parsing, validation, normalization
├── registry/ discovery, indexing, search, and sources
├── router/ analysis, factors, planning, conflicts, fallbacks
├── runtime/ consent-gated activation and deactivation
├── security/ risk, permissions, secrets, trust, signing, audit
├── storage/ SQLite-backed replaceable storage interface
└── verify/ project and capability verification
The project uses a small runtime dependency surface: yaml plus Node built-ins. Local state is stored behind a replaceable storage interface using node:sqlite; project configuration is YAML, and routing state can be locked in skillrouter.lock.9
How scoring works
Each candidate receives a weighted score that is clamped to the 0–100 range. Signals include task keywords and technologies, project language/framework/dependencies, Git and file patterns, compatibility, trust, quality, intent, context requirements, historical success, declared cost and latency, context cost, permission cost, and constraint preferences. Blocked candidates are removed; conflicts keep the higher-scoring candidate, with lower risk breaking ties. The normalized scoreBreakdownV2 is exposed in route JSON for inspection.3
How context and intent work
Context providers collect normalized project, Git, runtime, filesystem, package-manager, and environment signals with per-provider timeouts and secret redaction. The intent classifier is deterministic and reports the inferred intent, confidence, domain, language, signals, and operations. Route constraints can hard-reject candidates, enforce permission boundaries, require capabilities, and apply soft language/framework preferences.11
How runtime safety works
The router proposes a plan; the runtime applies it. Before activation, SkillRouter computes risk, constructs permission requests, evaluates policy, and asks for consent when required. Agents are updated through adapters, lifecycle transitions are enforced, and actions are recorded in the audit log. manual mode remains dry-run only; assisted mode is the default interactive path, while automatic and autonomous modes can apply plans according to configuration.1 12
How fallback and learning work
Fallback chains are declared per capability and resolved in order. The resolver skips already-attempted, unavailable, unknown, or over-limit candidates. skillrouter learn <capability> --success|--failure records observations, emits typed events, and can recommend a declared fallback after failure. skillrouter stats exposes the stored metrics in table or JSON form.5 4
The current implementation has moved through foundation, capability management, routing, adapters, security, CLI, reliability, context, and intent milestones. The next layer is broader orchestration, not a claim that those features already exist.
skillrouter/v1 manifests, capability graph traversal, context collection, deterministic intent classification, constraints, strategy-aware scoring, fallback chains, bounded metrics, lifecycle runtime, adapters, security policy, audit logging, CLI reporting, and static dashboard export are implemented to the extent tracked in IMPLEMENTATION.md.
The documented future direction includes a runtime daemon, embedding-based semantic matching, ranking signals built from history, publishing and registry APIs, a marketplace, sandboxing, Ed25519 capability signing, MCP server mode, CI/CD integration, cookbook skills, and a routing timeline view. These are roadmap items, not current README promises.2
Clone the repository, install dependencies, and keep strict TypeScript checks clean before opening a pull request. The project follows Conventional Commits and intentionally keeps runtime dependencies minimal.10
Every push and pull request targeting main is verified by .github/workflows/ci.yml, which installs dependencies with npm ci, runs the TypeScript typecheck and test suite, and builds the project on Node.js 22.
npm install
npm run typecheck
npm test
npm run buildFocused checks are available when working in a specific area:
npm run test:unit
npm run test:router
npm run test:cli
npm run test:security
npm run test:adapters
npm run doctorThe README redesign was validated against the repository at commit cf5db4c: the full suite passed with 151 tests, npm run typecheck passed, and npm run build passed. Those results describe this documentation audit environment, not a permanent CI badge.
Please read CONTRIBUTING.md before making changes. In brief: fork or clone the repository, create a focused branch, preserve strict TypeScript boundaries, add or update tests, run typecheck and the relevant verification commands, document architectural decisions in DECISIONS.md, and open a pull request with a clear explanation of the change.
Security reports should follow SECURITY.md rather than being opened as public issues.
Isometric 3D language stack computed from live GitHub language stats. Regenerate the graphics any time with the built-in generator — stdlib only, zero dependencies:
python tools/generate_3d_assets.pySkillRouter is released under the MIT License. Copyright © 2026 Mayank Bhaskar.
Footnotes
-
docs/routing/how-routing-works.md— the verified routing pipeline, runtime flow, lifecycle states, and recording behavior. ↩ ↩2 -
IMPLEMENTATION.md— the repository's implementation tracker and future-work boundary. ↩ ↩2 -
docs/routing/scoring.md— scoring factors, strategy presets, normalized breakdowns, and risk-floor behavior. ↩ ↩2 -
src/learning/metrics.ts— bounded observations, reliability estimates, and the metrics recording engine. ↩ ↩2 -
src/router/fallback.tsandsrc/cli/commands/learn.ts— fallback resolution and outcome recording. ↩ ↩2 -
docs/manifests/manifest-reference.mdandexamples/manifests/security-auditor.yaml— manifest schema and a checked-in example. ↩ -
src/cli/commands/route.ts— route command flags and JSON payload fields. ↩ -
src/cli/index.ts— the registered command surface. ↩ -
package.json— package version, Node engine, scripts, dependencies, and binary entry point. ↩ ↩2 -
CONTRIBUTING.md— supported Node execution modes and contribution checks. ↩ ↩2 -
docs/routing/intent-constraints.md— deterministic intent and constraint behavior. ↩ -
docs/security/security-model.mdandsrc/security/policy.ts— security model and consent policy. ↩