# pi-extensions

A monorepo of independently installable [pi coding agent](https://github.com/earendil-works/pi)
extensions, published to npm under the `@sreetej510` scope so each package name is globally unique
(`@sreetej510/pi-<extension-name>`). Structure and tooling are modeled after
[narumiruna/pi-extensions](https://github.com/narumiruna/pi-extensions).

## Packages

| Package | Description | Source entry | Published entry |
|---|---|---|---|
| [`@sreetej510/pi-hpc-tools`](extensions/pi-hpc-tools) | Remote HPC/SSH exploration (`ls`/`read`/`grep`) via `plink`, gated per-project by `/hpc:on` | `src/index.ts` | `dist/index.js` |
| [`@sreetej510/pi-prompt-manager`](extensions/pi-prompt-manager) | Save, browse, and paste reusable prompts via `/prompt` | `src/index.ts` | `dist/index.js` |
| [`@sreetej510/pi-usage`](extensions/pi-usage) | Provider usage / rate-limit reporting + statusline via `/usage` | `src/index.ts` | `dist/index.js` |
| [`@sreetej510/pi-shipd-checks`](extensions/pi-shipd-checks) | Multi-agent fairness review + test-gap analysis via `/checks` | `src/index.ts` | `dist/index.js` |

Each package has its own README with commands, configuration, and usage details.

## Repository layout

```
pi-extensions/
├── extensions/
│   ├── pi-hpc-tools/
│   │   ├── src/hpc-tools.ts
│   │   ├── package.json
│   │   ├── tsconfig.json
│   │   ├── README.md
│   │   └── LICENSE
│   ├── pi-prompt-manager/
│   ├── pi-usage/
│   └── pi-shipd-checks/
├── scripts/
│   ├── build-extension.mjs   # bundle + minify one extension → dist/index.js
│   ├── build-all.mjs         # build every extension workspace
│   └── bump-shared-version.mjs
├── .github/workflows/
│   ├── ci.yml              # lint + typecheck on push/PR
│   ├── bump-version.yml    # manual: bump all package versions in lockstep + tag
│   ├── release.yml         # tag push -> GitHub Release
│   └── publish.yml         # tag push -> build + publish minified dist/ to npm
├── package.json             # npm workspaces root (private)
├── tsconfig.json            # shared, workspace-wide typecheck config
├── biome.json                # shared lint/format config
└── LICENSE
```

This is an **npm workspaces monorepo**: the root `package.json` is `private` and only exists to
drive tooling (install, lint, typecheck, version bumps). Every folder under `extensions/*` is an
independently publishable npm package.

## Getting started

```bash
git clone <this-repo>
cd pi-extensions
npm install
```

### Common scripts (run from the repo root)

| Command | Effect |
|---|---|
| `npm run build` | Bundle + minify every extension to `dist/index.js` (comments stripped) |
| `npm run check` | Biome check + typecheck + build across all workspaces |
| `npm run lint` | Biome lint |
| `npm run format` | Biome format (writes changes) |
| `npm run typecheck` | `tsc --noEmit` in every workspace |
| `npm run pack:<name>` | `npm pack --dry-run` for one package (sanity-check `files`/tarball contents) |
| `npm run publish:dry` | Dry-run publish of every non-private workspace |

### Build pipeline

Source lives in `src/` (multi-file TypeScript, with comments). **npm publishes only `dist/`** —
a single minified ESM bundle per extension, produced by [esbuild](https://esbuild.github.io/):

```bash
npm run build                              # all extensions
npm run --workspace @sreetej510/pi-usage build   # one extension
```

What the build does:

- Bundles all `src/**/*.ts` into one `dist/index.js` per package
- Minifies and strips comments (`legalComments: "none"`)
- Keeps `@earendil-works/*` external (provided by pi at runtime)
- Bundles runtime deps like `typebox` into the output

`prepublishOnly` on each package runs `build` automatically before `npm publish`. The GitHub
**Publish** workflow also runs `npm run build` before publishing.

For local pi development against source (not the minified npm build), point `settings.json` at
`src/index.ts` directly — see each package README.

You can also scope any script to a single package:

```bash
npm run --workspace @sreetej510/pi-usage check
npm run --workspace @sreetej510/pi-usage typecheck
```

## Adding a new extension

1. Create `extensions/pi-<name>/` with a `src/` folder containing your extension's entry file
   (and any supporting modules).
2. Add a `package.json` (copy an existing one as a template) with:
   - `"name": "@sreetej510/pi-<name>"`
   - `"private": false`
   - `"pi": { "extensions": ["./dist/index.js"] }`
   - `"files": ["dist", "README.md", "LICENSE"]`
   - `"build": "node ../../scripts/build-extension.mjs"`
   - `"prepublishOnly": "npm run build"`
3. Add `src/index.ts` as the extension entry (esbuild bundles from here).
4. Add a `tsconfig.json` (copy an existing one), a `README.md` documenting commands/config, and
   a `LICENSE` (copy the root `LICENSE`).
5. Add a `pack:<name>` script to the root `package.json` for convenience (optional).
6. Run `npm install` at the repo root so the new workspace is linked, then
   `npm run --workspace @sreetej510/pi-<name> check`.
7. For local testing without publishing, point your pi `settings.json` at the source file directly:

   ```json
   {
     "extensions": ["/absolute/path/to/pi-extensions/extensions/pi-<name>/src/index.ts"]
   }
   ```

## Versioning

All packages share a single version number (lockstep versioning), bumped together via:

```bash
node scripts/bump-shared-version.mjs patch   # or minor / major
```

This updates the root `package.json` and every non-private `extensions/*/package.json`. In CI,
the same logic is available as the manual **"Bump version"** workflow, which commits the bump
and creates a `vX.Y.Z` tag.

## Release & publish pipeline

The full pipeline is push-button once configured:

1. **CI** (`.github/workflows/ci.yml`) — runs on every push/PR to `main`: installs deps, runs
   `npm run check` (biome + typecheck) across all workspaces.
2. **Bump version** (`.github/workflows/bump-version.yml`, manual `workflow_dispatch`) — pick
   `patch`/`minor`/`major`, it bumps every package's version, commits
   `chore(release): vX.Y.Z`, and pushes a matching git tag.
3. **Release** (`.github/workflows/release.yml`) — triggered by the `vX.Y.Z` tag push; creates a
   GitHub Release with auto-generated notes.
4. **Publish** (`.github/workflows/publish.yml`) — also triggered by the `vX.Y.Z` tag push (or
   manually); installs deps, runs `npm run check` again as a safety gate, then publishes every
   non-private workspace package whose `name@version` isn't already on the npm registry
   (`npm --workspace <name> publish --access public`).

### One-time setup

- Create an npm **automation/publish token** for the `@sreetej510` org/scope and add it to the repo
  as the `NPM_TOKEN` secret (used by `publish.yml`).
- If `bump-version.yml` needs to push to a protected `main` branch, add a `PAT_TOKEN` secret
  with a personal access token that has `contents: write` (repo `Settings → Secrets`).
- Make sure the `@sreetej510` scope exists on npm and this repo's publishing account is a member with
  publish rights: `npm org ls omega` / `npm access ls-packages @sreetej510`.

### Cutting a release manually (no CI)

```bash
npm install
npm run check
node scripts/bump-shared-version.mjs patch
git add package.json extensions/*/package.json
git commit -m "chore(release): v$(node -p "require('./package.json').version")"
git tag "v$(node -p "require('./package.json').version")"
git push origin main --tags

# Publish (requires npm login with publish rights on @sreetej510)
npm publish --workspace @sreetej510/pi-hpc-tools --access public
npm publish --workspace @sreetej510/pi-prompt-manager --access public
npm publish --workspace @sreetej510/pi-usage --access public
npm publish --workspace @sreetej510/pi-shipd-checks --access public
```

## Installing published extensions

Once published, add any package to your pi `settings.json` under `packages` (pi resolves the
`pi.extensions` entry points from the installed npm package automatically):

```json
{
  "packages": [
    "npm:@sreetej510/pi-hpc-tools",
    "npm:@sreetej510/pi-prompt-manager",
    "npm:@sreetej510/pi-usage",
    "npm:@sreetej510/pi-shipd-checks"
  ]
}
```

## License

MIT — see [LICENSE](LICENSE). Individual packages carry a copy of the same license.
