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

pulltergeist

v0.2.0

Published

A supervised TypeScript agent factory with swappable Codex, Claude Code, OpenAI, and Anthropic backends.

Readme

Pulltergeist

A small TypeScript project for learning two related layers:

  1. An inner tool-calling loop where a model can inspect a task list and answer.
  2. An outer engineering loop that claims one code task, executes it in an isolated Git worktree, verifies it, retries within a fixed budget, and stops for review.

Providers

  • codex: Codex SDK using your existing ChatGPT/Codex login
  • claude-code: Claude Code CLI using your existing Claude Code login
  • openai: OpenAI API using OPENAI_API_KEY
  • anthropic: Anthropic API using ANTHROPIC_API_KEY

The Codex and Claude Code backends are coding-agent runtimes with filesystem and shell capabilities. The OpenAI and Anthropic backends currently run inside our smaller tool-calling runtime and only receive the read-only listTasks tool. They can power the task coach, but the engineering loop rejects them until we deliberately add bounded filesystem tools.

Setup

Requires Node.js 20 or later.

npm install
cp .env.example .env

For Codex, authenticate once:

codex login
codex login status

Do not copy or read credentials from ~/.codex/auth.json; the Codex CLI and SDK manage the session. For API providers, add the corresponding key to .env. Select the model explicitly for each invocation with --model.

For Claude Code, install version 2.1.169 or later and authenticate outside Pulltergeist:

claude update
claude auth login
claude auth status

Pulltergeist invokes claude -p directly and relies on that stored login. It does not read Claude credential files or require ANTHROPIC_API_KEY for the claude-code provider. API credential and cloud-provider override variables are removed from the child process so an API key configured for the separate anthropic provider cannot silently replace the stored CLI login. Set CLAUDE_CODE_EXECUTABLE only when the executable is not available as claude on PATH.

Local package consumption

Pulltergeist exposes its compiled public API for sibling local projects. A consumer can depend on the checkout without publishing it:

{
  "dependencies": {
    "pulltergeist": "file:../Pulltergeist"
  }
}

Build Pulltergeist before installing it into a local consumer:

npm run build

Consumers should import only from pulltergeist, never from Pulltergeist's src/ directory. Local installation uses the existing dist output and does not run lifecycle scripts in or modify the Pulltergeist checkout. The prepack script builds fresh output when creating a package archive.

Project initialization and doctor

Install Pulltergeist in an existing TypeScript project, then inspect the complete initialization plan. Initialization is a dry-run unless the exact displayed digest is supplied with --approve:

npm install --save-dev pulltergeist
npx pulltergeist init --provider codex --model gpt-5.6-sol
npx pulltergeist init --provider codex --model gpt-5.6-sol --approve <displayed-digest>
npx pulltergeist doctor

The approved initialization writes .pulltergeist/config.json atomically and idempotently reconciles the configured GitHub Project, repository link, coarse Status field, and setup labels. It does not create product issues, start engineering runs, commit, push, or open a pull request. doctor is read-only and checks the configured Node, package-manager, TypeScript, verification, Git, remote, and GitHub authentication prerequisites. Add .pulltergeist/runs/ to source-control ignores while retaining the versioned configuration.

Pulltergeist itself now carries the configuration generated through this workflow. Its local doctor report is the first self-hosting prerequisite; later roadmap commands will use the same file for issue refinement, durable runs, approvals, and source delivery.

Supervised issue creation

Refine one explicit requirement source against the current project and tracker evidence. The first invocation is read-only outside .pulltergeist/intake/: it prints the recommended small-review issue set and persists the exact digest-bound proposal locally.

npx pulltergeist issue create --file requirement.txt
npx pulltergeist issue create --stdin
npx pulltergeist issue create --clipboard

Review the complete proposal, then repeat the same source with its displayed digest:

npx pulltergeist issue create --file requirement.txt --approve <displayed-digest>

Durable criterion execution uses conservative defaults of three implementation invocations, 30 minutes elapsed time, and two repeated normalized failure signatures. Projects can override these ceilings with criterionExecution.maxImplementationInvocations, maxElapsedMs, and maxRepeatedFailureSignature in .pulltergeist/config.json. Exhaustion or regression failure retains the worktree and diagnostics and moves the run to needs-operator; it never authorizes cleanup or publication.

