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

@kristoffer-karl-axel-ekstrand/office-space

v0.9.1

Published

Profile-driven, harness-neutral multi-agent workflow runtime for repository-local AI teams.

Downloads

1,925

Readme

@kristoffer-karl-axel-ekstrand/office-space

npm version license node

Profile-driven, harness-neutral multi-agent workflow runtime for repository-local AI teams.

Why office-space?

Why does office-space exist?

AI coding tools produce code fast when run unattended, but not code you can trust. Long runs and "vibe coding" sessions tend to end the same way: the happy path works, but the feature has not been tested or checked. A human must sit there, re-prompt, re-review, and re-test the same work. That is not less effort than writing it yourself. It is babysitting. office-space lets someone run a team pretty much unattended.

Who runs it?

Anyone who wants to produce software without watching every step: a solo developer building a side project, someone who enjoys building but not supervising an agent all day, or a team using AI on a real work project. If using AI ever felt like it gave you a different job — prompt, re-check, prompt again — instead of more freedom, this is for that problem.

Why use it instead of just running an AI CLI directly?

Running an AI CLI directly — Claude, Codex, Devin, or whatever comes next — gets you fast output and no structure: no independent review, no enforced tests, no memory of what was already tried and rejected, and no built-in coordination for multiple agents. office-space adds the missing structure — a task board with review and QA stages, path locks so agents don't collide, evidence requirements before anything is marked done, and health checks — so you can walk away and come back to real, checked progress instead of a mess to clean up.

It's built for more than a quick one-off prompt: hand it an epic or a technical spec for a large, repetitive change across a big codebase, and the team keeps grinding through it for hours or days without you in the loop. Roles can even run different models — one vendor implements, a genuinely different one reviews — so quality isn't just one model checking its own work.

The task board, progress, and mail are plain repo files, not state trapped in one vendor chat session. You can commit the workflow state, pause work when you hit token or rate limits, and resume later with another vendor or model from the recorded state.

(Runs natively on macOS/Linux; on Windows, use WSL2 or — our recommendation — the built-in dev container.)

Contents

Quick start

The package is dependency-free at runtime. A host repository supplies one or more workflow profiles under .agents/office-space/<workflow>/ (each with a space.json). The CLI discovers the host by walking upward from the current directory until it finds .agents/office-space/.

This repository also serves as a runnable example: .agents/office-space/ contains a sample developer-team workflow that exercises the CLI and validation checks. Agent-facing commands and boundaries live in AGENTS.md (with a CLAUDE.md @AGENTS.md shim for Claude Code).

npx @kristoffer-karl-axel-ekstrand/office-space init

