Docs/CLI reference

CLI reference

tama request

Answers one Tama Desktop request and exits: the JSON body on stdin, NDJSON events on stdout. Tama Desktop runs one tama request process per operation, so no Tama process stays running between two operations and no port is opened.

Answers one Tama Desktop request and exits: the JSON body on stdin, NDJSON events on stdout. Tama Desktop runs one tama request process per operation, so no Tama process stays running between two operations and no port is opened.

#Invocation

tama request <operation> [--root <release-path>]

<operation> names one operation from the table below. --root selects the sealed hook release the operation reads; the desktop passes the release bundled into the app. The body is read from stdin to its end before anything runs, and an empty body is {}, so an operation that takes no fields needs no input: tama request coverage < /dev/null.

#Operations

OperationBodyAnswer
coveragenoneRegistry-declared provider coverage, the document Coverage reads
install/plannoneThe document tama install plan --json prints
mcp/confignoneThe document tama mcp config prints
enforcementnoneThe machine hook selection tama enforcement status --json prints
enforcement/update{mode, enabled}: mode is all with no enabled, or only, add or remove with a non-empty array of hook ids. add and remove change the named hooks against the selection as it is when the change is written, as tama enforcement add|remove do. Another mode is a 400, mode must be "all", "only", "add" or "remove"; every refusal of those commands is a 400 with its sentenceThe selection after the change
hooks/warm{only?}: hook ids; empty or absent warms every hookThe report tama hooks warm --json prints
policy-bundlesnoneRetained inactive source identities
policy-bundles/import{sourcePath, replace?}The same validating transaction as tama policy import; it never enables hooks
violations/scan{repo, mode?}: mode is size-only, duplicates, internal-names or time-limits; absent replays the hooks, anything else is a 400 naming the fourA streamed job: tama violations find --repo <repo> --json [--<mode>]
violations/clean{repo, maxRounds}: maxRounds is how many repair rounds the run may take, a number above zero; without it the request is a 400, clean requires maxRounds: how many repair rounds the run may take, a number above zero; tama violations clean --max-rounds has no default eitherA streamed job: tama violations clean --repo <repo> --max-rounds <maxRounds>; it may modify the repository
worktrees/list, worktrees/removeroots: nonempty strings; removal adds optional except strings and apply/force booleans. Omitted optional fields mean preview-only, non-forced behavior with no exclusions. Malformed fields are refused with their decode cause.The documents tama worktrees prints under --json
copies/list, copies/remove{roots}; removal adds {except?, only?, apply?, force?}The documents tama copies prints under --json
reviews/list, reviews/shownone; {id}The listing or record from tama reviews; per-record read failures remain explicit rows, never passing review results.
builds, builds/record, builds/closenone; {kind, target, reason, revision?, repository?, minutes?, approvalSession?, approvalQuote?}; {kind, target}The registry and entries tama build reads and writes
rules/digest, rules/dismissnone; {id}The digest tama rules digest prints under --json; {dismissed, detail}
justifications/cuanone{kind, registry, authorizations}
justifications/cua/record{sessionId, app, actions, quote} or {sessionId, app, actions, quoteMatch}, with actions an array of strings{kind, registry, sessionId, authorization}
justifications/cua/remove{quote}{kind, registry, removed, count}
justifications/sshnone{kind, registry, authorizations}: every grant block-unauthorized-ssh reads
justifications/ssh/record{sessionId, targets, operation, paths, commands, quote} or the same with quoteMatch; targets, paths and commands arrays of strings, exactly one of paths (read, write) or commands (exec, transfer, tunnel, git) non-empty{kind, registry, sessionId, authorization}
justifications/ssh/remove{quote}{kind, registry, removed, count}
justifications/record{kind, file, justification, expiresAt?, trajectoryEvidence?}, where kind is file; trajectoryEvidence is written as trajectory_evidence_justification beside the justification, as tama justify record --trajectory-evidence writes it{recorded, kind, registry}
tests/approvalsnone{approved, record}: every approval tama tests list reads
tests/approve, tests/revoke{paths}, an array of files or directories; a relative path is read against the home{changed, action, approved, record}, the same change tama tests approve|revoke makes
tests/audit{roots, remove?}: repositories or directories holding them; remove: true deletes every unapproved test filethe document tama tests audit --json prints: {approval_record, repositories_read, approved, unapproved, remaining, repositories, failures}

The justification operations reuse tama justify validation and registry transactions. They use the process's home and runtime transcript directory; a request cannot choose another home or transcript source. Recording requests reject unknown fields, and none of these operations issues capabilities, enables hooks or starts Cua Driver.

#Output and state

stdout carries only NDJSON events. A bounded operation prints exactly one:

{"type":"response","status":<status>,"json":{…}}

status is 200 for an answer, and json is the document the matching command prints. Any other status is a refusal named in HTTP's vocabulary — 400 a request the operation refuses, 403 an operation disabled on this machine, 404 an unknown operation, 500 a failure while it ran — and its json is {"error": "<one sentence>"}, the product's own refusal, verbatim.

A streamed job (violations/scan, violations/clean) prints its own output as it happens, then one result:

{"type":"log","stream":"stdout"|"stderr","chunk":"…"}   (zero or more)
{"type":"result","status":<exit-code>,"json":{…}}       (exactly one, last)

The result's status is the exit code the command would have ended with — for a scan, 1 means violations were found, not that the scan failed — and json is its document. A job refused before it starts prints one response instead. The process exits 0 after a 200 response, 1 after any other response, and with the job's own status after a result. Tama keeps no state of its own for a request; the operation writes what the matching command writes, and cleanup may modify the requested repository.

#Refusals and failures

  • No operation: request requires an operation, exit 2, nothing on stdout.
  • A second positional argument: unexpected request argument: <argument>, exit 2.
  • Any option but --root: unknown request option: <option>, and missing value for --root for a bare --root; both exit 2.
  • An unknown operation: a 404 response, unknown operation: <operation>.
  • A body that does not parse: a 400 response, request body is not valid JSON.
  • Unreadable stdin: failed to read the request body from stdin: <reason> on stderr, exit 1, nothing on stdout.
  • A missing HOME for the build and justification operations: a 500 response, HOME is not set.
  • Policy import requires a nonempty sourcePath and a supported bundle. Invalid input returns the core refusal; conflict and rejected results remain structured documents with no partial writes.
  • A reader that closes stdout ends the process at its next event. Tama Desktop ends the whole process tree when a scan or cleanup is cancelled or the app quits.

Return to the complete CLI command tree.