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

bb-plugin-global-workflows

v0.1.3

Published

Run bb workflows from any project, from a catalog outside the repo.

Downloads

608

Readme

bb-plugin-global-workflows

Run bb workflows from any project, from a catalog that lives outside every repo.

bb global-workflows list
bb global-workflows run review-gate --thread <id> --args '{"lane":"claude"}'

Or open any thread, click Global workflows in the thread header, and pick one.

Catalog default: <dataDir>/plugins/global-workflows/workflows/ (~/.bb/plugins/global-workflows/workflows/). Override with the catalogDir setting.

Screenshots

global-workflows

The workflow catalog panel inside a thread.

Install from source

npm install
bb plugin types        # regenerates types/ — gitignored, and stale types mislead
bb plugin build .
bb plugin install . --yes

Requires the builtin workflows plugin to be enabled. See the dependency note below.


Relationship to the builtin workflows plugin

This plugin does not replace, fork, or reimplement the builtin. It adds a catalog and a dispatch surface in front of it. The builtin still parses, validates, schedules, and executes every run, and owns all the durability: run records, resume, history, agent fan-out, the live progress card.

          this plugin                        builtin `workflows`
  ┌───────────────────────────┐      ┌──────────────────────────────┐
  │ catalog on disk           │      │ parse + validate meta        │
  │ meta pre-flight checks    │ ───▶ │ execute agents, phases       │
  │ thread-header UI + CLI    │      │ run records, resume, history │
  │ dispatch via threads.send │      │ progress card in the thread  │
  └───────────────────────────┘      └──────────────────────────────┘

The dependency is real, and undeclarable

The builtin workflows plugin is a hard runtime requirement. Disable it and this plugin's Run button does nothing useful: dispatch still sends the turn, but the target thread has no bb_workflow_run tool to answer it.

bb has no plugin dependency mechanism. Nothing in the plugin SDK expresses "requires plugin X" — PluginRpc* is a plugin's own frontend/backend channel, not a cross-plugin call. So the requirement cannot be declared in the manifest and is not enforced at load. It is documented here and nowhere else.

There is also no bb.sdk.workflows API. The plugin SDK cannot start a workflow run at all; every workflow symbol in the SDK types is for rendering provider workflow rows, not launching bb runs. That is why dispatch goes through bb.sdk.threads.send into a thread that has the agent tool, rather than calling a runner directly. It is not a workaround for something cleaner — it is the only supported path.

What overlaps, and which one wins

| Concern | Builtin | This plugin | | --- | --- | --- | | Where scripts live | <env>/.bb/workflows/*.js, per project, must be committed | one catalog dir, any project, no git needed | | Invocation | bb workflows run --name <n> inside a thread | bb global-workflows run <n>, or the thread-header panel | | Meta validation | at run time, after the thread takes a turn | pre-flight, before dispatch | | Execution | owns it | delegates | | Run records, resume, history | owns it | none of its own |

Both can be used side by side. A workflow committed at .bb/workflows/x.js stays reachable by name in its own project; the catalog is additive. Keeping the same workflow in both places is the one combination to avoid — two copies drift, which is the problem this plugin exists to remove.

Use bb workflows status|history|stop <run-id> for anything after dispatch. This plugin deliberately adds no commands there; they would be a thin shim over the builtin's, and a second way to ask the same question is a second way to be wrong.

Why a catalog is needed at all

resolveWorkflowSource in the builtin resolves against the thread's environment:

  • it throws when environment.projectId !== context.projectId
  • a named workflow reads from <environment.path>/.bb/workflows/<name>.js

So workflows are project-scoped, and more precisely environment-scoped. An isolated worktree checks out tracked files only, so an uncommitted workflow silently does not exist there — a file-not-found rather than anything that explains itself.

There is exactly one seam. resolveWorkflowSource returns early for mode.kind === "script", before the environment lookup and before the projectId check. A workflow passed as script text runs in any project. That early return is the entire basis for this plugin.

Verified: a workflow held only in this catalog dispatched from a leadsurface thread and returned {ok: true, echoed: {from: "leadsurface"}}.

Pre-flight checks

The catalog is read without executing anything — evaluating a file to list it would run arbitrary code every time the panel opens. A file that fails a check still lists, carrying its problem, because a workflow that silently vanishes is the failure mode this plugin exists to end. run refuses a workflow with a known problem, so the cost is not paid before the error is seen.

  • filename is lowercase kebab-case, max 64 chars (the runner's own ^[a-z][a-z0-9-]{0,63}$)
  • an export const meta block is present
  • meta.name matches the filename — otherwise the panel offers one name and runs another
  • meta carries only the five fields the runner allows: name, description, inputSchema, outputSchema, phases

That last one is worth its own line. bb's runner hardcodes that allow-list and throws Unknown meta field "..." before the script body runs, and the error does not name the file it came from. The Claude Code Workflow tool accepts a whenToUse key; bb's runner does not. This check exists because that near-miss cost a real run to discover.

Known limits

  • The header button uses an experimental slot. experimental_threadHeaderAction is bb's marker for an unstable surface and may be renamed or changed. The threadPanelAction registration is the stable one, and both open the same component — so if the header slot breaks, the panel is still reachable from the side panel's new-tab launcher. Do not collapse them into one.
  • Frontend changes need an app reload. bb plugin reload swaps the server side only; dist/app.js is picked up when the desktop app or browser tab reloads.
  • Single-host assumption. Dispatch tells the agent to read the catalog file by absolute path, which is exact where inlining a script into a prompt risks truncation. It assumes the thread's host can see the catalog directory. With one enrolled machine this is fine; with a remote execution machine the catalog would need to be readable there too.
  • No --name for catalog workflows. Inline script mode is what makes them global, so runs are recorded with a script origin rather than a name.
  • Catalog lives under the plugin data dir by default. bb plugin remove leaves local path sources alone, and I found no evidence it clears <dataDir>/plugins/<id>/ — but that is unverified. Point catalogDir at a git-tracked directory if the scripts matter.