@cloudglue/tinycloud 0.3.3 → 0.3.5

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.
package/README.md CHANGED
@@ -16,11 +16,11 @@ The npm package is a small launcher: on first run it downloads the matching
16
16
  platform distribution from Cloudglue's CDN (cached under
17
17
  `~/.tinycloud/versions/<version>/`), verifies its checksum, and execs the real
18
18
  binary. The package version pins the binary version, so
19
- `npx @cloudglue/tinycloud@0.3.3` always runs tinycloud 0.3.3. It also adds two
19
+ `npx @cloudglue/tinycloud@0.3.5` always runs tinycloud 0.3.5. It also adds two
20
20
  wrapper commands:
21
21
 
22
22
  ```bash
23
- tinycloud install --version 0.3.3 # pre-download a version
23
+ tinycloud install --version 0.3.5 # pre-download a version
24
24
  tinycloud install --latest # install latest stable and pin to it
25
25
  tinycloud update # move to latest stable, prune old versions
26
26
  ```
@@ -123,7 +123,8 @@ go to stderr) — pass `--json`.
123
123
  | `ask` | Grounded Q&A over one or more videos |
124
124
  | `clip` | ffmpeg-backed cut, thumbs, stitch, transcode, burn, split, audio, info |
125
125
  | `grab` | Download a remote video (YouTube, TikTok, Loom, direct) |
126
- | `library` | Browse and sync Cloudglue collections and connectors |
126
+ | `face` | Detect faces in a video, or match/search a known face, ranked by similarity |
127
+ | `library` | Build & query Cloudglue collections (create/add/remove/delete) and browse connectors |
127
128
  | `jobs` | Poll, wait on, or forget async jobs |
128
129
  | `workflow` | Run packaged pipeline recipes (see below) |
129
130
  | `publish` | Publish HTML artifacts as Cloudglue Sites; share videos |
@@ -142,8 +143,26 @@ tinycloud caption ./demo.mp4 --format srt --transcript --json
142
143
  tinycloud clip cut ./demo.mp4 --start 12 --end 28 -o clip.mp4 --json
143
144
  # Grounded Q&A over one or more videos
144
145
  tinycloud ask "What objections came up?" --in ./demo.mp4 --json
146
+ # Detect faces, or match a known face against a video (0.3.4+)
147
+ tinycloud face match ./person.jpg ./demo.mp4 --max-faces 10 --json
145
148
  ```
146
149
 
150
+ **Collections (0.3.4+)** turn a set of videos into a reusable, queryable
151
+ knowledge base. Build one and query it — every type follows the same
152
+ `create → add → poll show → query → delete` shape, differing only in `--type`
153
+ and the verb that reads it:
154
+
155
+ ```bash
156
+ tinycloud library collections create "calls" --type media-descriptions --json
157
+ tinycloud library collections add ./call.mp4 --to col_123 --json # enrichment is async
158
+ tinycloud library collections show col_123 --json # poll files[].status → completed
159
+ tinycloud ask "What did customers object to?" --in collection:col_123 --json
160
+ ```
161
+
162
+ `media-descriptions` backs `ask`/`probe`/`search`, `face-analysis` backs
163
+ `face list`/`face search`, and `entities` (created with `--prompt`/`--schema`)
164
+ backs `library collections entities`.
165
+
147
166
  `tinycloud commands --json` is the authoritative, machine-readable list of
148
167
  every command and flag. Full per-verb flags and cost classes:
149
168
  [skills/tinycloud/reference/verbs.md](skills/tinycloud/reference/verbs.md).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudglue/tinycloud",
3
- "version": "0.3.3",
3
+ "version": "0.3.5",
4
4
  "description": "Agent CLI for deep video work, by Cloudglue. Downloads the tinycloud binary on first run.",
5
5
  "bin": {
6
6
  "tinycloud": "bin/tinycloud.js"
@@ -23,6 +23,6 @@
23
23
  "url": "git+https://github.com/cloudglue/tinycloud.git"
24
24
  },
25
25
  "homepage": "https://tinycloud.sh",
26
- "keywords": ["video", "cloudglue", "cli", "agent", "captions", "clips"],
26
+ "keywords": ["video", "cloudglue", "cli", "agent", "captions", "clips", "face-detection"],
27
27
  "license": "SEE LICENSE IN LICENSE.md"
28
28
  }
@@ -61,8 +61,8 @@ Full schema and error codes: [reference/envelope.md](reference/envelope.md).
61
61
 
62
62
  ## 2. Core verbs (cheat sheet)
63
63
 
64
- Cloud verbs (`watch extract probe ask publish`) call the Cloudglue API using
65
- the configured key — usage is billed per the
64
+ Cloud verbs (`watch extract probe ask publish face`) call the Cloudglue API
65
+ using the configured key — usage is billed per the
66
66
  [rate card](https://app.cloudglue.dev/home/billing/rate-card). `search clip
