# 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](/docs/external-services.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 new <Name> --library` or `--provider` `[--publisher <handle>]` | Starts a package in its own repository |
| `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 protocol <document>` | Checks a registry's OpenAPI document against the registry protocol |
| `jadpo package check` | Runs the publishing bar on a package |
| `jadpo package publish [--dry-run]` | Asks the registry to release the package from a tag |
| `jadpo package preview [<folder>]` | Serves the package's registry page locally |
| `jadpo package search <words> [--from <type>] [--to <type>] [--kind <kind>]` | Finds packages and standard-library functions for a need |
| `jadpo package audit` | Lists the advisories against the app's packages, and whether the app reaches each |
| `jadpo package verify <folder> [--previous <folder>] [--publisher <handle>] [--no-run]`, `jadpo package verify --serve` | The registry's verifier: the bar, facts, change record and fingerprints, and the service that answers the registry |

| Command | What it does |
|---|---|
| [`jadpo package`](/docs/jadpo-package.md) | Show, check, import and install packages. |

## `jadpo package new`

Starts a package in its own repository ([Developing and publishing a
package](/docs/developing-and-publishing-a-package.md)): `new <Name>
--library` for code an app calls, or `--provider` for a package that describes
an API. `<Name>` is its name in code, in UpperCamelCase and without a version,
since it starts at `v1`. The folder is made where the command runs and named as
the registry writes the name: `AcmeCouriers` goes in `acme-couriers/`.

It writes the package format, `recipes/`, a `sample/` app and `GUIDE.md`, with
a small example of each kind of file to replace, and the `CHANGELOG.md` and
`surface.jadpo_record` of its first release, so it passes `jadpo package check`
as written and that command has nothing to change. A library starts with the
`starter` library, a recipe and a test. A provider starts with the `account`
resource, a recipe and hosts ending `.example`, and no recording, so its contract
says nothing is confirmed until `jadpo package record` has called the API.
`.gitignore` and `.gitattributes` sit beside them, and git isn't run: making the
repository is yours.

- `--publisher <handle>` writes the index's `publisher:`. Without it the command
  asks on a terminal, where enter leaves the key out, and leaves it out
  everywhere else, `--json` included.
- The licence is `Licence.proprietary` until you choose another, because which
  rights to give others is yours to say. `check` passes it, and `verify` and
  `publish` refuse it (`publish.licence_proprietary`).
- A name that isn't one, or that a package can't compile under, is
  `cli.package_arguments`. A folder that holds anything, or a file of that name,
  is refused as `jadpo new` refuses it, and if a write fails partway the command
  removes what it wrote.

The screen is one status line, then the command to run next:

```text
Created acme-couriers
    package    AcmeCouriers.v1, provider
    publisher  @acme
    licence    proprietary, publishing needs an open one
    jadpo      X.Y
    files      15 written

next: cd acme-couriers && jadpo package check  runs the publishing bar on it
```

With `--json`, `data` holds the `path`, the `root`, the `package`, its `kind`,
`publisher` and `licence`, the `jadpo` line and the `files` it wrote.

## `jadpo package add`

Installs a package into `packages/<name>/<version>/` and `jadpo.lock`. It
installs from the registry by its exact name, `@acme/postcodes`, from a
folder, or from a git repository's tag, such as
`github.com/acme/acme-pricing@v2.1.0` ([Where packages come
from](/docs/where-packages-come-from.md)). A bare name means Jadpo's
own package. The public registry isn't live yet, so a name stops with
`registry.unreachable`: use a folder or a tag.

