Shape: Library

A package library ships as a versioned artifact to a public registry -- npm for JavaScript / TypeScript, PyPI for Python, Maven Central for Java / Kotlin / Scala. Like the plugin shape, you don't deploy a library to a running server; the registry distributes it for downstream consumers.

When this shape applies

  • You author a reusable package others consume (not an application).
  • Your release surface is a registry version bump (e.g., npm publish, twine upload, mvn deploy).
  • There is no deployable URL -- the registry IS the deployment target.

project-config.yaml

Pick the channel that matches your registry. Three examples:

# npm
environments:
  - id: registry
    kind: distribution-only

distribution:
  channel: npm
  registry: https://registry.npmjs.org
  manifest: package.json
  release_workflow: gaia-release.yml
# pypi
distribution:
  channel: pypi
  registry: https://pypi.org/simple
  manifest: pyproject.toml
  release_workflow: gaia-release.yml
# maven (group_id + artifact_id required)
distribution:
  channel: maven
  registry: https://oss.sonatype.org/service/local/staging/deploy/maven2
  manifest: pom.xml
  release_workflow: gaia-release.yml
  group_id: com.example
  artifact_id: my-library

manifest points at the file that carries the version (package.json version field, pyproject.toml [project] version, pom.xml <version>). The maven channel requires group_id + artifact_id as per-channel sub-fields; missing either one is rejected by /gaia-config-validate.

Phase 5 routing

With kind: distribution-only + a distribution: block, the Phase 5 router resolves to publish-primary and suggests /gaia-publish. /gaia-post-deploy HALTs with the symmetric use /gaia-publish instead message -- there is no deployed URL to post-deploy verify against.

CI overlays

Library CI typically wants extra steps before the canonical test run -- coverage upload, lint, doc generation. Add them via gaia-ci.user-steps.yml:

steps_before_gaia:
  - name: install dependencies
    run: npm ci
steps_after_gaia:
  - name: upload coverage
    uses: codecov/codecov-action@v4

The stitcher splices steps_before_gaia ahead of the GAIA-generated steps and steps_after_gaia after them. The managed steps are never reordered.

Publish to npm / pypi / maven

/gaia-publish

The orchestrator dispatches the channel-matching adapter (publish-npm, publish-pypi, publish-maven). Each adapter reads the version from the manifest field and invokes the configured release_workflow with the appropriate credentials.

For ecosystems not first-class in this iteration -- cargo (Rust), nuget (.NET), rubygems (Ruby), hex (Elixir), cran (R), helm-chart (Kubernetes) -- use the custom channel and point at a custom adapter under .gaia/custom/adapters/publish-{adapter_name}/. See Shape: CLI for an example.

You'll know it worked when

  • /gaia-config-validate exits 0; ajv accepts the per-channel sub-fields (maven's group_id + artifact_id if applicable).
  • /gaia-help suggests /gaia-publish on the Phase 5 row.
  • A /gaia-publish run posts the version from manifest to the registry, and the registry-side version matches the local manifest.