67
67
  setup` are local and free; `grab jobs` are network-only.
68
68
  `tinycloud commands --json` is the authoritative command/flag list.
@@ -89,19 +89,37 @@ tinycloud clip cut ./demo.mp4 --start 12 --end 28 -o ./tinycloud-output/clip.mp4
89
89
  tinycloud clip thumbs ./demo.mp4 --interval 5 -o ./tinycloud-output/thumbs/ --json
90
90
  tinycloud clip burn ./demo.mp4 --subtitle-file ./captions/demo.srt -o ./out.mp4 --json
91
91
 
92
- # Remote videos, collections, async jobs
92
+ # Faces on a single video (cloud, 0.3.4+) — for collection-scale face search/list, see Collections below
93
+ tinycloud face detect ./demo.mp4 --json # every face → normalized box + timestamp
94
+ tinycloud face match ./person.jpg ./demo.mp4 --max-faces 10 --json # query image, ranked 0–100 similarity
95
+
96
+ # Remote videos, async jobs
93
97
  tinycloud grab https://youtu.be/<id> -o ./tinycloud-output/grabbed/ --json
94
98
  tinycloud library connectors sync https://example.com/clip.mp4 --json # public URL → Cloudglue file (not YouTube — use grab)
95
- tinycloud library collections list --json
96
99
  tinycloud watch ./long.mp4 --background --json # returns pending + meta.job_id
97
100
  tinycloud jobs wait <job-id> --timeout 120s --json
98
101
 
102
+ # Collections (0.3.4+) — turn videos into a reusable, queryable knowledge base.
103
+ # Lifecycle (every --type): create → add → poll show → query → delete.
104
+ tinycloud library collections list --json
105
+ tinycloud library collections create my-desc --type media-descriptions --json # types: media-descriptions | face-analysis | entities (--prompt) | rich-transcripts
106
+ tinycloud library collections add ./demo.mp4 --to col_desc --json # uploads a local source first; enrichment is async (pending)
107
+ tinycloud library collections show col_desc --json # poll files[].status until completed, then query —
108
+ # the collection's --type decides the read verb (each line below is a DIFFERENT, matching-type collection):
109
+ tinycloud ask "what's discussed?" --in collection:col_desc --json # media-descriptions → ask / probe / search
110
+ tinycloud face search ./person.jpg --in collection:col_faces --json # face-analysis → face list / face search
111
+ tinycloud library collections entities col_ents ./demo.mp4 --json # entities → collections entities
112
+ tinycloud library collections remove cloudglue://files/<id> --from col_desc --json
113
+ tinycloud library collections delete col_desc --json
114
+
99
115
  # Publish an HTML artifact to Cloudglue Sites (manage with list / unpublish)
100
116
  tinycloud publish ./tinycloud-output/html/report.html --name report --visibility private --json
101
117
  tinycloud publish list --json
102
118
 
103
119
  # Share a video itself (hosted share page + HLS stream, like a Loom link)
104
120
  tinycloud publish video ./demo.mp4 --visibility public --json
121
+ # Share a single moment — also returns data.moment_url (0.3.5+)
122
+ tinycloud publish video ./demo.mp4 --clip-start 18 --clip-end 33 --json
105
123
  ```
106
124
 
107
125
  Per-verb details and all flags: [reference/verbs.md](reference/verbs.md).
