@cloudglue/tinycloud 0.3.0 → 0.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cloudglue/tinycloud",
3
- "version": "0.3.0",
3
+ "version": "0.3.2",
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"
@@ -57,7 +57,9 @@ Parse the single JSON envelope from stdout (machine output; logs are stderr):
57
57
  Default: `./tinycloud-output/runs/<data.run_id>/ad-analysis.html`.
58
58
  - Report the HTML path; offer
59
59
  `tinycloud publish <html> --name ad-analysis --visibility private --json`
60
- to host it as a shareable page.
60
+ to host it as a shareable page. Share the returned `data.url` (fresh
61
+ content can take ~1 min to appear there; `data.version_url` is live
62
+ immediately, so a brief 403 at `data.url` is not a failure).
61
63
 
62
64
  Any other `status` (`needs_credentials`, `needs_upload`, `pending`, `paused`,
63
65
  `error`) or `data.status` of `partial`/`failed`: stop, report the envelope's
@@ -57,7 +57,9 @@ Parse the single JSON envelope from stdout (machine output; logs are stderr):
57
57
  Default: `./tinycloud-output/runs/<data.run_id>/blog-post.html`.
58
58
  - Report the HTML path; offer
59
59
  `tinycloud publish <html> --name blog-post --visibility private --json`
60
- to host it as a shareable page.
60
+ to host it as a shareable page. Share the returned `data.url` (fresh
61
+ content can take ~1 min to appear there; `data.version_url` is live
62
+ immediately, so a brief 403 at `data.url` is not a failure).
61
63
 
62
64
  Any other `status` (`needs_credentials`, `needs_upload`, `pending`, `paused`,
63
65
  `error`) or `data.status` of `partial`/`failed`: stop, report the envelope's
@@ -57,7 +57,9 @@ Parse the single JSON envelope from stdout (machine output; logs are stderr):
57
57
  Default: `./tinycloud-output/runs/<data.run_id>/meeting-breakdown.html`.
58
58
  - Report the HTML path; offer
59
59
  `tinycloud publish <html> --name meeting-breakdown --visibility private --json`
60
- to host it as a shareable page.
60
+ to host it as a shareable page. Share the returned `data.url` (fresh
61
+ content can take ~1 min to appear there; `data.version_url` is live
62
+ immediately, so a brief 403 at `data.url` is not a failure).
61
63
 
62
64
  Any other `status` (`needs_credentials`, `needs_upload`, `pending`, `paused`,
63
65
  `error`) or `data.status` of `partial`/`failed`: stop, report the envelope's
@@ -58,7 +58,9 @@ Parse the single JSON envelope from stdout (machine output; logs are stderr):
58
58
  Default: `./tinycloud-output/runs/<data.run_id>/sales-coaching.html`.
59
59
  - Report the HTML path to the user; offer
60
60
  `tinycloud publish <html> --name sales-coaching --visibility private --json`
61
- to host it as a shareable page.
61
+ to host it as a shareable page. Share the returned `data.url` (fresh
62
+ content can take ~1 min to appear there; `data.version_url` is live
63
+ immediately, so a brief 403 at `data.url` is not a failure).
62
64
 
63
65
  Any other `status` (`needs_credentials`, `needs_upload`, `pending`, `paused`,
64
66
  `error`) or `data.status` of `partial`/`failed`: stop, report the envelope's
@@ -91,6 +91,7 @@ tinycloud clip burn ./demo.mp4 --subtitle-file ./captions/demo.srt -o ./out.mp4
91
91
 
92
92
  # Remote videos, collections, async jobs
93
93
  tinycloud grab https://youtu.be/<id> -o ./tinycloud-output/grabbed/ --json
94
+ tinycloud library connectors sync https://example.com/clip.mp4 --json # public URL → Cloudglue file (not YouTube — use grab)
94
95
  tinycloud library collections list --json
95
96
  tinycloud watch ./long.mp4 --background --json # returns pending + meta.job_id
96
97
  tinycloud jobs wait <job-id> --timeout 120s --json
@@ -98,10 +99,16 @@ tinycloud jobs wait <job-id> --timeout 120s --json
98
99
  # Publish an HTML artifact to Cloudglue Sites (manage with list / unpublish)
