Packages
On this page
Ours (developed here)
| Package | Purpose |
|---|---|
|
The distribution. |
|
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 |
|
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 |
|
Delivery-workflow enforcement, mode-independent by design (yolo included):
commit format and mechanical attribution, |
|
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 |
|
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 |
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 |
|---|---|---|
|
MIT |
Deterministic permission gates: bash decomposition, symlink-resolved path
denies, fail-closed posture, subagent ask-forwarding, the |
|
MIT |
Subagent delegation. Chosen over alternatives for its native permission-system
integration ( |
|
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.