@@ -169,7 +187,8 @@ Authoring your own recipes: [reference/workflow-authoring.md](reference/workflow
169
187
  are signed and short-lived (never hard-code them) — embed via
170
188
  `data.embed_snippet` (`<cg-video>`), which only plays on a private site of
171
189
  the same account. When writing HTML around an embed, use the component's
172
- built-ins (`autoplay`+`muted`, `loop`, `start-time`, `exclusive`; JS
190
+ built-ins (`autoplay`+`muted`, `loop`, `start-time`, `exclusive`,
191
+ `clip-start`/`clip-end` to frame one "back to moment" clip; JS
173
192
  `playSegment(start, end?)`) and the container components
174
193
  (`<cg-playlist>`, `<cg-grid>`, `<cg-chapters>`) rather than hand-rolled
175
194
  players, galleries, or segment-list JS — details in
@@ -23,7 +23,15 @@ connector?" or an envelope field needs explaining.
23
23
  reuse the file.
24
24
  - **Collection** — a named group of Cloudglue files (id `col_…`), e.g. "all
25
25
  sales calls". Verbs scope to one with `--in collection:col_…`. Collection
26
- ids are stable; display names are not.
26
+ ids are stable; display names are not. A collection has a type that decides
27
+ which verb reads it: `media-descriptions` (default) backs `ask`/`probe`/`search`,
28
+ `face-analysis` backs `face list`/`face search`, and `entities` (created with
29
+ `--prompt`/`--schema`) backs `library collections entities` (`rich-transcripts`
30
+ also exists). Manage them with `library collections create|add|remove|delete`
31
+ (0.3.4+); every type follows `create → add → poll show → query → delete`. `add`
32
+ enriches each file asynchronously and returns `pending` — poll
33
+ `library collections show <col>` until every `files[].status` is `completed`
34
+ before querying.
27
35
  - **Data connector** — a linked external source of recordings (Zoom, Grain,
28
36
  Google Drive, Dropbox, Loom, S3/GCS). `tinycloud library connectors …`
29
37
  lists, browses (`files`, with provider-specific filters), and syncs
@@ -80,11 +88,15 @@ connector?" or an envelope field needs explaining.
80
88
  `publish unpublish <site-id | site-name | label>`.
81
89
  - **Video share (shareable asset)** — `tinycloud publish video <source>`
82
90
  wraps a Cloudglue file in a hosted share page (`data.share.share_url`) plus
83
- an HLS stream; one active share per (file, visibility). Private shares
91
+ an HLS stream; one active share per (file, visibility). Adding
92
+ `--clip-start`/`--clip-end` (seconds, 0.3.5+) also returns `data.moment_url`,
93
+ the share page bounded to that "back to moment" window (also reachable as
94
+ `?s=<start>&e=<end>` on a `share_url`). Private shares
84
95
  embed via the `data.embed_snippet` `<cg-video>` tag, which only plays on a
85
96
  private published site of the same account. The embed has playback
86
97
  attributes (`autoplay`+`muted`, `loop`, `start-time`, `poster`,
87
- `accent-color`, `exclusive`) and a JS API (`playSegment`, `seekTo`, media
98
+ `accent-color`, `exclusive`, and `clip-start`/`clip-end` to frame a single
99
+ "back to moment" clip) and a JS API (`playSegment`, `seekTo`, media
88
100
  events re-dispatched on the element) for custom site HTML, and plays
89
101
  standalone or inside the container components (`<cg-playlist>`,
90
102
  `<cg-grid>`, `<cg-chapters>`) — see reference/verbs.md.
@@ -92,10 +92,34 @@ tinycloud clip burn ./demo.mp4 \
92
92
  tinycloud grab https://youtu.be/<id> -o ./tinycloud-output/grabbed/ --json
93
93
  tinycloud watch ./tinycloud-output/grabbed/<file>.mp4 --json
94
94
 
95
- # Collection: mirror artifacts locally, then search/Q&A against it
95
+ # Collections (0.3.4+) all follow one lifecycle create → add → poll show → query → delete.
96
+ # `add` enriches each file asynchronously and returns pending; poll `collections show`
97
+ # and wait until every files[].status is `completed` before querying.
98
+
99
+ # media-descriptions (default) → ask / probe / search
100
+ tinycloud library collections create "sales-calls" --type media-descriptions --json
101
+ tinycloud library collections add ./call-1.mp4 --to col_123 --json # → pending
102
+ tinycloud library collections show col_123 --json # poll files[].status → completed
103
+ tinycloud probe "pricing objections" --in collection:col_123 --scope segment --json
104
+ tinycloud ask "What did customers object to across these calls?" --in collection:col_123 --json
105
+ tinycloud library collections delete col_123 --json
106
+
107
+ # face-analysis → face list / face search
108
+ tinycloud library collections create faces --type face-analysis --json
109
+ tinycloud library collections add ./interview.mp4 --to col_123 --json # → pending
110
+ tinycloud library collections show col_123 --json # poll files[].status → completed
111
+ tinycloud face list ./interview.mp4 --in collection:col_123 --json # stored detections for that video
112
+ tinycloud face search ./headshot.jpg --in collection:col_123 --group-by file --json
113
+
114
+ # entities (create needs --prompt or --schema) → library collections entities
115
+ tinycloud library collections create ents --type entities --prompt "people, places, objects" --json
116
+ tinycloud library collections add ./interview.mp4 --to col_123 --json # → pending
117
+ tinycloud library collections show col_123 --json # poll files[].status → completed
118
+ tinycloud library collections entities col_123 ./interview.mp4 --json # structured entities (video + segment level)
119
+
120
+ # Already-built collection: mirror description/transcript artifacts locally for free `search`
96
121
  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
122
+ tinycloud search "discount" --in collection:col_123 --json
99
123
 
100
124
  # Extract timestamped findings → cut them into clips
101
125
  tinycloud watch ./talk.mp4 --json \
@@ -25,7 +25,8 @@ supported — use WSL2. More at https://tinycloud.sh.
25
25
 
26
26
  ## Credentials
27
27
 
28
- Cloud verbs (`watch extract probe ask publish`) need a Cloudglue API key.
28
+ Cloud verbs (`watch extract probe ask publish face`) need a Cloudglue API key
29
+ (as do `library collections add` and the collection reads).
29
30
  Usage is billed to that key per the
30
31
  [rate card](https://app.cloudglue.dev/home/billing/rate-card).
31
32
 
@@ -14,7 +14,8 @@ every verb. Regenerate doubts from it instead of trusting prose.
14
14
  | `ask` | cloud | yes | Grounded Q&A over one or more videos |
15
15
  | `clip` | local | no | Cuts, thumbs, audio, stitch, split, transcode, burn, explore |
16
16
  | `grab` | network | no | Download a remote video (YouTube, TikTok, Loom, direct) |
17
- | `library` | varies | no | Collections, connectors, local mirrors, sync |
17
+ | `face` | cloud | yes | Detect faces in a video, or match/search a query face (0.3.4+) |
18
+ | `library` | varies | no | Collections (incl. create/add/remove/delete), connectors, mirrors, sync |
18
19
  | `jobs` | network | yes | Poll/wait/forget tracked async jobs |
19
20
  | `workflow` | varies | no | Validate/plan/run workflow recipes |
20
21
  | `publish` | cloud | yes | Publish HTML/code artifacts as Cloudglue Sites; share videos |
@@ -126,17 +127,84 @@ tinycloud clip cut --from-findings -o clips/ # cut timestamped findings p
126
127
  tinycloud grab <url> [-o <file-or-dir>] [--audio-only] [--format <yt-dlp-selector>]
127
128
  ```
128
129
 
130
+ ### face — detect & match faces (cloud, 0.3.4+)
131
+
132
+ ```bash
133
+ tinycloud face detect <source> [--fps <n>] [--start <t>] [--end <t>]
134
+ [--thumbnails] [--limit <n>] --json
135
+ tinycloud face match <image> <source> [--max-faces <n>] [--min-similarity <0-100>]
136
+ [--fps <n>] [--start <t>] [--end <t>] [--thumbnails] --json
137
+ tinycloud face list <source> --in collection:col_… [--limit <n>] [--offset <n>] --json
138
+ tinycloud face search <image> --in collection:col_… [col_…]
139
+ [--min-score <n>] [--group-by file] [--limit <n>] --json
140
+ ```
141
+
142
+ `detect` runs Cloudglue face detection over a video and returns every face as
143
+ a normalized 0–1 bounding box (`{top,left,width,height}`) plus a timestamp.
144
+ `match` takes a query image — a local file (downscaled and sent inline, **never
145
+ uploaded**) or an http(s) URL — and returns the closest faces ranked by a 0–100
146
+ `similarity`. Both upload the *video* first like `watch`/`extract`
147
+ (`needs_upload` without `--no-upload`) and cache by source + options, so re-runs
148
+ are free. `--fps`/`--start`/`--end` tune sampling and window;
149
+ `--max-faces`/`--min-similarity` bound `match`, `--limit` bounds `detect`,
150
+ `--thumbnails` adds per-face frame URLs.
151
+
152
+ `list` and `search` operate over a **face-analysis collection** (create one with
153
+ `library collections create --type face-analysis` and add videos with
154
+ `library collections add`): `list` reads a video's stored detections; `search`
155
+ finds the query face across one or more collections (`--min-score`,
156
+ `--group-by file`). `total` reports the server-available count across all modes
157
+ (never rewritten by client `--min-*`/`--limit` filters).
158
+
129
159
  ### library — collections and connectors
130
160
 
131
161
  ```bash
132
162
  tinycloud library collections list --json
133
- tinycloud library collections show <col_id> --json
163
+ tinycloud library collections show <col_id> --json # files[].status: pending|processing|completed (readiness)
134
164
  tinycloud library collections sync <col_id> --artifacts descriptions,transcripts,thumbnails,metadata --json
165
+ # Collection writes (0.3.4+) — the only write paths in library:
166
+ tinycloud library collections create <name> [--type media-descriptions|entities|rich-transcripts|face-analysis] [--description <text>] [--prompt <text> | --schema <file>] --json
167
+ tinycloud library collections add <source> --to <col_id> [--no-upload] [--no-download] --json
168
+ tinycloud library collections remove <source> --from <col_id> --json
169
+ tinycloud library collections delete <col_id> --json
170
+ tinycloud library collections entities <col_id> <source> [--limit <n>] [--offset <n>] --json # read a video's entities
135
171
  tinycloud library connectors list --json
136
172
  tinycloud library connectors files <connector-id> [--limit 25] [--page-token <t>] --json
137
173
  tinycloud library connectors sync [<connector-id>] <uri-share-link-or-public-url> --json
138
174
  ```
139
175
 
176
+ `collections create|add|remove|delete` are the only writes in an otherwise
177
+ read-only `library` (gated by the `library.collections.create.v1` /
178
+ `library.collections.mutate.v1` feature ids). `create` defaults to
179
+ `--type media-descriptions`; an `entities` collection also needs an extraction
180
+ spec — `--prompt <text>` or `--schema <file.json>` — or `create` errors. `add`
181
+ (`--to <col>`, or `--collection`) resolves the source like `watch`/`extract` —
182
+ a local file uploads first (or `needs_upload` with `--no-upload`) — and records
183
+ the file→collection mapping; `remove` (`--from <col>`) takes a Cloudglue file
184
+ id/uri; `delete` removes the whole collection (and cleans the local mirror).
185
+ Collection ids accept a bare uuid, a `col_…` slug, or `collection:<id>` /
186
+ `cloudglue://collections/<id>` forms, consistently across read and write paths.
187
+
188
+ **Readiness — always poll before querying.** `add` enriches each file
189
+ asynchronously and returns `pending`. Poll `collections show <col> --json` and
190
+ wait until every `files[].status` is `completed` (`pending → processing →
191
+ completed`; `failed` is terminal) — a query before then returns empty or errors.
192
+
193
+ The collection's `--type` decides which verb reads it (every type follows the
194
+ same `create → add → poll show → query → delete` lifecycle):
195
+
196
+ | `--type` | read with |
197
+ |---|---|
198
+ | `media-descriptions` (default) | `ask` / `probe` / `search` (`--in collection:<col>`) |
199
+ | `face-analysis` | `face list` / `face search` |
200
+ | `entities` (needs `--prompt`/`--schema`) | `library collections entities <col> <source>` |
201
+ | `rich-transcripts` | `collections sync --artifacts transcripts` |
202
+
203
+ `collections entities <col> <source>` returns a video's extracted entities
204
+ (video- and segment-level, `--limit`/`--offset`) from an `entities` collection.
205
+ For a one-off per-video pull without standing up a collection, `extract` returns
206
+ entities/facts directly (free-form query or `--schema`).
207
+
140
208
  `connectors sync` materializes its argument into a Cloudglue file without
141
209
  starting analysis (idempotent). The connector id is optional — with just a
142
210
  URI or link, sync routes through the matching connector type. Connector URIs
@@ -210,7 +278,7 @@ generated site name, or your `--name` label.
210
278
 
211
279
  ```bash
212
280
  tinycloud publish video <source> [--visibility public|private] # default public
213
- [--name <title>] [--segment-id <id>] --json
281
+ [--name <title>] [--segment-id <id>] [--clip-start <s> --clip-end <e>] --json
214
282
  tinycloud publish video list [--in <source>] [--visibility public|private] --json
215
283
  tinycloud publish video unpublish <share-id | source> --json # --visibility disambiguates
216
284
  ```
@@ -229,6 +297,14 @@ feature id.
229
297
  `data.embed_snippet` (a `<cg-video share-id="...">` tag), which only plays
230
298
  on a PRIVATE published site of the same account — `tinycloud publish`
231
299
  rejects an artifact with a private embed targeted at a public site.
300
+ - Moment window (0.3.5+): pass `--clip-start <s> --clip-end <e>` (seconds,
301
+ `clip-end > clip-start >= 0`, both required together or the command errors)
302
+ to also get `data.moment_url` — the hosted share page bounded to
303
+ `[start, end]`, with the same length badge, region strip, and "↺ Back to
304
+ moment" pill as the `<cg-video>` clip embed, and it survives the
305
+ private-share sign-in. Optional — omit it for a plain full-video share. The
306
+ same window is just `?s=<start>&e=<end>` appended to a `share_url`, so you
307
+ can hand-build a moment link from an existing share without re-publishing.
232
308
 
233
309
  When generating custom site HTML around a `<cg-video>` embed, use the
234
310
  component's built-ins instead of reinventing them. It defaults to a
@@ -241,6 +317,17 @@ rest). Its JS API queues until ready — `playSegment(start, end?)`,
241
317
  element (`timeupdate`, `ended`, `cg-ready`); prefer `playSegment` over
242
318
  hand-rolled seek logic for "click a moment to play that segment" pages.
243
319
 
320
+ To frame a single moment inside the full recording — a cited highlight you
321
+ want to share on its own — add `clip-start`/`clip-end` (seconds) to a bare
322
+ `<cg-video>`: the player draws a clip-length badge, a clip-region strip with a
323
+ live playhead, snaps the first play to `clip-start`, and auto-pauses at
324
+ `clip-end` (via `playSegment`). Scrubbing out of the window fades in a soft
325
+ "↺ Back to moment" pill — a manual scrub-out is never forced back. Both are
326
+ required and `clip-end` is ignored unless it is greater than `clip-start`; the
327
+ pair is `<cg-video>`-only (not read on `<cg-playlist-item>`/`<cg-grid-item>`).
328
+ Rule of thumb: one moment → `clip-start`/`clip-end` on a `<cg-video>`; several
329
+ segments a viewer navigates between → `<cg-chapters>` (below).
330
+
244
331
  For multi-video or segment-navigation pages, prefer the container components
245
332
  over hand-rolled galleries and segment-list JS:
246
333
 
@@ -275,11 +362,16 @@ Output: `--json` (force JSONL envelopes), `--pretty` (one JSON array),
275
362
  `--data raw`, `--raw-output` (raw backend payload; disables pipe protocol),
276
363
  `--quiet`, `--verbose`.
277
364
 
278
- Cache/spend — on `watch`, `extract`, `caption`, and `workflow` only:
365
+ Cache — on `watch`, `extract`, `caption`, `face`, and `workflow` only:
279
366
  `--refresh` (recompute), `--no-cache` (no persistence), `--cached` (reuse
280
- exact-match history), `--no-upload` (refuse cloud upload `needs_upload`),
281
- `--no-download` (refuse local materialization → `needs_download`).
282
- `ask`/`probe` always call the cloud; use `search` for a free cached lookup.
367
+ exact-match history). `ask`/`probe` always call the cloud; use `search` for a
368
+ free cached lookup.
369
+
370
+ Upload/download refusal — on every verb that resolves a source:
371
+ `--no-upload` (refuse cloud upload → `needs_upload`) on `watch`/`extract`/
372
+ `caption`/`face`/`workflow`/`publish` and `library collections add`;
373
+ `--no-download` (refuse local materialization → `needs_download`) on the same
374
+ set minus `publish`.
283
375
 
