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

@afshar7/toolkit

v1.3.2

Published

Portable development workspace recipes

Readme

@afshar7/toolkit

Toolkit creates portable workspace recipes: declarative manifests for reconstructing workspace structure, not backups of arbitrary local files.

toolkit scan
toolkit scan .
toolkit scan . --name my-workspace
toolkit scan . --name my-workspace --output ./my-workspace.workspace.json

toolkit setup
toolkit setup ./my-workspace.workspace.json
toolkit setup ./my-workspace.workspace.json --destination ~/work

toolkit doctor --workspace ./my-workspace.workspace.json

toolkit context init
toolkit context init --dry-run
toolkit context sync
toolkit context diff
toolkit context validate
toolkit context agents

toolkit agents status
toolkit agents update
toolkit agents publish coder
toolkit agents override coder
toolkit agents manage coder --yes

toolkit registry init
toolkit registry status
toolkit registry update

toolkit models list
toolkit models profiles
toolkit models configure
toolkit models use openai
toolkit models set coder
toolkit models status

toolkit plugins status
toolkit plugins install context-inspector
toolkit plugins install context-inspector --global
toolkit plugins update

scan is interactive by default. A supplied workspace, name, or output skips that prompt. It records a root Git repository when the workspace itself is a repository, otherwise discovers child Git repositories using relative paths. Every discovered remote is recorded; origin is selected for cloning when available, and Toolkit asks you to choose when multiple remotes exist without an origin.

Recipes also record package-manager lockfile hints, Node-version hints, and standalone structural or empty directories where applicable. Generated, sensitive, and machine-specific directories (such as .git, node_modules, .nuxt, dist, and IDE caches) are ignored.

Recipe names are portable single directory names: they may contain ordinary human-readable characters and spaces, but not path separators, absolute or drive-qualified paths, or ./... Git remote URLs must not embed HTTP(S) usernames, passwords, tokens, or credential-like query parameters. Use SSH (including normal addresses such as [email protected]:owner/repo.git) or a Git credential manager instead. Toolkit rejects an unsafe remote rather than stripping credentials and producing a recipe that may not authenticate.

setup is interactive by default; a supplied manifest or destination skips the matching prompt. It recreates declared directories and clones repositories without installing dependencies. Existing destinations are validated as matching Git repositories and skipped; non-matching repositories or other existing content are reported as conflicts and never overwritten. If the selected clone remote fails, interactive setup can retry another recorded remote and updates the recipe’s selection after a successful fallback clone. If a secondary remote cannot be configured, the successful clone is kept and the setup error names the repository and remote.

All planned project-relative writes are checked before content is created. Existing symbolic links or Windows junctions in a workspace path, agent destination, or context-backup path are rejected when they could redirect writes; target-file links are never overwritten. Explicit destinations remain user-selected roots, while children declared by a recipe must stay within the selected root. Toolkit rechecks paths near writes, but—as with ordinary filesystem tools—these checks do not claim complete protection against a privileged process racing filesystem changes.

doctor checks Git, Node, and recorded package managers. Node compatibility is checked only for exact major.minor.patch hints (with an optional v); ranges and major-only hints remain advisory.

context init creates an AGENTS.md entry point and a routed .ai/ Markdown context structure for the current workspace. Markdown context is authoritative: AGENTS.md selects a project, each local .ai/README.md selects the narrowest task route, and ongoing/README.md indexes only tasks that must persist across sessions. Existing files are kept by default and are replaced only after explicit approval with backups.

Run toolkit context init without arguments for a preflight plan and interactive conflict choices. Existing files can be kept while missing files are created, reviewed individually, or explicitly replaced with timestamped backups. Generated Markdown carries a small ownership hash so context sync can distinguish an unchanged Toolkit file from one edited by a person. Use context sync to update unmodified Toolkit-managed files and context diff or --dry-run to preview without writing.

For new workspaces in scripts, supply the destination and all context flags with --non-interactive; sync and diff can infer values from an existing generated router. Conflicts abort by default. Select --on-conflict=skip to keep existing files or --on-conflict=replace --backup to replace them safely. Supported policies are abort, skip, replace, and prompt; prompt is interactive only.

context validate checks that the Markdown context entry point and referenced structure are present without changing files. context agents creates the currently bundled personal OpenCode agent files in either the workspace or global OpenCode agents directory, also without overwriting existing files.

