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

@trenchwork/erosolar

v1.1.38

Published

DeepSeek AI-powered CLI agent for code assistance and automation. Source: ECCN 4E001 / binary: 4D004 — see SECURITY.md for the export-classification matrix and BIS Note 1 carve-out for vulnerability disclosure output.

Readme

Trenchwork · @trenchwork/erosolar

npm version license: MIT

A multi-provider terminal agent for coding work and authorized offensive-security research. Default backend is DeepSeek-V4-Pro via a shared key gated by Erosolar Auth (no key bundled in the npm tarball); Anthropic / OpenAI / Google / xAI / Qwen / Ollama are opt-in providers with bring-your-own keys.

This README documents the current shipped state of the CLI — the auth-gated boot, profiles, capability surface, MCP integration, artifact store, and operational knobs. Examples, "try asking…" hints, and onboarding fluff are deliberately absent (CLAUDE.md is strict about that). Deep technical reference lives in docs/ENGINEERING.md; security model and threat boundaries live in SECURITY.md.


Install

npm install -g @trenchwork/erosolar

Two binaries land on $PATH and point at the same entry:

  • erosolar — preferred
  • trenchwork — alternate name

Node ≥ 20 required.

First-run boot

erosolar

On first launch the CLI:

  1. Opens a browser tab to https://ero.solar/auth?port=…. Sign in with Google SSO (Firebase Auth, project erosolar-1b0db). SSO is enforced both at the auth page and at the Firestore rule layer (request.auth.token.firebase.sign_in_provider == 'google.com').
  2. Stores a Firebase ID token + refresh token at ~/.erosolar/auth.json (0o600). The refresh token is long-lived; the ID token rotates automatically before expiry.
  3. Approval gate. The CLI checks approved_users/{your-email} in Firestore. The package ships offsec capabilities (Kali tools, AFL++, gdb, pwntools, Ghidra), so only allowlisted emails can launch. If your email isn't approved, the CLI writes a pending request to approval_requests/{uid} and exits with a clear message — re-run once the operator approves.
  4. Fetches the shared DeepSeek API key from Firestore at shared_secrets/deepseek and writes it into the process env for the duration of the run. Nothing lands on disk. Reads are gated to authenticated + approved users; writes are admin-only.
  5. Starts the Ink-based interactive shell.

Requesting approval

Sign in once via Google SSO. The CLI files a pending request at approval_requests/{uid}. The operator reviews and approves with:

node scripts/approve-user.mjs <your-email>

Re-run erosolar after approval is confirmed.

Bring-your-own key

If DEEPSEEK_API_KEY is set in env, the Firestore fetch is skipped. Resolution order:

  1. process.env.DEEPSEEK_API_KEY (env override always wins)
  2. ~/.erosolar/secrets.json (set in-CLI via /key sk-… or /secrets set)
  3. Firestore shared_secrets/deepseek (the post-login fallback)

The same chain applies to TAVILY_API_KEY and any provider key the shared-secrets module recognises.

Modes

erosolar                        # interactive
erosolar -q "explain X"         # one-shot, prints answer, exits
git diff | erosolar             # pipe mode — stdin becomes the prompt
erosolar --profile variant-research "<goal>"
erosolar --self-test            # provider/auth/capability smoke test

Profiles

A profile binds a system prompt template, default model + provider, and a rulebook (a phase-structured guidance document inlined into the system prompt). Switch via --profile <name> or the EROSOLAR_PROFILE environment variable. Three profiles ship:

erosolar-code (default)

General-purpose terminal agent for coding, builds, tests, sysadmin, package management. Default model deepseek-v4-pro, default provider deepseek. Coding tool inventory only — the offsec capabilities are withheld so the model's tool list isn't padded with sqlmap / ROP-search in normal sessions. Rulebook: agents/erosolar-code.rules.json.

variant-research

Authorized offsec / vulnerability-research surface. Walks the standard n-day-to-0-day pivot: recon → vulnerable+patched binary acquisition → patch diff (Ghidra) → variant search → fuzz campaign (AFL++) → crash triage (gdb/pwndbg) → PoC development (pwntools) → coordinated disclosure. Rulebook: agents/variant-research.rules.json.

