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

loopwithai-runner

v0.9.3

Published

Local runner for Loop with AI — executes your project's queued agent jobs (report/implement/drift) on your machine using your own AI CLI (Claude, Antigravity, or a custom agent), can START your dev server itself (LOOPAI_DEV) and expose it via a public pre

Readme

Loop with AI runner (loopwithai-runner)

Executes agent jobs on your machine. When someone clicks "Ask agent" / "Request report" in the app, a job is queued; this runner polls, claims it, runs your local AI CLI, and posts the result back — the "app requests → your localhost agent delivers" loop. No inbound connection needed (pull-based). Works with Claude (default), Antigravity (agy), or a custom CLI — see SYNCEFFORTS_AGENT below.

Run

# published to npm — no clone/download; npx fetches + runs it (Node.js 18+):
SYNCEFFORTS_API_KEY=se_live_... SYNCEFFORTS_PROJECT_ID=<project id> npx -y loopwithai-runner

# or from source in this folder (Node built-ins only):
SYNCEFFORTS_API_KEY=se_live_...  \
SYNCEFFORTS_PROJECT_ID=<project id>  \
node runner.mjs
  • Requires the Claude CLI (claude) installed and logged in — the runner pipes each job's prompt to claude -p. Point at a different binary/wrapper with SYNCEFFORTS_CLAUDE_CMD.
  • Test the loop without Claude: add SYNCEFFORTS_DRY=1 — it claims jobs and posts a stub result, so you can verify the round-trip before wiring real inference.

Two job modes

Chosen per request in the app's New-request modal:

  • report (default) — Claude writes an analysis/report; the Markdown is posted back to the app. No code changes. This runner needs nothing special.

  • implement — Claude edits your repository in place (following the project rules), then the runner appends a change report (new commits + diffstat + untracked files) to the result. To serve implement jobs, start the runner at/with your repo:

    SYNCEFFORTS_API_KEY=se_live_...  \
    SYNCEFFORTS_PROJECT_ID=<project id>  \
    SYNCEFFORTS_REPO=/path/to/your/repo  \
    node /path/to/syncefforts/runner/runner.mjs

    It runs claude -p --permission-mode bypassPermissions in that repo. It never commits or pushes — changes are left in your working tree; you review and commit them (localhost-first). bypassPermissions is required so a headless run doesn't hang on an approval prompt; it's your own machine. Override with SYNCEFFORTS_PERMISSION (e.g. acceptEdits) if you want narrower autonomy — but note stricter modes can stall a non-interactive run on tool prompts.

Env

| var | default | purpose | |---|---|---| | SYNCEFFORTS_API_KEY | — | org key (app → your project → API keys) | | SYNCEFFORTS_PROJECT_ID | — | project to serve | | SYNCEFFORTS_API_URL | deployed se-api | API base | | SYNCEFFORTS_CLAUDE_CMD | claude | Claude CLI (reads prompt on stdin via -p) | | SYNCEFFORTS_AGENT | claude | which agent CLI to run: claude | antigravity | custom. Fixed once at startup — a running runner never switches agents (so existing Claude runners never change). | | SYNCEFFORTS_AGENT_MODEL | — | which model the chosen agent runs on (passed to the CLI's --model). Claude: an alias (opus/sonnet/haiku/fable) or full id; Antigravity: a name from agy models (e.g. "Gemini 3.1 Pro (High)") or a slug (gemini-3.5-flash); custom: whatever its model flag takes. Fixed once at startup like the agent. Blank ⇒ no flag ⇒ the CLI's own default (so an unset model keeps the Claude command byte-identical). | | SYNCEFFORTS_ANTIGRAVITY_CMD | agy | Antigravity CLI, ≥1.1.5 (prompt via stdin → headless print mode, --print-timeout 15m, --dangerously-skip-permissions to auto-approve implement jobs). Install + sign it in separately. | | SYNCEFFORTS_AGENT_MODEL_FLAG | --model | the custom adapter's model flag (used only when SYNCEFFORTS_AGENT_MODEL is set) | | SYNCEFFORTS_AGENT_CMD / _ARGS / _APPROVE_ARGS / _PROMPT (stdin|file|arg) | — | the custom adapter | | SYNCEFFORTS_REPO | current dir | repo dir for implement jobs (agent's cwd) | | SYNCEFFORTS_PERMISSION | bypassPermissions | Claude permission mode for implement jobs | | SYNCEFFORTS_POLL_MS | 5000 | poll interval | | SYNCEFFORTS_DRY | — | 1 = stub result, don't call the agent |

Multiple agents: one runner runs one agent. To use Claude and Antigravity, start a second runner with SYNCEFFORTS_AGENT=antigravity — the atomic job /claim lets them coexist. Which agents the app's Connect screen offers is a per-project toggle (Project Settings → AI Agents); it drives the generated command only, never a running runner.

Model choice (SE-038): a runner also fixes ONE model (SYNCEFFORTS_AGENT_MODEL) at startup, layered on the agent. The Connect surfaces (header popover, onboarding wizard, AgentGuide) offer a model dropdown per agent from a shared catalog (src/lib/agentModels.js) and append SYNCEFFORTS_AGENT_MODEL=… to the generated command; Project Settings → AI Agents sets the per-agent default the dropdowns pre-select. Blank = the CLI's default, so a runner started without it behaves exactly as before. To run the same agent on two different models, start two runners with different SYNCEFFORTS_AGENT_MODEL.

Documentation loop (keeps the knowledge base current)

Every prompt now carries project memory from /context — existing Knowledge docs (with ids), recent Decisions, and open Tasks — not just rules, so the agent works with institutional context instead of blind.

After a successful implement job, the runner runs a second, credit-free local-Claude pass that reviews the actual diff and records what changed via POST /projects/:id/document:

  • Knowledge — updates the relevant doc in place (by id), or creates one for a genuinely new area.
  • Decisions — appends one only when a real architectural/technical choice was made (context + decision + rejected alternatives).
  • Tasks — marks the linked task done / in-progress, or files a follow-up the work surfaced.

Everything is written to the project's Knowledge / Decisions / Tasks, attributed to the runner in the Activity feed, and appended to the job result as a 📚 Documentation updated section — fully editable or reversible in the app. The pass is conservative (empty change → nothing recorded).

Toggle: on by default; turn it off per project in Project settings → Modules → Auto-document (settings.modules.autodoc = false).

What it does per job

  1. GET /projects/:id/jobs?status=pending → for each, POST …/claim (atomic; skips if another runner grabbed it).
  2. Builds a prompt = the project's rules + project memory (knowledge/decisions/open tasks from /context) + the job's instruction + any referenced issue → runs Claude (in the repo for implement jobs).
  3. POST …/result with the Markdown output — plus, for implement jobs, the git change report and the documentation summary — (or …/fail on error). The app's Agents view shows it live; the result is attributed to this key's title.

The runner honors the operating contract: it works under the project's rules and records output as job results. It does not edit rules, and for implement jobs it does not commit/push on your behalf.