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

@hudishkin/agit

v0.7.2

Published

A boring, reviewable handoff from a coding agent to a draft pull request

Readme

agit

One task. One worktree. One PR.

Agents work locally. You control what gets published.

Agit gives each coding-agent task its own worktree and turns finished local work into a draft pull request.

agit start AUTH-123
# open the printed path; the agent edits and commits with git
agit finish AUTH-123

finish is the handoff: checks, push, a draft PR. You run it. Later runs update the same PR.

Parallel agents

Run multiple coding agents without mixing their Git state.

agit start AUTH-123
agit start TESTS-124
agit start REFACTOR-125

agit status --all

Each start creates a worktree under the store (~/.agit/<project>/worktrees/<task-id> by default) on agit/<task-id>. The main checkout stays on the default branch. Each task keeps its own dirty tree, branch, and later draft PR. finish from the main checkout publishes only that task.

Install

Needs Node 20+ and git. finish also needs the host CLI for the configured pr.provider: GitHub CLI (gh) or GitLab CLI (glab). Set pr.provider: none to only push the branch.

npm i -g @hudishkin/agit

Or keep it in the repo:

npm i -D @hudishkin/agit
npx agit init --yes --checks "npm test"

init defaults to the home store: ~/.agit/<project>/ (profile, tasks, worktrees, logs). The working tree stays clean. The project id is {owner}-{name}-{hash} from the remote and the clone path. Override the parent directory with AGIT_HOME.

npx agit edit          # open this project's profile.yml

Store location is only an environment override: AGIT_HOME (parent directory, default ~/.agit) and AGIT_STORE=repo if you explicitly want .agit/ in the clone. An in-repo profile does not override the home store.

Editor skill

agit init asks which editor should get the skill (Cursor, Claude Code, or both) and whether to install it locally (this repository) or globally (this machine). The same answers can be passed as flags:

agit init --yes --editor cursor --skills global
agit init --yes --editor both --skills local

--yes without --editor / --skills skips the skill, so scripts stay non-interactive.

Manual copy still works:

# Cursor
mkdir -p ~/.cursor/skills/agit
cp AGIT.md ~/.cursor/skills/agit/SKILL.md

# Claude Code
mkdir -p ~/.claude/skills/agit
cp AGIT.md ~/.claude/skills/agit/SKILL.md

From a published install: cp "$(npm root -g)/@hudishkin/agit/AGIT.md" ~/.cursor/skills/agit/SKILL.md.

The skill tells the agent to use npx @hudishkin/agit. State stays in ~/.agit/<project>/. On first start it asks how to publish (default: always ask). Edit the profile with agit edit. If you say yes to finishing a task, you run agit finish.

Why this workflow

one task → one worktree → one branch → one PR

Give several coding agents several tasks and get several reviewable draft PRs — without creating worktrees by hand, remembering which agent is where, or publishing from the wrong tree.

The publish boundary

Local work and publishing are different trust boundaries.

Locally, the agent can edit, commit, rebase, and inspect history. Mistakes stay in that worktree.

Publishing — push, PR, CI, review, shared history — is a shared side effect. That path is agit finish, run by a human.

How it works

  1. agit start creates or resumes one worktree and one branch per task.
  2. The agent works there with normal local Git.
  3. You run agit finish.
  4. Local checks run.
  5. The branch is pushed.
  6. A draft PR is created or updated.
  7. A human reviews and merges.

Who this is for

A good fit if you regularly use Claude Code, Cursor, or another coding agent, let it commit, juggle more than one task, and want a separate reviewable PR per task.

A weak fit if one agent does one tiny change and you already review the diff and push yourself. Then Agit may be extra ceremony.

Hooks are first-class for Cursor and Claude Code. Other agents can still work in the task worktree; Copilot gets instruction files.

Why not just…

git worktree. Worktrees isolate a working tree. Agit is the lifecycle around them: task, branch, status, checks, publish handoff, draft PR.

Branch protection. GitHub/GitLab rulesets control what the host accepts. Agit does not create or manage them. Configure them on the host if you want that boundary.

Cursor / Claude permissions. Use them. Agit uses native guards where it can and adds one workflow above them: task → worktree → local work → finish → PR.

Keeping the workflow predictable

agit doctor reports what is actually on.

  1. Agent guards — Cursor beforeShellExecution and Claude Code PreToolUse call agit guard. In the default workflow, direct publishing is discouraged. In protocol, git mutations are redirected to agit.
  2. pre-push hook — a raw git push fails unless agit finish issued a one-use token. Works alongside husky.
  3. Agent OS sandbox (opt-in) — agit start --sandbox (or agit init --sandbox) sets workflow.sandbox: agents. agit start writes Cursor, Claude Code, and Codex sandbox configs, points origin at a local mirror, and locks git credentials in the task worktree. agit finish still pushes with host credentials from the main checkout. agit doctor probes the OS runtime, then the files. Fail-closed: missing runtime or insecure_none / danger-full-access is a failure. Cursor can still read ~/.ssh; GH_TOKEN in your shell is for finish, not for the agent worktree. Undo the mirror with agit doctor --undo-isolate.

finish never force-pushes. On conflict or rewritten history, it stops.

agit doctor             # confirm what is actually active

Commands

agit init [--finish ask|human|agent] [--sandbox] [--store home|repo]
          [--editor cursor|claude|both] [--skills local|global]
                            Prepare this project (default: home store)
