Tide

CLI reference

tide run / resume / test / schema / serve and every flag.

The tide binary has eight subcommands. A bare tide <file> is shorthand for tide run <file>.

tide install  [project-dir]
tide publish  --server <registry-url> --name <name> --version <semver> <dir>
tide run     [options] <file>
tide follow  --server <url> <invocation-id>
tide resume  <invocation-id> --action <action> [options] <file>
tide test    [options] [paths...]
tide schema  <file>
tide serve   [options]
tide --version
tide --help

tide install

Parse tide.json, resolve exact plugin versions, invoke statically available host installers, write tide.lock, and generate verified JavaScript/type artifacts under .tide/plugins/.

tide install
tide install examples/employment-onboarding

Phase 1 supports known "source": "builtin" plugins. Registry, URL, local native, and Rust dylib installs fail explicitly; a JavaScript shim cannot add native Rust code to an already-compiled executable.

tide run

Run or replay a workflow, continuing through interactive human waits when safe.

tide run workflow.ts --input '{"name":"Ada"}'
tide run workflow.ts -i order-001 --input '{"name":"Ada"}'   # explicit id
tide run workflow.ts -i order-001                            # replay
FlagDefaultDescription
-i, --invocation-id <id>random UUIDNames the journal. Re-running with the same id replays it. Omit it and every run is a fresh one-shot.
--input <json>JSON input, validated against the workflow schema.
--input-file <path>Read JSON input from a file. Mutually exclusive with --input.
--store <memory|fs|sqlite|postgres>memoryWorkflow journal store. Memory is process-local; use a persistent backend for replay after exit. See Storage.
--argon <url>embeddedBack the installed argon plugin with a remote ox runtime serve endpoint instead of the static embedded host.
--jsonoffEmit one machine-readable JSON result object instead of streaming console output (see below). Disables HITL prompting.
--no-interactiveoffSuspend at hitl.wait without prompting, even in a terminal.
--server <url>Submit and follow an exact <name>@<semver> on a Tide server. Local paths are not accepted remotely.

The shipped binary embeds Argon and runs against a durable main world. Two embedded-only flags tune that world on run/resume:

FlagDefaultDescription
--world-dir <dir><project>/.tide/worldRoot the durable main event log elsewhere.
--freshoffWipe the durable world before this run (start from the .oxbin seed; equivalent to rm -rf .tide/world).

Tide prints the invocation id to stderr at startup (invocation: <id>). Workflow log / console.log output goes to stdout; console.error to stderr.

Interactive human waits

In human-readable mode, when both stdin and stdout are terminals, tide run handles hitl.wait in place. It prints the complete task request, asks for the action, optional payload JSON, and optional comment, appends the validated decision, and replays the same invocation immediately. Sequential waits repeat the prompt until the workflow completes, fails, or input is cancelled. A finite actions list is shown as numbered choices; otherwise the action is free text.

The invocation id, workflow store instance, and backend are retained across the loop. This makes the default memory store useful for interactive approvals while the process remains alive. With embedded Argon, the invocation fork stays attached across each suspension and is promoted only when the run completes.

Prompts are disabled by --json, --no-interactive, or piped/non-TTY stdio. Those modes return waiting_human without blocking. Choose --store fs, sqlite, or postgres if another process must later run tide resume. EOF or Ctrl-C records no partial decision; a persistent run stays resumable, while a memory-backed run prints that it cannot survive process exit.

--json output

For driving tide run programmatically. One JSON object to stdout:

{
  "status": "completed",
  "output": [{ "level": "log", "message": "hired Ada …" }],
  "error": null,
  "pendingHumanWait": null,
  "result": { "employeeId": "…" },
  "resultDigest": "sha256:…",
  "settlement": "promote_on_success",
  "invocationId": "…"
}

status is completed, failed, or waiting_human. A waiting_human status carries pendingHumanWait (task id + wait ordinal). With a persistent workflow store, a caller can issue the matching tide resume. A memory-backed run emits a warning to stderr instead because its invocation disappears at process exit. See Driving Tide programmatically.

Remote execution

tide run --server http://127.0.0.1:4100 onboarding@1.2.0 \
  --invocation-id onboarding_signal_123 --input '{"name":"Ada"}'