This scaffolds a developer-team workflow with six roles (team-lead, dev-1, dev-2, scout, quality, tests) under .agents/office-space/developer-team/, plus:

  • co-workers/<agent>.prompt.md + .prompt.json — one role body and one config file per agent, already wired to a role-appropriate set of shared doctrine partials (an implementer gets more than a reviewer, a reviewer gets more than the team lead)
  • co-workers/_shared/*.md — generalized cross-cutting rules every role can opt into: messaging format, mailbox hygiene, memory discipline, git/commit boundaries, concurrency and locking, self-verification, spec discipline, and the plan-approval gate
  • .agents/skills/office-space-protocol/SKILL.md — the canonical mail/Slack/tasks/memory protocol, generalized from a production multi-agent team and installed automatically so agents have real doctrine on first boot, not an empty folder
  • Root AGENTS.md + CLAUDE.md (@AGENTS.md shim) when missing — portable agent instructions so Claude and other harnesses share one policy file
  • WORKFLOW.md — a starter mission doc with the section skeleton a real team needs (mission, co-workers, claiming/locks, pipeline, human gates, quality bars, bootstrapping, changelog); rewrite it to describe your own project
  • spec/, records/{checkpoints,decisions,retros,memory}, epics/{drafts,todo} — the durable and semi-durable layers a team accumulates over time, pre-created so nobody invents their own convention later

None of the generated content mentions any specific product or domain — it is a starting point to edit, not a finished team.

After init

Init scaffolds folders and seeds package skills; it does not design your team. Prove the host, then redesign:

office-space check-system
office-space doctor
office-space sync --write
office-space check --tier fast

Then rewrite WORKFLOW.md, tune co-workers, and replace seed T001 with a real first task. Init installs these package-owned skills under .agents/skills/:

  • Core workflow: office-space-protocol, office-space, office-space-answer-mail, and model-chooser
  • Setup and team design: office-space-onboard, office-space-team-design, agent-agnostic, and share-skills
  • Authoring and integration: create-skill, agent-cli-integration, tmux-automation, watch-and-improve-office-space, and technical-writing

The office-space-onboard and office-space-team-design skills provide guided setup sequences.

When doctrine is hard to open in the harness, print it with office-space explain onboard (or team-design, protocol, …; office-space explain --list for topics).

When you're ready to actually run the team (needs bash, jq, tmux, realpath, timeout, flock, and sha256sum — see System requirements):

office-space team start
office-space team status
office-space team stop

team start opens a tmux session with one pane per agent plus a control pane, a health-monitor, and a dashboard window; each agent launches with its fully composed prompt (role body + opted-in partials + spec index) and begins its wake/work loop. The control pane lists every co-worker, enabled and disabled, in one place. Select a row, then press t to toggle it on or off. Press s to stop the whole team.

Intercom (wait/poller): between turns the harness (oneshot) or the agent (persistent) runs intercom — the mailbox poller that watches slack//mail/, heartbeats, and wakes the next turn. This is an internal process name, not Intercom.com. Canonical binary: node …/intercom.js <workflow> <agent>. Compat: await-messages.js is a silent thin forwarder for at least one package minor; stop/reap matches both basenames during that window. Lock and heartbeat paths (.await-lock-*, health/heartbeats/) are unchanged.

You can inspect the running session from outside the CLI with tmux ls and tmux attach -t <workflow>-agents. The health monitor runs in a dedicated monitor window (src/run-team and src/lib/team-monitor.sh); each agent's intercom poller writes health/heartbeats/<agent>.json every 30 seconds (src/intercom.js). The monitor uses heartbeat age, pane command, and poller state to classify genuinely stagnant agents and calls restart_agent (src/run-team) to respawn their panes. Heartbeats carry pid and startTime so a reused OS pid is not mistaken for a live agent, and the .temp/.await-lock-* files keep only one poller per mailbox after a restart.

Keeping current

After bumping the office-space package, do not use init --force to upgrade skills or partials (too broad; clobbers workflow content). Read host notes, refresh package-owned skills and partials, then re-bridge discovery:

office-space whats-new                # host notes since host stamp (semver); --all / --from VER
office-space skills refresh --check   # package-owned skills that differ from bundled templates
office-space skills refresh --write   # updates package-owned only; optional --notify → mail/in digest
# multi-workflow hosts (this monorepo): pin product; bare check also scans fixture workflows
office-space partials refresh --check --workflow developer-team
office-space partials refresh --write --workflow developer-team
office-space sync --write
office-space doctor

Bare partials refresh --check scans every host workflow with space.json (product plus fixtures such as demo and sync-check on this monorepo). Use --workflow <product> when you only need the product workflow current. Use office-space explain <topic-or-host-skill-name> when agents cannot see skill bodies after a bump. Host-owned skills under .agents/skills/ and host-only _shared basenames are never overwritten by refresh.

Host-facing upgrade log: package templates/host-upgrades.md (this repo: src/templates/host-upgrades.md). That file is what whats-new prints. Setup-affecting releases must add a ## X.Y.Z section there before publish. The release-qualification driver rejects a newest section that differs from the package version; this is not an npm pack check.

One-shot runners

team start is for resident co-workers that watch mail and pick up tasks continuously. For bounded maintenance jobs use a runner under runners/<runner-id>.prompt.json + <runner-id>.prompt.md with runner: true and start_mode: "one-shot" (one-shot = job bounds: authored prompt only, turn/time budget — not “no host”).

Job contract (E003 / D006):

  • Invoke with office-space run <runner-id> [--workflow <name>] (no ad-hoc prompt override), or post a type: run-request addressed to the runner id in mail/in/.
  • Defaults: 5-turn budget and 15-minute wall-clock timeout (max_turns / timeout_minutes).
  • Runners claim owned_paths and follow queued → ... → done unless the entire diff is a single deterministic, idempotent formatter invocation that passes a formatter-canonical text comparison and a syntax check. That fast-path lands in tasks/done/ with health/runner-runs/<run-id>/run.json.

Team-hosted (live — D007 scaffolding):

  • team start opens a runners window: one pane per runner plus a controller.
  • When the team is up, run-request mail is queued via the controller path (queueRunnerRequest); the lead intercom loop does not block on the full job.
  • Default office-space run <runner-id> also enqueues on that same durable path when {workflow}-agents is up and the runner pane + controller exist — returns after queue write, no dual inline execution.
  • Pending queue files live under health/runner-requests/ (not .temp/) so a team restart does not drop undelivered work; activation/busy markers under .temp/ remain ephemeral.
  • Synchronous / headless path when the team is down, the runner is not pane-hosted, or for CI: use office-space run … --foreground or --headless (forces run_one_shot; no tmux pane kept open by the CLI alone).

Set-time schedule (controller-owned):

"schedule": {
  "tz": "UTC",
  "times": ["09:00", "13:00", "18:30"]
}
  • The controller pane fires each listed HH:MM once per calendar day while the team is up (timezone from schedule.tz, default UTC).
  • Last-fired state lives under health/runner-schedule/<runner>.json so a restart does not re-fire the same slot.
  • Busy or path-conflict (working-on overlap) delays within the minute; once the clock moves on, the slot is a miss — no backlog catch-up.
  • Empty/missing times → on-demand only (run-request / office-space run). No full cron in v1.

CLI

office-space init
office-space init -h
office-space init --help
office-space init --preset thin
office-space init --preset full --workflow my-team
office-space init --workflow my-team --agents lead,dev-1,reviewer --agent-roles "lead=lead,dev-1=implementer,reviewer=reviewer+qa"
office-space init --harness claude
office-space init --force
office-space init --force --clobber-default-mission
office-space check-system
office-space doctor
office-space explain [TOPIC] | --list
office-space whats-new [--all|--from VER]
office-space skills refresh --check|--write [--notify]
office-space partials refresh --check|--write [--workflow NAME]
office-space sync --check
office-space sync --write
office-space check --tier fast
office-space check --tier fast my-team
office-space check --tier full
office-space team start developer-team
office-space team stop developer-team
office-space team status developer-team
office-space team drain developer-team
office-space team roles developer-team
office-space run <runner-id> [--workflow <name>] [--foreground|--headless]
office-space collaboration-digest [WORKFLOW] [--write] [--json]
office-space evidence-audit <command> [<workflow> <task-id>]
office-space state checkpoint developer-team
office-space state checkpoint developer-team --label pre-release
office-space state restore developer-team
office-space state compact developer-team
office-space lock --resource package.json -- npm test
office-space lock --workflow my-team --lane release --resource package.json -- npm test
office-space models audit [--live] [--include-rows] [--strict] [--catalog PATH] [--registry PATH]
office-space models propose [--roles PATH] [--output PATH] [--workflow NAME] [--catalog PATH] [--registry PATH]
office-space models apply PROPOSAL [--confirm] [--workflow NAME] [--catalog PATH] [--registry PATH]
office-space ctrl

models runs as a sequence. audit inspects the model catalog and classification. Use --live for optional live availability. audit supports --include-rows for detailed output and --strict for stricter validation.

propose drafts a model assignment proposal from role requirements. apply validates a chosen proposal by default. Use --confirm to write into the workflow's co-worker prompts.

init scaffolds a workflow profile (space.json) under .agents/office-space/. It also creates role prompts, specs, and all required runtime directories in an empty repository.

Use --force to re-scaffold an existing workflow folder when it is not the default workflow with customized mission content. Non-default workflows are fine. A default workflow still on template content is also fine.

The command refuses a default workflow with customized mission content (WORKFLOW.md and/or approved-class specs) under bare --force. Add --clobber-default-mission only when you want to destroy WORKFLOW, co-worker prompts, space.json, and spec/*.

Path upgrades still use skills/partials refresh (see Keeping current), not init --force.

Greenfield verification is intentionally repository-neutral. space.json starts with only the portable workflow-integrity machine check.

Before using machine review for code changes, define the repository's real test, lint, build, or package commands in review.machineChecks. Describe the required evidence ladder in the workflow's WORKFLOW.md.

Presets: --preset thin scaffolds lead, implementer, and combined reviewer/qa. --preset full is the default six-agent map with an explicit name. Omitting --preset keeps today's default lineup. Do not pass --preset together with --agents or --agent-roles. This is an error. There is no solo preset.

check

  • check --tier fast runs doctor (workflow profile and adapter validation) plus check-workflow (references, specs, tasks, and messages). This is the default CI gate for a working repository.
  • check --tier full runs the same gates as fast and then runs the default check-system gate and any host-defined gates. Use it before a release or after changing the host environment.

Host-defined gates live in .agents/office-space/check-manifest.json (one-release fallback: .agents/office-space/space.json with a deprecation warning). This file is optional and separate from the per-workflow space.json profile. It may contain freshness and verification.full arrays of command specs.

The per-workflow .agents/office-space/<workflow>/space.json profile does not accept freshness or verification keys. doctor rejects a workflow profile that contains them with a path-named error naming the workflow file and the unknown property.

A command spec is either an argv array of non-empty strings or an object with a non-empty name and a non-empty command array. For example:

{
  "freshness": [{ "name": "build", "command": ["npm", "run", "build"] }],
  "verification": {
    "full": [{ "name": "integration", "command": ["npm", "run", "test:unit:integration"] }]
  }
}

Hosts may use their own script names in this file. The sample above matches this package's test:unit:integration script (heavy run-team / tmux / poller coverage).

Malformed top-level shape (bad JSON, wrong types) is warned and ignored: check --tier full falls back to the default check-system gate. Malformed individual entries exit non-zero with a path-named error such as .agents/office-space/check-manifest.json: verification.full[0] requires a non-empty command array and non-empty name.

collaboration-digest prints board throughput and coordination metrics. It shows stalls and reject budget signals. It does not show health or uptime. Use --write to store a snapshot under the workflow's live health/ tree.

explain prints a skill body. Host install first, else package template.

whats-new prints host-facing notes from package templates/host-upgrades.md. Default shows sections with version > host stamp. No stamp shows latest only.

--all prints the full notes file. --from VER uses an exclusive floor (sections with version > VER). --all and --from VER are mutually exclusive. whats-new does not update the host stamp.

skills refresh diffs or updates package-owned skills only. --check exits nonzero when any package-owned file is stale or missing. --write prints the check summary first. --write updates the host-meta stamp.

Keep path after skills refresh: partials refresh --check|--write [--workflow NAME]sync --writedoctor. On multi-workflow hosts, pass --workflow for the product workflow. --notify (with --write only) drops an opt-in lead digest under mail/in/.

partials refresh diffs or updates package-owned co-workers/_shared partials. The command never modifies host-owned basenames. Default applies to every host workflow with space.json (product and fixtures). --workflow NAME limits to one. The command reports per workflow path.

On monorepos with fixture workflows, prefer --workflow for product-only check and write. Bare --check fails when any fixture partial is stale or missing even if the product workflow is clean. Bare --write can clobber intentional fixture drift. --write prints the check summary first. --write does not stamp host-meta. --check exits nonzero when any package-owned partial is stale or missing.

Package templates serve as the source of truth for consumer hosts. This repo's dogfood _shared may differ until refresh/promote.

sync --write bridges discovery adapters. It handles skills, personas, and commands. sync --write --mirror creates deterministic generated mirrors for Windows checkouts without symlink support. See Keeping current.

When supplying custom --agents, include one --agent-roles entry for every listed agent. Entries use the agent=role+role syntax shown above. Supported roles are lead, implementer, reviewer, qa, and none.

Optional specialty prompts (architect, researcher, product, tech-writer, security, release) live under package templates/co-worker-roles/. They are not in thin/full presets. Include the id with matching flags (usually =none) or copy onto an existing workflow.

Pipeline handoffs use task-transition with capability tokens, not conventional agent names. --assignee auto-implementer selects the least-loaded enabled implementer: true agent (stage implementing only). --assignee auto-reviewer and --assignee auto-qa do the same for reviewer: true at review and qa: true at qa. Staffed moves into implementing require implementer: true (lead and specialists are not on that allowlist).

--harness sets which CLI every scaffolded agent defaults to. Options are claude, codex, devin, copilot, cursor, antigravity, and grok. The default is devin. The command writes the harness into each agent's <agent>.prompt.json as cli.

Only devin needs an explicit default model. Every other harness picks its own default when you omit model. init omits it for those. grok is oneshot-capable (like claude and devin).

team drain writes a durable checkpoint. It blocks every transition into implementing while the drain marker exists (not only queued→implementing; blocked re-claims and review/qa bounces wait for team start). Already-implementing work may still advance. team start restores required runtime directories. It clears the drain marker and starts the configured workflow.

state compact checkpoints first. Then it applies the workflow's Slack, completed-task, and health-report retention limits from space.json state.retention (including healthReports, default 3). Continuous health-report writes use the same state.retention.healthReports keep count and prune only [HEALTH-REPORT]-* files; compact may still thin every file under health/reports/ by mtime. Invalid or non-finite healthReports values default to 3 (not wipe-all). state checkpoint accepts an optional --label NAME to name the checkpoint. state restore only ensures the runtime directory layout (mail/tasks/slack/health/memory/.temp); it does not load or apply checkpoints. lock accepts optional --workflow NAME and --lane NAME to target a specific workflow and build lane. ctrl launches the interactive team dashboard. The command requires a TTY.

Evidence audit

evidence-audit invalidates and restores the evidence behind a done task without reopening it. Workflow and task-id are required for invalidate, run, restore, and repair-projection. They are optional on the summary form because path-only gates (scoped-format, scoped-lint) take paths instead. Full subcommands: office-space evidence-audit --help.

stage: done stays terminal; the audit appends an invalidation/restoration ledger to the task record and updates the task projection.

Use it when a previously passing task needs to be re-checked: the configured lead invalidates the old evidence, QA re-runs the required tier gates, and QA restores verification only when the replacement runs match the current source fingerprint and are no older than the 60-minute reuse window at the moment of restoration.

Only the single configured lead may invalidate or repair-projection. Only configured QA may run and restore.

System requirements

The runtime scripts need bash 4+, jq 1.5+, tmux 3.0+, realpath, timeout, sha256sum (from coreutils), and flock (from util-linux). Shell entrypoints use realpath for SCRIPT_DIR; run-team / cli-tools hard-require timeout for wall-clock probes; path locks use sha256sum + flock; global / integration locks also call flock. Run office-space check-system and it will print the right install command for your platform, or install them manually:

# Debian / Ubuntu / WSL2
sudo apt update && sudo apt install -y bash jq tmux coreutils util-linux

# RHEL / Fedora
sudo dnf install -y bash jq tmux coreutils util-linux

# Arch Linux
sudo pacman -S bash jq tmux coreutils util-linux

# macOS / Homebrew
brew install bash jq tmux coreutils flock
# put GNU realpath/timeout/sha256sum first if only grealpath/gtimeout/gsha256sum are on PATH:
# export PATH="$(brew --prefix)/opt/coreutils/libexec/gnubin:$PATH"

# macOS / MacPorts
sudo port install bash jq tmux coreutils
# flock is util-linux (not coreutils); install a flock/util-linux port if missing

# Windows (requires WSL2)
wsl --install
wsl -e sudo apt update && wsl -e sudo apt install -y bash jq tmux coreutils util-linux

WSL2 is required (not WSL1). tmux needs a real Linux kernel/pty layer; WSL1 is a compatibility shim and is unreliable for tmux.

check-system also verifies the Node.js version (≥ 22.12) and that realpath, timeout, flock, and sha256sum are on PATH.

Canonical skills can be checked against the Agent Skills specification with:

npm run validate:skills

Development setup

Using the devcontainer is optional, but we strongly recommend it. If you open the repo in the devcontainer, it uses the mcr.microsoft.com/devcontainers/typescript-node:4-24-trixie image and a postCreateCommand that installs jq, tmux, shellcheck, shfmt, and runs npm install for you. Agents run with full/elevated permissions inside the container; the devcontainer is the containment boundary, so that elevated runtime stays inside the container rather than on the host. It does not add extra sandboxing beyond the normal Dev Containers workspace mount and network/filesystem exposure.

On Windows, the devcontainer runs via Docker Desktop's WSL2 backend — choosing the devcontainer is itself a WSL2 path (bundling tmux/jq/shellcheck/shfmt) versus bare wsl --install plus manual tool installation.

To develop locally, first satisfy the System requirements, then add the lint/test tools:

# Debian/Ubuntu/WSL2
sudo apt-get install -y shellcheck

# shfmt
curl -fsSL -o /tmp/shfmt https://github.com/mvdan/sh/releases/download/v3.11.0/shfmt_v3.11.0_linux_amd64
sudo install -m 755 /tmp/shfmt /usr/local/bin/shfmt

Run office-space check-system (or npm run check:system from the repo) to verify bash, jq, tmux, realpath, timeout, flock, sha256sum, and Node. Then install Node dependencies:

npm install

Release check

npm run verify

npm run verify runs formatting, linting, skill validation (validate:skills), all unit tests (including run-team integration), the global-lock self-test, the runtime self-test, workflow checks, and a dry-run pack of dist/ (npm run npm:pack). CI runs the same command on every push and pull request. To re-check the pack alone after npm run build, run npm run npm:pack (not bare npm pack from the repo root). Publish with npm run npm:publish / npm publish dist/ — never root npm publish.

Day-to-day: npm run test:unit is the fast suite (excludes *.integration.test.js and test/release/** E005 soaks). Prefer npm run test:unit -- <file> while editing. Use npm run test:unit:integration when changing run-team / tmux / poller / runner-controller behavior, npm run test:unit:all for fast+integration, and npm run test:unit:release only for E005 qualification.

Portability

Repository paths, workflow names, task stages, message types, state retention, build lanes, and adapter mappings belong in configuration.

Local discovery adapters use directory symlinks on Unix. sync --write --mirror creates deterministic generated mirrors for Windows checkouts without symlink support. The command refuses to replace unmanaged content.

License

MIT — see LICENSE.