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

workspace-manager-cli

v1.2.2

Published

Cross-platform CLI to assemble project workspaces from shared core boilerplate plus custom folders

Readme

workspace-manager-cli

A cross-platform Node/TypeScript CLI that assembles a project workspace from a shared core boilerplate plus a project's custom folder.

Features

  • Smart caching: Clones core repositories to local cache (.wmc-cache/)
  • Update notifications: Shows when new commits are available with wmc status
  • Overlay system: Layer your custom code on top of core boilerplate
  • Cross-platform: Pure Node.js APIs, no shell dependencies
  • Automation-friendly: --json flag for machine-readable output

Quick Start

# Initialize cache and build workspace
wmc init --build

# Skip npm install after build
wmc init --build --no-install
# If not installed globally, use: npx workspace-manager-cli init --build

Installation

Global Installation

npm install -g workspace-manager-cli

Configuration

Run wmc init (or wmc init -i or wmc init --interactive) in a folder without a config and the CLI will generate workspace.config.json for you, prompting for project type plus core/base URLs. It also writes a minimal .gitignore covering the generated workspace and cache.

Example of a generated workspace.config.json (base-core-custom):

{
  "projectType": "base-core-custom",
  "base": {
    "name": "base",
    "url": "https://github.com/example/base.git",
    "ref": "main"
  },
  "core": {
    "name": "core",
    "url": "https://github.com/example/core.git",
    "ref": "main"
  },
  "custom": {
    "path": "custom"
  },
  "install": {
    "command": "npm install"
  }
}

Configuration Options

| Field | Type | Default | Description | | ----------------- | -------- | --------------- | ---------------------------------------------------------------------------------------------------------------- | | projectType | enum | required | One of core-custom, base-core, base-core-custom; determines which repos are required and how they overlay. | | base.name | string | _required* | Base repo name (cache dir). Required when the project type includes base. | | base.url | string | _required* | Git URL of base repo. | | base.ref | string | "main" | Branch/tag/commit for base. | | base.from | string | n/a | Set by wmc init to the friendly branch/tag if the input ref was a hash; otherwise matches the ref used. | | core.name | string | required | Core repo name (cache dir). | | core.url | string | _required** | Git URL of core repo (required for core-custom and base-core-custom; omit for base-core). | | core.path | string | "core" | Local path to core folder (only for base-core type). | | core.ref | string | "main" | Branch/tag/commit for core (only used when core.url is set). | | core.from | string | n/a | Set by wmc init to the friendly branch/tag if the input ref was a hash; otherwise matches the ref used. | | (fixed) workspace | string | "workspace" | The workspace directory is fixed to ./workspace and is not configurable | | custom.path | string | "custom" | Path to your custom code directory | | install.command | string | "npm install" | Command to run inside workspace after copying (skipped with --no-install) | | excludes | string[] | [] | Additional glob patterns to exclude when copying |

* Required when the selected projectType includes a base repository.
** Required for core-custom and base-core-custom; omit for base-core (use core.path instead).

Excludes & dry-run visibility 🛑

  • Use excludes to skip copying files or directories into the assembled workspace folder (./workspace).
  • Examples: excludes: ["**/*.log", "dist/**", "node_modules/**", "**/*.tmp"] will prevent matching files from being copied.
  • Use --dry-run (or --dry-run option) to preview actions — the build will add an action Excludes: <patterns> and log Effective excludes: ... so you can verify which globs will be applied before any copying occurs.

Project Types

  • core-custom: Remote core + local custom overlay (no base). Core is cached in .wmc-cache/<core> and copied to workspace; custom overlays into workspace/src/core/custom.
  • base-core: Remote base + local core folder. Base comes from cache; core is taken from a local path; custom is optional.
  • base-core-custom: Remote base + remote core + local custom. Both base and core are cached; core replaces base's core area; custom overlays on top.

Commands

init

Initialize repositories (core/base) by cloning to local cache, optionally build.

wmc init [options]

Options:

  • --ref <ref>: Override core ref (branch/tag/commit)
  • --base-ref <ref>: Override base ref
  • --core-latest: Checkout latest commit on core branch
  • --base-latest: Checkout latest commit on base branch
  • --interactive: Pick refs interactively (non-JSON mode)
  • --build: Build workspace after initialization
  • --no-install: Skip running npm install inside workspace (only applies when --build is used)

What it does:

  • Clones configured repos to .wmc-cache/<name> (behavior depends on project type):
    • core-custom: Clones core only
    • base-core: Clones base only (core is local)
    • base-core-custom: Clones both base and core
  • Checks out the chosen refs
  • Persists the resolved hashes/refs to workspace.config.json
    • If you pass a commit hash, wmc will try to resolve a friendly branch/tag and store it in base.from / core.from; otherwise it stores the ref you provided.
  • (Optional) Builds the workspace when --build is provided

build (alias: sync)

Build the workspace by assembling repositories and overlaying custom code based on project type.

wmc build [options]

Options:

  • --no-install: Skip running npm install inside workspace

  • --dry-run: Preview what will happen without actually making any changes. Useful for testing your config before committing to the build.

    Example:

    wmc build --dry-run

    What happens:

    • Reads your config and checks what files will be copied/excluded
    • Logs each action it would perform (copy, overlay, install, etc.)
    • Does NOT create or modify any files
    • Exits without touching workspace/ or running npm install

    Real-world scenario: You just updated your excludes list and want to verify the right files will be copied before actually running the build. Run wmc build --dry-run first to see the preview, then if it looks good, run wmc build to execute it.