99
100
  tinycloud publish ./tinycloud-output/html/report.html --name report --visibility private --json
100
101
  tinycloud publish list --json
102
+
103
+ # Share a video itself (hosted share page + HLS stream, like a Loom link)
104
+ tinycloud publish video ./demo.mp4 --visibility public --json
101
105
  ```
102
106
 
103
107
  Per-verb details and all flags: [reference/verbs.md](reference/verbs.md).
104
108
  Multi-video batching and pipe semantics: [reference/pipelines.md](reference/pipelines.md).
109
+ Evaluating a video the host project's code rendered (render → evaluate →
110
+ edit → rerender): the render-review loop in
111
+ [reference/pipelines.md](reference/pipelines.md).
105
112
 
106
113
  ## 3. Workflows (packaged recipes)
107
114
 
@@ -131,8 +138,9 @@ Authoring your own recipes: [reference/workflow-authoring.md](reference/workflow
131
138
  [command]`) — don't add `--allow-command` for them (host-agent permission
132
139
  classifiers may flag it); it's only needed for path-run recipes without
133
140
  that permission.
134
- - Sources: local paths, URLs, `cloudglue://files/<id>` URIs, or
135
- `collection:col_…` a bare file-id UUID is not accepted.
141
+ - Sources: local paths, URLs, `cloudglue://files/<id>` URIs,
142
+ `collection:col_…`, or a bare Cloudglue file-id UUID (normalized to
143
+ `cloudglue://files/<id>`; an existing local path of the same name wins).
136
144
  - Do not pass `--background` to `ask`; background jobs exist only for tracked
137
145
  async ops (`watch`, `extract`).
138
146
  - `workflow status` / `workflow resume` are not implemented in 0.3.x; treat
@@ -146,6 +154,19 @@ Authoring your own recipes: [reference/workflow-authoring.md](reference/workflow
146
154
  `--out` flag where supported).
147
155
  - Cached results are reused automatically; `--refresh` forces re-computation,
148
156
  `--no-cache` disables persistence.
157
+ - After `publish`, share `data.url` (the stable site link). Fresh content can
158
+ take up to a minute to appear there — a brief 403 right after publishing is
159
+ propagation, not a failure; `data.version_url` serves that exact version
160
+ immediately.
161
+ - Never pair a private video share with a public site: private stream URLs
162
+ are signed and short-lived (never hard-code them) — embed via
163
+ `data.embed_snippet` (`<cg-video>`), which only plays on a private site of
164
+ the same account. When writing HTML around an embed, use the component's
165
+ built-ins (`autoplay`+`muted`, `loop`, `start-time`, `exclusive`; JS
166
+ `playSegment(start, end?)`) and the container components
167
+ (`<cg-playlist>`, `<cg-grid>`, `<cg-chapters>`) rather than hand-rolled
168
+ players, galleries, or segment-list JS — details in
169
+ [reference/verbs.md](reference/verbs.md).
149
170
 
150
171
  ## 5. Reference (load on demand)
151
172
 
@@ -59,7 +59,11 @@ the exit code alone.
59
59
  `needs_download`, `visual_analysis_requires_download`, `upstream`.
60
60
 
61
61
  `upstream` on a piped command means the upstream envelope was not `ready` —
62
- fix the upstream failure, don't retry downstream.
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 processing — retry
66
+ or raise the knob.
63
67
 
64
68
  ## JSON vs JSONL vs text
65
69
 
@@ -30,8 +30,9 @@ connector?" or an envelope field needs explaining.
30
30
  individual items by URI (e.g. `grain://recording/<id>`) so they become
31
31
  Cloudglue files.
32
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>`.
33
+ `cloudglue://files/<id>` URI, connector URI, collection, or a bare file-id
34
+ UUID (normalized to `cloudglue://files/<id>`; an existing local path of the
35
+ same name wins).
35
36
  - **`ref` / `source_id` / `result_id`** — stable identifiers in every
36
37
  envelope. `ref` is a reusable pointer to the analyzed source (including
37
38
  `cloud_ready` and the Cloudglue file id) that pipes between verbs;
@@ -47,7 +48,9 @@ connector?" or an envelope field needs explaining.
47
48
  mirrored in Cloudglue, so later `extract`/`ask`/`search` reuse it instead