Approval is rejected if the requirement, repository baseline, relevant project evidence, or tracker evidence has changed. Approved creation uses stable hidden markers and lookup-before-create, so a retry resumes partial work without duplicating issues and fails closed on conflicting provider state. Add .pulltergeist/intake/ to source-control ignores; these local approval artifacts can contain the original requirement text.

Durable run control

Start one restart-safe durable run from an exact GitHub issue node identity in the configured repository. Supplying an idempotency key makes command redelivery resolve to the original run; when the key is omitted, Pulltergeist generates and displays one for reuse:

npx pulltergeist run start --issue <github-issue-node-id>
npx pulltergeist run start --issue <github-issue-node-id> --idempotency-key <key> --json

Run start requires the configured Git root at a clean committed baseline. It binds the exact issue revision, repository baseline, project policy, runtime profile, request evidence, and retained worktree. The invocation reservation is durable before request evidence or the worktree is created; retries reconcile the same run and never create a second worktree for an already committed launch. Human output identifies whether the run was started or reused, its run ID, issue URL, state, revision, and idempotency key. JSON output has this stable top-level shape:

{
  "created": true,
  "runId": "run-...",
  "idempotencyKey": "start:...",
  "state": "planning",
  "revision": 0,
  "issue": {
    "externalId": "I_...",
    "revisionDigest": "...",
    "url": "https://github.com/.../issues/..."
  }
}

Treat the idempotency key as the identity of the launch request. Retrying the same issue with the same key returns the original run. A different key means a different launch request and can create a different run; omission generates a new key, so retain the displayed value before retrying.

Inspect one durable run without acquiring its transaction lock or changing its aggregate, worktree, tracker, or repository:

npx pulltergeist run status --run <run-id>
npx pulltergeist run status --run <run-id> --json

Status reads the configured run-state root and reports the aggregate revision, durable state, next safe operator action, approvals, attempts, artifacts, external effects, worktree retention, and relevant failure or reconciliation reasons. Its next-action value is conservative: ambiguous effects, needs-operator, and an active interrupted implementation require operator disposition; approval boundaries require review; publication stages require reconciliation; terminal runs do not advertise another action. Missing, malformed, or unsafe state fails without invoking a model or performing recovery.

The JSON status contract includes schemaVersion, runId, state, revision, nextSafeAction, repository and tracker bindings, approvals, attempts, artifacts, retained-worktree data, external effects, and bounded diagnostic reasons. Human output presents the same safety-relevant state in a compact report.

Publish the run's coarse progress to its already-bound GitHub issue and Project item explicitly:

npx pulltergeist run sync --run <run-id>
npx pulltergeist run sync --run <run-id> --json

The command derives a bounded public projection, records the issue summary and Project status as separate durable effects, and reconciles them in that order. It resolves the Project item only from the run's bound project and issue identities. Redelivery reuses interrupted effects, skips confirmed mutations, and reports only safe effect identities and statuses; ambiguous, conflicting, or failed provider observations require operator disposition.

Request policy-governed GitHub auto-merge as a separate command:

npx pulltergeist merge enable-auto --run <run-id>
npx pulltergeist merge reconcile --run <run-id>

The command requires a confirmed published pull request and pushed head, evaluates the configured autoMerge policy against fresh GitHub check, approval, head, base, and mergeability evidence, then records and reconciles one idempotent merge effect. Disabled or unsatisfied policy creates no merge intent. Confirmed enablement stops at merge-queued; only later merge reconciliation may record the run as merged or publish Done status.

Resume exactly one durable execution boundary:

npx pulltergeist run resume --run <run-id>
npx pulltergeist run resume --run <run-id> --expected-revision <revision>
npx pulltergeist run resume --run <run-id> --expected-revision <revision> --json

--expected-revision is an optimistic-concurrency guard. Resume fails as stale unless the stored aggregate revision exactly matches it. Read the latest revision with run status; never blindly retry a stale command with the new revision without reviewing what advanced the run.

Each invocation acquires the run's exclusive lease, performs read-only recovery preflight, and may advance only the current boundary:

| Current state | One resume invocation | Stops at | | ------------------------- | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- | | planning | Creates and durably binds an implementation plan | awaiting-plan-approval | | acceptance-authoring | Authors and freezes acceptance evidence | awaiting-acceptance-approval | | red-verification | Runs the configured commands for the active criterion | implementing or regression-verification | | implementing | Invokes the implementer once for the active criterion | focused-verification | | focused-verification | Runs the configured focused boundary | implementing or regression-verification | | regression-verification | Records regression evidence and advances criterion progress | the next criterion's red-verification, implementing, or reviewing | | reviewing | Verifies plan, acceptance, criterion evidence, commands, and diff; invokes a read-only reviewer | awaiting-solution-approval |

