@cloudglue/tinycloud 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,157 @@
1
+ ---
2
+ name: tinycloud
3
+ description: >-
4
+ Deep video work via the tinycloud CLI (Cloudglue). Use whenever the task
5
+ involves understanding or manipulating video or audio-visual media: analyze
6
+ or summarize a video, extract structured facts/moments/entities, generate
7
+ captions or transcripts (SRT/VTT), search inside videos, answer questions
8
+ about footage, cut/stitch/thumbnail/transcode clips, download remote videos,
9
+ browse Cloudglue collections, or run packaged video workflows. Triggers on
10
+ video files (.mp4, .mov, .webm, ...), YouTube/video URLs, Cloudglue
11
+ collections, or any "what's in this video / make clips / caption this"
12
+ request. Every command returns a machine-readable JSON envelope.
13
+ ---
14
+
15
+ # Tinycloud: video operations for agents
16
+
17
+ `tinycloud` is a CLI for video understanding and editing, backed by Cloudglue.
18
+ Drive it with shell commands and parse JSON from stdout. Never scrape its
19
+ human-readable output; always pass `--json` (single envelope) or rely on JSONL
20
+ when piping.
21
+
22
+ ## 0. Preflight (always do this first)
23
+
24
+ ```bash
25
+ bash ${CLAUDE_SKILL_DIR}/scripts/preflight.sh
26
+ ```
27
+
28
+ (Outside Claude Code, run `scripts/preflight.sh` from this skill's directory.)
29
+ It prints exactly one line telling you what to do: install, upgrade, configure
30
+ credentials, or proceed. If `tinycloud` is missing entirely:
31
+
32
+ ```bash
33
+ npm install -g @cloudglue/tinycloud
34
+ # or: curl -fsSL https://app.cloudglue.dev/tinycloud.sh | bash
35
+ ```
36
+
37
+ Credentials (required for cloud verbs): `tinycloud setup cloudglue --api-key <key>`
38
+ (or `export CLOUDGLUE_API_KEY=...`). Verify with
39
+ `tinycloud setup --check --json` → `data.ok == true`.
40
+
41
+ ## 1. The envelope contract
42
+
43
+ Every command emits a Tinycloud envelope on stdout. Logs go to stderr. Fields
44
+ you branch on: `status`, `data` (verb-specific payload), `ref` (reusable
45
+ source reference), `next` (suggested follow-ups), `setup` (how to fix missing
46
+ credentials), `error` (`{code, message, retryable}`).
47
+
48
+ | status | what you do |
49
+ |---|---|
50
+ | `ready` | consume `data` / `ref` / file paths and continue |
51
+ | `pending` | async job started — `tinycloud jobs wait <meta.job_id> --timeout 120s --json` |
52
+ | `needs_credentials` | run the command in `setup.command` or set the env in `setup.env` |
53
+ | `needs_upload` | cloud upload required (runs through the user's Cloudglue account) — rerun without `--no-upload` or confirm with the user |
54
+ | `needs_download` | fetch locally first: `tinycloud grab <url> --json` |
55
+ | `paused` | stop; surface `resume` info to the user (resume is not automated in 0.3.x) |
56
+ | `error` | stop; report `error.message`; retry only if `error.retryable` |
57
+
58
+ Exit codes: 0 = ready/pending/paused, 1 = error, 2 = needs_credentials,
59
+ 3 = needs_upload/needs_download. Branch on `status`, not exit code alone.
60
+ Full schema and error codes: [reference/envelope.md](reference/envelope.md).
61
+
62
+ ## 2. Core verbs (cheat sheet)
63
+
64
+ Cloud verbs (`watch extract probe ask publish`) call the Cloudglue API using
65
+ the configured key — usage is billed per the
66
+ [rate card](https://app.cloudglue.dev/home/billing/rate-card). `search clip
67
+ setup` are local and free; `grab jobs` are network-only.
68
+ `tinycloud commands --json` is the authoritative command/flag list.
69
+
70
+ ```bash
71
+ # Understand a video (creates reusable cached context + cloud-ready ref)
72
+ tinycloud watch ./demo.mp4 --json
73
+
74
+ # Pipe context into structured extraction (JSONL flows between pipes)
75
+ tinycloud watch ./demo.mp4 --json | tinycloud extract "key moments with timestamps" --json
76
+ tinycloud extract --schema ./schema.json ./demo.mp4 --segment-level --json
77
+
78
+ # Captions / transcripts
79
+ tinycloud caption ./demo.mp4 --format srt --transcript -o ./tinycloud-output/captions/ --json
80
+
81
+ # Find things: local keyword search vs cloud semantic search vs Q&A
82
+ tinycloud search "pricing" --in ./demo.mp4 --json
83
+ tinycloud probe "product demo moments" --in collection:col_123 --scope segment --limit 5 --json
84
+ tinycloud ask "What objections came up?" --in ./demo.mp4 --json
85
+
86
+ # Local editing (free, ffmpeg-backed)
87
+ tinycloud clip info ./demo.mp4 --json
88
+ tinycloud clip cut ./demo.mp4 --start 12 --end 28 -o ./tinycloud-output/clip.mp4 --json
89
+ tinycloud clip thumbs ./demo.mp4 --interval 5 -o ./tinycloud-output/thumbs/ --json
90
+ tinycloud clip burn ./demo.mp4 --subtitle-file ./captions/demo.srt -o ./out.mp4 --json
91
+
92
+ # Remote videos, collections, async jobs
93
+ tinycloud grab https://youtu.be/<id> -o ./tinycloud-output/grabbed/ --json
94
+ tinycloud library collections list --json
95
+ tinycloud watch ./long.mp4 --background --json # returns pending + meta.job_id
96
+ tinycloud jobs wait <job-id> --timeout 120s --json
97
+
98
+ # Publish an HTML artifact to Cloudglue Sites (manage with list / unpublish)
99
+ tinycloud publish ./tinycloud-output/html/report.html --name report --visibility private --json
100
+ tinycloud publish list --json
101
+ ```
102
+
103
+ Per-verb details and all flags: [reference/verbs.md](reference/verbs.md).
104
+ Multi-video batching and pipe semantics: [reference/pipelines.md](reference/pipelines.md).
105
+
106
+ ## 3. Workflows (packaged recipes)
107
+
108
+ Repeatable pipelines run with one command and write outputs into a run
109
+ directory:
110
+
111
+ ```bash
112
+ tinycloud workflow list --json
113
+ tinycloud workflow validate sales-coaching --json
114
+ tinycloud workflow plan sales-coaching ./call.mp4 --json # resolves the graph; free, no side effects
115
+ tinycloud workflow sales-coaching ./call.mp4 --json
116
+ ```
117
+
118
+ Parse the final envelope: `data.status` (`completed|partial|failed|paused`),
119
+ `data.outputs` (named outputs, e.g. `outputs.html`), `data.artifacts[].path`.
120
+ Files land under `./tinycloud-output/runs/<run_id>/`. Recipe render steps run
121
+ local scripts: built-in recipes self-permit them (`permissions: [command]`),
122
+ so no extra flag is needed; pass `--allow-command` only for a recipe run by
123
+ path that lacks that permission. `--no-command` always disables them.
124
+ Authoring your own recipes: [reference/workflow-authoring.md](reference/workflow-authoring.md).
125
+
126
+ ## 4. Gotchas
127
+
128
+ - Machine output is stdout; logs/progress are stderr. Keep stderr visible for
129
+ debugging, but never parse it.
130
+ - Built-in recipes already permit their render steps (`permissions:
131
+ [command]`) — don't add `--allow-command` for them (host-agent permission
132
+ classifiers may flag it); it's only needed for path-run recipes without
133
+ that permission.
134
+ - Sources: local paths, URLs, `cloudglue://files/<id>` URIs, or
135
+ `collection:col_…` — a bare file-id UUID is not accepted.
136
+ - Do not pass `--background` to `ask`; background jobs exist only for tracked
137
+ async ops (`watch`, `extract`).
138
+ - `workflow status` / `workflow resume` are not implemented in 0.3.x; treat
139
+ `paused`/`partial` as terminal and surface `resume` metadata to the user.
140
+ - `--no-upload` / `--no-download` make commands refuse cloud upload / local
141
+ materialization and return `needs_upload` / `needs_download` instead — use
142
+ them to control spend, then branch.
143
+ - Piping: downstream verbs consume JSONL envelopes from stdin; a non-`ready`
144
+ upstream envelope produces a blocked envelope downstream instead of running.
145
+ - Keep generated files under `./tinycloud-output/` (override with the
146
+ `--out` flag where supported).
147
+ - Cached results are reused automatically; `--refresh` forces re-computation,
148
+ `--no-cache` disables persistence.
149
+
150
+ ## 5. Reference (load on demand)
151
+
152
+ - [reference/setup.md](reference/setup.md) — install, credentials, env vars, preflight details
153
+ - [reference/verbs.md](reference/verbs.md) — every verb, flag, and cost class
154
+ - [reference/envelope.md](reference/envelope.md) — full envelope schema, statuses, error codes, exit codes
155
+ - [reference/pipelines.md](reference/pipelines.md) — pipes, batching, jobs, cache/spend-control flags
156
+ - [reference/workflow-authoring.md](reference/workflow-authoring.md) — workflow YAML schema and custom recipes
157
+ - [reference/glossary.md](reference/glossary.md) — tinycloud/Cloudglue terms (files, collections, connectors, refs, …)
@@ -0,0 +1,73 @@
1
+ # The Tinycloud envelope
2
+
3
+ Every command emits one envelope (or a JSONL stream of them) on stdout.
4
+ Envelope schema version: `"1"` (reported in `--version --json` as
5
+ `envelope_schema`). Absent fields are omitted, never `null` or `[]`.
6
+
7
+ ```json
8
+ {
9
+ "tinycloud": "1",
10
+ "kind": "watch",
11
+ "status": "ready",
12
+ "result_id": "res_…",
13
+ "source_id": "src_…",
14
+ "ref": { "…": "reusable source reference" },
15
+ "data": { "…": "verb-specific payload" },
16
+ "meta": { "elapsed_ms": 1234, "requires": "cloud", "cache": { "identity": "hit" } },
17
+ "summary": "one-line human summary",
18
+ "next": [ { "…": "suggested follow-up commands" } ],
19
+ "setup": { "service": "cloudglue", "env": ["CLOUDGLUE_API_KEY"], "command": "tinycloud setup cloudglue" },
20
+ "resume": { "run_id": "…", "paused_step": "…", "resume_command": "…" },
21
+ "error": { "code": "validation", "message": "…", "retryable": false }
22
+ }
23
+ ```
24
+
25
+ | Field | Purpose |
26
+ |---|---|
27
+ | `status` | The branching field — see table below |
28
+ | `kind` | Operation kind: `watch`, `extract`, `ask`, `workflow`, `setup`, … |
29
+ | `result_id` | Stable result id for `--result-id` reuse and logs |
30
+ | `source_id` | Stable source id when the operation targets media |
31
+ | `ref` | Reusable source reference (carries `cloud_ready`, Cloudglue file/collection ids) for piping or later ops |
32
+ | `data` | Verb-specific payload |
33
+ | `meta` | `elapsed_ms`, `requires` (local\|network\|cloud\|varies), `cache` states (hit\|miss\|written\|skipped), `job_id`, `usage`, `model` |
34
+ | `summary` | One-line human summary (do not parse) |
35
+ | `next` | Suggested follow-up actions |
36
+ | `setup` | Present with `needs_credentials`: how to fix |
37
+ | `resume` | Present with `paused`: run/step info to surface to the user |
38
+ | `error` | Present with `error` status: `{code, message, retryable, detail?}` |
39
+
40
+ ## Statuses and exit codes
41
+
42
+ | status | exit | invariant | what you do |
43
+ |---|---|---|---|
44
+ | `ready` | 0 | `data` usable | consume and continue |
45
+ | `pending` | 0 | `meta.job_id` set | `tinycloud jobs wait <id> --timeout 120s --json`; do NOT start downstream work |
46
+ | `paused` | 0 | `resume` present | stop; surface resume info (resume not automated in 0.3.x) |
47
+ | `needs_credentials` | 2 | `setup` present | run `setup.command` or set `setup.env` |
48
+ | `needs_upload` | 3 | — | cloud upload required (runs through the user's Cloudglue account); rerun without `--no-upload` after confirming |
49
+ | `needs_download` | 3 | — | materialize locally first (`tinycloud grab …`) |
50
+ | `error` | 1 | `error` present | stop; report `error.message`; retry only if `error.retryable` |
51
+
52
+ Batch runs exit with the worst status seen. Always branch on `status`, not
53
+ the exit code alone.
54
+
55
+ ## Error codes
56
+
57
+ `missing_api_key`, `insufficient_credits`, `file_not_found`,
58
+ `file_not_ready`, `not_found`, `validation`, `needs_upload`,
59
+ `needs_download`, `visual_analysis_requires_download`, `upstream`.
60
+
61
+ `upstream` on a piped command means the upstream envelope was not `ready` —
62
+ fix the upstream failure, don't retry downstream.
63
+
64
+ ## JSON vs JSONL vs text
65
+
66
+ - On a TTY, commands default to human text. **Always pass `--json`.**
67
+ - When piped, output defaults to JSONL (one envelope per line) — this is the
68
+ pipe protocol downstream verbs consume.
69
+ - `--pretty` emits a single JSON array instead of JSONL.
70
+ - `--view segments|findings|citations|outputs|matches` selects a data subset;
71
+ `--format tsv` renders tabular views for shell processing.
72
+ - `--raw-output` prints the raw backend payload and disables the pipe
73
+ protocol — only for debugging.
@@ -0,0 +1,73 @@
1
+ # Glossary: tinycloud and Cloudglue terms
2
+
3
+ Quick definitions for terms that appear in tinycloud output, flags, and these
4
+ docs. Use this when the user asks "what is a Cloudglue file / collection /
5
+ connector?" or an envelope field needs explaining.
6
+
7
+ ## Platform
8
+
9
+ - **Cloudglue** — the video-understanding API platform that powers
10
+ tinycloud's cloud verbs (analysis, extraction, semantic search, Q&A,
11
+ publishing). Account, API keys, and billing live at
12
+ [app.cloudglue.dev](https://app.cloudglue.dev); usage is billed per the
13
+ [rate card](https://app.cloudglue.dev/home/billing/rate-card).
14
+ - **tinycloud** — the agent CLI distributed from this repo
15
+ (https://tinycloud.sh). Local verbs (`clip`, `search`, `setup`) run on your
16
+ machine; cloud verbs call Cloudglue with your API key.
17
+
18
+ ## Media and identity
19
+
20
+ - **Cloudglue file** — a video uploaded to (or registered with) Cloudglue,
21
+ identified by a file id and addressable as `cloudglue://files/<id>`. The
22
+ first cloud operation on a local video uploads it once; later operations
23
+ reuse the file.
24
+ - **Collection** — a named group of Cloudglue files (id `col_…`), e.g. "all
25
+ sales calls". Verbs scope to one with `--in collection:col_…`. Collection
26
+ ids are stable; display names are not.
27
+ - **Data connector** — a linked external source of recordings (Zoom, Grain,
28
+ Google Drive, Dropbox, Loom, S3/GCS). `tinycloud library connectors …`
29
+ lists, browses (`files`, with provider-specific filters), and syncs
30
+ individual items by URI (e.g. `grain://recording/<id>`) so they become
31
+ Cloudglue files.
32
+ - **Source** — anything a verb accepts as input: a local path, URL,
33
+ `cloudglue://files/<id>` URI, connector URI, or collection. Bare file-id
34
+ UUIDs are not accepted — wrap them as `cloudglue://files/<id>`.
35
+ - **`ref` / `source_id` / `result_id`** — stable identifiers in every
36
+ envelope. `ref` is a reusable pointer to the analyzed source (including
37
+ `cloud_ready` and the Cloudglue file id) that pipes between verbs;
38
+ `--source-id`/`--result-id` flags reuse prior work explicitly.
39
+
40
+ ## Operations
41
+
42
+ - **Envelope** — the JSON object every command prints on stdout
43
+ (`status`, `data`, `ref`, `meta`, `error`, …). The machine contract; see
44
+ reference/envelope.md.
45
+ - **Watch context / describe** — the reusable analysis `tinycloud watch`
46
+ produces (summary, segments, transcript-ish context). Cached locally and
47
+ mirrored in Cloudglue, so later `extract`/`ask`/`search` reuse it instead
48
+ of re-analyzing.
49
+ - **Segmentation** — how a video is split for analysis: `chapters`
50
+ (semantic), `shots` (visual cuts), `uniform:<seconds>` (fixed windows).
51
+ - **Cache layers** — `meta.cache` reports `identity` (is this the same file
52
+ we've seen?) and `enrichment` (analysis results) as
53
+ `hit | miss | written | skipped`.
54
+ - **Job** — a tracked async cloud operation (from `--background`), with
55
+ `meta.job_id`; managed via `tinycloud jobs list|poll|wait|forget`.
56
+
57
+ ## Workflows and outputs
58
+
59
+ - **Workflow / recipe** — a YAML DAG of verb steps run by
60
+ `tinycloud workflow <name|path>`. Built-in recipes (sales-coaching,
61
+ blog-post, …) ship inside the binary.
62
+ - **Run directory** — where a workflow writes everything:
63
+ `./tinycloud-output/runs/<run_id>/`. Single-verb outputs default under
64
+ `./tinycloud-output/`.
65
+ - **Artifacts / outputs** — the workflow envelope's `data.artifacts[]`
66
+ (produced files with paths) and `data.outputs{}` (named results, e.g.
67
+ `outputs.html`).
68
+ - **Command step** — a workflow step that runs a local script (e.g. an HTML
69
+ renderer); gated by `--allow-command` / recipe `permissions: [command]`.
70
+ - **Cloudglue Sites** — hosted pages for published artifacts:
71
+ `tinycloud publish <html> --visibility public|private` returns a shareable
72
+ URL (private = Cloudglue account members only, same URL). Manage with
73
+ `publish list` and `publish unpublish <site-id | site-name | label>`.
@@ -0,0 +1,104 @@
1
+ # Pipelines: pipes, batching, async jobs, and spend control
2
+
3
+ ## The pipe protocol
4
+
5
+ Tinycloud verbs compose through JSONL envelopes on stdin/stdout:
6
+
7
+ ```bash
8
+ tinycloud watch ./demo.mp4 --json | tinycloud extract "key moments" --json
9
+ ```
10
+
11
+ - The downstream verb parses each stdin line as an envelope; `ref` /
12
+ `source_id` flow through, so `extract` knows exactly which analyzed source
13
+ to use without re-uploading.
14
+ - A non-`ready` upstream envelope produces a blocked downstream envelope with
15
+ `error.code: "upstream"` instead of running — fix upstream, don't retry
16
+ downstream.
17
+ - Raw stdin lines that are file paths also work as batch sources:
18
+
19
+ ```bash
20
+ cat sources.txt | tinycloud watch --json
21
+ ```
22
+
23
+ - Piping watch envelopes into `search` / `probe` / `ask` auto-scopes them via
24
+ `ref.cloudglue_file_id` / collection ids.
25
+
26
+ ## Multi-video batching
27
+
28
+ Most verbs accept multiple sources; output is JSONL with one envelope per
29
+ source. The process exit code is the worst status seen. Iterate the lines and
30
+ branch per envelope.
31
+
32
+ ```bash
33
+ tinycloud watch ./a.mp4 ./b.mp4 --json
34
+ tinycloud caption ./talks/*.mp4 --format srt -o ./tinycloud-output/captions/ --json
35
+ ```
36
+
37
+ ## Async jobs
38
+
39
+ Long cloud operations (`watch`, `extract`) support `--background`:
40
+
41
+ ```bash
42
+ tinycloud watch ./long.mp4 --background --json # → status:"pending", meta.job_id
43
+ tinycloud jobs wait <job-id> --timeout 120s --json
44
+ tinycloud jobs list --status running --json
45
+ tinycloud jobs poll <job-id> --json # single non-blocking check
46
+ tinycloud jobs forget <job-id> --json
47
+ ```
48
+
49
+ Never start downstream work while an envelope is `pending`. `ask` does not
50
+ support `--background`.
51
+
52
+ ## Spend control
53
+
54
+ Cloud verbs run through the configured Cloudglue API key (usage per the
55
+ [rate card](https://app.cloudglue.dev/home/billing/rate-card)). Patterns to
56
+ control spend:
57
+
58
+ ```bash
59
+ # Refuse uploads: returns needs_upload instead of spending
60
+ tinycloud watch ./new.mp4 --no-upload --json
61
+
62
+ # Reuse a prior watch's enrichment without re-uploading
63
+ tinycloud extract "key moments" ./demo.mp4 --cached --json
64
+
65
+ # Free local lookup over already-cached context (no cloud call at all)
66
+ tinycloud search "pricing" --in ./demo.mp4 --json
67
+ ```
68
+
69
+ - `--no-upload` → refuse Cloudglue upload/materialization (`needs_upload`).
70
+ - `--no-download` → refuse local materialization (`needs_download`).
71
+ - `--refresh` → force recompute (spends even on cache hits).
72
+ - `--no-cache` → don't persist results (still spends).
73
+ - These four flags exist on `watch`, `extract`, `caption`, and `workflow`
74
+ only — `ask`/`probe` always go to the cloud (use `search` for a free
75
+ cached lookup).
76
+ - `meta.cache` in every envelope tells you what was reused vs written.
77
+
78
+ ## Worked examples
79
+
80
+ ```bash
81
+ # Analyze → structured extraction (schema-shaped)
82
+ tinycloud watch ./demo.mp4 --json \
83
+ | tinycloud extract --schema ./schema.json --segment-level --json
84
+
85
+ # Caption → burn subtitles into the video
86
+ tinycloud caption ./demo.mp4 --format srt -o ./tinycloud-output/captions/ --json
87
+ tinycloud clip burn ./demo.mp4 \
88
+ --subtitle-file ./tinycloud-output/captions/demo.srt \
89
+ -o ./tinycloud-output/demo-captioned.mp4 --json
90
+
91
+ # Remote video → analyze
92
+ tinycloud grab https://youtu.be/<id> -o ./tinycloud-output/grabbed/ --json
93
+ tinycloud watch ./tinycloud-output/grabbed/<file>.mp4 --json
94
+
95
+ # Collection: mirror artifacts locally, then search/Q&A against it
96
+ tinycloud library collections sync col_123 --artifacts descriptions,transcripts --json
97
+ tinycloud probe "pricing discussion" --in collection:col_123 --scope segment --json
98
+ tinycloud ask "What did customers object to?" --in collection:col_123 --json
99
+
100
+ # Extract timestamped findings → cut them into clips
101
+ tinycloud watch ./talk.mp4 --json \
102
+ | tinycloud extract "the three strongest quotes with timestamps" --json \
103
+ | tinycloud clip cut --from-findings -o ./tinycloud-output/quotes/ --json
104
+ ```
@@ -0,0 +1,97 @@
1
+ # Setup: install, credentials, and verification
2
+
3
+ ## Install
4
+
5
+ ```bash
6
+ npm install -g @cloudglue/tinycloud # then run: tinycloud
7
+ # or run directly without installing:
8
+ npx @cloudglue/tinycloud --version --json
9
+ ```
10
+
11
+ The npm package is a small launcher: on first run it downloads the matching
12
+ platform distribution (cached under `~/.tinycloud/versions/<version>/`),
13
+ verifies its checksum, and execs the real binary. The package version pins
14
+ the binary version, so `npx @cloudglue/tinycloud@<v>` always runs that exact
15
+ tinycloud. `tinycloud update` moves to the latest release.
16
+
17
+ Alternative (shell installer, installs to `~/.tinycloud/bin`):
18
+
19
+ ```bash
20
+ curl -fsSL https://app.cloudglue.dev/tinycloud.sh | bash
21
+ ```
22
+
23
+ Platforms: macOS (arm64, x64) and Linux (x64, arm64). Windows is not
24
+ supported — use WSL2. More at https://tinycloud.sh.
25
+
26
+ ## Credentials
27
+
28
+ Cloud verbs (`watch extract probe ask publish`) need a Cloudglue API key.
29
+ Usage is billed to that key per the
30
+ [rate card](https://app.cloudglue.dev/home/billing/rate-card).
31
+
32
+ ```bash
33
+ tinycloud setup cloudglue --api-key <key> # persist the key
34
+ # or
35
+ export CLOUDGLUE_API_KEY=<key> # env only, nothing persisted
36
+ ```
37
+
38
+ `frameio` is an optional service and requires interactive OAuth
39
+ (`tinycloud setup frameio` inside the tinycloud agent TUI).
40
+
41
+ ## Verifying an install
42
+
43
+ ```bash
44
+ tinycloud --version --json
45
+ ```
46
+
47
+ Returns (annotated):
48
+
49
+ ```json
50
+ {
51
+ "name": "tinycloud",
52
+ "version": "0.3.0", // semver — compare against min_version
53
+ "git_sha": "…",
54
+ "build_id": "0.3.0+…",
55
+ "channel": "stable",
56
+ "platform": "darwin",
57
+ "arch": "arm64",
58
+ "protocol_version": "1", // CLI protocol contract
59
+ "envelope_schema": "1", // envelope shape version
60
+ "workflow_schema": "1", // workflow recipe schema version
61
+ "command_spec_revision": "…", // changes when commands/flags change
62
+ "features": ["envelope.v1", "watch.v1", "..."] // feature ids to gate on
63
+ }
64
+ ```
65
+
66
+ ```bash
67
+ tinycloud setup --check --json
68
+ ```
69
+
70
+ Exits 0 even when unconfigured; branch on `data.ok`. `data.services[]` lists
71
+ each service with `configured`, `env`, `interactive_required`, and a
72
+ `message`. `data.capabilities` repeats the protocol/feature contract.
73
+
74
+ ## Preflight script
75
+
76
+ `scripts/preflight.sh` (next to this skill's SKILL.md) checks everything and
77
+ prints exactly one actionable line:
78
+
79
+ | exit | meaning |
80
+ |---|---|
81
+ | 0 | ok — install, version, features, and credentials all good |
82
+ | 10 | tinycloud binary missing or broken — install |
83
+ | 11 | version below the skill's `min_version` — upgrade |
84
+ | 12 | required feature ids missing from `features[]` — upgrade |
85
+ | 13 | binary fine, Cloudglue credentials missing — configure key |
86
+
87
+ The version/feature requirements live in `tinycloud-skill.json`
88
+ (`min_version`, `supported_range`, `required_features`) and mirror what the
89
+ binary reports in `--version --json`.
90
+
91
+ ## Environment variables
92
+
93
+ | Variable | Effect |
94
+ |---|---|
95
+ | `CLOUDGLUE_API_KEY` | Cloudglue API key (alternative to `tinycloud setup cloudglue`) |
96
+ | `TINYCLOUD_VERSION` | npm launcher: run a specific binary version |
97
+ | `TINYCLOUD_INSTALL_DIR` | npm launcher: cache root (default `~/.tinycloud`) |