The generated structure includes shared workspace guidance under .ai/, project guidance under .ai/projects/, project-local indexes, an indexed ongoing/ directory for each active project, and a shared technical-debt/ directory. Project, ongoing-task, and technical-debt records are intentionally maintained in Markdown; Toolkit does not infer or rewrite them after initialization.

Technical debt

technical-debt/README.md indexes unresolved engineering debt across the workspace. Copy technical-debt/TEMPLATE.md to a descriptive filename and add it to the index. Record the problem, dated evidence and affected scope, impact, migration constraints, completion criteria, and verification. Keep project-specific debt scoped inside its record; do not duplicate the index in every project.

Debt is deferred work, not cross-session task state or an instruction to start a migration. Use project-local ongoing/ for active work, and read only debt records relevant to the current task. Update the record and index when debt is resolved or its disposition changes. The scaffold follows a custom shared context path when one is selected, and existing records retain the normal preservation and explicit-replacement protections.

Model management

Install/authenticate OpenCode with your preferred provider, install Toolkit-managed agents with toolkit agents update, then run toolkit models configure to create or edit a named profile. The wizard searches the exact model IDs exposed by opencode models; it does not assume a model's vendor from the provider name. Create profiles named openai and anthropic with your chosen models, then switch:

toolkit models use openai
toolkit models use anthropic
toolkit models set coder cpa-gui/gpt-6.1-sol --non-interactive
toolkit models use openai --dry-run --non-interactive
toolkit models list --provider cpa-gui --search sonnet --json
toolkit models status --json
toolkit models doctor --json

Profile names are user-defined, not built-in provider presets. models set updates only the selected agent in the active profile, after safe application succeeds. Omit its model argument to open a searchable selector. Read-only profile listing and status work without OpenCode installed. Use --destination <project> for a project or --global for the global OpenCode scope, never both. models doctor adds read-only discovery diagnostics for missing/ambiguous models, stale ownership and recovery warnings. It does not make inference requests; warnings or failed discovery produce a nonzero exit code. Provider stderr is withheld to avoid leaking credentials; inspect provider errors locally with opencode models.

A preference is portable intent, a resolution is an exact model ID selected on this machine, and an applied assignment is OpenCode configuration. These are not proof of runtime inference availability. Protected assignments need explicit per-agent consent; legacy managed Markdown models need approved staged migration. Existing sessions may require a new OpenCode session to use changed configuration. See model management and integration for command details, proxy suffix handling, ownership, and recovery.

Canonical agents

Project agents remain the default. Use --global on agents status, update, override, manage, or publish to select OpenCode's global Markdown definitions:

toolkit agents status --global
toolkit agents update --global
toolkit agents publish coder --global --dry-run
toolkit agents override coder --global
toolkit agents manage coder --global --yes

Global agents live in $XDG_CONFIG_HOME/opencode/agents when XDG_CONFIG_HOME is nonempty and absolute, otherwise ~/.config/opencode/agents on all platforms. Global ownership is stored separately in that config directory's .toolkit/agents.json; project ownership is unchanged. Global status is offline and never creates a missing config directory; update safely creates it. --global cannot be combined with an explicit destination (including the positional directory on status/update). Global files follow the same hash, collision, override, explicit replacement, and publication-baseline rules as project files. After publication reconciliation fails, use toolkit agents update --global, and if needed toolkit agents manage NAME --global --yes, not a project update.

Canonical definitions live under agents/, with their membership and human-readable set version in agents/manifest.json. The current registry includes lead, coder, researcher, and external-researcher, but the manifest can add or remove names over time. Agent definitions have a lifecycle independent from the npm CLI:

GitHub Afshar07/toolkit/agents
              ↓ sparse Git checkout
      ~/.toolkit/registry/agents
              ↓ safe synchronization
       project/.opencode/agents

The user data path is resolved with Node's platform APIs, so the conceptual ~/.toolkit/registry location works on Linux and Windows. Every project on a machine consumes this one local registry; projects are not separate Toolkit clones. The npm package still contains bundled definitions as an explicit bootstrap/offline fallback.

From a project root, inspect and apply agent updates with:

toolkit agents status
toolkit agents update

agents status is entirely local and offline. It compares the project with the machine registry immediately and never fetches from GitHub. If the Git registry has not been initialized, status clearly identifies the bundled fallback and points to registry init or agents update.

