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) and one small
domain, hello:
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.jadponames the release line of thejadpothat rannew, sojadpo newfrom 0.1.x writesjadpo: "0.1"(Which jadpo runs). It also holds the project'ssuggestions { project_token: }, 32 random hex digits from the operating system's generator (Sharing with Jadpo HQ); when the generator fails it leaves the block out, andsharewrites it later.- The
hellodomain is one route,POST /hello, withauthentication: RouteAuthentication.none. It takes aVisitorand runsgreet, which returns aGreeting. Becausegreetreaches no entity, root policy grants it withhello.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 codejadpo api updateruns, from these routes. AGENTS.mdsays what Jadpo is, the release lineapp.jadponames, where the docs are (the primer, the index and the error pages on the site, as How an agent uses it describes), and which commands to run after a change..gitignoreholdsbuild/, and.gitattributesholds the lines that keep records readable in a diff (Records and manifest). 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:
Created todo-app jadpo 0.1 route POST /hello files 12 writtennext: 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).
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).
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).
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 routeone kind of test, and--failedthe 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). 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 binarybuild/target/app/app, andbuild/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). - 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). - A deployable built for
Target.wasmis a WebAssembly module with Jadpo's module shim and a Wrangler file, and the screen gives the module's size (A Workers deployable).
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,
"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).
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).
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).
Not built yet:
jadpo test --affected, which runs the tests a change reaches, measured against the merge-base withmain.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). The flag saystoolchain.not_built_yet.- The trace
--keep-failedkeeps, which comes with Debugging and review. jadpo devstarting the services the app's connections declare (External services).
Markdown for agents: /docs/the-jadpo-command.md.Built from Jadpo main at a707efb.