@cloudglue/tinycloud 0.3.4 → 0.3.6

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.4` always runs tinycloud 0.3.4. It also adds two
19
+ `npx @cloudglue/tinycloud@0.3.6` always runs tinycloud 0.3.6. It also adds two
20
20
  wrapper commands:
21
21
 
22
22
  ```bash
23
- tinycloud install --version 0.3.4 # pre-download a version
23
+ tinycloud install --version 0.3.6 # 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
  ```
@@ -143,7 +143,7 @@ tinycloud caption ./demo.mp4 --format srt --transcript --json
143
143
  tinycloud clip cut ./demo.mp4 --start 12 --end 28 -o clip.mp4 --json
144
144
  # Grounded Q&A over one or more videos
145
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+)
146
+ # Detect faces, or match a known face against a video (0.3.4+; query image: JPEG/PNG)
147
147
  tinycloud face match ./person.jpg ./demo.mp4 --max-faces 10 --json
148
148
  ```
149
149
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudglue/tinycloud",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
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"
@@ -91,7 +91,7 @@ tinycloud clip burn ./demo.mp4 --subtitle-file ./captions/demo.srt -o ./out.mp4
91
91
 
92
92
  # Faces on a single video (cloud, 0.3.4+) — for collection-scale face search/list, see Collections below
93
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
94
+ tinycloud face match ./person.jpg ./demo.mp4 --max-faces 10 --json # query image (JPEG/PNG), ranked 0–100 similarity
95
95
 
96
96
  # Remote videos, async jobs
97
97
  tinycloud grab https://youtu.be/<id> -o ./tinycloud-output/grabbed/ --json
@@ -118,6 +118,8 @@ tinycloud publish list --json
118
118
 
119
119
  # Share a video itself (hosted share page + HLS stream, like a Loom link)
120
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
121
123
  ```
122
124
 
123
125
  Per-verb details and all flags: [reference/verbs.md](reference/verbs.md).
@@ -185,11 +187,19 @@ Authoring your own recipes: [reference/workflow-authoring.md](reference/workflow
185
187
  are signed and short-lived (never hard-code them) — embed via
186
188
  `data.embed_snippet` (`<cg-video>`), which only plays on a private site of
187
189
  the same account. When writing HTML around an embed, use the component's
188
- 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
189
192
  `playSegment(start, end?)`) and the container components
190
193
  (`<cg-playlist>`, `<cg-grid>`, `<cg-chapters>`) rather than hand-rolled
191
194
  players, galleries, or segment-list JS — details in
192
195
  [reference/verbs.md](reference/verbs.md).
196
+ - Live-API discovery components (0.3.6+): the same embed script also defines
197
+ collection-scoped, **private-site-only** elements that let viewers search/chat
198
+ inside a published site — `<cg-chat>`, `<cg-search>`, `<cg-deep-search>`,
199
+ `<cg-face-search>` (chat/search/deep-search need a media-descriptions or
200
+ rich-transcripts collection; face-search needs face-analysis). `publish`
201
+ **hard-rejects** them on a public site → publish with `--visibility private`.
202
+ See [reference/verbs.md](reference/verbs.md).
193
203
 
194
204
  ## 5. Reference (load on demand)
195
205
 
@@ -60,10 +60,12 @@ the exit code alone.
60
60
 
61
61
  `upstream` on a piped command means the upstream envelope was not `ready` —
62
62
  fix the upstream failure, don't retry downstream. `upstream` from a cloud
63
- call itself is a Cloudglue API failure; when it's a request deadline
64
- (retryable, message names `TINYCLOUD_HTTP_TIMEOUT_MS` /
65
- `TINYCLOUD_UPLOAD_TIMEOUT_MS`), the server may still be processingretry
66
- or raise the knob.
63
+ call itself is a Cloudglue API failure; transient ones (request deadline,
64
+ 408/429/5xx, idle-timeout abort) are marked `retryable`, and idempotent reads
65
+ are already auto-retried with backoff before surfacingso a retryable
66
+ `upstream` means the server may still be processing or retries were exhausted:
67
+ retry later or raise the knob the message names (`TINYCLOUD_HTTP_TIMEOUT_MS` /
68
+ `TINYCLOUD_UPLOAD_TIMEOUT_MS`).
67
69
 
68
70
  ## JSON vs JSONL vs text
69
71
 
@@ -41,6 +41,15 @@ connector?" or an envelope field needs explaining.
41
41
  `cloudglue://files/<id>` URI, connector URI, collection, or a bare file-id
