Artifacts
The hutly artifact command group manages artifacts — files produced by or attached to conversations, workflow executions, and the org library. Use it to publish a local file, list and inspect artifacts, download their bytes, share them via a public link, promote them into the org library, or forward them into a knowledge base.
All subcommands authenticate with HUTLY_ORG_ID and HUTLY_API_KEY (or .hutlyrc.yaml / ~/.hutly/credentials). Conversation- and workflow-scoped commands read context from HUTLY_CONVERSATION_ID and HUTLY_WORKFLOW_EXECUTION_ID when the matching flag is omitted. Every subcommand accepts --json for machine-readable output.
Subcommands
publish
Publish a local file as an artifact. The display title comes from --name, but the filename and MIME type are always inferred from the file’s actual basename. Artifacts are scoped to a conversation by default, or to a workflow execution when running inside a workflow sandbox.
hutly artifact publish ./report.pdf --name "Q2 Report"
hutly artifact publish ./out.csv --conversation-id conv_123 --push-to-canvas
hutly artifact publish ./v2.pdf --append-to art_456| Option | Description |
|---|---|
--name <name> |
Display title (does not change filename or MIME inference) |
--description <text> |
Optional description |
--content-type <mime> |
Override the inferred Content-Type (only when the extension lies) |
--push-to-canvas |
Also push the artifact to the conversation canvas |
--append-to <artifactId> |
Add as a new version of an existing artifact |
--conversation-id <id> |
Override conversation context (default: HUTLY_CONVERSATION_ID) |
--workflow-execution-id <id> |
Publish as a workflow-execution-scoped artifact (default: config / HUTLY_WORKFLOW_EXECUTION_ID) |
--source-message-id <id> |
Originating message ID (telemetry) |
--conversation-id and --workflow-execution-id are mutually exclusive. --push-to-canvas requires a conversation context — pass --conversation-id or set HUTLY_CONVERSATION_ID.
list
List artifacts. Defaults to the org library; pass --conversation or --workflow-execution-id to scope to a conversation or a specific workflow execution.
hutly artifact list
hutly artifact list --conversation --conversation-id conv_123
hutly artifact list --search "invoice" --kind pdf --limit 100| Option | Description |
|---|---|
--library |
List org library artifacts (default) |
--conversation |
List artifacts from the current conversation |
--conversation-id <id> |
Conversation ID (default: HUTLY_CONVERSATION_ID) |
--workflow-execution-id <id> |
List artifacts pinned to a workflow execution (default: HUTLY_WORKFLOW_EXECUTION_ID) |
--search <query> |
Filter by search query |
--kind <kind> |
Filter by kind |
--limit <n> |
Max results (default: 50) |
--cursor <iso> |
Pagination cursor |
get
Fetch an artifact’s metadata and signed URLs (inline and download). The signed URLs expire — urlExpiresAt is shown in the output.
hutly artifact get art_456
hutly artifact get art_456 --json| Option | Description |
|---|---|
--download <path> |
Deprecated — download bytes to a local path. Use hutly artifact download instead |
download
Stream an artifact’s bytes to a local path via its signed URL. Safe for files up to the 100 MB cap. Defaults the output path to ./<sanitised-filename> in the current directory.
hutly artifact download art_456
hutly artifact download art_456 --out ./report.pdf --checksum| Option | Description |
|---|---|
--out <path> |
Local output path (default: ./<sanitised-filename>) |
--checksum |
Verify the downloaded file’s SHA-256 against the version’s recorded checksum |
With --checksum, a mismatch fails the command with a checksum_mismatch error rather than leaving a corrupt file unflagged.
share
Create a public share link for an artifact. Optionally set a title, description, and expiry.
hutly artifact share art_456
hutly artifact share art_456 --title "Signed lease" --expires-in 7d
hutly artifact share art_456 --expires-in 2026-09-01T00:00:00Z| Option | Description |
|---|---|
--title <text> |
Share title |
--description <text> |
Share description |
--expires-in <duration> |
Expiry — 7d, 30d, or an ISO timestamp |
The command prints the public shareUrl and the shareId.
promote
Promote an artifact to the org library, making it available across the organization rather than only within its originating conversation or workflow execution.
hutly artifact promote art_456This command takes no options beyond --json.
send-to-kb
Forward a chat artifact into a knowledge base. The artifact’s bytes are downloaded and then ingested through the KB pipeline. Use this when adding an artifact to a knowledge base — not for moving it into the org library (that’s hutly artifact promote).
hutly artifact send-to-kb art_456 kb_789
hutly artifact send-to-kb art_456 kb_789 --wait --timeout 600
hutly artifact send-to-kb art_456 kb_789 --filename "lease-2026.pdf"| Option | Description |
|---|---|
--filename <name> |
Override the filename presented to the KB (default: the artifact’s current-version filename) |
--wait |
Poll until KB ingestion finishes (READY or ERROR) |
--timeout <seconds> |
Wait timeout in seconds (default: 300) |
Without --wait, the file is queued for ingestion and the command returns immediately. With --wait, the command exits non-zero if ingestion ends in ERROR or the timeout elapses while the file is still pending.
pin
Pin an HTML artifact as an App. “Apps” are pinned HTML artifacts — pinning is what makes one show up there. Non-app artifacts (no hutly.manifest.ts scope) and apps whose declared scope is already approved pin directly.
An app whose declared manifest is not yet approved is refused: the command prints the declared workflow/table scope and exits non-zero without pinning. Re-run with --approve to approve that scope and pin in one step.
An app whose embedded manifest is malformed (invalid JSON or shape) is refused even with --approve — a malformed manifest can’t be approved, and pinning it would ship an app whose window.hutly calls fail at runtime. Rebuild and republish the app, then pin.
hutly artifact pin art_456
hutly artifact pin art_456 --approveRefused (unapproved, no --approve):
This app is not yet approved. Declared scope:
Workflows: create-lead
Tables:
- leads (write)
Re-run with --approve to approve this scope and pin.
Error: Unapproved app: re-run with --approve to pin it.| Option | Description |
|---|---|
--approve |
Approve the app’s declared scope (workflows + tables) before pinning |
unpin
Remove an artifact from Apps. The artifact itself is untouched — it stays in the library.
hutly artifact unpin art_456This command takes no options beyond --json.
rename
Rename an artifact’s display name. Does not touch the filename, MIME type, or any artifact version.
hutly artifact rename art_456 "Lead Intake"This command takes no options beyond --json.
reorder
Set the manual display order of the org’s pinned Apps. Pass every pinned artifact ID in the desired order — each gets its position recorded.
hutly artifact reorder art_456 art_789 art_123This command takes no options beyond --json.