CLI

@herald-run/cli sends messages and requests, waits for answers, moves files and secrets, and runs tasks. It needs Node.js 20 or later.

Three commands carry everything: herald send and herald ask reach every message, form, file and secret capability through flags, and herald register defines the task types the app can dispatch. wait, listen and the rest support them.

npx @herald-run/cli --help        # or: npm install -g @herald-run/cli
herald login

Authentication

herald login approves the device in your browser and stores a scoped token in ~/.config/herald (mode 0600). It requests every scope unless --scopes names fewer, and reuses its connection when you log in again. herald logout revokes the token. The token holds the connection's end-to-end key, so content is encrypted on your machine. The approval page shows your safety code; herald login prints the code it received and asks you to confirm they match, or takes --safety-code <code> without a terminal. It stores nothing on a mismatch. A new account gets its keys when you first open Herald on a signed-in device, so do that before herald login.

The token is taken from, in order: HERALD_API_KEY, HERALD_TOKEN, then the stored login. --profile NAME (or HERALD_PROFILE) keeps separate logins, for example for two accounts; --url (or HERALD_URL) selects another server.

Output and exit codes

Output is human-readable; --json prints the API records instead. Exit codes: 0 success or answered, 1 error (including a wait that timed out), 2 usage, 3 expired, 4 cancelled. herald completion bash|zsh|fish prints a completion script.

Sending and asking

Flags build any message without a JSON file:

herald send --kind report --title 'Nightly report' --body-file summary.md --block table=metrics.csv --block image=latency.png --file report.pdf
herald ask --title 'Deploy 2.4.0?' --review --block diff=change.diff --action approve --action reject --json
herald ask --title 'Release settings' --field 'channel:select:Channel:beta,stable' --field 'notes?:textarea'
herald ask --title 'GitHub token' --field 'token:secret:GitHub token (repo scope)' --out ~/.config/tool/token
herald ask --title 'Staging kubeconfig' --field 'kubeconfig:secret-file' --out ~/.kube/staging
herald send --secret-file ./generated-password --title 'Staging password'
  • --field ID:TYPE[:LABEL[:CHOICES]] adds a form field, required unless the ID ends in ?. Types: text, textarea, number, boolean, select, multiselect, date, secret, file, secret-file. Choices are value[=Label], comma-separated.
  • --action ID[:LABEL] adds a one-tap button that answers with no values, so every field must be optional and none secret or file.
  • --block TYPE=PATH shows a file above the form: code (language from the extension), diff, json, table (CSV, first row as columns) or image (attached and shown inline). - reads stdin. --review opens the full view before answering.
  • --out [FIELD=]PATH writes a secret, or a secret-file/file upload, to a new file with mode 0600; every secret field needs one, and values never reach the output. herald wait takes --out too.
  • --secret-file PATH offers the file's content as an encrypted secret and waits until your device collects it.

Input files

-i, --input FILE takes the full JSON body for send, ask and destinations, so everything in Concepts, including JSON Schema forms and actions with values, works from the CLI. Flags merge on top: --title and --body replace, fields, actions, blocks and files add. An image block may name a local "file" instead of an attachmentId; the CLI uploads it.

{
  "title": "Ready to deploy?",
  "body": "The checks passed.",
  "fields": [
    { "id": "approve", "type": "boolean", "label": "Deploy now?", "required": true },
    { "id": "notes", "type": "textarea", "label": "Anything else?" }
  ]
}
herald ask -i approval.json --timeout 10m --json

Commands

This reference is generated from the CLI's own help.

Usage: herald <command> [options]

Commands:
  login         Connect this device in the browser and store a token
  logout        Revoke the stored token and delete it locally
  whoami        Show the token, its scopes, the account and its safety code
  status        Check the server and the stored token
  send          Send a message; --wait waits for an answer
  ask           Send a request and wait for the answer
  wait          Wait for a request to finish
  cancel        Cancel a pending request
  messages      List messages, newest first
  search        Search messages
  show          Show a message with its answer and logs
  thread        List a thread, oldest first
  logs          Print task logs
  download      Download an attachment (--out - writes stdout)
  destinations  Manage this connection's destinations
  register      Register or update a destination by key
  listen        Run tasks for a pull destination
  watch         Print messages as they change
  account       Show the account holder, this connection, plan and usage
  completion    Print a shell completion script
  help          Show help for a command