48
49
  of re-analyzing.
49
50
  - **Segmentation** — how a video is split for analysis: `chapters`
50
- (semantic), `shots` (visual cuts), `uniform:<seconds>` (fixed windows).
51
+ (semantic), `shots` (visual cuts; bounds tunable via
52
+ `--shot-min-seconds`/`--shot-max-seconds`, sub-second min allowed),
53
+ `uniform:<seconds>` (fixed windows).
51
54
  - **Cache layers** — `meta.cache` reports `identity` (is this the same file
52
55
  we've seen?) and `enrichment` (analysis results) as
53
56
  `hit | miss | written | skipped`.
@@ -68,6 +71,20 @@ connector?" or an envelope field needs explaining.
68
71
  - **Command step** — a workflow step that runs a local script (e.g. an HTML
69
72
  renderer); gated by `--allow-command` / recipe `permissions: [command]`.
70
73
  - **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>`.
74
+ `tinycloud publish <html> --visibility public|private` returns the stable
75
+ site URL (`{name}.cloudglue.site`) as `url` the share link plus a
76
+ `version_url` permalink to that exact version (live immediately; the site
77
+ URL can take up to a minute to serve fresh content). Private = Cloudglue
78
+ account members only, same URL. Manage with `publish list` (rows show
79
+ `published` / `site_version_id`) and
80
+ `publish unpublish <site-id | site-name | label>`.
81
+ - **Video share (shareable asset)** — `tinycloud publish video <source>`
82
+ 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
84
+ embed via the `data.embed_snippet` `<cg-video>` tag, which only plays on a
85
+ private published site of the same account. The embed has playback
86
+ attributes (`autoplay`+`muted`, `loop`, `start-time`, `poster`,
87
+ `accent-color`, `exclusive`) and a JS API (`playSegment`, `seekTo`, media
88
+ events re-dispatched on the element) for custom site HTML, and plays
89
+ standalone or inside the container components (`<cg-playlist>`,
90
+ `<cg-grid>`, `<cg-chapters>`) — see reference/verbs.md.
@@ -102,3 +102,50 @@ tinycloud watch ./talk.mp4 --json \
102
102
  | tinycloud extract "the three strongest quotes with timestamps" --json \
103
103
  | tinycloud clip cut --from-findings -o ./tinycloud-output/quotes/ --json
104
104
  ```
105
+
106
+ ## Render-review loop (videos your code generates)
107
+
108
+ When the host project's code produces a video (Remotion, Manim, ffmpeg
109
+ filter graphs, slide-render pipelines, recorded E2E runs), don't stop at a
110
+ successful render exit code — a clean render is not a good video. Use
111
+ tinycloud as the eyes in the edit loop:
112
+
113
+ ```bash
114
+ # 1. Render with the project's own tooling (example: Remotion).
115
+ npx remotion render Promo out/promo.mp4
116
+
117
+ # 2. Evaluate the result.
118
+ tinycloud watch ./out/promo.mp4 --segment shots --json \
119
+ | tinycloud extract "Evaluate pacing, text readability and clipping, scene \
120
+ continuity, and audio/visual sync. Return timestamped findings with \
121
+ severity and concrete edit instructions." --json
122
+
123
+ # 3. Map each finding's timestamp to code (frame = seconds x fps for
124
+ # frame-based renderers), apply fixes, rerender to the SAME path.
125
+
126
+ # 4. Re-evaluate, feeding the previous findings back so the model confirms fixes.
127
+ tinycloud watch ./out/promo.mp4 --segment shots --json \
128
+ | tinycloud extract "Re-evaluate this render. Previous findings: <summarize \
129
+ prior findings>. Confirm whether each is resolved and report any new \
130
+ issues." --json
131
+ ```
132
+
133
+ Loop rules:
134
+
135
+ - Stop when findings are empty or low-severity only; then report done with
136
+ the final findings summary. "Done" means evaluated, not rendered.
137
+ - Hunting sub-second flash frames or rapid cuts? Tighten the shot pass with
138
+ `--shot-min-seconds 0.6` (fractional values allowed);
139
+ `--shot-max-seconds` caps overly long shots the same way.
140
+ - Each rerender is a new file, so each iteration uploads and runs through
141
+ the configured Cloudglue API key
142
+ (https://app.cloudglue.dev/home/billing/rate-card). Tell the user, and
143
+ prefer short/low-res preview renders while iterating when the project
144
+ supports them.
145
+ - Reuse the same output path between iterations so stale renders don't pile
146
+ up; the new file content makes the cache treat it as a new source (that is
147
+ correct — you want the new render evaluated, not the cached old one).
148
+
149
+ You own the renderer-specific half of the loop (mapping timestamps to frames
150
+ and code, editing, rerendering); tinycloud only ever sees the media file.
151
+ The loop applies to any pipeline that emits video.
@@ -95,3 +95,9 @@ binary reports in `--version --json`.
95
95
  | `CLOUDGLUE_API_KEY` | Cloudglue API key (alternative to `tinycloud setup cloudglue`) |
96
96
  | `TINYCLOUD_VERSION` | npm launcher: run a specific binary version |
97
97
  | `TINYCLOUD_INSTALL_DIR` | npm launcher: cache root (default `~/.tinycloud`) |
98
+ | `TINYCLOUD_HTTP_TIMEOUT_MS` | Hard deadline per Cloudglue request (default 120s; `0` disables) |
99
+ | `TINYCLOUD_UPLOAD_TIMEOUT_MS` | Deadline for upload-shaped requests (default 60min; `0` disables) |
100
+
101
+ Every Cloudglue request carries a hard deadline, so a stalled route can never
102
+ hang the CLI indefinitely; a timeout surfaces as a retryable `upstream` error
103
+ envelope whose message names the knob to adjust.
@@ -17,7 +17,7 @@ every verb. Regenerate doubts from it instead of trusting prose.
17
17
  | `library` | varies | no | Collections, connectors, local mirrors, sync |
18
18
  | `jobs` | network | yes | Poll/wait/forget tracked async jobs |
19
19
  | `workflow` | varies | no | Validate/plan/run workflow recipes |
20
- | `publish` | cloud | yes | Publish HTML/code artifacts as Cloudglue Sites |
20
+ | `publish` | cloud | yes | Publish HTML/code artifacts as Cloudglue Sites; share videos |
21
21
  | `setup` | local | no | Credentials and service connections |
22
22
 
23
23
  Cloud verbs run through the configured Cloudglue API key.
@@ -31,20 +31,31 @@ Flags shared by most verbs are listed once at the bottom.
31
31
 
32
32
  ```bash
33
33
  tinycloud watch <source> [--segment uniform:20|chapters|shots|segments]
34
+ [--shot-min-seconds <s>] [--shot-max-seconds <s>]
34
35
  [--profile default|light|custom] [--speech-only | --visual-only]
35
36
  [--start <t>] [--end <t>] [--transcript] [--content] [--json-index]
36
37
  [--background]
37
38
  ```
38
39
 
40
+ Shot bounds tune `--segment shots` only: min 0.6–600 (fractional/sub-second
41
+ values catch flash frames and rapid cuts), max 1–600, min ≤ max. Out-of-range
42
+ or wrong-mode values fail with a validation envelope before any upload. The
43
+ bounds are part of the cache key, so tuned and default shot passes never
44
+ collide.
45
+
39
46
  ### extract — structured facts
40
47
 
41
48
  ```bash
42
49
  tinycloud extract "<query>" <source> --json # free-form query
43
50
  tinycloud extract --schema ./schema.json <source> # JSON-schema-shaped output
44
51
  [--segment-level] [--segmentation chapters|shots|segments]
52
+ [--shot-min-seconds <s>] [--shot-max-seconds <s>]
45
53
  [--include-thumbnails] [--transcript-mode] [--background]
46
54
  ```
47
55
 
56
+ `--shot-min-seconds`/`--shot-max-seconds` work exactly as on `watch`, against
57
+ `--segmentation shots`.
58
+
48
59
  ### caption — subtitles and transcripts
49
60
 
50
61
  ```bash
@@ -105,9 +116,23 @@ tinycloud library collections show <col_id> --json
105
116
  tinycloud library collections sync <col_id> --artifacts descriptions,transcripts,thumbnails,metadata --json
106
117
  tinycloud library connectors list --json
107
118
  tinycloud library connectors files <connector-id> [--limit 25] [--page-token <t>] --json
108
- tinycloud library connectors sync <connector-id> <uri> --json # e.g. grain://recording/<id>
119
+ tinycloud library connectors sync [<connector-id>] <uri-share-link-or-public-url> --json
109
120
  ```
110
121
 
122
+ `connectors sync` materializes its argument into a Cloudglue file without
123
+ starting analysis (idempotent). The connector id is optional — with just a
124
+ URI or link, sync routes through the matching connector type. Connector URIs
125
+ (`grain://recording/<id>`, `gdrive://file/<id>`, `dropbox://<path>`,
126
+ `zoom://uuid/<uuid>`, `s3://<bucket>/<key>`, …) and share links are accepted:
127
+ Dropbox file share links sync server-side via the connector's OAuth
128
+ (including login-gated links); `zoom.us/rec/share` links resolve best-effort
129
+ (Zoom mints a new token per copy — the recording-detail link is the reliable
130
+ form). Link warnings are advisory and surface in `data.warnings` rather than
131
+ blocking the sync. Non-connector public URLs (direct media URLs, TikTok,
132
+ Loom, public Dropbox links without a connector) sync into a standalone
133
+ Cloudglue file via direct URL ingestion — same command, no connector needed.
134
+ YouTube URLs cannot sync; use `tinycloud grab` instead.
135
+
111
136
  `connectors files` also takes provider-specific filters: `--from`/`--to`
112
137
  (Zoom, Grain dates), `--folder-id` (Google Drive), `--path` (Dropbox),
113
138
  `--bucket`/`--prefix` (S3/GCS), `--title-search`/`--team`/`--meeting-type`
@@ -150,11 +175,72 @@ Republishing identical content makes no network calls; flipping visibility
150
175
  patches without re-uploading. `list`/`unpublish` are gated by the
151
176
  `publish.manage.v1` feature id.
152
177
 
178
+ The returned `data.url` is the stable site link (`{name}.cloudglue.site`) —
179
+ share that one. It can take up to a minute to serve fresh content after a
180
+ publish (a brief 403 there is propagation, not a failure); `data.version_url`
181
+ is a permalink to that exact version and is live immediately. `publish list`
182
+ rows carry `published` (whether a version is live at `url`) and
183
+ `site_version_id`; text output marks unpublished sites with
184
+ `(no published version)`.
185
+
153
186
  Note: `--name` is a label for the artifact (republishing reuses it) — the
154
187
  site itself gets a generated name (e.g. `young-fire-2486`) shown by
155
188
  `publish list`. `unpublish` resolves any of: the `site_id` UUID, the
156
189
  generated site name, or your `--name` label.
157
190
 
191
+ ### publish video — share a video
192
+
193
+ ```bash
194
+ tinycloud publish video <source> [--visibility public|private] # default public
195
+ [--name <title>] [--segment-id <id>] --json
196
+ tinycloud publish video list [--in <source>] [--visibility public|private] --json
197
+ tinycloud publish video unpublish <share-id | source> --json # --visibility disambiguates
198
+ ```
199
+
200
+ Wraps a Cloudglue file in a shareable asset — a stable hosted share page
201
+ (`data.share.share_url`) plus an HLS stream. Local sources upload first (same
202
+ prepare step as `watch`). One active share per (file, visibility); re-running
203
+ returns the existing share. Stream processing surfaces as a `pending`
204
+ envelope — re-run per its `next` hint. Gated by the `publish.video.v1`
205
+ feature id.
206
+
207
+ - Public: `data.share.stream_url` is plain HLS usable anywhere players
208
+ support it — bare `<video>` tags only play HLS in Safari.
209
+ - Private: only account members can watch; stream URLs are signed and
210
+ short-lived (redacted in machine output — never hard-code them). Embed with
211
+ `data.embed_snippet` (a `<cg-video share-id="...">` tag), which only plays
212
+ on a PRIVATE published site of the same account — `tinycloud publish`
213
+ rejects an artifact with a private embed targeted at a public site.
214
+
215
+ When generating custom site HTML around a `<cg-video>` embed, use the
216
+ component's built-ins instead of reinventing them. It defaults to a
217
+ responsive 16:9 dark placeholder (override with plain page CSS on the
218
+ `cg-video` selector); mount-time attributes: `autoplay` (pair with `muted` or
219
+ browsers block it), `loop`, `start-time`, `poster`, `accent-color`, and
220
+ `exclusive` (put it on every player in a gallery so starting one pauses the
221
+ rest). Its JS API queues until ready — `playSegment(start, end?)`,
222
+ `seekTo()`, `play()`/`pause()` — and media events are re-dispatched on the
223
+ element (`timeupdate`, `ended`, `cg-ready`); prefer `playSegment` over
224
+ hand-rolled seek logic for "click a moment to play that segment" pages.
225
+
226
+ For multi-video or segment-navigation pages, prefer the container components
227
+ over hand-rolled galleries and segment-list JS:
228
+
229
+ - `<cg-playlist>` + `<cg-playlist-item share-id="…">` — one player plus a
230
+ clickable track list, with auto-advance.
231
+ - `<cg-grid>` + `<cg-grid-item share-id="…">` — lazy poster-card gallery,
232
+ inline or lightbox modal, at most one live player.
233
+ - `<cg-chapters>` + `<cg-chapter start="…" [end="…"]>` — segment navigation
234
+ bound to a player by id; an `end` attribute plays just that clip via
235
+ `playSegment`. Hand-rolled `playSegment` calls remain the fallback for
236
+ fully custom layouts.
237
+
238
+ Share ids inside `<cg-playlist-item>`/`<cg-grid-item>` tags count toward the
239
+ private-embed guard: `tinycloud publish` rejects an artifact embedding a
240
+ private share — directly or through a container — on a public site. The full
241
+ reference ships with the binary as `references/cg-video.md` inside the
242
+ bundled media-artifact skill (under the install's `skills/` directory).
243
+
158
244
  ### setup — credentials
159
245
 
160
246
  ```bash
@@ -178,3 +264,9 @@ exact-match history), `--no-upload` (refuse cloud upload → `needs_upload`),
178
264
  `ask`/`probe` always call the cloud; use `search` for a free cached lookup.
179
265
 
180
266
  Source reuse (`watch`/`extract`/`caption`): `--source-id <id>`, `--result-id <id>`.
267
+
268
+ Sources: local paths, URLs, `cloudglue://files/<id>` URIs,
269
+ `collection:col_…`, or a bare Cloudglue file-id UUID — bare ids are
270
+ normalized to `cloudglue://files/<id>` (an existing local path of the same
271
+ name wins), so file ids echoed in tinycloud output can be passed straight
272
+ back as sources or `--in` scopes.
@@ -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.0"
12
+ MIN_VERSION="0.3.2"
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 workflow.v1 publish.v1 publish.manage.v1 setup.v1"
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"
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.1.0",
2
+ "skill_version": "0.3.0",
3
3
  "tinycloud": {
4
- "min_version": "0.3.0",
5
- "supported_range": ">=0.3.0 <0.4.0",
4
+ "min_version": "0.3.2",
5
+ "supported_range": ">=0.3.2 <0.4.0",
6
6
  "required_features": [
7
7
  "envelope.v1",
8
8
  "watch.v1",
@@ -15,9 +15,11 @@
15
15
  "grab.v1",
16
16
  "jobs.v1",
17
17
  "library.collections.v1",
18
+ "library.sync.url.v1",
18
19
  "workflow.v1",
19
20
  "publish.v1",
20
21
  "publish.manage.v1",
22
+ "publish.video.v1",
21
23
  "setup.v1"
22
24
  ],
23
25
  "envelope_schema": "1",
@@ -94,7 +94,9 @@ Edit the scaffolded files with the user's specifics.
94
94
  interpolated JS object literals.
95
95
  - If the deliverable should be a URL, finish with
96
96
  `tinycloud publish <html-or-dir> --visibility public|private --json` and
97
- ask the user public-or-private before the first publish.
97
+ ask the user public-or-private before the first publish. Report `data.url`
98
+ (the stable site link) as the deliverable; fresh content can take ~1 min to
99
+ appear there — `data.version_url` serves that exact version immediately.
98
100
 
99
101
  ## 4. Validate and dry-run
100
102