What it does (varies by project type):

  • core-custom:

    1. Copy core from .wmc-cache/<core> to workspace
    2. Overlay custom/ into workspace/src/core/custom
    3. Run install.command in workspace
  • base-core:

    1. Copy base from .wmc-cache/<base> to workspace
    2. Copy local core from config.core.path to workspace/src/core
    3. Run install.command in workspace
  • base-core-custom:

    1. Copy base from .wmc-cache/<base> to workspace
    2. Copy core from .wmc-cache/<core> to workspace/src/core (replacing base's core)
    3. Overlay custom/ into workspace/src/core/custom
    4. Run install.command in workspace

status

Print current status of repositories and directories based on project type.

wmc status

Shows (varies by project type):

  • core-custom:

    • Core repo cache status (cloned, commit, branch)
    • Core ref/from (shows friendly branch/tag if initialized with a hash)
    • Core updates available (if any)
    • Custom directory uncommitted changes
  • base-core:

    • Base repo cache status (cloned, commit, branch)
    • Base ref/from (shows friendly branch/tag if initialized with a hash)
    • Base updates available (if any)
    • Local core directory location
    • Custom directory uncommitted changes (if applicable)
  • base-core-custom:

    • Base repo cache status (cloned, commit, branch)
    • Base ref/from (shows friendly branch/tag if initialized with a hash)
    • Base updates available (if any)
    • Core repo cache status (cloned, commit, branch)
    • Core ref/from (shows friendly branch/tag if initialized with a hash)
    • Core updates available (if any)
    • Custom directory uncommitted changes

Global Options

| Option | Description | | ----------- | ---------------------------------------------------- | | --json | Output machine-readable JSON (useful for automation) | | --version | Show version number | | --help | Show help |

What to Commit

Commit these:

  • workspace.config.json
  • custom/ directory (your custom code)

Don't commit:

  • workspace/ (generated)
  • .wmc-cache/ (local cache)
  • workspace/node_modules/ (dependencies)

How It Works

Core repository is cloned to a local cache directory and reused across builds:

  • Cache location: .wmc-cache/<name> (in project root)
  • Fast builds: Reuses cached repositories, only fetches when needed
  • Update notifications: wmc status shows when new commits are available

Workflow Diagram

graph TD
    A["wmc init --build"] --> B{Project Type?}
    B -->|core-custom| C["Clone core to<br/>.wmc-cache/"]
    B -->|base-core| D["Clone base to<br/>.wmc-cache/"]
    B -->|base-core-custom| E["Clone base & core<br/>to .wmc-cache/"]
    C --> F["Copy core →<br/>workspace/"]
    D --> G["Copy base →<br/>workspace/"]
    E --> H["Copy base →<br/>workspace/"]
    F --> I["Overlay custom/ →<br/>workspace/src/custom"]
    G --> J["Overlay local core →<br/>workspace/src/core"]
    H --> K["Copy ./wmc-cache/{core}/src/core →<br/>workspace/src/core"]
    I --> L["Run npm install"]
    J --> L
    K --> M["Overlay custom/ →<br/>workspace/src/core/custom"]
    M --> L
    L --> N["✅ Workspace Ready"]

Project Structure:

┌─────────────────────────────────────────────────────────────────┐
│  Your Project                                                   │
├─────────────────────────────────────────────────────────────────┤
│  workspace.config.json                                          │
│  custom/                                                        │
│  .wmc-cache/                ← Git repos cloned here             │
│    └── CORE-Project/                                          │
│        ├── .git/                                                │
│        └── src/                                                 │
│  workspace/ (generated)     ← Files copied here                 │
└─────────────────────────────────────────────────────────────────┘

Workflow:

# Developer A initializes and builds
wmc init --build            # Clones to local .wmc-cache and builds workspace

# Developer A commits their work
git add custom/ workspace.config.json
git commit -m "Add feature X"
git push

# Developer B pulls and builds
git pull
wmc init --build            # Populates their own .wmc-cache and rebuilds workspace
                            # Note: .wmc-cache is local per developer, not shared

# Check for updates
wmc status                  # Shows if new commits are available
wmc init --core-latest --build   # Fetch latest core, then rebuild

Note on sharing:

  • Each developer has their own .wmc-cache/ (not committed to git)
  • Developers share: workspace.config.json, custom/ folder, and core/ folder (if local)
  • After git pull, run wmc init --build to populate your local cache and rebuild workspace

Automation (not tested)

CI/CD Pipeline Example

# GitHub Actions example
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: "20"

      - name: Initialize core
        run: wmc init --json

      - name: Build workspace
        run: wmc build --json

      - name: Build project
        run: cd workspace && npm run build

JSON Output

Use --json for machine-readable output:

wmc status --json   # or: npx workspace-manager-cli status --json
{
  "command": "status",
  "config": { ... },
  "status": {
    "coreInitialized": true,
    "coreCommit": "abc123...",
    "customHasChanges": false
  }
}

Troubleshooting

"Could not find workspace.config.json"

Make sure you're running the CLI from a directory that has workspace.config.json or one of its parent directories.

"Core repository not found"

Run wmc init (or npx workspace-manager-cli init if not installed globally).

"Failed to checkout ref"

Ensure the ref (branch/tag/commit) exists in the core repository. Try:

wmc init --ref main --build   # or: npx workspace-manager-cli init --ref main --build

Build fails with permission errors

On Windows, ensure no processes are using files in the workspace directory.

License

MIT