From the registry it takes the newest release that isn't yanked or a
pre-release, or the one `--to <version>` names, once the registry's public log
proves it (`install.not_proved`). It shows the publisher, whether they are
verified, the package's age and its facts. A name or release the registry
doesn't have is `install.not_in_registry`, a yanked release `install.yanked`,
and a registry it can't read `registry.unreachable` ([How the registry commands
work](/docs/how-the-registry-commands-work.md)).

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, a git package
to its newest release of the same major version, and a package from the
registry to its newest release of that major version at least three days old,
or one marked urgent, naming the newer ones it skipped; `--to <version>` takes
that release at once. An installed
folder changed by hand (`package.digest_mismatch`) is installed again
from its source, even when its release is the newest. It lists each
surface entry added, changed or removed, marked `used by the app`, then
under `Needs a person` each change of what the app uses that an acceptance
must list: the review [Records and
manifest](/docs/package-upgrades.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 ([A package's surface](/docs/the-surface.md)).

The description is in bold. The package's facts follow: its version and
source from its lock line, or "the app's own". Then come [what a release
shows](/docs/the-public-registry.md#what-a-release-shows), as `jadpo package check`
prints it and left out while the app's own integration has errors, 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](/docs/where-packages-come-from.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](/docs/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 protocol`

`protocol <document>` is [the registry protocol](/docs/the-public-registry.md#the-registry-protocol)'s
conformance test: it checks a registry application's OpenAPI document against
the protocol's table, so that application's CI needs only `jadpo`, at the
release it targets. The document is a file, such as the
`build/openapi/main.json` that `jadpo check` writes, an `https://` address, or
an `http://` address on this machine. It needs no project.

A document that conforms is one line:

```text
✓ Conforms to the registry protocol  build/openapi/main.json · 10 requests
```

One that differs is `protocol.mismatch` with each difference under its request,
and exits 1; `--json` gives `document`, `conforms`, `requests` and
`mismatches`, each with its `operation` and `problem`. A document it can't read
is `protocol.unreadable`, which is not a difference.

## `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](/docs/developing-and-publishing-a-package.md)).

- 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).
- A `publisher` row shows who `package.jadpo` names, and says `left out` when
  it names no one: a package only used by path or from git may, and only `verify`
  and `publish` refuse it.
- A `licence` row shows the licence and the lowest Jadpo version it declares. A
  `Licence.proprietary` package passes it, as a private package may, and the row
  says the registry refuses it; only `verify` and `publish` do.

- A `behaviour` row runs the last release's examples and tests against the
  new code. One that fails is a change the types don't show, refused within
  a major version unless the new version's section marks it a fix
  (`publish.behaviour_changed`).

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.

Above the bar, once the package compiles, come the release's
[facts](/docs/the-public-registry.md#what-a-release-shows) and its [change
record](/docs/the-public-registry.md#the-changelog), exactly as the registry will show
them. `--json` gives the same as `facts` and `change_record`, and what the
last release's examples and tests gave as `previous`:

```text
Facts
  kind      library, pure
  storable  OutwardCode, UkPostcode, WrittenPostcode
  failures  uk.tidy: InvalidPostcode

Changes since 2.0.0
  + added  type OutwardCode
```

When the package compiles and sends personal data, a section before the bar
says where: each host, then each operation with what it sends and its
category ([Where personal data goes](/docs/the-personal-data-report.md#where-personal-data-goes)).
`--json` gives the same as `personal_data`, `null` for a package with errors:

```text
Personal data sent
  to https://api.acme-pay.example
  to https://sandbox.acme-pay.example
  customers.create  CustomerRequest.notes  health, sensitive
```

## `jadpo package search`

`search <words> [--from <type>] [--to <type>] [--kind <library or provider>]`
asks the registry for what answers a need, the standard library's first, each
result naming the function and why it matched ([Search](/docs/the-public-registry.md#search)).
`--from` and `--to` read a standard type, or a type of the app here, and send
its shape, never its name or source.

## `jadpo package audit`

Lists the advisories against the app's packages from the registry, and says
whether the app reaches each declaration they name. One it reaches is
`package.advisory`, which fails the command, so CI stops on it; one it doesn't
is listed, and the command passes. It is the one check that goes online
([Yanks, takedowns and advisories](/docs/the-public-registry.md#yanks-takedowns-and-advisories)).

## `jadpo package publish`

Asks the registry to release the package in this repository from its tag,
sending only the repository and the tag, with no sign-in: a releaser confirms
it with a passkey on jadpo.dev ([Releasing](/docs/the-public-registry.md#releasing)). The
tag has to be pushed and the checkout that commit, unchanged
(`publish.not_at_tag`), and the repository reached over HTTPS
(`publish.repository_refused`). It holds the package to the bar here first, then
shows what the registry's verifier found; a refusal is `publish.failed`. A
package whose index names no publisher stops at the bar, having asked nothing
(`publish.publisher_missing`), and a release that isn't its publisher's to make
is `publish.publisher_mismatch` ([Names and
publishers](/docs/the-public-registry.md#names-and-publishers)). So does a package whose licence is `Licence.proprietary`
(`publish.licence_proprietary`). `--dry-run` runs the
verifier and publishes nothing.

## `jadpo package preview`

Serves the package's registry page on this machine, read-only, until it is
stopped: `preview [<folder>]`. It runs the bar as `verify` does and writes
nothing ([Developing for the registry](/docs/the-public-registry.md#developing-for-the-registry)).

## `jadpo package verify`

The registry's verifier, which you can run yourself ([The
verifier](/docs/the-verifier.md)). `verify <folder> --previous
<folder>` runs `check`'s bar on a package as it stands, against the release
in the second folder, and writes nothing. With no `--previous` it is a first
release.

The commit has to carry what its code gives: its `surface.jadpo_record` and
the new version's list in `CHANGELOG.md` are compared rather than written
(`publish.stale_files`).

`--json` writes everything a release shows: the bar's rows, the surface,
facts, change record, each public declaration's fingerprints, what the
previous release's examples and tests gave, and the Jadpo release it was
checked with and the one its `jadpo:` declares ([How they are worked
out](/docs/how-a-releases-facts-change-record-and-fingerprints-are-worked-out.md)).

Its first row, `files`, holds a commit to what a release may hold: only Jadpo
source and the package's text files, within the size limit
(`publish.file_not_allowed`, `publish.too_large`).

Its `publisher` row needs `package.jadpo` to name one
(`publish.publisher_missing`); `check`'s only says `left out`, since a package
used by path or from git may. `--publisher <handle>` says who the release is
for, and a package naming anyone else fails it (`publish.publisher_mismatch`).

Its `licence` row refuses `Licence.proprietary`, which the public registry
doesn't carry (`publish.licence_proprietary`); `check`'s passes it, since a
private package may be.

`--no-run` runs none of the package's code: the rows that need it say
`not run`, and everything worked out from its source is as it would be. It is
how the verifier gets a release's facts from a process the package's code
never ran in.

`--serve` is that verifier, answering the registry: `--listen` says where,
`127.0.0.1:8080` unless given, and `--registry` where previous releases'
archives come from. It needs `JADPO_VERIFIER_TOKEN` and a sandbox, and serves
only on Linux, from its container image (`cli.verifier_start_failed`; [The
verifier](/docs/the-verifier.md)).

Not built yet:

- `jadpo package add` from another Jadpo app's folder (its OpenAPI, such as
  `../orders`), or from a URL serving an OpenAPI document. Another app's
  folder says `toolchain.not_built_yet` until the importer. A package from git needs a person's
  acceptance once installed (`PackageChange.git_source`), unless its
  repository is under one of `packages:`'s `own_sources:`.
- `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`.
