# The `jadpo` command

You work with Jadpo through one command, `jadpo`, and a short list of
subcommands. Run them anywhere inside your project: each finds the project
by walking up from the current folder to `app.jadpo`, so you only give a
path to work on another project. Every subcommand takes `--json`, for
output an agent reads instead of prose, except the interactive modes,
which need a terminal.

Commands have plain synonyms where people reach for either word, such as
`fmt` and `format`, and an unknown command suggests the nearest. Tab
completes commands, flags and your project's own names, and a command
missing an argument asks for it from a searchable list.

The commands you use every day:

| Command | Does |
|---|---|
| `jadpo new <name>` | Starts a project |
| `jadpo check` | Checks everything and writes the derived files in `build/` |
| `jadpo fmt` | Formats your code |
| `jadpo test` | Runs your tests |
| `jadpo build [<deployable>]` | Builds the programs you deploy, into `build/target/` |
| `jadpo dev` | Runs the app locally, rebuilding it on every save |

## `jadpo new`

`jadpo new <name>` starts a project in a folder that doesn't exist yet or
is empty, and the project passes `jadpo check`, `jadpo fmt --check` and
`jadpo test` as soon as it is written. It writes the fixed root
([The root](the-root.md)) and one small
domain, `hello`:

```text
todo-app/
  app.jadpo        application { jadpo: "0.1" } and the project token
  config.jadpo     config {}, with no settings yet
  policy.jadpo     who may run greet: Access.public
  api/
    main.jadpo_record    as jadpo api update writes it
  domains/
    hello/
      types/       visitor.jadpo  greeting.jadpo
      actions/     greet.jadpo
      routes/      hello.jadpo  hello.test.jadpo
  database/        empty
  tests/           empty
  AGENTS.md  .gitignore  .gitattributes
```

