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

@geut/pi-cowork-mode

v0.1.0

Published

Pi extension for operating a long-lived Docker Compose cowork environment.

Readme

pi-cowork-mode

A pi extension for operating a long-lived Docker Compose "cowork" environment for local development and testing.

The extension does not author Dockerfiles or compose files. It expects a cowork service that was scaffolded by the separate cowork-mode skill (or created manually). Install that skill too if you want the consent-gated scaffolding flow.


What it gives you

  • Eight tools the agent can call: cowork_up, cowork_status, cowork_exec, cowork_test, cowork_run, cowork_logs, cowork_down, cowork_reset.
  • /cowork command namespace for humans: /cowork up|status|test|run|logs|down|shell.
  • A footer one-liner (always on, added to pi's default footer via setStatus — pi's model/branch/tokens/provider info is preserved) and an expanded status widget (shown as a non-capturing overlay by /cowork status, closed with Escape) with container state, published ports with URLs, and the last test result.
  • Persisted runtime state (.pi/cowork-state.json) so the last test result and container state survive restarts.
  • Lazy + event-driven refresh via a docker events stream (auto-restart with backoff). No polling loop.
  • Consent-gated scaffolding handoff to the separate cowork-mode skill.

Prerequisites

Install the companion skill so the agent can scaffold a cowork service when one does not exist:

npx skills add geut/cowork-mode-skill

The skill is standalone and works without pi; the extension is pi-only.

Install

pi install npm:@geut/pi-cowork-mode

Discovery rules

The extension is convention-driven:

  1. Find docker-compose.yml / docker-compose.yaml / compose.yml / compose.yaml in the project root (and ancestors up to the git repo root).
  2. Look for a service named cowork (or the service override in .pi/cowork.json).
  3. If a cowork service already exists, use it as-is. The extension never modifies your compose file or service.
  4. If none exists, the footer shows cowork: not configured. Calling cowork_up (or /cowork up) asks for consent; on consent, the extension writes a minimal .pi/cowork.json and hands off to the separate cowork-mode skill (/skill:cowork-mode) to scaffold docker-compose.yml, Dockerfile.cowork, and scripts/cowork-entrypoint.sh. Install the skill via npx skills add geut/cowork-mode-skill if it is not already available. The extension itself never authors Dockerfiles.

Configuration: .pi/cowork.json

Optional. Created automatically on consent. Fields:

{
  // Override the service name (default "cowork").
  "service": "cowork",
  // Override the compose file path (default: auto-discovered).
  "composeFile": "docker-compose.yml",
  // Test command(s) the extension recognizes as "test runs". String or array. Overrides package.json derivation.
  "testCommand": ["npx vitest run", "npm test"],
}

Test-command cascade:

  1. .pi/cowork.json testCommand
  2. package.json scripts.test:cowork
  3. package.json scripts.test
  4. omit (no test signal).

Tools

| Tool | Description | |------|-------------| | cowork_up | docker compose up -d [--build] cowork. Rebuilds only when Dockerfile.cowork, the compose file, or the lockfile changed since the last successful up. Pass forceBuild: true to force a rebuild. Returns service, container name, ports, state. | | cowork_status | Reports container lifecycle, health (if a HEALTHCHECK is defined), published ports with URLs, and last test result. Does not start or stop anything. | | cowork_exec | Runs a command inside the container, always at the configured workdir (/workspace by default). Streams stdout/stderr. Recognizes test runs (via the test-command cascade) and updates the last-test-result signal. Errors if the env is down — does not auto-start. Don't run watch mode / REPLs. | | cowork_test | Runs the recognized test command(s) (from .pi/cowork.json testCommand or package.json scripts) and updates the last-test-result signal. Streams output. Stops on first failure. Use this instead of cowork_exec when you intend to run tests. | | cowork_run | Runs an arbitrary package command string in the container (e.g. npm run lint, npm run test:e2e, npm run dev). Streams output. Does not update the last-test-result signal — use cowork_test for tracked test runs. Errors if the env is down. Avoid watch mode / long-running servers; use /cowork shell for those. | | cowork_logs | One-shot fetch of the last N lines (default 200). No follow mode. | | cowork_down | Stops the service, keeps named volumes. | | cowork_reset | Stops the service and removes named volumes (full reinstall). Always confirms with the user first. |

/cowork subcommands

/cowork up        bring the environment up (smart build)
/cowork status    show expanded status in the widget (Escape to close)
/cowork test      run the recognized test command(s) and track the result
/cowork run <cmd> run a command string in the container (e.g. npm run lint)
/cowork logs [N]  show last N log lines (default 200)
/cowork down      stop the environment
/cowork shell     interactive shell inside the container (TUI only)

/cowork run captures output and notifies when the command finishes. For long-running commands (e.g. a dev server) it will block until the command exits or you abort; use /cowork shell for an interactive session instead.

State model

Two independent signals:

  • Container lifecycle: up / paused / restarting / exited / dead / … from docker compose ps.
  • Last test result: passing / failing / unknown. cowork_test always sets it; cowork_exec sets it when the command matches the test-command cascade; cowork_run does not. Timeout/abort counts as failing.

Health is whatever Docker reports on docker compose ps (healthy / unhealthy / starting). If the image or compose service has no HEALTHCHECK, the extension shows none and does not probe ports. For an HTTP app, add a HEALTHCHECK (in the Dockerfile or a compose healthcheck:) so the footer can show reachability. CLI/module projects can skip it.

Customizing the container workdir

cowork_exec runs commands at /workspace (the conventional bind-mount root) by default. If your project mounts the repo elsewhere, edit DEFAULT_WORKDIR in src/tools.ts.

Refresh model

  • One docker compose ps on session_start and after every cowork_* tool call.
  • A docker events stream (filtered to the compose project) flips state between tool calls.
  • The events stream auto-restarts on exit with exponential backoff (1s → 2s → 4s → … capped at 30s). Torn down on session_shutdown.
  • Docker-unavailable: probed on session_start; footer shows cowork: docker unavailable; tools return a clear daemon-unreachable error. Re-probed on each cowork_* call (self-heals when docker comes back, without a polling timer).

Development

git clone [email protected]:geut/pi-cowork-mode.git
cd pi-cowork-mode
npm install
npm run check   # tsc --noEmit
npm run lint    # oxlint .
npm test        # vitest run

Tests use fakes/fixtures (no real docker). See __tests__/.

Packaging notes

  • peerDependencies (@earendil-works/pi-coding-agent, @earendil-works/pi-ai, @earendil-works/pi-tui, typebox) are provided by the host pi at runtime — never bundled.
  • devDependencies are for typecheck/lint/test inside the package.
  • pi.extensions in package.json registers only the extension. The cowork-mode skill is shipped separately as @geut/cowork-mode-skill.

License

MIT