tide follow --server http://127.0.0.1:4100 <invocation-id>

Remote mode follows status and cursor-addressed console output and uses the same terminal HITL prompt as local mode. --json remains non-interactive. Ctrl-C stops following without cancelling the server invocation; use tide follow to reconnect. Completed and waiting invocations exit zero; failed or transport errors exit non-zero. --invocation-id supplies the caller-owned idempotency key; an exact retry follows the existing invocation instead of requeueing it.

tide publish

Build and upload a deterministic immutable workflow package:

tide publish --server http://127.0.0.1:4200 \
  --name onboarding --version 1.2.0 ./workflows/onboarding

--entry <path> overrides main.ts; --json emits name, exact version, digest, size, and idempotency. Identical republish succeeds; different bytes at an existing version fail with a conflict. This workflow registry is separate from tide.json plugin resolution.

tide follow

Reconnect to an existing remote invocation. It accepts --json and --no-interactive with the same meaning as remote run.

tide resume

Resolve a workflow suspended at hitl.wait and continue it.

tide resume order-001 workflow.ts --action approved \
  --payload '{"note":"ok"}' --comment "verified"

For a remote invocation the workflow file and local store are not needed:

tide resume --server http://127.0.0.1:4100 order-001 \
  --action approved --comment "verified"
Argument / flagDescription
<invocation-id> (positional)The suspended invocation.
<file> (positional)The workflow file to replay.
--action <action>Required. Must match a configured request action, or any non-empty string when the request leaves actions open.
--payload <json>Optional JSON payload attached to the decision.
--comment <text>Optional free-text comment.
--store <memory|fs|sqlite|postgres>Workflow store backend (default fs). A new process cannot resume a memory-backed run.
--argon <url>Remote Argon endpoint (as for run).
--server <url>Resolve the current remote task and continue following it.

tide resume records the decision into the journal, replays the run to the suspension point, and resumes. See Human-in-the-loop.

tide test

Discover and run *.test.ts / *.spec.ts files through the built-in describe / test / assert / expect harness.

tide test                 # discover from the current directory
tide test workflows/      # restrict to a path
tide test --json          # structured per-suite / per-case results
FlagDefaultDescription
[paths...].Files or directories to search for tests.
--store <memory|fs|sqlite|postgres>fsStore backend.
--jsonoffPrint { status, suites: [...] } JSON.

Each test case runs in its own isolated, throwaway world store — one case's writes never leak into the next, and tests never touch the persistent .tide/world. Exit code is non-zero if any case fails.

tide schema

Print a workflow's input schema as JSON — the machine-readable manifest of the inputs it accepts.

tide schema workflow.ts

tide serve

Run the HTTP /v1 control surface over the workflow runner. Flags and routes are documented in the serve guide.

tide serve --workflows workflows --port 4100 --workers 4
tide serve --workflows workflows --registry http://127.0.0.1:4200
FlagDefaultDescription
--port <port>4100TCP port (bound on 127.0.0.1).
--workflows <dir>workflowsWorkflow source root (<dir>/<name>/main.ts).
--registry <url>TIDE_REGISTRY_URLRegistry for exact name@version; unversioned names remain local.
--store <memory|fs|sqlite|postgres>fsStore backend.
--workers <n>1Worker-pool size; >1 runs invocations in parallel.
--argon <url>embeddedServe against a remote Argon endpoint.

Exit codes

CodeMeaning
0Success — completed, or waiting_human (suspended, awaiting tide resume).
non-zeroA failed run, a test failure, or a usage / infrastructure error.

Driving Tide programmatically

tide is built to be driven by a coding agent with three commands and no other tooling:

  1. Discover the input. tide schema workflow.ts prints the input schema as JSON — the manifest for constructing a valid --input.
  2. Run it. tide run workflow.ts --input '<json>' --json runs the workflow and prints one JSON result object (status, console output, error, pending human wait, invocation id). For resumable human waits, select a persistent store when starting the run, then issue tide resume <invocationId> --action <action> --store <same-store>.
  3. Test it. tide test --json prints { status, suites: [...] }, each suite carrying per-case status and error, exiting non-zero on any failure.

On this page