284
376
  Source reuse (`watch`/`extract`/`caption`): `--source-id <id>`, `--result-id <id>`.
285
377
 
@@ -9,11 +9,11 @@ set -u
9
9
 
10
10
  # Mirror tinycloud-skill.json: min_version / supported_range upper bound
11
11
  # (CI diffs these against the manifest).
12
- MIN_VERSION="0.3.2"
12
+ MIN_VERSION="0.3.4"
13
13
  MAX_VERSION_EXCLUSIVE="0.4.0"
14
14
  INSTALL_CMD='curl -fsSL https://app.cloudglue.dev/tinycloud.sh | bash'
15
15
  # Kept in sync with ../tinycloud-skill.json required_features (CI diffs them).
16
- REQUIRED_FEATURES="envelope.v1 watch.v1 extract.v1 caption.v1 search.v1 probe.v1 ask.v1 clip.v1 grab.v1 jobs.v1 library.collections.v1 library.sync.url.v1 workflow.v1 publish.v1 publish.manage.v1 publish.video.v1 setup.v1"
16
+ REQUIRED_FEATURES="envelope.v1 watch.v1 extract.v1 caption.v1 search.v1 probe.v1 ask.v1 clip.v1 grab.v1 face.v1 jobs.v1 library.collections.v1 library.collections.create.v1 library.collections.mutate.v1 library.collections.entities.v1 library.sync.url.v1 workflow.v1 publish.v1 publish.manage.v1 publish.video.v1 setup.v1"
17
17
 
