# Commands for packages

A package is code you install rather than write: a library, or a provider
package that calls an outside service such as Stripe ([External
services](11-integrations.md)). These commands install, inspect, change and
publish them. Each built one takes `--json`, and an unknown package,
connection or operation is `cli.package_arguments`, with the nearest.

| Command | Does |
|---|---|
| `jadpo package add <name or source>` | Installs a package |
| `jadpo package import <format> <file>` | Turns a published API description into the app's own integration |
| `jadpo package update <name>` / `remove <name>` | Moves a package to a new version, or removes it |
| `jadpo package show <name> [<declaration>]` | Prints a package's description and public surface |
| `jadpo package link <path>` / `unlink <name>` | Compiles the app against a package's live checkout |
| `jadpo package recipe <package> <recipe> --into <domain>` | Copies a package's recipe into your code |
| `jadpo package record <connection> <operation>` | Confirms an operation against the sandbox and saves the recording |
| `jadpo package conform <package> <capability>` | Runs a capability's conformance suite |
| `jadpo package check` | Runs the publishing bar on a package |

## `jadpo package add`

Installs a package into `packages/<name>/<version>/` and `jadpo.lock`. It
installs from a folder or a git repository's tag, such as
`github.com/acme/acme-pricing@v2.1.0` ([Where packages come
from](11-integrations.md#where-packages-come-from)).

The package is compiled as the app's own integration, and its surface (the
names it makes public) is checked byte for byte against its committed
`surface.jadpo_record` (`install.surface_mismatch`). It is copied without
hidden files and locked with its version, digest and source. A repository
or tag that can't be read is `install.fetch_failed`. An install that adds
a name the app already uses is undone.

## `jadpo package import`

Turns a published description of an API into the app's own integration,
in `shared/providers/<name>/<version>/`, merging your corrections.
`--as <Name.vN>` names it. It reads `openapi`.

## `jadpo package update` and `remove`

`update` moves a folder's package to what the folder holds, and a git
package to its newest release of the same major version. It lists each
surface entry added, changed or removed, marked `used by the app` and
`needs a person`: the review of the surface the app uses that [Records and
manifest](18-records-and-manifest.md) describes. `remove` is refused while
the app's code has `use packages/<name>` (`install.in_use`).

## `jadpo package show`

Prints a package's description, licence, version, kind and public
surface, or one declaration with its file. `packages` is a synonym ([The
surface](11-integrations.md#the-surface)).

The description is in bold. The package's facts follow: its version and
source from its lock line, or "the app's own". Then comes a list per
section and a footer counting them. Given a declaration, it prints that in
full with its file and line and its whole description. `--guide` prints
the package's `GUIDE.md`.

## `jadpo package link` and `unlink`

`link <path>` compiles the app against a package's live checkout: the
lock's line becomes `link <path>`, and the line it replaced is kept in
`.jadpo/links`. Every check reads the checkout in place of the installed
folder and shows its problems there. `unlink <name>` restores the
installed version.

A link is for development only. With `CI` set, `jadpo check` and
`jadpo test` refuse it (`install.link_refused`), and `jadpo build` always
does.

## `jadpo package recipe`

Copies a package's recipe into a domain, where it becomes the app's own
code. Every file under the package's `recipes/<recipe>/` is copied to the
same path under `domains/<domain>/`, all or nothing, and never over a file
the app has. The screen lists each file written, then `jadpo check` as
the hint. `jadpo package check` compiles each recipe in the package's
`sample/` app.

## `jadpo package record`

Confirms an operation against the provider's sandbox and saves the
answer as a recording, for tests ([Provenance and
confirmation](11-integrations.md#provenance-and-confirmation)).

`--input` gives the operation's input as JSON, written as a route's body
is. It calls the sandbox once through the connection, never the live
service and never with a stand-in credential (`recording.refused`). It
checks the answer against the operation's output type and keeps it as
`recordings/<resource>.<operation>.json`, in the app's own integration or
a linked checkout, its plain values replaced by placeholders. A refusal,
no answer, or an answer that doesn't decode keeps nothing
(`recording.failed`). A missing or wrong `--input` is
`cli.package_arguments`.

## `jadpo package conform`

`conform <package> ai` runs the `ai` capability's six cases against a
package: a typed answer, a refusal, a cut-off, a stream, an embedding of
the declared length, and the usage reported ([AI](ai.md)). They run in
a scratch app holding the package as installed. By default they use its
recordings and a local fake on the loopback address, so nothing leaves
your machine.

`--live` runs them against the provider's API, through the app's
connection to the package. It is refused without that connection, without
its credential or address set, or without `ai:` through it
(`conform.refused`). A case that fails is `conform.failed`.

## `jadpo package check`

Runs the publishing bar, the checks a package passes before it is
released, in a package's own repository or the folder given ([Developing
and publishing a package](11-integrations.md#developing-and-publishing-a-package)).

- The package is checked as the app's own integration, each problem shown
  at its place in the package.
- The examples in its descriptions run as tests (`publish.example_missing`,
  `publish.example_failed`).
- The new version's section of `CHANGELOG.md` is written, and needs your
  reason for the release (`publish.changelog_missing`).
- The version is worked out from the surface at the last `v<version>` tag,
  and a breaking change is refused (`publish.breaking_change`).
- A `recipes` row compiles each recipe in the one domain of the package's
  `sample/` app (`publish.sample_missing` without one).

The bar is shown a row per item: passed, failed or not checked yet. When
the package compiles and its version is allowed, `surface.jadpo_record` is
written, to be compared with the previous tag's.

Not built yet:

- `jadpo package new <Name> --library` or `--provider`, which writes a
  package's own repository: the package format, `recipes/`, a `sample/`
  app and `GUIDE.md`.
- `jadpo package publish`, which publishes to the registry. It comes with
  the hosted registry.
- `jadpo package add` from the registry (in the fixed order [Where
  packages come from](11-integrations.md#where-packages-come-from)
  gives), from another Jadpo app's folder (its OpenAPI, such as
  `../orders`), or from a URL serving an OpenAPI document. A registry name
  and another app's folder say `toolchain.not_built_yet` until the
  registry and the importer. A third party's git package will need an
  acceptance, and publisher trust waits for `jadpo approval`.
- `jadpo package import` for `smithy`, `postman`, `har` and `dts`. They
  are `toolchain.not_built_yet` until first needed.
- `jadpo package conform` for any capability but `ai`, which is
  `toolchain.not_built_yet`.