The JSON result is the stage-specific durable receipt. Planning returns the verified plan and plan artifact. Acceptance authoring returns its suite hash and artifacts. Criterion execution returns completedStage, the new state and revision, active criterion when applicable, and verification evidence when a verifier ran. Review returns the review artifact identity and digest, reviewer decision, and review-solution as the next operator action.

Approval remains a separate explicit operation. Resume never infers plan, acceptance, or solution approval. Plan decisions are published as their own boundary-only commands:

npx pulltergeist approve plan --run <run-id> --reason "Plan reviewed" --actor <identity> \
  --expected-revision <revision> --artifact <artifact-id>:<sha256-digest> \
  --idempotency-key <stable-delivery-key>
npx pulltergeist reject plan <same-required-options> --json
npx pulltergeist request-revision plan <same-required-options>

The supplied artifact must exactly match the current durable plan. The command holds the exclusive run lease while checking revision, artifact bytes and digest, repository baseline, branch, and worktree. It records only the decision receipt and stops at acceptance-authoring, plan-rejected, or planning. Exact delivery-key replay returns the original receipt without another revision; changed payload or scope conflicts, and a new stale delivery fails. The receipt's complete actor, decision, reason, artifact, baseline, worktree, permitted-next-state, and command scope appear in both human and JSON output.

Acceptance decisions use the same required options and safety boundary, with one --artifact <id>:<digest> for the frozen suite followed by one for its manifest:

npx pulltergeist approve acceptance --run <run-id> --reason "Acceptance reviewed" \
  --actor <identity> --expected-revision <revision> \
  --artifact <suite-id>:<suite-digest> --artifact <manifest-id>:<manifest-digest> \
  --idempotency-key <stable-delivery-key>

Approve stops at the active criterion's red-verification; reject stops at acceptance-rejected; request revision stops at acceptance-authoring. Missing, additional, duplicate, reordered, or digest-substituted artifacts fail closed. Solution decision commands bind every successful verification artifact followed by the current review artifact with the same safety guarantees:

npx pulltergeist approve solution --run <run-id> --reason "Solution reviewed" \
  --actor <identity> --expected-revision <revision> \
  --artifact <verification-id>:<verification-digest> \
  --artifact <review-id>:<review-digest> --idempotency-key <stable-delivery-key>
npx pulltergeist reject solution <same-required-options> --json
npx pulltergeist request-revision solution <same-required-options>

Approve stops at publishing without pushing or opening a pull request; reject stops at solution-rejected; request revision stops at reviewing. The review artifact itself binds the review verdict, diff digest, and reviewed evidence identities. The same immutable evidence list is included in each governed commit, push, and draft-pull-request request digest. Missing, additional, substituted, or stale solution scope fails closed before an external effect is intended.

Resume fails closed when:

  • the expected revision is stale, the state is terminal, awaiting approval, or in publication;
  • the run, artifact, worktree, baseline, branch, tracker, policy, runtime, or configured command binding is missing, changed, unsafe, or ambiguous;
  • an external effect is unresolved or requires reconciliation;
  • an interrupted implementation may have changed durable work and needs operator disposition;
  • an approval does not exactly bind the required artifact set, baseline, worktree, and permitted next state.

Replayable planning, acceptance-authoring, verification, and review interruptions use new command and attempt identities. Pulltergeist never automatically replays an interrupted implementation. run resume does not publish, push, open a pull request, merge, mutate GitHub Projects, enable auto merge, deploy, or clean a retained worktree. Publication and cleanup require separately governed commands and evidence.

Durable orchestration evidence

Phase 2's recovery guarantees are backed by an exhaustive state and approval interruption matrix and file-backed fault tests for planning, acceptance authoring, criterion verification and implementation safety, and review, publication, and status. The exercised checkpoints cover immutable artifact persistence, aggregate commits, exact-scope decision redelivery, operator disposition for potentially mutating implementation, and reconciliation of commit, push, and draft-pull-request effects.

Every semantic agent invocation has a content-addressed execution profile, a normalized redacted runtime outcome, and stage-correlated durable evidence. These guarantees were delivered through semantic call-site profiles, runtime outcome capture, and durable evidence correlation.