- `app.jadpo` names the release line of the `jadpo` that ran `new`, so
  `jadpo new` from 0.1.x writes `jadpo: "0.1"`
  ([Which jadpo runs](which-jadpo-runs.md)). It also holds the project's
  `suggestions { project_token: }`, 32 random hex digits from the
  operating system's generator ([Sharing with Jadpo
  HQ](#sharing-with-jadpo-hq)); when the generator fails it leaves the
  block out, and `share` writes it later.
- The `hello` domain is one route, `POST /hello`, with
  `authentication: RouteAuthentication.none`. It takes a `Visitor` and
  runs `greet`, which returns a `Greeting`. Because `greet` reaches no
  entity, root policy grants it with `hello.greet: [Access.public]`. The
  route's test, beside it, posts a visitor and checks the status and the
  greeting. The API record is written by the code `jadpo api update`
  runs, from these routes.
- `AGENTS.md` says what Jadpo is, the release line `app.jadpo` names,
  where the docs are (the primer, the index and the error pages on the
  site, as [How an agent uses it](https://github.com/jadpo-dev/jadpo/blob/main/docs/documentation.md) describes), and
  which commands to run after a change. `.gitignore` holds `build/`, and
  `.gitattributes` holds the lines that keep records readable in a diff
  ([Records and manifest](records-and-manifest.md)). There are no
  hidden folders.

The project is named after the folder: the last part of `<name>`, or the
folder it runs in for `jadpo new .`. A folder that holds anything, hidden
files included, is refused with `toolchain.scaffold_destination_not_empty`
and left as it was; a file of that name is
`toolchain.scaffold_destination_exists`, and a `<name>` that ends in no
folder's name, such as `..`, is `toolchain.scaffold_name_invalid`. If a
write fails partway, `jadpo new` removes what it wrote and reports
`toolchain.scaffold_write_failed`.

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

```text
Created todo-app
    jadpo  0.1
    route  POST /hello
    files  12 written

next: cd todo-app && jadpo dev  serves it on http://localhost:3000
```

With `--json`, `data` holds the `path` as typed, the `root`, the `jadpo`
line, the `routes` and the `files` it wrote.

## `jadpo check`

`jadpo check` checks the whole project and writes the files derived from
it: `build/manifest.json` and the catalogues in `build/catalogue/`
([The `build/` folder](the-build-folder.md)).

## `jadpo fmt`

`jadpo fmt` formats every file. It fixes each file's imports first, then
lays the file out, writing each file's declarations before their use, the
primary declaration last. `--check` only reports what it would change, and
`--layout` also makes promotion moves ([Formatting](formatting.md)).

## `jadpo test`

`jadpo test` runs every test. It runs pure and action tests in the
interpreter, route tests, and schedule tests (`--kind schedule`). It also
reads each recording of the app's own integrations through its
operation's decoders (`--kind recording`), and each recorded answer to a
prompt through each type the prompt is asked for as. A recording made from
an older version of the prompt is an alert on the report and in
`data.alerts` ([Kinds of test](kinds-of-test.md)).

To run fewer tests:

- `jadpo test <file>` runs one test file, and `<file>:<line>` the test at
  that line. A folder runs the tests under it.
- `--name <text>` runs the tests whose names match, `--kind route` one
  kind of test, and `--failed` the last run's failures.
- `--seed <n>` reruns the tests in the order a given seed sets.

`jadpo test --watch` reruns the affected tests on every save. Each save
reruns the tests that reach something whose digest, a hash of its code,
changed since the last run, within the path, name and kind you gave. While
the build is broken it shows the errors and runs nothing. With `--json` it
writes one envelope per line. Ctrl-c quits.

`--keep-failed` keeps a failed test's database and names it in the report.

## `jadpo build`

`jadpo build` writes the runnable app into `build/target/`, with each
API's `<api>.failures.<locale>.json` beside its OpenAPI document
([Configuration and time](configuration-and-time.md)). It takes
`--json`. It first checks as `jadpo check` does, writing the same files,
and stops at the errors.

- An app that declares no deployables builds its one deployable, `app`,
  natively: the binary `build/target/app/app`, and `build/target/app/openapi/`
  with each API's document and failure files. It is built with the
  toolchain and lock this Jadpo pins ([A native
  deployable](#a-native-deployable)).
- An app that declares deployables builds every one, or the one you name,
  each into `build/target/<deployable>/` beside only its own APIs'
  documents ([Declared deployables](declared-deployables.md)).
- A deployable built for `Target.wasm` is a WebAssembly module with
  Jadpo's module shim and a Wrangler file, and the screen gives the
  module's size ([A Workers deployable](a-workers-deployable.md)).

## `jadpo dev`

`jadpo dev` runs your app locally and keeps it up to date as you edit. It
runs the app in the interpreter at `http://localhost:3000` (`--port`
changes it) and prints one line per request with its request id.

Each save that checks cleanly serves the next request. While a save has
errors, the last good version keeps serving. `--no-run` only checks on
every save and writes `build/`, and `--json` writes one envelope per line.

An editor that saves a file in place first empties it, then writes its
text. So a save that leaves a file empty that had text isn't taken as
finished yet: the reload waits up to 2 seconds for the file's text. An
empty routes file checks cleanly, with no routes, so this keeps a
half-saved file from replacing the version serving. A file still empty
after that reloads as saved ([design notes](https://github.com/jadpo-dev/jadpo/blob/main/docs/language/notes/14-tooling.md),
"Watching saves"). `jadpo test --watch` waits the same way.

**Settings.** The settings `config.jadpo` declares are read from the
environment, then `.env.local`, and checked before the app starts. A
missing or invalid value stops it starting, and the screen names the
setting and its variable, never the value. A save of `.env.local` is
checked like a save of source, so the last good version keeps serving.

**Databases.** Each database opens at the address its connection's `url:`
setting holds, or the one `--url` names. A store whose address no
variable gives gets a disposable PostgreSQL for the session. Jadpo starts
that from PostgreSQL's own programs (`initdb`, `pg_ctl` and `postgres`), so
PostgreSQL has to be installed on your machine; you don't create a
database or set a password. Pending migrations are applied as they appear.
While it runs, the address of each database it started is in
`build/dev/stores.json`, for `jadpo schedules` and `jadpo why`.

**Background work.** Each schedule run and each skipped tick (a paused
schedule's, once) gets a line with its trace's id, its outcome, what it
emitted or its failure, and its time. Each alert gets a line when it
starts. Each step reached by an action with several changing calls is a
line under its request's line. A delivery whose action reached steps gets
a line of its own, with `jadpo deliveries show <id>` when it needs an
operator ([Jobs and events](jobs-and-events.md)).

**Provider calls.** Every call to an outside provider is faked by default,
so you need no credential. A connection's `development: { sandbox: }`
lets calls through to the provider's sandbox, never to its live service.
`--fake <connection>` and `--sandbox <operation>` change which for one
session only. Each request's line lists its calls, and each call is logged
for `jadpo calls` ([Provider calls in
development](11-integrations.md#provider-calls-in-development)).

**Stopping.** Ctrl-c or SIGTERM stops it cleanly: the server finishes the
requests it has, its background work gives back what it holds, and it
exits 0. A second signal ends it at once ([Running background
work](12-jobs-and-events.md#running-background-work)).

Not built yet:

- `jadpo test --affected`, which runs the tests a change reaches,
  measured against the merge-base with `main`.
- `jadpo test --interactive`, a keyboard view of every test: search,
  move between tests, run a file, one test or all, rerun failures and
  turn watching on and off ([Testing](testing.md)). The flag says
  `toolchain.not_built_yet`.
- The trace `--keep-failed` keeps, which comes with
  [Debugging and review](debugging-and-review.md).
- `jadpo dev` starting the services the app's connections declare
  ([External services](external-services.md)).