The disclosure terminal is pinned to coordinated channels (HackerOne / Bugcrowd / vendor PSIRT / CERT-CC / internal write-up / 90-day published advisory). The rulebook contains an explicit vr.r.no_brokerage rule — it is not a vector for selling unreported exploits.

The companion research workspace is Aroxora/patchpivot (private): target portfolio, per-investigation findings dirs, and a disclosure log driven by this profile.

erosolar --profile variant-research "investigate the patch at <commit-url>"

engagement-delivery

Sibling of variant-research running the same eight-phase VR workflow, but the terminal phase delivers to an authorized engagement recipient — a U.S. government contract / task order, a U.S. defense prime under contract, or a published bug-bounty program. The rulebook adds an intake phase that requires an active engagement identifier in the artifact store before any other phase advances; missing engagement id → halt + prompt operator. Rulebook: agents/engagement-delivery.rules.json.

erosolar --profile engagement-delivery "<task>"

Both variant-research and engagement-delivery get the offsec capability surface. erosolar-code does not. Gating lives in src/runtime/profileGates.ts.


Capability surface

Capabilities are typed wrappers around external tools, registered in src/capabilities/ and exposed flat in the LLM's tool list.

Coding default (always on)

| Family | Tools | |---|---| | Filesystem | Read, Write, Edit, MultiEdit, Glob, Grep, Search | | Process | Bash (bracketed-paste-safe stdin, 1MB stdout cap) | | Git | git_status, git_log, git_diff, git_show, git_blame, git_revert, full enhanced-git surface | | Memory | memory_save, memory_load, memory_list, memory_delete | | Planning | TodoWrite (state + plan-formatter integration), PlanMode | | Skills | Skill, list_skills (loads ~/.erosolar/skills/<name>/SKILL.md) | | Web | WebSearch, WebExtract (Tavily under the hood) | | Sub-agent | spawn_agent, agent_status, agent_output, agent_stop | | Notebook | NotebookEdit | | HITL | hitl_decision, hitl_approve, hitl_choose | | Worktree | worktree_create, worktree_remove, worktree_list | | Monitor | monitor_start, monitor_stop (long-running command observers) | | Schedule | schedule_*, trigger_* (in-session reminders / cron-style triggers) |

Offensive (variant-research / engagement-delivery only)

| Capability | Module | Tools | |---|---|---| | Kali (network/web) | kaliCapability.ts | kali_sqlmap, kali_gobuster, kali_ffuf, kali_feroxbuster, kali_nikto, kali_wpscan, kali_hydra, kali_john, kali_hashcat, kali_masscan, kali_amass, kali_subfinder | | Static binary analysis | binaryAnalysisCapability.ts | bin_file, bin_strings, bin_objdump, bin_readelf, bin_nm, bin_checksec, bin_ropgadget, bin_radare2_cmd | | Headless Ghidra | ghidraHeadlessCapability.ts | ghidra_analyze, ghidra_decompile, ghidra_diff | | AFL++ fuzzing | aflppCapability.ts | afl_compile_harness, afl_fuzz_start (detached), afl_fuzz_status (auto-registers crashes in artifact store), afl_fuzz_stop, afl_showmap, afl_cmin, afl_tmin | | Crash triage | gdbCapability.ts | gdb_run_with_input, gdb_inspect_at, gdb_disassemble (pwndbg/GEF inherited from ~/.gdbinit) | | Exploit dev | pwntoolsCapability.ts | pwn_eval, pwn_rop_search, pwn_packed |

The offsec capabilities are guardrail-free per ero.solar/about — the operator authorizes their own engagements; the CLI does not validate target/argv. Install the underlying binaries via kali-linux-everything + ghidra on Kali, or the Kali rolling repo on Debian/Ubuntu.


MCP servers

The CLI auto-loads MCP servers declared in mcp.json (or mcp.json.example as a template). MCP tools appear in the flat tool list with the prefix mcp__<server>__<tool>.

{
  "mcpServers": {
    "ghidra":          { "command": "python3", "args": ["-m", "ghidra_mcp"], "env": { "GHIDRA_INSTALL_DIR": "/usr/share/ghidra" } },
    "mcp_kali_server": { "command": "mcp-kali-server", "args": [] },
    "metasploitmcp":   { "command": "metasploitmcp", "args": [] },
    "tavily":          { "command": "tavily-mcp", "args": [] }
  }
}