42
42
  UUID (normalized to `cloudglue://files/<id>`; an existing local path of the
43
43
  same name wins).
44
+ - **Supported inputs** — local uploads (`watch`, `extract`, `face`,
45
+ `library collections add`) map by extension: video `.mp4 .mov .webm .mkv .m4v`,
46
+ audio `.mp3 .wav .m4a`. Other extensions upload as `application/octet-stream`
47
+ and may be rejected upstream — transcode to a mapped container first
48
+ (`clip transcode`). Local uploads are bounded by Cloudglue at ~3 GB and
49
+ 2 s–3 h (connector ingests allow more). `face match`/`face search` query
50
+ images must be **JPEG or PNG**. Use `grab` for YouTube and
51
+ `library connectors sync` for share links rather than passing those URLs to
52
+ upload verbs.
44
53
  - **`ref` / `source_id` / `result_id`** — stable identifiers in every
45
54
  envelope. `ref` is a reusable pointer to the analyzed source (including
46
55
  `cloud_ready` and the Cloudglue file id) that pipes between verbs;
@@ -88,14 +97,26 @@ connector?" or an envelope field needs explaining.
88
97
  `publish unpublish <site-id | site-name | label>`.
89
98
  - **Video share (shareable asset)** — `tinycloud publish video <source>`
90
99
  wraps a Cloudglue file in a hosted share page (`data.share.share_url`) plus
91
- an HLS stream; one active share per (file, visibility). Private shares
100
+ an HLS stream; one active share per (file, visibility). Adding
101
+ `--clip-start`/`--clip-end` (seconds, 0.3.5+) also returns `data.moment_url`,
102
+ the share page bounded to that "back to moment" window (also reachable as
103
+ `?s=<start>&e=<end>` on a `share_url`). Private shares
92
104
  embed via the `data.embed_snippet` `<cg-video>` tag, which only plays on a
93
105
  private published site of the same account. The embed has playback
94
106
  attributes (`autoplay`+`muted`, `loop`, `start-time`, `poster`,
95
- `accent-color`, `exclusive`) and a JS API (`playSegment`, `seekTo`, media
107
+ `accent-color`, `exclusive`, and `clip-start`/`clip-end` to frame a single
108
+ "back to moment" clip) and a JS API (`playSegment`, `seekTo`, media
96
109
  events re-dispatched on the element) for custom site HTML, and plays
97
110
  standalone or inside the container components (`<cg-playlist>`,
98
111
  `<cg-grid>`, `<cg-chapters>`) — see reference/verbs.md.
112
+ - **Discovery components (live API, 0.3.6+)** — the same embed script also
113
+ defines four collection-scoped, **private-site-only** elements that let a
114
+ viewer search or chat inside a published site and play results inline via
115
+ `<cg-video>`: `<cg-chat>`, `<cg-search>`, `<cg-deep-search>` (over a
116
+ media-descriptions / rich-transcripts collection) and `<cg-face-search>` (over
117
+ a face-analysis collection). They carry no share id, but `tinycloud publish`
118
+ rejects them on a public site — publish `--visibility private`. See
119
+ reference/verbs.md.
99
120
 
100
121
  ## State and isolation (0.3.3+)
101
122
 
@@ -22,6 +22,11 @@ cat sources.txt | tinycloud watch --json
22
22
 
23
23
  - Piping watch envelopes into `search` / `probe` / `ask` auto-scopes them via
24
24
  `ref.cloudglue_file_id` / collection ids.
25
+ - A verb invoked with an explicit source/scope never reads stdin — only the
26
+ pipe form above (a source-less verb after `|`), `setup --stdin`, and a bare
27
+ `tinycloud` prompt do. When spawning tinycloud non-interactively (a subprocess
28
+ or a script), close or ignore its stdin (`</dev/null`, or Node
29
+ `stdio: ["ignore", …]`) and wrap the call in a timeout as a backstop.
25
30
 