Package evidence uses tracked-source production builds, proves dirty-checkout tarball isolation, installs the exact packed artifact into a fresh private TypeScript consumer, verifies package version, commit, and tarball provenance, and runs the installed durable workflow. This is a registry-equivalent package-manager and tarball boundary; it is not evidence of downloading from the public npm registry. The tests do not publish a package or perform external delivery.

Task-coach CLI

The original read-only example remains available. It reads data/tasks.json and recommends one task.

npm run dev -- --provider codex --model gpt-5.6-sol "What should I work on for 30 minutes?"
npm run dev -- --provider claude-code --model sonnet "Choose my next task"
npm run dev -- --provider openai --model gpt-5.6-sol "Choose my next task"
npm run dev -- --provider anthropic --model your-anthropic-model "Choose my next task"

ToolCallingRuntime is the inner model/tool loop for the API providers. Codex and Claude Code use their own built-in agent loops instead.

Engineering loop

The engineering loop processes at most one queued task per invocation:

queued -> claimed -> preparing -> executing -> verifying
                              |         |
                              |         +-> retrying -> executing
                              |
                              +------------> failed

verifying -> awaiting-approval

It never commits, merges, pushes, publishes, or deploys. Passing work stops at awaiting-approval, and the worktree is retained for inspection.

Prerequisite: initial commit

Git worktrees require a commit. Before the first engineering-loop run, create the project's initial commit yourself so you can review exactly what becomes the baseline:

git add .
git commit -m "Initialize agent provider MVP"

Queue a sample task

data/loop-tasks.json starts empty so running the loop cannot unexpectedly edit code. To try the supplied example, copy it into the active queue and review it:

cp data/loop-tasks.example.json data/loop-tasks.json

An engineering task defines the requested change, deterministic acceptance commands, and a retry limit:

{
  "id": "task-001",
  "prompt": "Add a test for invalid task importance without changing existing behavior.",
  "setupCommands": ["npm ci"],
  "acceptanceCommands": ["npm run typecheck", "npm test"],
  "maxAttempts": 2,
  "status": "queued",
  "attempts": 0
}

Setup and acceptance commands are trusted local configuration and are executed by your shell. Review them before queueing a task. Setup runs once in the fresh worktree; acceptance commands run independently after each agent attempt.

Run one task with the workspace-capable Codex runtime:

npm run loop -- --provider codex --model gpt-5.6-sol

Or use the authenticated Claude Code CLI runtime:

npm run loop -- --provider claude-code --model sonnet

Run artifacts are stored under .agent-runs/:

  • events.jsonl: timestamped lifecycle, agent, and verification events
  • worktrees/: isolated task worktrees retained for review

Task state is persisted back to data/loop-tasks.json. This first implementation supports one worker at a time; it does not yet provide cross-process locking.

Engineering change pipeline

runEngineeringChangePipeline accepts a requested improvement and coordinates a role-separated workflow against a target codebase:

request + target codebase -> read-only planner -> plan approval
                          -> acceptance-test author -> frozen suite approval
                          -> workspace-write implementer -> deterministic verifier
                          -> read-only reviewer -> awaiting human approval

Plans, acceptance manifests, and review verdicts are schema-validated. Every approved criterion must map to a behavioral test, and the acceptance directory is hashed before implementation. The pipeline checks the hash before and after verification so the implementer cannot silently weaken the approved suite. Approval callbacks remain explicit policy boundaries; the pipeline never publishes the result.

Planner, acceptance-test author, implementer, and reviewer are first-class semantic agents under src/agents. Each role owns its instructions, execution authority, and structured response protocol. The pipeline coordinates those agents and owns approvals, artifact integrity, verification, and terminal state.

The current command uses one explicitly selected provider and model for every role and performs one implementation pass. It does not yet support per-role provider, model, effort, or budget profiles; automatic remediation after failed verification or review; progress-aware escalation; or evaluated automatic routing. These are roadmap capabilities rather than implied behavior of the current CLI.

Engineering change command

The local command assembles the pipeline roles around one requested improvement and a clean target Git repository:

npm run change -- \
  --provider codex \
  --model gpt-5.6-sol \
  --target ../some-project \
  --verify 'npm run check' \
  'Add a read-only task recommendation agent.'