agents update is the normal convenience workflow. It lazily initializes the sparse registry when needed, otherwise performs a clean fast-forward-only Git update, validates agents/manifest.json, and then runs the existing safe project synchronization. If the remote is unavailable but the existing registry is valid and clean, Toolkit warns and uses its existing commit. If first-time initialization cannot reach GitHub, Toolkit warns and uses the bundled definitions. A dirty, invalid, or diverged registry stops the update and is never reset, merged, rebased, deleted, or silently replaced.

For explicit registry management:

toolkit registry init     # create and validate the sparse checkout
toolkit registry status   # local/offline path, version, commit, branch, cleanliness
toolkit registry update   # require a clean tree and fast-forward only

The registry is a distribution cache, not an editing checkout. To share an improvement from the project where it was developed, publish that one canonical agent through a temporary authoring checkout:

$EDITOR .opencode/agents/coder.md
toolkit agents publish coder

To publish all canonical agents together, use toolkit agents publish --all (or --all --global for global OpenCode definitions). Select exactly one of a name or --all. Membership comes from the upstream agents/manifest.json, not local filenames. Every selected file must exist and pass ownership and conflict checks before the combined diff and single confirmation. Only changed definitions are committed, with one version bump and normal push; unchanged files and unrelated local agents are not reconciled. --include-override and --allow-unmanaged apply to every selected agent without bypassing stale baselines. Before any local reconciliation, all changed files are rechecked for edits made during publication. A post-push failure may leave local synchronization partial; it does not roll back the remote publication.

Publication writes to the actual Toolkit source repository's default branch; it never authors in ~/.toolkit/registry. It requires Git read and direct-push access using the user's existing credentials, but no npm token or npm release. Use --dry-run for the upstream diff and proposed version without persistent changes, or --yes to confirm in a non-interactive environment. --destination selects another project directory.

Canonical agent definitions are LF text. Publishing converts only CRLF line endings to LF, preserving all other content and trailing-newline behavior; an agent differing from upstream only by CRLF versus LF has no shared change to publish. After an actual publication, Toolkit verifies that the project file did not change during the operation, installs the published LF bytes locally, and records the hash of those exact installed bytes.

Then, on another computer and inside any project, run:

toolkit agents update

The latest definition is fetched and distributed with the same ownership-hash protections. No npm publication or CLI update is required for agent-only changes; changes to Toolkit code under src/ still require a normal npm CLI release.

Publishing refuses a stale managed baseline when the same shared agent changed; run toolkit agents update, reconcile that agent, and retry. Changes to other shared agents do not conflict. An override requires --include-override (and is returned to Toolkit management after success), while an unowned canonical-name file requires --allow-unmanaged. These acknowledgements never bypass a known stale baseline. Protected-branch or permission push failures are reported and never force-pushed or converted into an automatic pull request.

If the remote push succeeds but registry refresh or ownership recording fails, Toolkit reports “published successfully; local synchronization incomplete.” Do not publish again: run toolkit agents update to refresh distribution state, then use toolkit agents manage NAME --yes only if ownership still needs repair.

New temporary authoring checkouts and machine registries explicitly disable Git checkout line-ending conversion. Existing clean registries created with core.autocrlf=true remain supported without a destructive rewrite: Toolkit interprets their validated canonical files as LF and deliberately converts eligible unchanged project agents through the normal synchronization flow. Dirty or diverged registries remain refused. If an existing registry cannot be safely refreshed, preserve it and resolve the reported Git state before running toolkit agents update; do not reset or edit the registry as an authoring clone.

The first update installs missing canonical agents and records their content hashes in .toolkit/agents.json. Later updates replace a managed file only when its current hash proves it is still the version Toolkit installed. Version labels make status output easier to understand, but hashes are the authoritative ownership and modification check.

Commit .toolkit/agents.json with the project so its managed and overridden ownership choices are consistent for everyone using that checkout.

Agent files fall into three categories:

  • Managed: installed and tracked by Toolkit. Unchanged files can be updated or restored when missing.
  • Local: files without Toolkit ownership metadata. Toolkit reports ordinary local agents and never modifies or deletes them. A pre-existing file such as lead.md is also preserved rather than claimed merely because its name matches a canonical agent.
  • Overrides: canonical names intentionally assigned to the project. Toolkit leaves their files untouched during updates.

Toolkit therefore does not own everything in .opencode/agents/. A project can mix Toolkit-managed and project-local agents, for example:

.opencode/agents/
├── lead.md                   Toolkit-managed
├── coder.md                  Toolkit-managed
├── migration-specialist.md   project-local
└── backend-reviewer.md        project-local

Updates ignore the project-local files. If a future canonical registry contains the same name, Toolkit reports an unmanaged collision instead of claiming or overwriting the file.

If a managed file was edited locally, agents status reports it as locally modified. agents update preserves it by default. In an interactive terminal, Toolkit offers to keep it, show a diff, or explicitly use the canonical version; --non-interactive always takes the safe path and reports the conflict.

To specialize a canonical agent for one project, record an override before or after editing it:

toolkit agents override coder
$EDITOR .opencode/agents/coder.md

To discard the project version and return it to Toolkit management, use:

toolkit agents manage coder --yes

This command intentionally replaces coder.md with the canonical definition and records its new ownership hash. Without --yes, a non-interactive invocation refuses to make that destructive ownership change.

OpenCode plugins

toolkit plugins installs OpenCode plugins that Toolkit knows about (currently context-inspector, from Afshar07/oc-context-inspector). A plugin cannot ship through npm here: OpenCode compiles a plugin's .tsx only outside node_modules, so it has to sit on disk as source and be listed in opencode.jsonc.

plugin Git repository (sparse checkout)
              ↓ fast-forward-only refresh
~/.toolkit/plugins/NAME           one checkout per plugin per machine
              ↓ copy with ownership hashes
project/.toolkit/plugins/NAME     or <OpenCode config>/.toolkit/plugins/NAME with --global
              ↓