agit start <task-id>        Create or resume a task worktree
agit start --finish ask     Save finish policy for this project (ask|human|agent)
agit start --sandbox        Enable agent sandboxes without re-running init
agit start --title --body --issue
                            Store PR title, body, and a GitHub issue
agit edit                   Open this project's profile.yml
agit finish <task-id>       Commit pending → checks → push → draft PR
agit finish --squash        Squash commits before the first push
agit finish --no-rebase     Skip rebase onto the default branch before the first push
agit status [task-id]       Task state
agit status --all           Every task: path, age, dirty, PR
agit abort <task-id>        Drop a local task and its branch
agit done <task-id>         Remove the local worktree after merge, or after a push with no PR
agit done <task-id> --merge [branch]  Merge into BRANCH, or a new branch named after the task, then remove it
agit done --stale           List stale worktrees (dry-run)
agit done --stale --apply   Delete stale worktrees and local branches
agit doctor                 Report environment, hooks, and sandbox status
agit doctor --fix           Reinstall the pre-push hook and agent guards
agit doctor --undo-isolate  Restore origin to the real remote (sandbox)

Every command accepts --json. Protocol enforcement still accepts agit commit; it is not shown in --help.

Configuration

agit edit opens this project's profile (~/.agit/<project>/profile.yml by default):

workflow:
  finish: ask             # default if omitted. ask | human | agent
                          # ask   → agent asks before each publish; you run agit finish
                          # human → do not ask each time; you publish from your terminal
                          # agent → agent asks, then may run agit finish
  sandbox: off            # agents = write Cursor/Claude/Codex sandbox configs on start

pr:
  provider: github        # github | gitlab | none
                          # github → gh pr create
                          # gitlab → glab mr create
                          # none → push the branch only

checks:
  - npm test
checks_timeout_sec: 900

commit:
  scope: all              # or explicit, to require agit commit --files

init --yes without --checks looks at the repo (package.json scripts.test, pytest, cargo, go) and writes what it finds. Existing non-empty checks are left alone.

Existing profiles without finish behave as ask. Existing profiles without enforcement stay on protocol. Existing profiles without sandbox stay off. Existing profiles without pr.provider stay on github. init writes gitlab when the remote URL looks like GitLab. Isolation lives in this clone's git config, not in the profile. init --sandbox is a flag, not a finish policy.

These profile keys are reserved and unused: one_push_policy, finish_mode, allow_direct_push, allow_force_push. Review-loop pushes after the first finish are allowed.

End-to-end

One agent, one PR. agit start AUTH-123 --title "Fix login" --issue 12. Work in the printed path. A human runs agit finish AUTH-123. Pending changes in the task worktree are committed first. Checks run, the branch is pushed, a draft PR opens with that title and Closes #12.

Two agents in parallel. agit start AUTH-123 and agit start TESTS-124. Each worktree has its own dirty tree. agit status --all shows both. agit finish from the main checkout publishes one task.

Review loop. After review comments, commit in the same worktree and run agit finish AUTH-123 again. It pushes to the same draft PR. It does not force-push. After the PR is merged, agit done AUTH-123 removes the local worktree and branch.

Troubleshooting

  • Checks failed. Read .agit/logs/<task-id>-checks.log, fix, run agit finish again.
  • Branch diverged after publish. agit never force-pushes. Reconcile locally or start a new task id.
  • gh or glab missing or not logged in. Push may have succeeded. Install and authenticate the CLI for pr.provider, then agit finish again to open the request. Or set pr.provider: none to skip that step. To drop the local worktree without opening a PR, run agit done <task-id> — the remote branch is left in place.
  • abort refuses. The worktree is dirty, or the task was already published. Commit/restore, or run agit done <task-id> if it was pushed without a PR.
  • PR merged. Run agit done <task-id> to remove the local worktree. finish and status hint this once GitHub/GitLab report merged.
  • Stale worktrees. agit abort drops one unpublished task. agit done drops a merged one, or one that was pushed with no PR. agit done --stale --apply clears the rest.

agit vs git worktree vs worktrunk

| | agit | git worktree | worktrunk | | --- | --- | --- | --- | | Isolate a working tree | yes | yes | yes | | One task → one branch → one draft PR | yes | no | no | | Local checks before publish | yes | no | optional | | Agent publish boundary | yes | no | no | | You still review and merge | yes | yes | yes |

Advanced workflows

New clones default to ask: the agent works with local git and asks whether to finish; you run agit finish. Pass --finish human or --finish agent on start (or init) to save a different policy for that project.

agit init --yes --mode protocol is a hidden legacy loop, where the agent also runs agit commit and agit finish.

Threat model

Agit is a workflow boundary. init --sandbox additionally configures vendor OS sandboxes (Cursor, Claude Code, Codex) and doctor fails if that runtime or those configs are missing.

Designed for accidental direct publishing, workflow drift, premature pushes, the wrong task or branch, and parallel-agent Git state conflicts.

Not designed for hostile processes, credential theft, unrestricted network attacks, or a compromised machine. Agent sandboxes do not hide ~/.ssh. Host GH_TOKEN stays in your shell for agit finish; the task worktree cannot use it for git.

Not a merge queue. Not a replacement for GitHub rulesets.

Name

The npm package is @hudishkin/agit; the binary is agit. If another agit is already on PATH, use npx agit.

License

MIT