mcp-kali-server and metasploitmcp ship in kali-linux-everything. ghidra-mcp is a separate pip install. tavily-mcp is on npm. None are required; they're additive.


Slash commands

Handled before the agent loop sees the input. The set below reflects the actual command table (src/shell/commandRegistry.ts plus the inline matchers in src/headless/interactiveShell.ts):

| Command | Aliases | Effect | |---|---|---| | /help | /h, /? | Inline help panel | | /model [name] | /m | No arg → picker menu; arg → silent switch (provider, provider model, provider/model, or model) | | /providers | | List configured providers | | /key <sk-…> | | Save DEEPSEEK_API_KEY to ~/.erosolar/secrets.json | | /secrets [set [name]] | /s | Inspect / set / unset every known provider key | | /auto | /continue, /loop, /dual | Cycle auto-continue mode (off → on → dual → off) | | /bash <cmd> | /sh | One-shot shell command, bypasses the agent | | /clear | /c | Clear screen, redraw welcome | | /context | | Refresh workspace context | | /sessions | | Session management menu | | /revert [confirm] | | Preview / roll back files modified during the current run | | /tools | | List active tools | | /mcp | | MCP server + tool status | | /learn | | Learning-system status | | /debug [on\|off\|status] | | Toggle agent-internal debug logging | | /stats | /status | Session token + cost stats | | /keys | /shortcuts, /kb | Keyboard shortcuts panel | | /exit | /quit, /q | Leave the shell |

Profile is selected at boot only — there is no in-session /profile switch; restart with --profile <name> or set EROSOLAR_PROFILE. HITL is configured per-tool through the capability's autoPause option (Option+V toggles the equivalent).


Configuration

Filesystem layout (~/.erosolar/)

| Path | Purpose | Permissions | |---|---|---| | auth.json | Firebase ID + refresh tokens | 0o600 | | secrets.json | User-set provider keys (overrides shared) | 0o600 | | sessions/<uuid>.json | Persisted conversation history | 0o600 | | artifacts/<sha256[:2]>/<sha256> | Content-addressed blob store | dir 0o700, files 0o600 | | artifacts/index.json | Artifact metadata | 0o600 | | jobs/aflpp/<jobId>.json | Detached AFL++ job state | 0o600 | | cache/ | Model discovery cache, etc. | 0o700 | | skills/<name>/SKILL.md | User-defined skill playbooks | — |

Environment variables

| Var | Effect | |---|---| | DEEPSEEK_API_KEY | Bypass shared-key fetch and use this key | | EROSOLAR_HOME | Override ~/.erosolar storage root | | EROSOLAR_PROFILE | Default profile (alternative to --profile) | | EROSOLAR_INK_DEBUG=1 | Verbose Ink prompt + state logging on stderr | | <PROFILE>_MODEL | Per-profile default model override (e.g. EROSOLAR_CODE_MODEL=claude-opus-4-7) | | <PROFILE>_PROVIDER | Per-profile default provider override | | <PROFILE>_SYSTEM_PROMPT | Per-profile system prompt override | | NO_COLOR, FORCE_COLOR | Standard color toggles | | ANTHROPIC_API_KEY, OPENAI_API_KEY, GEMINI_API_KEY, XAI_API_KEY, DASHSCOPE_API_KEY, OLLAMA_BASE_URL | Other provider credentials when those models are selected |

~/.erosolar/settings.json (hooks + permissions)

The harness reads ~/.erosolar/settings.json (user) and <workspace>/.erosolar/settings.json (project) for hooks, allow/deny permission lists, and env injection. See src/core/hooks.ts for the contract.


Variant research workflow

The variant-research and engagement-delivery rulebooks drive the same eight-phase pivot the LLM reads from its system prompt:

| Phase | Intent | Tools | |---|---|---| | recon | Identify target patch / CVE / advisory; record bug-class hypothesis | Tavily / WebSearch | | acquire | Build vulnerable + patched binaries; persist to artifact store | Bash, Git, bin_* | | bindiff | Diff binaries; pull decompiled C of changed functions | Ghidra MCP / ghidra_* | | variant | Hunt the same buggy pattern in older versions / forks / siblings | Ghidra, Grep | | fuzz | Build harness + run AFL++ campaign as detached job | afl_* | | triage | Classify each crash; correlate to decomp; identify primitive | gdb_*, Ghidra | | poc | Develop minimal reliable PoC reproducing the primitive | pwn_* | | disclose / deliver | Author write-up; ship through coordinated / contracted channel | — (rulebook lists allowed channels) |

engagement-delivery adds a leading intake phase that gates the workflow on a registered engagement identifier (USG contract / task order, defense-prime engagement reference, or published bug-bounty program scope).

The artifact store is the load-bearing piece: every multi-megabyte output (binaries, decompilations, crash corpora) is registered with a sha256 id and tagged. The LLM passes ids around in conversation instead of pasting blobs into context — without this, a long workflow gets summarized away mid-investigation.


Architecture

Agent loop

src/core/agent.ts runs a single-turn provider-native tool-use loop:

while (true) {
  const r = await provider.generate(messages, tools);
  if (r.type === 'tool_calls') { await resolveToolCalls(r); continue; }
  break;   // text response — turn complete
}

No DAG planner, no ReAct scratchpad. Multi-step planning is implicit in the LLM's tool calls, guided by the rulebook injected into the system prompt. Sub-agents (spawn_agent / agent_status / agent_output / agent_stop) are the long-task supervisor — anything running for hours (fuzz campaigns, large recompiles) goes detached and the parent polls.

Capability registry

Each capability module implements CapabilityModule and contributes a flat ToolSuite to the runtime. Registration happens in src/capabilities/index.ts. Tools declare JSON Schema parameters; inputs are validated and coerced via src/core/schemaValidator.ts before the handler runs. MCP tools are first-class — same ToolDefinition shape, mcp__<server>__ prefix.

Profile-based gating (src/runtime/profileGates.ts) decides which capabilities are mounted. Cowork / productivity capabilities were extracted to ~/GitHub/erosolar-cowork in 2026-05 and are not present in this repo (enforced by test/capability-separation.test.ts).

Rulebooks

A rulebook (src/contracts/schemas/agent-rules.schema.json) is a phase-structured JSON document with globalPrinciples, phases, and per-step entryCriteria / exitCriteria / rules. The CLI renders it to markdown and inlines it into the profile's system prompt at boot. It is declarative guidance, not an enforced state machine — the LLM is expected to follow it; nothing in the runtime blocks a phase from being skipped. Rule severities (critical / required / recommended) influence how strongly the LLM treats them.

Artifact store

src/core/artifactStore.ts — content-addressed blob store at ~/.erosolar/artifacts/. JSON metadata index, sha256-keyed blob dir, no extra deps. Tools that produce large outputs return { artifact_id, summary } instead of pasting raw bytes into chat; downstream tools fetch by id when they need the content. This is what makes a 12-hour fuzz + triage + ROP-build workflow survive context compaction.

Shared secrets

src/core/sharedSecrets.ts — REST fetch of shared_secrets/<name> from Firestore using the user's Firebase ID token. Auto-refreshes the token if expired. Writes to process.env, no on-disk cache (a rotated key shouldn't get stuck stale on a user's machine). Triggered once at boot from src/bin/deepseek.ts after requireAuth().

Context manager

src/core/contextManager.ts — token-budget aware sliding window with LLM-driven summarization. Defaults: 130k max, 100k target compaction trigger, last 10 exchanges always preserved, file-read truncation keeps head + tail of large files. Uses the profile's default model for the summarization pass.

HITL

src/capabilities/hitlCapability.ts — confirmation/approval/choice tools that pause the run timer until the user responds. Configurable via autoPause and timeoutMs on the capability instance. Driven by the LLM (it decides when to ask), not the runtime — there's no "pause every tool call" mode.


Companion surfaces