opencode.jsonc  "plugins": [{ "package": "./.toolkit/plugins/NAME" }]
toolkit plugins status [NAME] [--global]     # offline; never contacts a remote
toolkit plugins install NAME [--global]      # fetch, copy, add the config entry
toolkit plugins update [NAME] [--global]     # refresh installed plugins; config untouched
  • Two scopes. Project installs live under .toolkit/plugins/ (Toolkit's own directory, not one OpenCode scans) and are listed with a relative path, so opencode.jsonc and .toolkit/ can be committed and work on every machine after toolkit plugins update. Global installs go beside the global OpenCode config with an absolute path. Ownership is tracked separately in .toolkit/plugins.json, like agents. Commit the project's copy.
  • The config edit is minimal. Toolkit appends one entry to plugins, keeping comments, formatting and every other entry. An entry you wrote for the same path is left as it is. A config that does not parse is never rewritten. update does not touch the config.
  • Ownership is by content hash. A file is replaced only when it is absent, already matches, or still matches what Toolkit installed. If any file was edited locally, or files exist that Toolkit never installed, nothing is written and the conflicts are listed. Files an update no longer provides are removed only when unmodified.
  • Project installs also append the plugin's runtime data directory (for context-inspector, .opencode/context-inspector) to .gitignore.
  • Offline and failure. A valid local checkout is used with a warning when the remote is unreachable; a dirty or diverged checkout stops the update. There is no bundled fallback, so the first install needs Git access to the plugin repository.
  • toolkit context init offers the plugin interactively after creating context (default: not now). A failed install there only warns.

Release verification

Run npm run verify before release. It compiles TypeScript, runs the fast domain suite and real local-Git integration tests, exercises the compiled CLI, packs the actual npm artifact, installs it into a temporary consumer, and verifies both the public API and bundled-agent fallback. Automated tests use temporary local bare remotes and never depend on GitHub or the user's Toolkit home.

Publication coverage is split into three sequential eight-test files with separate fixture cleanup. Each file lazily builds one immutable author/bare-remote seed; each test recursively copies both repositories (no shared links or object stores) and retargets its author's origin. Registry initialization, Git environment, and project ownership remain per-test. After-each cleanup removes only test fixtures; after-all disposal waits for seed setup and removes the separate seed root, even after setup failure. Focused lifecycle tests cover copy isolation and disposal. Release Verify keeps npm run verify on Ubuntu; Windows runs npm run build followed by npm test -- --maxWorkers=2 --minWorkers=2, preserving the complete gate while allowing two files to run concurrently. This is a bounded performance experiment, not a validated Windows speedup: baseline run 37037832998 took 141.5s for Windows tests (74.2s for publication), versus 4.6s for Ubuntu publication. Compare subsequent Windows runs before tuning further; Linux timings do not establish a Windows improvement. A subsequent Windows run took 104.28s for tests, with approximately 46s of publication setup and 1.2s of cleanup. Seed reuse trades repeated Git initialization/commits for filesystem copies; its Windows speedup remains unverified. Once these changes are pushed, manually run Release Verify from GitHub Actions to benchmark them without bumping a version. Manual runs do not qualify for the release gate, which still requires an exact-commit push run.

Set TOOLKIT_TEST_TIMINGS=1 to print test-only, per-file aggregate counts and elapsed milliseconds for helper Git commands, publication fixture setup/cleanup, and seed build/copy/cleanup (enabled in Release Verify's Windows test step). No arguments, output, paths, or fixture contents are logged. Production Git operations are not instrumented; setup totals include their time, and aggregate durations overlap with seed build/copy and the measured helper commands rather than summing to wall-clock time. Seed disposal is separate from after-each cleanup.

GitHub Actions runs Verify on Ubuntu for pull requests and pushes to main, except when all changed files are under agents/. Mixed changes still run Ubuntu verification. Feature-branch pushes do not start a duplicate push run, and superseded pull-request verification is cancelled. If branch protection requires Verify checks, path-filtered pull requests can remain blocked with pending checks; configure those rules to accommodate agent-only updates.

Release Verify (.github/workflows/release-verify.yml) runs the full Ubuntu/Windows matrix on pushes to main that change package.json or package-lock.json, including version bumps and dependency changes. It never cancels in-progress runs and does not run on pull requests; do not require it as a PR check. Releases require this successful complete workflow for the exact tagged commit's default-branch push. Ordinary Verify success alone, or an agent-only commit without Release Verify, cannot qualify for npm publication.

Publishing a release

npm run release             # patch bump (default)
npm run release -- minor    # or major
npm run release -- --resume # retry current version/HEAD without another bump

Run from a clean checkout (including untracked files) on the GitHub default branch, with Git, npm, and authenticated gh available, Git push credentials, and GitHub write permission. Both origin URLs must identify that GitHub repository. No local npm login or publish token is needed.

The script pulls fast-forward only, bumps package.json and package-lock.json, commits only those files, and normally pushes the default branch. It waits up to 15 minutes for the latest exact-commit default-branch push Release Verify attempt to succeed before creating an annotated version tag and a generated-notes GitHub Release. Failed/cancelled/skipped verification stops immediately with a run URL and log command. No force push, tag movement, stash, reset, or rollback is used.

After a partial failure, follow the printed recovery instructions and use --resume with the same version and HEAD. If the bump was not committed, first inspect and finish that version commit. Resume accepts matching existing tags (including remote-only tags) and published releases, but refuses tag conflicts or draft releases; explicitly publish an existing draft in GitHub. If npm publication later fails, rerun Publish rather than creating another release.

The GitHub publication pipeline remains:

  1. The released version and its lockfile entry are committed on the default branch.
  2. A GitHub Release uses the matching tag, such as v1.1.0 for version 1.1.0.
  3. Publishing the release triggers .github/workflows/publish.yml. It resolves annotated or lightweight tags to a commit, requires that commit in main's history, and waits (for a bounded period) for the latest exact-SHA Release Verify push run. Missing, failed, cancelled, skipped, or timed-out verification stops publication. After the qualifying verification is available, re-run the failed Publish workflow from GitHub Actions rather than moving the tag.
  4. A preparation job validates the tag against package.json, builds, and packs that exact checkout. A separate OIDC-enabled job downloads the immutable workflow artifact and publishes that tarball without rebuilding it or running package lifecycle scripts.
  5. npm authenticates the publish through Trusted Publishing (OIDC); no npm publishing token or automated OTP is used.

Before the first release, configure the package's trusted publisher on npm with these GitHub Actions settings:

GitHub owner: Afshar07
Repository:   toolkit
Workflow:     publish.yml

This npm-side configuration is an external setup step and cannot be established by committing the workflow. Keep npm account 2FA enabled and do not create an NPM_TOKEN for this workflow.

The source repository is private while @afshar7/toolkit is public. Treat every file selected by package.json#files as public: the package contains only the compiled dist/ output and bundled agents/, not .ai context, tests, Git metadata, workspace recipes, or local credentials. The workflow does not claim npm provenance from the private repository. Administrators must separately configure the npm trusted publisher, keep account 2FA enabled, and enforce the desired GitHub default-branch and tag/release protections; workflows cannot prove those external settings exist.