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

workler

v0.1.3

Published

Local workspace manager with copy/link rules for untracked project files.

Downloads

494

Readme

workler

First version of a local workspace manager.

Workler does not use git worktree. It creates normal local clones under .worktrees/ and then applies local file rules from .workler.

📖 Full documentation: yjjosh.github.io/Workler

Config

.workler is line-based, like .gitignore but with an action first:

# full-line comment
link node_modules   # inline comment
copy .env
copy "some folder/file.txt"
copy 'another file.txt'
  • link <path> creates a symlink in the workspace back to the main project.
  • copy <path> copies the file/folder into the workspace.
  • Blank lines are ignored. A # at the start of a line or preceded by whitespace starts a comment; a # inside a quoted path (or glued to a word, like file#1.txt) does not.
  • Quote a path with double or single quotes if it contains spaces or #.
  • Paths must stay inside the project: absolute paths, .., .git, and .worktrees are rejected. Parse errors report the line, column, and the offending line content.

Install

npm install -g workler
workler help

Commands

workler init
workler add <name> [base] [--branch <branch>] [--checkout <ref>] [--force] [--dry-run]
workler apply [name] [--force] [--dry-run]
workler apply --all
workler list
workler path <name>
workler remove <name>

workler add branch behavior

| Command | Result | | --- | --- | | workler add feat | Creates a new branch feat from the main project's current HEAD and checks it out. | | workler add feat main | Creates a new branch feat starting at main. <base> may be a local branch, a remote branch (e.g. origin/main), a tag, or a commit. A remote-branch base also sets upstream tracking. | | workler add exp --branch feat/x | Workspace named exp, branch named feat/x. Creates feat/x from HEAD if it does not exist, otherwise checks it out. | | workler add exp main --branch feat/x | Creates the explicitly named branch feat/x from main. This is useful when the workspace name must be filesystem-safe but the branch contains /. | | workler add hotfix --checkout main | No new branch: checks out main directly. Tags/commits are checked out on a detached HEAD. This is the supported way to have several workspaces on the same branch. |

Rules:

  • --checkout cannot be combined with --branch or positional [base]. [base] may be combined with --branch to create that explicitly named branch from the base.
  • workler add <name> / workler add <name> <base> always create a new branch and fail if branch <name> already exists; use --checkout <name> to reuse the existing branch.
  • workler add also accepts --force and --dry-run; see the next section.

Safety, --force, and --dry-run

add and apply never overwrite an existing destination by default. A symlink that already points at the right source counts as "already linked", and a copy whose destination matches the source counts as up to date; both are reported as ok and left alone. Anything else (a symlink pointing elsewhere, a regular file, or a directory) is a conflict, and the error shows both the source and the destination along with what is currently there:

cannot link node_modules: destination already exists
  source:      /path/to/project/node_modules
  destination: /path/to/project/.worktrees/feature-a/node_modules (existing directory)
re-run with --force to replace the destination
  • --dry-run prints exactly what would be copied, linked, skipped, replaced, or conflicted without changing anything. For add, no clone is created; the whole plan (clone, branch, rules) is printed instead.
  • --force replaces conflicting destinations and reports what was replaced.

Multi-workspace commands

Because every workspace is an independent clone, each one has its own fetch/pull state and its own local branches. These commands operate on the main project and all workspaces at once:

workler status
workler fetch
workler sync
workler branch-sync
  • workler status prints one line per workspace: current branch (or detached SHA), ahead/behind vs its upstream, and clean/dirty. Directories under .worktrees/ that are not usable clones are flagged as broken.
  • workler fetch runs git fetch --prune origin in the main project and every workspace. Workspaces without an origin remote are skipped with a note.
  • workler sync fetches everything, then fast-forwards each workspace's current branch where an upstream exists. Workspaces with uncommitted changes to tracked files are never touched (untracked files, such as the ones created by copy rules, do not block a sync), and branches that have diverged from their upstream are reported as diverged, skipped — nothing is ever merged, rebased, or forced.
  • workler branch-sync syncs local branches across clones:
    • ensures every workspace has a workler-root remote pointing at the main project (added even when there is no origin, fixed if the URL is wrong)
    • creates the root's local branches in each workspace, and fast-forwards branches that are strictly behind the root
    • never moves the branch currently checked out in a workspace, and never moves a branch with local-only or diverged commits (skipped with a note)
    • mirrors each workspace's local branches back into the root as read-only refs under refs/workler/<workspace>/<branch> (inspect them with git for-each-ref refs/workler/); no local branches are created in the root

