tufty.aitufty.ai CLI
CLI

Output Modes

The JSON envelope, URL-only output, saving files locally, and --dry-run estimates.

Stdout and stderr

tufty keeps two kinds of output strictly apart:

  • stdout holds exactly one JSON envelope (or, with --format url, a list of URLs) — safe to hand to a parser;
  • stderr holds progress, the credit estimate, saved file paths and hints. While waiting in an interactive terminal it also prints dots; agents and pipes get none.

Success

{
  "ok": true,
  "result": {
    "tool": "pet-dressup",
    "runId": "3f6c2a1e-8b4d-4e7a-9c55-0d2b7e1f4a90",
    "status": "completed",
    "outputs": [
      { "type": "image", "url": "https://static.tufty.ai/.../result.png" }
    ]
  }
}
FieldDescription
toolTool id
runIdRun id, usable with tufty status
statuscompleted; running with --no-wait
outputs[].typeimage or video
outputs[].urlOutput URL, hosted on static.tufty.ai
outputs[].pathWith --save, the absolute path of the local file

result for other commands:

Commandresult
tufty tools list{ tool: "tools.list", data: { locale, tools: [{ id, kind, name, description, command }] } }
tufty tools describe <id>{ tool: "tools.describe", data: the tool's manifest entry }
tufty upload <file>{ tool: "upload", data: { url } }
tufty auth set <apiKey>{ tool: "auth.set", data: { source: "config", saved: true } }
tufty auth get{ tool: "auth.get", data: { source, apiKey } }
tufty login{ tool: "login", data: { saved: true } }
tufty logout{ tool: "logout", data: { removed } }

Failure

{
  "ok": false,
  "code": "insufficient_balance",
  "message": "Not enough credits (this step needs 75).",
  "details": { "status": 402, "required": 75 }
}

message is fit to show a person; branch on code in code. Every code is listed in Error codes; see also Exit codes.

--format url

tufty pet-dressup --product ./sweater.jpg --model ./corgi.jpg --format url

Stdout lists one output URL per line:

https://static.tufty.ai/.../result.png

It only applies when the result actually has URLs. Results without any — tufty tools list, --no-wait — still print the full envelope, and so do failures. tufty upload and tufty status accept --format url too.

--save <dir>

tufty image-to-video --still ./corgi-sweater.png --duration 5 --save ./out

When the run finishes, the CLI downloads each output into the directory (creating it if needed) as <runId>-<n><extension>. Each download is written to a .partial file and renamed when complete, with up to 3 attempts; the absolute path is added as outputs[].path.

--save only works while waiting for the result; combined with --no-wait nothing is downloaded.

--dry-run

tufty pet-dressup --product ./sweater.jpg --model ./corgi.jpg ./shiba.jpg --quality medium --count 2 --dry-run

Validates the inputs and prints the request payload and credit estimate — nothing is uploaded or charged, and no sign-in is needed.

{
  "ok": true,
  "result": {
    "tool": "pet-dressup",
    "dryRun": true,
    "payload": {
      "tool": "pet-dressup",
      "products": ["./sweater.jpg"],
      "models": ["./corgi.jpg", "./shiba.jpg"],
      "count": 2,
      "quality": "medium"
    },
    "estimatedCredits": 75,
    "creditBreakdown": { "generation": 72, "cutout": 3 }
  }
}

The payload holds local paths rather than uploaded URLs — the CLI uploads only on a real run. How the estimate is computed: Credits.

On this page