26
31
  ## Multi-video batching
27
32
 
@@ -99,11 +99,19 @@ binary reports in `--version --json`.
99
99
  | `TINYCLOUD_HOME` | Isolated state home — config, sessions, cache, jobs, artifacts, skills (default `~/.tinycloud`; same as `--home`). 0.3.3+ |
100
100
  | `TINYCLOUD_OUT` | Output base for generated files (wins over a config `outputBase`) |
101
101
  | `TINYCLOUD_HTTP_TIMEOUT_MS` | Hard deadline per Cloudglue request (default 120s; `0` disables) |
102
- | `TINYCLOUD_UPLOAD_TIMEOUT_MS` | Deadline for upload-shaped requests (default 60min; `0` disables) |
102
+ | `TINYCLOUD_UPLOAD_TIMEOUT_MS` | Total deadline for upload-shaped requests (default 60min; `0` disables) |
103
+ | `TINYCLOUD_UPLOAD_IDLE_TIMEOUT_MS` | Idle (no-progress) deadline for an upload — aborts a wedged transfer in ~1min instead of waiting out the total upload deadline (default 60s; `0` disables) |
104
+ | `TINYCLOUD_HTTP_RETRIES` | Bounded auto-retries for idempotent (GET/HEAD) Cloudglue calls on transient errors — 408/429/5xx, network blips (default 3; `0` disables) |
105
+ | `TINYCLOUD_JOB_WAIT_TIMEOUT_MS` | Wall-clock budget for async job waits (the `waitForReady` poll behind `watch`/`extract`/`face`) (default 10min; `0` disables) |
103
106
 
104
107
  Every Cloudglue request carries a hard deadline, so a stalled route can never
105
108
  hang the CLI indefinitely; a timeout surfaces as a retryable `upstream` error
106
- envelope whose message names the knob to adjust.
109
+ envelope whose message names the knob to adjust. Idempotent reads (GET/HEAD,
110
+ including the status polls behind async waits) auto-retry transient failures
111
+ (408/429/5xx, network blips, idle-timeout aborts) with backoff + jitter before
112
+ surfacing, and uploads abort early if no progress is seen within the idle
113
+ window. Non-idempotent mutations (upload/create/add/delete) are never
114
+ auto-retried — a retryable `upstream` there is yours to re-issue.
107
115
 
108
116
  ## Profiles & isolated homes (0.3.3+)
109
117
 
@@ -143,7 +143,9 @@ tinycloud face search <image> --in collection:col_… [col_…]
143
143
  a normalized 0–1 bounding box (`{top,left,width,height}`) plus a timestamp.