Build locally with:

npm run build

For development, link it as workler:

npm install
npm link
workler help

Or run without linking:

npm run dev -- help

Programmatic API

Workler is also a library: tools can create, list, and remove workspaces without shelling out or parsing console text. The CLI and the API share the same core.

import { initProject, createWorkspace, listWorkspaces, removeWorkspace } from "workler";

const root = "/path/to/project";

initProject(root);
const ws = createWorkspace(root, { name: "agent-1" }); // same semantics as `workler add agent-1`
console.log(ws.path, ws.branch, ws.head);

for (const info of listWorkspaces(root)) {
  console.log(info.name, info.branch ?? info.shortHead, info.clean, info.broken ?? "ok");
}

removeWorkspace(root, "agent-1", { force: true }); // dirty protection unless force
  • Every function takes an explicit project root — nothing reads process.cwd() or mutates global state. Use findWorklerRoot(startDir) if you want CLI-style discovery.
  • Failures throw WorklerError with a stable code (NOT_INITIALIZED, WORKSPACE_EXISTS, WORKSPACE_DIRTY, BRANCH_EXISTS, BAD_REF, RULE_CONFLICT, SETUP_FAILED, LOCKED, …) and the same message the CLI prints.
  • Mutating operations (initProject, createWorkspace, removeWorkspace) hold a per-project lock file at .worktrees/.workler.lock for their duration. A held lock fails fast with LockError; a lock whose holder is provably dead (same host, pid gone, or unreadable file) is reclaimed automatically, and a lock from another host never is.
  • inspectProject(root), planWorkspaceCreation(root, options), and resolveWorkspacePath(root, name) cover inspection without side effects.

See the API reference for the full contract.

Nested workspaces (subagents)

Workspaces are ordinary clones, so workler also works inside them. Running workler add inside a managed workspace creates the new workspace under that workspace's own .worktrees/ — useful when you work on multiple features and each feature workspace needs more checkouts, e.g. one per subagent:

project/
  .worktrees/
    feature-a/
      .worktrees/
        agent-1/
        agent-2/

How it behaves at the nested level:

  • Every command operates on the nearest enclosing workler project: list, path, remove, apply, and add run inside feature-a only see feature-a's own workspaces.
  • Rules for nested workspaces come from the .workler checked out in the workspace, so commit .workler if nested workspaces should inherit the rules.
  • link targets resolve to the immediate parent: agent-1/node_modules links to feature-a/node_modules, which may itself be a link back to the root.
  • Bare workler apply inside a workspace refreshes it from its immediate parent.
  • workler.root in each clone points at its immediate parent; nesting depth is unlimited.

Shell switching helper

A CLI cannot directly cd your current shell, so load the helper:

eval "$(workler shell-init)"

Then switch with:

wcd main
wcd feature-a

Project structure

src/index.ts            programmatic API entry point (package main)
src/cli.ts              CLI entry point
src/commands/           command implementations (thin wrappers over src/core)
src/core/               core operations shared by CLI and API
src/config.ts           .workler parser
src/rules.ts            copy/link rule application
src/workspaces.ts       root/workspace discovery
src/lock.ts             per-project lock for mutating operations
src/errors.ts           structured WorklerError/LockError
src/git.ts              git command helpers
src/fs-utils.ts         filesystem helpers
test/                   node:test suite (`npm test`)