Pulltergeist creates and retains an isolated worktree, displays the proposed plan and acceptance manifest for explicit approval, runs each trusted --verify command, performs a read-only review, and stops at awaiting-approval. Verification commands run in the target worktree with PULLTERGEIST_TARGET_DIRECTORY and PULLTERGEIST_ACCEPTANCE_DIRECTORY available in their environment. Use those values when a command needs to exercise the external frozen acceptance suite.

The target must have at least one commit and a clean source checkout. Run artifacts are stored outside the target by default under a sibling .pulltergeist-runs directory; --run-root overrides that location. The command does not commit, merge, push, publish, deploy, or delete retained work. Choose --provider claude-code --model sonnet to run the same semantic roles through the authenticated Claude Code CLI instead.

Supervised factory intake

The factory command connects read-only issue intake to the engineering change pipeline. It lists eligible GitHub issues, asks the recommendation agent to rank them, re-reads the selected immutable issue identity to detect stale input, displays the recommendation and alternatives, and requires an explicit operator approval or rejection. Approval creates an engineering run; rejection creates no worktree or engineering run. Both decisions are retained with the issue snapshot and recommendation under the sibling *-intakes directory.

Issue titles, bodies, labels, and other tracker fields are treated as untrusted product input. They cannot select the target repository, model, verification commands, or approval policy. The command does not edit issues, labels, milestones, comments, or GitHub Project fields, and the downstream pipeline still stops at awaiting-approval before any commit, push, merge, or deployment. Directly displayed untrusted strings are stripped of terminal control, bidirectional-formatting, and invisible formatting characters before the operator is asked to approve them.

Create a token with read access to repository issues and export it as GITHUB_TOKEN. Obtain the repository's immutable node ID, then run:

export GITHUB_TOKEN=your-read-token
gh api repos/80sbabydev/Pulltergeist --jq .node_id

npm run factory -- \
  --provider codex \
  --model gpt-5.6-sol \
  --target . \
  --github-repository 80sbabydev/Pulltergeist \
  --github-repository-id R_REPOSITORY_NODE_ID \
  --operator your-github-login \
  --verify 'npm run check' \
  --required-label ready \
  'Recommend the smallest approved Pulltergeist improvement that is ready to implement.'

The target checkout must be clean before approving the recommendation because the engineering pipeline creates an isolated worktree from its current commit. The GitHub access performed by this command is read-only even when the supplied token has broader permissions.

Verification

npm run check

This runs formatting, linting, strict type checking, tests with coverage, and the production build.

Releasing to npm

Publishing is authorized by a GitHub Release rather than by every merge to main. Before the first automated release, configure pulltergeist on npm with a GitHub Actions trusted publisher using these exact values:

  • Organization or user: 80sbabydev
  • Repository: Pulltergeist
  • Workflow filename: release.yml
  • Allowed action: npm publish

Do not add an NPM_TOKEN repository secret. The release workflow uses a short-lived npm identity from GitHub Actions. After merging a version change to main, create and publish a GitHub Release whose tag exactly matches the package version:

gh release create v0.2.0 \
  --repo 80sbabydev/Pulltergeist \
  --target main \
  --generate-notes

GitHub creates the tag when the Release is published. The workflow checks out that exact tag, requires it to point to a commit on main, verifies that it matches package.json, runs the full quality gate, inspects the package contents, publishes through npm trusted publishing, and confirms the new registry version. Existing npm versions and prerelease versions are rejected.

Documentation

The Pulltergeist wiki contains the complete project documentation, including:

Structure

src/
├── agents/          # Semantic agent roles, instructions, authority, and response protocols
├── change/          # Request-to-change command parsing and run coordination
├── core/            # Provider-neutral contracts and capabilities
├── events/          # JSONL execution evidence
├── execution/       # Git worktree isolation
├── loop/            # Outer state machine, retry policy, and coordinator
├── queue/           # Persistent file-backed task queue
├── runtimes/        # Codex and API tool-calling adapters
├── tools/           # Capabilities offered to API-backed agents
├── verification/    # Independent acceptance-command runner
├── cli.ts           # Read-only task-coach trigger
├── change-cli.ts    # Interactive request-to-change trigger
└── loop-cli.ts      # One-task engineering-loop trigger

Good next experiments are a queue lock or SQLite store, structured cost and token events, a separate review agent, API-provider filesystem tools, and explicit CLI commands for approving or rejecting a verified task.