Packages

On this page

Ours (developed here)

Package Purpose

@gadhs/pi

The distribution. pi install npm:@gadhs/pi gives a developer everything below with agency defaults. Ships eight loader shims that re-export each dependency’s extension factory (pi does not transitively load dependency pi packages); dependencies are exact-pinned and resolved by pi’s installer (npm install --prefix into one flat root). Bundling was rejected: pnpm-built bundledDependencies tarballs from a workspace emit ..-escaping members. Load order is fixed by loader filename (modes first — it seeds the permission config before that system reads it). Loaders for the vendored packages import their factories by relative path into the flat root (their exports maps expose service APIs, not factories) — layout deviations fail loudly at pi startup.

@gadhs/pi-vertex

Every publisher on Google Cloud Vertex AI — Claude through the Anthropic SDK, Gemini through pi’s own Vertex adapter, the Model-as-a-Service catalogue (Grok, gpt-oss, Kimi, Qwen, MiniMax …) through Vertex’s OpenAI-compatible endpoint — as three provider ids from one config file (ADR-005). Per-model region routing (quota and availability are granted per (model, region) — no single region serves every model), static JSON catalog, ADC auth throughout with no login. Ships probe.mjs so each team discovers which (model, region) pairs return a real HTTP 200 for their project, kind by kind. @gadhs/pi-vertex-anthropic through 0.6.0; renamed in #77.

@gadhs/pi-modes

The policy layer: four modes with per-mode models and rules, the deterministic permission stages, the safety-only judge, subagent contracts, the status line and inline traces. Consumes @gadhs/pi-guidance as a peer for prompt composition and publishes the observability bridge the workflow guards render through. Reference · cookbook.

@gadhs/pi-workflow

Delivery-workflow enforcement, mode-independent by design (yolo included): commit format and mechanical attribution, --no-verify refusal, stage/commit separation, GitLab identity preflight, SPDX-at-write, debt markers, setup-drift warnings, and the independent cold-reader review of every commit and every plan - a reviewer that reads the candidate snapshot within a budget (#97) and whose flagged findings the author answers in the commit message (#96). Decisions are standalone; rendering flows through pi-modes' bridge when present and no-ops when not. One bridge member runs the other way: planReviewed tells pi-modes the outcome of each plan review so the approval pane can show it beside the plan it reviewed (#43).

@gadhs/pi-guidance

Agency standards as content: the working-agreements digest, four language profiles (Rust, TypeScript, Python, Java), the composition seam that injects them each session, and the /gadhs-init AGENTS.md skeleton. Split from pi-modes under ADR-004 so a wording change gets prose review and ships without version-bumping the judge. The session handler stays in pi-modes (composition interleaves the mode addendum and memory in one idempotent pass); the dependency points policy→content as a version range, never the reverse.

@gadhs/pi-agents

Agency-standard subagent definitions (Explore and Verify on Gemini 3.8 Flash, argued on the model-battery page; Research on Sonnet), seeded as managed files into the global agents directory — pi packages cannot ship agent definitions and the subagents extension has no registration seam (upstream request #35), so seeding is the delivery. Absent files are written; files carrying the gadhs_managed marker update with the package; files without the marker are never touched (delete the marker line to own a file forever). Every write is announced at session start. One operator knob: ~/.pi/agent/gadhs-pi-agents.json names a different model per helper, applied when the seed is rendered so the file stays managed (recipe).

The meta package also ships the four Orchard TUI themes (themes/, generated from the agency palette data — node tools/task.mjs themes regenerates, and a drift check runs in validate).

Vendored upstream (pinned, unmodified)

Package License Role

@gotgenes/pi-permission-system

MIT

Deterministic permission gates: bash decomposition, symlink-resolved path denies, fail-closed posture, subagent ask-forwarding, the authorizerChain seam our judge plugs into.

@gotgenes/pi-subagents

MIT

Subagent delegation. Chosen over alternatives for its native permission-system integration (<active_agent> tag → per-agent allow/ask/deny frontmatter) and typed service API.

pi-web-access

MIT

Web search, URL fetch, repo cloning, PDF/video extraction. Already routes model calls through pi’s registry-complete path, so it works with Vertex ADC models out of the box.

Upstream updates are normal dependency management: get notified → bump the pin → CI → publish a new @gadhs/pi. No local patches, ever (see Architecture).

Import resolution inside extensions

pi resolves an extension’s imports of upstream code through an alias map that covers only the @earendil-works/* package roots plus three subpaths: /compat, /oauth, and /providers/all. Any deeper subpath import resolves in this workspace (where node_modules has the real tree) and then breaks in a consumer install — which is exactly the kind of gap task consumer-sim exists to catch.

Registry

Packages publish to the GitLab npm registry under the @gadhs scope (internal; not published to npmjs.com). Consumers resolve the scope from the GROUP endpoint, which serves reads publicly — no token to install:

npm config set @gadhs:registry https://gitlab.com/api/v4/groups/55134190/-/packages/npm/

The group endpoint is the deliberate choice, decided by the constraint that npm permits exactly ONE registry per scope: the @gadhs → registry mapping on a developer’s box covers the whole namespace, and the agency publishes @gadhs packages from more than one project (this repo’s five, the shared docs theme and its search extensions from theirs). A project-endpoint mapping would serve this repo’s packages and 404 on every other package the agency ships, now or later.

The accepted residual: the group endpoint’s namespace is every project in gadhs, so an accidental name collision (a fork that keeps package names and publishes from its own project) would enter consumers' resolution, on a surface where GitLab’s cross-project name handling has a history of churn. Under the agency threat model that is an accident class, not an adversary class; if it ever occurs, GitLab package-protection rules and the fork’s own cleanup are the remedy. Verification pins what the instructions compose: task consumer-sim --registry installs through the group endpoint exactly as a consumer does — it has to, since 0.45.0, because the distribution depends on @gadhs/pivot-wire from pivot’s project and npm maps a scope to one registry — and then asserts provenance from what npm recorded: the group endpoint’s metadata names each tarball’s project, and every package of ours must have resolved from this project’s endpoint, pivot’s wire from pivot’s (#143). A same-named package from any other project in the group installs, and the check fails naming it.

Publishing targets the per-project endpoint; auth comes from the environment, never from a committed token (see .npmrc).

One packaging rule learned the hard way: the files allowlists use globs pinned by tests that read npm pack --json — a hand-maintained file list rots invisibly in a workspace, because the files are always present locally.

Edit this page · latest