Global options:
  --json             Machine-readable JSON output
  --profile NAME     Use a named profile (or HERALD_PROFILE)
  --url ORIGIN       Server (or HERALD_URL; default https://app.herald.run)
  -h, --help         Show help
  --version          Print the version

Exit codes: 0 success or answered, 1 error, 2 usage, 3 expired, 4 cancelled.
HERALD_API_KEY or HERALD_TOKEN supplies a token. Run herald help <command> for details.

herald login

Usage: herald login [options]

Connect this device in the browser and store a token.
Default scopes: messages:send, messages:read, destinations:manage, events:read, files:write.
The approval also certifies an end-to-end key stored with the token. Confirm that the safety code matches the approval page, or pass it with --safety-code when not in a terminal.

Options:
  --name NAME        Connection name (default: Herald CLI (<host>))
  --scopes LIST      all, or comma-separated scopes
  --no-browser       Print the approval link only
  --safety-code CODE Expected 30-digit account safety code (end-to-end encryption)

herald logout

Usage: herald logout

Revoke the stored token and delete it locally.

herald whoami

Usage: herald whoami

Show the token, its scopes, the account and its safety code.

herald status

Usage: herald status

Check the server and the stored token.

herald send

Usage: herald send [options]

Send a message; --wait waits for an answer.
Fields: ID[?]:TYPE[:LABEL[:CHOICES]], required unless ID ends with ?. TYPE: text, textarea,
number, boolean, select, multiselect, date, secret, file or secret-file (one file for this
connection only). LABEL (no colons) defaults to the ID; select and multiselect need CHOICES: a,b or
a=Label,b. Actions: ID[:LABEL] answers in one tap; every field must be optional, none secret or file.
Blocks: code, diff, json and table (CSV) read PATH (- for stdin); image attaches the file.
--out [FIELD=]PATH writes a secret or file answer to a new 0600 file (several files: a 0700
directory); every secret needs one, and values are never printed. PATH alone fits a single field.
With -i, flags win for title, body and kind and add fields, actions, blocks and files; an image
block there may give "file": PATH instead of attachmentId. Instead of fields, -i input may give
"questions": [{question, header?, options: [{label, description?, preview?}], multiSelect?}],
answered as q1, q2… (each also accepts Other text).
--secret-file offers a secret from a private file (≤16,000 bytes) and waits for its delivery.

Options:
  -i, --input FILE   JSON input (message, form or destination)
  --title TEXT
  --body TEXT        Markdown body
  --body-file PATH   Markdown body from a file (- for stdin)
  --kind KIND        message (default), report or files; form with fields or waiting
  --field SPEC       Add a form field; repeatable (see above)
  --action ID[:LABEL] Add a one-tap answer; repeatable
  --block TYPE=PATH  Add a code, diff, json, table or image block; repeatable
  --file PATH        Attach a file; repeatable
  --review           Mark the request as needing review
  --reply-to ID      Reply in a thread
  --deadline 10m     Server deadline for the request
  --key KEY          Idempotency key for safe retries
  --wait             Wait for the answer
  --timeout 1h       How long to wait (default 3600 s)
  -o, --out [FIELD=]PATH New output file (must not exist); repeatable for answers
  --secret-file PATH Offer the secret in a private file instead

herald ask

Usage: herald ask [options]

Send a request and wait for the answer.
Fields: ID[?]:TYPE[:LABEL[:CHOICES]], required unless ID ends with ?. TYPE: text, textarea,
number, boolean, select, multiselect, date, secret, file or secret-file (one file for this
connection only). LABEL (no colons) defaults to the ID; select and multiselect need CHOICES: a,b or
a=Label,b. Actions: ID[:LABEL] answers in one tap; every field must be optional, none secret or file.
Blocks: code, diff, json and table (CSV) read PATH (- for stdin); image attaches the file.
--out [FIELD=]PATH writes a secret or file answer to a new 0600 file (several files: a 0700
directory); every secret needs one, and values are never printed. PATH alone fits a single field.
With -i, flags win for title, body and kind and add fields, actions, blocks and files; an image
block there may give "file": PATH instead of attachmentId. Instead of fields, -i input may give
"questions": [{question, header?, options: [{label, description?, preview?}], multiSelect?}],
answered as q1, q2… (each also accepts Other text).
Without fields or actions, it asks for a free-text reply.

Options:
  -i, --input FILE   JSON input (message, form or destination)
  --title TEXT
  --body TEXT        Markdown body
  --body-file PATH   Markdown body from a file (- for stdin)
  --kind KIND        message (default), report or files; form with fields or waiting
  --field SPEC       Add a form field; repeatable (see above)
  --action ID[:LABEL] Add a one-tap answer; repeatable
  --block TYPE=PATH  Add a code, diff, json, table or image block; repeatable
  --file PATH        Attach a file; repeatable
  --review           Mark the request as needing review
  --reply-to ID      Reply in a thread
  --deadline 10m     Server deadline for the request
  --key KEY          Idempotency key for safe retries
  --timeout 1h       How long to wait (default 3600 s)
  -o, --out [FIELD=]PATH New output file (must not exist); repeatable for answers

herald wait

Usage: herald wait <message-id> [options]

Wait for a request to finish.
Secret answers are shown as not collected unless --out FIELD=PATH stores them.

Options:
  --timeout 1h       How long to wait (default 3600 s)
  -o, --out [FIELD=]PATH New output file (must not exist); repeatable for answers

herald cancel

Usage: herald cancel <message-id>

Cancel a pending request.

herald messages

Usage: herald messages [options]

List messages, newest first.
Content is end-to-end encrypted, so the server cannot search it: the newest five pages are decrypted and filtered locally.

Options:
  --search TEXT
  --status STATUS    pending, answered, expired, cancelled, ...
  --direction DIR    inbound or outbound
  --before CURSOR    Older page: createdAt|id
  --after N          Revision or log sequence to start after
Usage: herald search <text> [options]

Search messages.
Content is end-to-end encrypted, so the server cannot search it: the newest five pages are decrypted and filtered locally.

Options:
  --status STATUS    pending, answered, expired, cancelled, ...
  --direction DIR    inbound or outbound

herald show

Usage: herald show <message-id>

Show a message with its answer and logs.

herald thread

Usage: herald thread <message-id>

List a thread, oldest first.

herald logs

Usage: herald logs <task-id> [options]

Print task logs.

Options:
  --after N          Revision or log sequence to start after

herald download

Usage: herald download <file-id> [options]

Download an attachment (--out - writes stdout).
Files are end-to-end encrypted: --message names the message that carries the file.

Options:
  -o, --out [FIELD=]PATH New output file (must not exist); repeatable for answers
  --message ID       Message with the attachment (decrypts it)

herald destinations

Usage: herald destinations [list | update <id> -i file | remove <id> | rotate-secret <id>] [options]

Manage this connection's destinations.

Options:
  -i, --input FILE   JSON input (message, form or destination)

herald register

Usage: herald register [options]

Register or update a destination by key.
Each --field (no secret or file types) belongs to the --type before it. Tasks are pulled with herald listen unless --webhook is set. Session types need -i.

Options:
  -i, --input FILE   JSON input (message, form or destination)
  --target KEY       Destination key
  --webhook URL      Deliver tasks to a webhook instead of herald listen
  --description TEXT
  --type ID[:LABEL]  Add a request type; repeatable
  --field SPEC       Add a form field; repeatable (see above)

herald listen

Usage: herald listen [options]

Run tasks for a pull destination.
The runner config may omit destinationId; --target then names the destination key.

Options:
  --target KEY       Destination key
  --config FILE      Runner config
  --concurrency N    Tasks at once (1-16)

herald watch

Usage: herald watch [options]

Print messages as they change.

Options:
  --after N          Revision or log sequence to start after

herald account

Usage: herald account

Show the account holder, this connection, plan and usage.

herald completion

Usage: herald completion bash|zsh|fish

Print a shell completion script.

herald help

Usage: herald help [command]

Show help for a command.