144
144
  `match` takes a query image — a local file (downscaled and sent inline, **never
145
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`
146
+ `similarity`. The query image must be a **JPEG or PNG** (Cloudglue face matching
147
+ decodes only JPEG/PNG — webp/heic/gif/bmp are rejected at preflight; a URL must
148
+ likewise point at a JPEG/PNG). Both upload the *video* first like `watch`/`extract`
147
149
  (`needs_upload` without `--no-upload`) and cache by source + options, so re-runs
148
150
  are free. `--fps`/`--start`/`--end` tune sampling and window;
149
151
  `--max-faces`/`--min-similarity` bound `match`, `--limit` bounds `detect`,
@@ -278,7 +280,7 @@ generated site name, or your `--name` label.
278
280
 
279
281
  ```bash
280
282
  tinycloud publish video <source> [--visibility public|private] # default public
281
- [--name <title>] [--segment-id <id>] --json
283
+ [--name <title>] [--segment-id <id>] [--clip-start <s> --clip-end <e>] --json
282
284
  tinycloud publish video list [--in <source>] [--visibility public|private] --json
283
285
  tinycloud publish video unpublish <share-id | source> --json # --visibility disambiguates
284
286
  ```
@@ -297,6 +299,14 @@ feature id.
297
299
  `data.embed_snippet` (a `<cg-video share-id="...">` tag), which only plays
298
300
  on a PRIVATE published site of the same account — `tinycloud publish`
299
301
  rejects an artifact with a private embed targeted at a public site.
302
+ - Moment window (0.3.5+): pass `--clip-start <s> --clip-end <e>` (seconds,
303
+ `clip-end > clip-start >= 0`, both required together or the command errors)
304
+ to also get `data.moment_url` — the hosted share page bounded to
305
+ `[start, end]`, with the same length badge, region strip, and "↺ Back to
306
+ moment" pill as the `<cg-video>` clip embed, and it survives the
307
+ private-share sign-in. Optional — omit it for a plain full-video share. The
308
+ same window is just `?s=<start>&e=<end>` appended to a `share_url`, so you
309
+ can hand-build a moment link from an existing share without re-publishing.
300
310
 
301
311
  When generating custom site HTML around a `<cg-video>` embed, use the
302
312
  component's built-ins instead of reinventing them. It defaults to a
@@ -309,6 +319,17 @@ rest). Its JS API queues until ready — `playSegment(start, end?)`,
309
319
  element (`timeupdate`, `ended`, `cg-ready`); prefer `playSegment` over
310
320
  hand-rolled seek logic for "click a moment to play that segment" pages.
311
321
 
322
+ To frame a single moment inside the full recording — a cited highlight you
323
+ want to share on its own — add `clip-start`/`clip-end` (seconds) to a bare
324
+ `<cg-video>`: the player draws a clip-length badge, a clip-region strip with a
325
+ live playhead, snaps the first play to `clip-start`, and auto-pauses at
326
+ `clip-end` (via `playSegment`). Scrubbing out of the window fades in a soft
327
+ "↺ Back to moment" pill — a manual scrub-out is never forced back. Both are
328
+ required and `clip-end` is ignored unless it is greater than `clip-start`; the
329
+ pair is `<cg-video>`-only (not read on `<cg-playlist-item>`/`<cg-grid-item>`).
330
+ Rule of thumb: one moment → `clip-start`/`clip-end` on a `<cg-video>`; several
331
+ segments a viewer navigates between → `<cg-chapters>` (below).
332
+
312
333
  For multi-video or segment-navigation pages, prefer the container components
313
334
  over hand-rolled galleries and segment-list JS:
314
335
 
@@ -327,6 +348,27 @@ private share — directly or through a container — on a public site. The full
327
348
  reference ships with the binary as `references/cg-video.md` inside the
328
349
  bundled media-artifact skill (under the install's `skills/` directory).
329
350
 
351
+ Discovery components (live API, 0.3.6+): the same `/__cg/embed.js` script also
352
+ defines four **collection-scoped** components that let a viewer search or chat
353
+ *inside* a published site and play the referenced moment inline via `<cg-video>`
354
+ — `<cg-chat>` (conversational Q&A, streaming answers + inline moment citations;
355
+ optional `placeholder`), `<cg-search>` (keyword/transcript text search),
356
+ `<cg-deep-search>` (agentic semantic search), and `<cg-face-search>` (upload or
357
+ paste a face image → matching moments). Each takes `collection="<id>"` (plus
358
+ optional `accent-color` and `--cg-height` CSS sizing); the collection's `--type`
359
+ must match the element — `<cg-chat>`/`<cg-search>`/`<cg-deep-search>` need a
360
+ `media-descriptions` or `rich-transcripts` collection, `<cg-face-search>` needs a
361
+ `face-analysis` collection. Unlike the playback elements they carry **no share
362
+ id**, but their live calls are refused on a public site, so `tinycloud publish`
363
+ **hard-rejects** a page that embeds any of them on a public site — publish with
364
+ `--visibility private`. End to end: build a collection of the right type
365
+ (`library collections create … --type …` → `library collections add` → poll
366
+ `library collections show` until each file is `completed`) → author HTML with
367
+ the component → `tinycloud publish <html> --visibility private`. Full reference
368
+ plus a kitchen-sink page wiring every component (props, JS API, events) ships
369
+ with the binary as `references/cg-video.md` and `references/kitchen-sink.html`
370
+ inside the bundled media-artifact skill.
371
+
330
372
  ### setup — credentials
331
373
 
332
374
  ```bash
@@ -1,5 +1,5 @@
1
1
  {
2
- "skill_version": "0.3.4",
2
+ "skill_version": "0.3.6",
3
3
  "tinycloud": {
4
4
  "min_version": "0.3.4",
5
5
  "supported_range": ">=0.3.4 <0.4.0",