This monorepo contains the CLI plus three companion surfaces that share Erosolar Auth, balance, and the model brain:

  • Helia (Erosolar_Browser/) — Electron + Chromium browser modeled after ChatGPT Atlas, with a side-panel Erosolar agent that has full page context and CDP-driven action automation. Cross-platform: macOS (dmg/zip, x64+arm64), Windows (NSIS + portable), Linux (AppImage + .deb). Distributed at ero.solar/helia with an S3-manifest auto-updater. Current Helia version: 0.1.21.
  • Site (site/) — Firebase-hosted marketing/portal (/about, /portal, /auth, /docs, /defense, /process, /audit, /admin, /npm, /helia).
  • AWS Lambda backend (aws/lambda/) — single Lambda fronted by API Gateway, Stripe checkout, Firestore for state, service-account JSON pulled from AWS Secrets Manager. Replaces the legacy Cloud Functions deployment; portal + CLI both call into it.

Cross-surface PRs are atomic by design. See CLAUDE.md "Monorepo for one product, separate repos for different products" for the rule.


Building from source

git clone https://github.com/Aroxora/deepseek-coder-cli.git
cd deepseek-coder-cli
npm install
npm run build      # tsc → dist/
npm test           # full jest suite
node dist/bin/erosolar.js --self-test

pretest runs the build, and prepublishOnly rebuilds before any npm publish so the published tarball is always rebuilt from source.

Tests

test/**/*.test.ts — driven by jest with the config in jest.config.cjs. Test discipline (per CLAUDE.md): real behavior end-to-end, no mocks for things the test claims to verify. Tests for provider calls require credentials; those are gated by env-var presence and skipped (with a clear reason) when absent. Skipped ≠ passing.

A pre-push git hook (scripts/git-hooks/pre-push) runs npm test before every push. Install once per checkout: git config core.hooksPath scripts/git-hooks. Bypass in an emergency with git push --no-verify.

Releasing

npm run releasescripts/create-release.sh patch (interactive — checks clean git, runs tests, bumps version, builds, publishes, tags). Non-interactive publishes: npm version patch && npm publish --access public.


Versioning + deprecation policy

Semver. Patches add features and fix bugs without API breakage; minor bumps signal new public surfaces; major bumps signal breaking changes.

Versions 1.1.161.1.19 are deprecated — they bundled an embedded DeepSeek API key that has been revoked. Installations on that range print an npm deprecate warning. Upgrade to ≥ 1.1.20. The shared-key fetch via Firebase Auth replaces the embedded key.


Security posture

Full threat model + controls live in SECURITY.md. The summary below is an index; SECURITY.md is the authoritative reference (SSO, allowlist, revocation, profile gating, audit log, threat model, residual risk).

  • The CLI is dual-use offensive-security tooling. U.S. classification is EAR-controlled (CCL ECCN 4D004
    • 4E001 for development technology). Domestic development and use is unrestricted; export controls apply to international transfer. Good-faith security research is affirmatively protected by Van Buren (2021), the DOJ May-2022 CFAA Charging Policy, and the LOC § 1201 Triennial Exemption (2024).
  • kaliCapability.ts and the offsec capability surface are guardrail-free. Operator authorization is assumed — both legal authorization (you have permission to test the target) and ethical authorization (the engagement scope covers what you're about to run).
  • Disclosure is pinned. The variant-research rulebook's disclose phase has explicit vr.r.no_brokerage and vr.r.respect_embargo rules. PoCs go to vendor / HackerOne / Bugcrowd / CERT-CC, not to brokers. engagement-delivery ships only to authorized contracted recipients.
  • Secrets handling: the npm package ships zero embedded API keys. Keys come from env, user-set local file, or Firestore via Firebase Auth (admin-managed). Error messages are sanitized through secretStore.sanitizeErrorMessage so leaked tokens in stack traces get redacted before they reach the terminal.
  • Auth tokens are stored at ~/.erosolar/auth.json with 0o600 permissions, in an 0o700 directory. Atomic writes prevent half-written JSON from breaking subsequent loads.

See /about for the full disclosure including BIS links and the relevant rulemaking.


Links

  • npm: https://www.npmjs.com/package/@trenchwork/erosolar
  • Source: https://github.com/Aroxora/deepseek-coder-cli
  • Companion research workspace: Aroxora/patchpivot (private)
  • Helia (browser companion, mac/win/linux): https://ero.solar/helia
  • Erosolar Auth: https://ero.solar/auth
  • Project context: https://ero.solar/about

License: MIT (see LICENSE).