stackbone storage

stackbone storage targets a running agent installation. With no --agent it uses the local-dev installation linked to the current project, so stackbone dev must be running. See target resolution. Every verb accepts --json and emits the standard envelope.

Operate the S3-style object store bound to the targeted installation. Every object verb needs --bucket <name> (an install can expose more than one bucket).

Command Purpose
stackbone storage buckets List the buckets the installation exposes.
stackbone storage list List objects in --bucket, optionally under --prefix. --limit is 1-1000 (default 100), with --cursor.
stackbone storage get <key> Download an object to stdout (or --out <path>) via a short-lived presigned URL.
stackbone storage put <key> Upload a local --file <path> under the key.
stackbone storage presign <key> Print a short-lived presigned download URL for the object.
stackbone storage remove <key> Delete an object. Requires --yes.

list pages with --limit/--cursor, described under pagination. remove is destructive and refuses to run without --yes, described under destructive verbs.

JSON payload

// storage buckets
{ "schema_version": 1, "items": [{ "name": "agent-data", "kind": "s3" }] }

// storage list: paginated, plus folder prefixes
{ "schema_version": 1,
  "items": [{ "key": "uploads/foo.txt", "size": 1024, "content_type": "text/plain",
              "last_modified": "2026-06-01T10:00:00Z", "etag": "\"9a0364b9…\"" }],
  "common_prefixes": ["uploads/"], "nextCursor": null, "prevCursor": null }

// storage put <key>
{ "schema_version": 1,
  "object": { "key": "uploads/foo.txt", "size": 1024, "etag": "\"9a0364b9…\"" } }

// storage presign <key>
{ "schema_version": 1, "url": "https://…", "expires_at": "2026-06-01T11:00:00Z" }

// storage get: the bytes go to --out or to stdout, so the payload only says where
{ "schema_version": 1, "key": "uploads/foo.txt", "out": null }

// storage remove <key>
{ "schema_version": 1, "key": "uploads/foo.txt", "bucket": "agent-data", "status": "deleted" }

A presigned URL lasts one hour and carries the address it was signed with. get and presign both go through one, so the download works from your machine only while that address resolves there. A box that keeps its objects in AWS S3 or Railway Buckets also needs STACKBONE_S3_FORCE_PATH_STYLE=false in its .env: those backends put the bucket in a subdomain, and the default puts it in the path (what the bundled MinIO speaks). See path-style or subdomain.

stackbone rag owns the reserved rag/ key prefix. A put or a remove under it is refused and exits 5, and the message names the key that landed inside it. Reading still works: list shows those keys and get downloads them.

Exit codes: 0 ok · 4 not found (unknown bucket or key) · 5 permission (remove without --yes, or a write under the reserved rag/ prefix) · 1 generic (missing --bucket or --file, a --file that cannot be read, a non-integer --limit). See exit codes.

BUILT WITH ❤️ FROM CANADA AND SPAIN