18
18
  # 1) Binary present and responsive?
19
19
  if ! command -v tinycloud >/dev/null 2>&1; then
@@ -1,8 +1,8 @@
1
1
  {
2
- "skill_version": "0.3.0",
2
+ "skill_version": "0.3.5",
3
3
  "tinycloud": {
4
- "min_version": "0.3.2",
5
- "supported_range": ">=0.3.2 <0.4.0",
4
+ "min_version": "0.3.4",
5
+ "supported_range": ">=0.3.4 <0.4.0",
6
6
  "required_features": [
7
7
  "envelope.v1",
8
8
  "watch.v1",
@@ -13,8 +13,12 @@
13
13
  "ask.v1",
14
14
  "clip.v1",
15
15
  "grab.v1",
16
+ "face.v1",
16
17
  "jobs.v1",
17
18
  "library.collections.v1",
19
+ "library.collections.create.v1",
20
+ "library.collections.mutate.v1",
21
+ "library.collections.entities.v1",
18
22
  "library.sync.url.v1",
19
23
  "workflow.v1",
20
24
  "publish.v1",
@@ -22,14 +22,16 @@ in order, skipping any that already pass.
22
22
  command -v tinycloud && tinycloud --version --json </dev/null
23
23
  ```
24
24
 
25
- If installed and the JSON reports `"version"` ≥ 0.3.0, go to step 2. If
26
- missing (or no machine-readable version), install it ask the user which
27
- they prefer:
25
+ If installed and the JSON reports `"version"` ≥ 0.3.4 (the floor the tinycloud
26
+ skill requires), go to step 2. If missing, older than 0.3.4, or no
27
+ machine-readable version, install or upgrade it — ask the user which they
28
+ prefer:
28
29
 
29
30
  ```bash
30
- npm install -g @cloudglue/tinycloud # canonical (Node >= 18)
31
+ npm install -g @cloudglue/tinycloud # canonical (Node >= 18); reinstall to upgrade
31
32
  # or
32
33
  curl -fsSL https://app.cloudglue.dev/tinycloud.sh | bash
34
+ tinycloud update # already installed but older → move to latest stable
33
35
  ```
34
36
 
35
37
  The first run downloads the platform distribution (~90 MB, one time). More