@miragon/bpmn-iq-agent
v0.7.0
Published
Per-developer CLI that syncs a directory of `.bpmn` files with the daemon. Two-way: chokidar watches local edits and pushes them; an SSE stream from the daemon mirrors remote changes back to disk so multiple developers on the same `repositoryId` stay in l
Readme
bpmn-iq agent
Per-developer CLI that syncs a directory of .bpmn files with the daemon.
Two-way: chokidar watches local edits and pushes them; an SSE stream from
the daemon mirrors remote changes back to disk so multiple developers on
the same repositoryId stay in lockstep.
chokidar ──push──▶ daemon ──SSE──▶ agents on the same repositoryId
◀──hydrateInstall
The bpmn-iq binary is wired up via package.json#bin. The repo root
declares @miragon/bpmn-iq-agent as a workspace devDependency, so
pnpm install (already part of normal setup) drops a symlink into
node_modules/.bin/bpmn-iq. From the repo root:
pnpm exec bpmn-iq <command>Equivalent and more explicit (works from anywhere in the monorepo):
pnpm --filter @miragon/bpmn-iq-agent exec bpmn-iq <command>Once published to GitHub Packages (issue #25), npm i -g @miragon/bpmn-iq-agent
makes bpmn-iq available globally on $PATH.
CWD matters. The agent reads
.env/.env.localand writes.bpmn-iq/repository.jsonrelative to the current working directory. Run it from the directory you want to sync, not from the repo root — or pass--root <dir>to point it elsewhere.
First-time setup
bpmn-iq login # opens the browser, runs WorkOS PKCE, stores tokens
bpmn-iq init # creates .bpmn-iq/repository.json in the current dir
bpmn-iq start # watches *.bpmn under the current dirBy default the agent points at the hosted Miragon Cloud
(https://bpmn-iq-server.fly.dev) — no config needed. Override with
--daemon or BPMN_IQ_DAEMON for a self-hosted or local stack.
Authentication
The agent talks to the daemon over an authenticated API; every call needs a bearer token. Three ways to provide one, in priority order:
--token <jwt>flag on the call.BPMN_IQ_TOKENenv var.bpmn-iq login— interactive browser sign-in via WorkOS AuthKit.
(1) and (2) are for CI / service accounts. (3) is the developer flow.
bpmn-iq login
bpmn-iq login [--client-id <id>]Runs the WorkOS PKCE flow against the User Management API:
- Spawns a one-shot HTTP listener on a random
127.0.0.1:<port>/callback. - Opens
https://api.workos.com/user_management/authorize?...in your default browser. - AuthKit handles the actual sign-in (email + password, SSO, magic link — whatever's configured in the WorkOS org).
- WorkOS redirects to the loopback with
?code=...; the CLI exchanges it for an access + refresh token and persists them.
Credentials live under ~/.bpmn-iq/credentials.json (override path via
BPMN_IQ_HOME). They contain a JWT access token, a refresh token, and
the JWT's exp for cache-busting. Subsequent commands refresh the
access token silently when it's within 60s of expiry — you should only
need to re-run login if you logout, change orgs, or the refresh
token is revoked server-side.
--client-id (or BPMN_IQ_CLIENT_ID) overrides the WorkOS client; the
default is the Miragon Cloud public client and works out of the box for
the hosted stack.
WorkOS dashboard requirement: the client must allow
http://127.0.0.1as a redirect URI (RFC 8252 loopback). The hosted client already has this; for a self-managed setup, add it under Authentication → Redirect URIs in the WorkOS dashboard.
bpmn-iq logout
bpmn-iq logoutDeletes ~/.bpmn-iq/credentials.json. The refresh token isn't revoked
server-side — do that from the WorkOS dashboard if you need to.
bpmn-iq whoami
bpmn-iq whoamiPrints the issuer, client id, user id, email, org id, and access-token TTL from the stored credentials. Exits non-zero if you're not signed in.
Commands
bpmn-iq init
Create .bpmn-iq/repository.json. In a git repository, the
repositoryId is derived deterministically from (repoId, branch) so
peers on the same branch share a repository; the file also stores
repoId, repoSlug, and branch. Outside git (or on detached HEAD),
a fresh UUID is generated.
bpmn-iq init [--root <dir>] [--name <name>]| Flag | Default | Effect |
| --------- | ---------------------------------------------------------------- | ------------------------------------------ |
| --root | . | Directory to initialise |
| --name | <repoSlug> · <branch> in git, basename of --root otherwise | Human-readable repository name |
If .bpmn-iq/repository.json already exists, it's left alone — except
when the saved (repoId, branch) no longer matches the current git
state, in which case start migrates the file under the new
repositoryId.
bpmn-iq pull --repositoryId <id>
One-shot hydrate: fetch every model on an existing repository from the
daemon and write them under --root, overwriting any local files at
the same paths. Stamps .bpmn-iq/repository.json so start can take over.
bpmn-iq pull --repositoryId <id> [--root <dir>] [--daemon <url>] [--token <jwt>]Useful for joining a teammate's repository from scratch.
| Flag | Default | Effect |
| ---------------- | -------------------------------- | ------------------------------------- |
| --repositoryId | (required) | Repository id to fetch |
| --root | . | Where to write models (overwrites) |
| --daemon | BPMN_IQ_DAEMON or cloud | Daemon base URL |
| --token | from login / env | Bearer override for one call |
bpmn-iq start
The main command. Hydrates from the daemon on startup, then watches
**/*.bpmn under --root for local edits (push) and listens to
/api/events for remote edits (pull). Multiple agents on the same
repositoryId converge; a sha256 map short-circuits push/pull
feedback loops.
In a git repo, start also watches .git/HEAD and re-registers under
a new repositoryId when the branch changes, so switching branches in
the surrounding repo follows the agent. Rapid git checkout A && B && C
collapses to a single transition to C.
bpmn-iq start [--root <dir>] [--daemon <url>] [--token <jwt>] [--repositoryId <id>] [--name <name>] [--no-pull]| Flag | Default | Effect |
| ---------------- | -------------------------------- | ----------------------------------------------------------------------------- |
| --root | . | Repository root |
| --daemon | BPMN_IQ_DAEMON or cloud | Daemon base URL |
| --token | from login / env | Bearer override for one call |
| --repositoryId | from repository.json | Seed a repository if repository.json is missing; must match if present |
| --name | basename of --root | Repository name when seeding |
| --no-pull | off | Push-only mode: local files are the source of truth, no SSE hydrate |
Press Ctrl-C to shut down. The agent stops its local watcher and SSE
stream but leaves the repository registered on the daemon so peers on
the same repositoryId keep working; the server-side TTL sweep collects
abandoned repositories eventually.
Environment
| Var | Used by | Default |
| ------------------- | ---------------------- | ---------------------------------------------------- |
| BPMN_IQ_DAEMON | pull, start | https://bpmn-iq-server.fly.dev (Miragon Cloud) |
| BPMN_IQ_CLIENT_ID | login | Miragon Cloud public client id |
| BPMN_IQ_TOKEN | every authenticated cmd | (unset — falls back to login credentials) |
| BPMN_IQ_HOME | login, logout, etc. | ~/.bpmn-iq |
--flags override env, env overrides cloud defaults. The agent also
loads .env and .env.local from the current working directory at
startup (skipped under NODE_ENV=production), so you can pin overrides
per project.
Examples
# sign in once
bpmn-iq login
# fresh repository in the current dir
bpmn-iq init --name my-project
# join a teammate's repository
bpmn-iq pull --repositoryId 7b2e... --root ./bpmn
# run the watcher (most common)
bpmn-iq start
# share local-only work with the team via the web UI without pulling
bpmn-iq start --no-pull
# point at a self-hosted daemon
BPMN_IQ_DAEMON=http://localhost:4000 bpmn-iq start
# CI / service account — no interactive login
BPMN_IQ_TOKEN=eyJ... bpmn-iq startSource layout
| File | Role |
| ---------------------------- | --------------------------------------------------- |
| src/cli.ts | Arg parser + command dispatch |
| src/auth/oauth.ts | Loopback callback server + browser launch + JWT peek |
| src/auth/credentials.ts | ~/.bpmn-iq/credentials.json read/write/delete |
| src/auth/token-provider.ts | Cached access token with silent refresh |
| src/auth/pkce.ts | RFC 7636 PKCE verifier + S256 challenge |
| src/repository-config.ts | .bpmn-iq/repository.json read/write |
| src/git-detect.ts | Detect repo + branch, derive deterministic id |
| src/branch-watch.ts | chokidar on .git/HEAD → debounced branch-change |
| src/watcher.ts | chokidar watcher → push loop |
| src/sse-sync.ts | SSE consumer → file write loop + sha dedupe |
Built output ships in dist/ (TypeScript → ES modules). The CLI binary
shim is bin/bpmn-iq.mjs.
