@cloudglue/tinycloud 0.3.2 → 0.3.4
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 +133 -7
- package/lib/skills.js +115 -20
- package/package.json +2 -2
- package/skills/tinycloud/SKILL.md +28 -5
- package/skills/tinycloud/reference/glossary.md +23 -1
- package/skills/tinycloud/reference/pipelines.md +27 -3
- package/skills/tinycloud/reference/setup.md +50 -1
- package/skills/tinycloud/reference/verbs.md +97 -6
- package/skills/tinycloud/reference/workflow-authoring.md +4 -0
- package/skills/tinycloud/scripts/preflight.sh +2 -2
- package/skills/tinycloud/tinycloud-skill.json +7 -3
- package/skills/tinycloud-init/SKILL.md +9 -4
- package/skills/tinycloud-skill-creator/SKILL.md +2 -0
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.
|
|
19
|
+
`npx @cloudglue/tinycloud@0.3.4` always runs tinycloud 0.3.4. It also adds two
|
|
20
20
|
wrapper commands:
|
|
21
21
|
|
|
22
22
|
```bash
|
|
23
|
-
tinycloud install --version 0.3.
|
|
23
|
+
tinycloud install --version 0.3.4 # 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
|
```
|
|
@@ -50,14 +50,21 @@ This repo also distributes agent skills that teach coding agents (Claude
|
|
|
50
50
|
Code, Codex, and anything else following the
|
|
51
51
|
[Agent Skills](https://agentskills.io) standard) to drive the tinycloud CLI.
|
|
52
52
|
|
|
53
|
-
**One command** (
|
|
53
|
+
**One command** (in a terminal it prompts you to pick the target agents):
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
-
npx @cloudglue/tinycloud skills install
|
|
57
|
-
npx @cloudglue/tinycloud skills install --
|
|
56
|
+
npx @cloudglue/tinycloud skills install # menu: claude-code, agents, codex, cursor
|
|
57
|
+
npx @cloudglue/tinycloud skills install --harness cursor,codex # pick targets non-interactively
|
|
58
|
+
npx @cloudglue/tinycloud skills install --global # ~/.claude/skills (Claude Code only)
|
|
58
59
|
npx @cloudglue/tinycloud skills install --skill tinycloud,blog-post # just some
|
|
59
60
|
```
|
|
60
61
|
|
|
62
|
+
Each agent reads skills from its own `<dir>/skills`: `claude-code` → `.claude`,
|
|
63
|
+
`agents` → `.agents` (the universal [Agent Skills](https://agentskills.io)
|
|
64
|
+
layout), `codex` → `.codex`, `cursor` → `.cursor`. The menu preselects dirs
|
|
65
|
+
that already exist; piped/CI runs (or `--yes`) skip it and install into
|
|
66
|
+
whichever dirs exist, defaulting to `.claude/skills` when none do.
|
|
67
|
+
|
|
61
68
|
**Claude Code** (as a plugin):
|
|
62
69
|
|
|
63
70
|
```text
|
|
@@ -91,14 +98,133 @@ To give every agent session in a repo the same skills, commit them:
|
|
|
91
98
|
|
|
92
99
|
```bash
|
|
93
100
|
cd your-project
|
|
94
|
-
npx @cloudglue/tinycloud skills install
|
|
95
|
-
git add .claude .agents 2>/dev/null; git commit -m "Add tinycloud agent skills"
|
|
101
|
+
npx @cloudglue/tinycloud skills install --harness claude-code,agents # or pick from the menu
|
|
102
|
+
git add .claude .agents .codex .cursor 2>/dev/null; git commit -m "Add tinycloud agent skills"
|
|
96
103
|
```
|
|
97
104
|
|
|
98
105
|
Optionally add a line to your project's `CLAUDE.md` so agents reach for them:
|
|
99
106
|
`Video work (analysis, captions, clips, workflows) goes through the tinycloud
|
|
100
107
|
CLI — see the tinycloud skill; run tinycloud-init if the CLI isn't set up.`
|
|
101
108
|
|
|
109
|
+
## Commands
|
|
110
|
+
|
|
111
|
+
Cloud commands run through your configured Cloudglue API key (billed per the
|
|
112
|
+
[rate card](https://app.cloudglue.dev/home/billing/rate-card)); local and
|
|
113
|
+
network commands are free. Every command prints a JSON envelope on stdout (logs
|
|
114
|
+
go to stderr) — pass `--json`.
|
|
115
|
+
|
|
116
|
+
| Command | What it does |
|
|
117
|
+
|---|---|
|
|
118
|
+
| `watch` | Analyze a video → reusable cached context + Cloudglue-ready ref |
|
|
119
|
+
| `extract` | Pull structured facts, entities, or moments (free-form or JSON-schema) |
|
|
120
|
+
| `caption` | Subtitles and transcripts (SRT/VTT/ASS) |
|
|
121
|
+
| `search` | Keyword search over cached video context |
|
|
122
|
+
| `probe` | Semantic moment/video search over a Cloudglue scope |
|
|
123
|
+
| `ask` | Grounded Q&A over one or more videos |
|
|
124
|
+
| `clip` | ffmpeg-backed cut, thumbs, stitch, transcode, burn, split, audio, info |
|
|
125
|
+
| `grab` | Download a remote video (YouTube, TikTok, Loom, direct) |
|
|
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 |
|
|
128
|
+
| `jobs` | Poll, wait on, or forget async jobs |
|
|
129
|
+
| `workflow` | Run packaged pipeline recipes (see below) |
|
|
130
|
+
| `publish` | Publish HTML artifacts as Cloudglue Sites; share videos |
|
|
131
|
+
| `setup` | Configure the Cloudglue API key and service connections |
|
|
132
|
+
|
|
133
|
+
A few common invocations:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
# Analyze a video into reusable, cached context + a Cloudglue-ready ref
|
|
137
|
+
tinycloud watch ./demo.mp4 --json
|
|
138
|
+
# Pull structured findings (free-form query here; pass --schema for a fixed shape)
|
|
139
|
+
tinycloud extract "key moments with timestamps" ./demo.mp4 --json
|
|
140
|
+
# Subtitles plus a markdown transcript
|
|
141
|
+
tinycloud caption ./demo.mp4 --format srt --transcript --json
|
|
142
|
+
# Trim a clip locally — no upload, ffmpeg-backed
|
|
143
|
+
tinycloud clip cut ./demo.mp4 --start 12 --end 28 -o clip.mp4 --json
|
|
144
|
+
# Grounded Q&A over one or more videos
|
|
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
|
|
148
|
+
```
|
|
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
|
+
|
|
166
|
+
`tinycloud commands --json` is the authoritative, machine-readable list of
|
|
167
|
+
every command and flag. Full per-verb flags and cost classes:
|
|
168
|
+
[skills/tinycloud/reference/verbs.md](skills/tinycloud/reference/verbs.md).
|
|
169
|
+
The envelope contract — statuses (`ready`, `pending`, `needs_credentials`, …)
|
|
170
|
+
and exit codes:
|
|
171
|
+
[skills/tinycloud/reference/envelope.md](skills/tinycloud/reference/envelope.md).
|
|
172
|
+
|
|
173
|
+
### Global flags & profiles (0.3.3+)
|
|
174
|
+
|
|
175
|
+
A few options are host-level — they isolate state rather than run a video
|
|
176
|
+
operation, so they go *before* the verb and don't appear in `commands --json`:
|
|
177
|
+
|
|
178
|
+
- `--home <dir>` (or `$TINYCLOUD_HOME`) — run against an isolated state home
|
|
179
|
+
(config, sessions, cache, jobs, artifacts, skills) instead of `~/.tinycloud`.
|
|
180
|
+
- `--profile <name>` — use a named profile's home, so multiple accounts or
|
|
181
|
+
installs run side by side without cross-contamination.
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
tinycloud --home ./.tc watch ./demo.mp4 --json # isolated state for this repo
|
|
185
|
+
tinycloud profile list # profiles and their homes
|
|
186
|
+
tinycloud profile create work --default # create one and make it default
|
|
187
|
+
tinycloud profile create staging --copy-from work # clone an existing home
|
|
188
|
+
tinycloud --profile work ask "..." --in ./demo.mp4 --json
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
Sessions are scoped per project (keyed by the git root), the agent takes a
|
|
192
|
+
`--skills <list>` allowlist alongside `--tools`, and a project-local
|
|
193
|
+
`.tinycloud/config.json` can pin tool/skill allowlists and an output base.
|
|
194
|
+
Details:
|
|
195
|
+
[skills/tinycloud/reference/setup.md](skills/tinycloud/reference/setup.md).
|
|
196
|
+
|
|
197
|
+
## Workflows
|
|
198
|
+
|
|
199
|
+
Workflows are packaged, repeatable pipelines that run with a single command
|
|
200
|
+
and write their outputs into a run directory under
|
|
201
|
+
`./tinycloud-output/runs/<run_id>/`. The five flagship recipes — each with a
|
|
202
|
+
matching agent skill — are:
|
|
203
|
+
|
|
204
|
+
| Workflow | Turns a video into |
|
|
205
|
+
|---|---|
|
|
206
|
+
| `sales-coaching` | Coaching dashboard — call scores, speech metrics, objections |
|
|
207
|
+
| `blog-post` | Rich blog post — sections, thumbnails, takeaways |
|
|
208
|
+
| `ad-analysis` | Ad breakdown — shot timeline, hook, pacing, CTA |
|
|
209
|
+
| `meeting-breakdown` | Speaker timeline, chapter summaries, action items |
|
|
210
|
+
| `youtube-publish` | YouTube title, description, chapters, tags, subtitles |
|
|
211
|
+
|
|
212
|
+
```bash
|
|
213
|
+
tinycloud workflow list --json # all available recipes
|
|
214
|
+
tinycloud workflow sales-coaching ./call.mp4 --json # run one
|
|
215
|
+
tinycloud workflow plan blog-post ./demo.mp4 --json # preview steps (free, no side effects)
|
|
216
|
+
tinycloud workflow validate ad-analysis --json # check a recipe (or a path)
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
The final envelope reports `data.status`
|
|
220
|
+
(`completed | partial | failed | paused`), `data.outputs` (named outputs such
|
|
221
|
+
as `outputs.html`), and `data.artifacts[].path`. The five above each have a
|
|
222
|
+
matching agent skill (see the table), so coding agents can run them directly;
|
|
223
|
+
`tinycloud workflow list` shows the full set, including building blocks like
|
|
224
|
+
`summary` and `clip-highlights`. Author your own recipes:
|
|
225
|
+
[skills/tinycloud/reference/workflow-authoring.md](skills/tinycloud/reference/workflow-authoring.md)
|
|
226
|
+
(or scaffold one with the `tinycloud-skill-creator` skill).
|
|
227
|
+
|
|
102
228
|
## License
|
|
103
229
|
|
|
104
230
|
© Aviary Inc. (d/b/a Cloudglue). All rights reserved. Use is subject to [Aviary Inc. Terms of Service](https://cloudglue.dev/terms).
|
package/lib/skills.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
const fs = require("node:fs");
|
|
4
4
|
const os = require("node:os");
|
|
5
5
|
const path = require("node:path");
|
|
6
|
+
const readline = require("node:readline");
|
|
6
7
|
|
|
7
8
|
// Agent skills bundled with this package (the npm tarball includes skills/).
|
|
8
9
|
function bundledSkillsDir() {
|
|
@@ -19,28 +20,95 @@ function listBundledSkills() {
|
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
23
|
+
* Known agent harnesses. Each keeps skills in its own <configDir>/skills dir,
|
|
24
|
+
* all using the SKILL.md layout. `id` is both the menu label and the
|
|
25
|
+
* --harness token; `aliases` are extra accepted tokens.
|
|
25
26
|
* claude-code: <project>/.claude/skills (global: ~/.claude/skills)
|
|
26
|
-
*
|
|
27
|
+
* agents: <project>/.agents/skills (universal agentskills.io layout)
|
|
28
|
+
* codex: <project>/.codex/skills
|
|
29
|
+
* cursor: <project>/.cursor/skills
|
|
27
30
|
*/
|
|
28
|
-
|
|
31
|
+
const HARNESSES = [
|
|
32
|
+
{ id: "claude-code", aliases: ["claude"], configDir: ".claude" },
|
|
33
|
+
{ id: "agents", aliases: [], configDir: ".agents" },
|
|
34
|
+
{ id: "codex", aliases: [], configDir: ".codex" },
|
|
35
|
+
{ id: "cursor", aliases: [], configDir: ".cursor" },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
function harnessIds() {
|
|
39
|
+
return HARNESSES.map((h) => h.id);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Resolve a --harness token (id or alias, case-insensitive) to its entry.
|
|
43
|
+
function findHarness(token) {
|
|
44
|
+
const t = String(token).trim().toLowerCase();
|
|
45
|
+
return HARNESSES.find((h) => h.id === t || h.aliases.includes(t));
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function harnessTarget(h, cwd) {
|
|
49
|
+
return { name: h.id, dir: path.join(cwd, h.configDir, "skills") };
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function detectHarnesses(cwd) {
|
|
53
|
+
return HARNESSES.filter((h) => fs.existsSync(path.join(cwd, h.configDir)));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Pick install targets from flags/detection only — no prompting or I/O beyond
|
|
58
|
+
* existence checks, so it stays deterministic for tests. The interactive menu
|
|
59
|
+
* lives in promptForTargets(). Precedence: --dir > --global > --harness >
|
|
60
|
+
* detection (and .claude when nothing is detected).
|
|
61
|
+
*/
|
|
62
|
+
function resolveTargets({ global: isGlobal, dir, harness, cwd = process.cwd() }) {
|
|
29
63
|
if (dir) return [{ name: "custom", dir: path.resolve(dir) }];
|
|
30
64
|
if (isGlobal) return [{ name: "claude-code (global)", dir: path.join(os.homedir(), ".claude", "skills") }];
|
|
31
65
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
66
|
+
if (harness && harness.length) {
|
|
67
|
+
return harness.map((token) => {
|
|
68
|
+
const h = findHarness(token);
|
|
69
|
+
if (!h) throw new Error(`Unknown harness: ${token}. Valid: ${harnessIds().join(", ")}`);
|
|
70
|
+
return harnessTarget(h, cwd);
|
|
71
|
+
});
|
|
38
72
|
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
73
|
+
|
|
74
|
+
const detected = detectHarnesses(cwd);
|
|
75
|
+
if (detected.length) return detected.map((h) => harnessTarget(h, cwd));
|
|
76
|
+
// No harness detected: default to claude-code project layout.
|
|
77
|
+
return [harnessTarget(HARNESSES[0], cwd)];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Interactive picker: list the four harnesses (detected ones preselected) and
|
|
82
|
+
* read a comma-separated choice. Streams are injectable for testing; empty or
|
|
83
|
+
* unparseable input falls back to the preselection.
|
|
84
|
+
*/
|
|
85
|
+
async function promptForTargets({ cwd = process.cwd(), input = process.stdin, output = process.stdout } = {}) {
|
|
86
|
+
const detected = new Set(detectHarnesses(cwd).map((h) => h.id));
|
|
87
|
+
const rows = HARNESSES.map((h, i) => ({ n: i + 1, h, detected: detected.has(h.id) }));
|
|
88
|
+
const preselected = rows.some((r) => r.detected)
|
|
89
|
+
? rows.filter((r) => r.detected).map((r) => r.n)
|
|
90
|
+
: [1];
|
|
91
|
+
|
|
92
|
+
output.write("Which agents should get the skills?\n");
|
|
93
|
+
for (const r of rows) {
|
|
94
|
+
const mark = preselected.includes(r.n) ? "x" : " ";
|
|
95
|
+
const tag = r.detected ? " (detected)" : "";
|
|
96
|
+
output.write(` ${r.n}) [${mark}] ${r.h.id.padEnd(11)} ${path.join(r.h.configDir, "skills")}${tag}\n`);
|
|
42
97
|
}
|
|
43
|
-
|
|
98
|
+
|
|
99
|
+
const rl = readline.createInterface({ input, output });
|
|
100
|
+
const answer = await new Promise((resolve) => {
|
|
101
|
+
rl.question(`Enter numbers (comma-separated) [${preselected.join(",")}]: `, resolve);
|
|
102
|
+
});
|
|
103
|
+
rl.close();
|
|
104
|
+
|
|
105
|
+
let nums = answer
|
|
106
|
+
.split(",")
|
|
107
|
+
.map((s) => parseInt(s.trim(), 10))
|
|
108
|
+
.filter((n) => Number.isInteger(n) && n >= 1 && n <= rows.length);
|
|
109
|
+
if (!nums.length) nums = preselected;
|
|
110
|
+
|
|
111
|
+
return rows.filter((r) => nums.includes(r.n)).map((r) => harnessTarget(r.h, cwd));
|
|
44
112
|
}
|
|
45
113
|
|
|
46
114
|
function installSkills({ skills, targets, force }) {
|
|
@@ -70,12 +138,17 @@ const USAGE = `Usage: tinycloud skills <list|install> [options]
|
|
|
70
138
|
|
|
71
139
|
Install options:
|
|
72
140
|
--skill <a,b,...> Only these skills (default: all)
|
|
73
|
-
--
|
|
141
|
+
--harness <a,b,...> Install into these agents: claude-code, agents, codex, cursor
|
|
142
|
+
(default: pick from a menu in a terminal; auto-detect otherwise)
|
|
143
|
+
--global Install to ~/.claude/skills instead of the project (Claude Code only)
|
|
74
144
|
--dir <path> Install to an explicit directory
|
|
145
|
+
--yes, -y Skip the interactive menu; use auto-detection
|
|
75
146
|
--force Overwrite skills that are already installed
|
|
76
147
|
|
|
77
|
-
|
|
78
|
-
|
|
148
|
+
Each harness holds skills under <dir>/skills: claude-code → .claude, agents → .agents
|
|
149
|
+
(universal agentskills.io layout), codex → .codex, cursor → .cursor. Run in a terminal
|
|
150
|
+
with no target and you'll be prompted to pick (detected dirs preselected); piped/CI runs
|
|
151
|
+
install into whichever dirs exist, or .claude when none do.
|
|
79
152
|
`;
|
|
80
153
|
|
|
81
154
|
async function cmdSkills(args) {
|
|
@@ -97,7 +170,9 @@ async function cmdSkills(args) {
|
|
|
97
170
|
let wanted = available;
|
|
98
171
|
let isGlobal = false;
|
|
99
172
|
let force = false;
|
|
173
|
+
let yes = false;
|
|
100
174
|
let dir;
|
|
175
|
+
let harness;
|
|
101
176
|
for (let i = 1; i < args.length; i++) {
|
|
102
177
|
if (args[i] === "--skill" && args[i + 1]) {
|
|
103
178
|
const names = args[++i].split(",").map((s) => s.trim()).filter(Boolean);
|
|
@@ -106,8 +181,15 @@ async function cmdSkills(args) {
|
|
|
106
181
|
throw new Error(`Unknown skill(s): ${unknown.join(", ")}. Available: ${available.join(", ")}`);
|
|
107
182
|
}
|
|
108
183
|
wanted = names;
|
|
184
|
+
} else if (args[i] === "--harness" && args[i + 1]) {
|
|
185
|
+
harness = args[++i].split(",").map((s) => s.trim()).filter(Boolean);
|
|
186
|
+
const unknown = harness.filter((id) => !findHarness(id));
|
|
187
|
+
if (unknown.length) {
|
|
188
|
+
throw new Error(`Unknown harness(es): ${unknown.join(", ")}. Valid: ${harnessIds().join(", ")}`);
|
|
189
|
+
}
|
|
109
190
|
} else if (args[i] === "--global") isGlobal = true;
|
|
110
191
|
else if (args[i] === "--force") force = true;
|
|
192
|
+
else if (args[i] === "--yes" || args[i] === "-y") yes = true;
|
|
111
193
|
else if (args[i] === "--dir" && args[i + 1]) dir = args[++i];
|
|
112
194
|
else throw new Error(`Unknown install option: ${args[i]}\n${USAGE}`);
|
|
113
195
|
}
|
|
@@ -116,11 +198,24 @@ async function cmdSkills(args) {
|
|
|
116
198
|
throw new Error("No bundled skills found in this package installation");
|
|
117
199
|
}
|
|
118
200
|
|
|
119
|
-
const
|
|
201
|
+
const explicit = dir || isGlobal || (harness && harness.length);
|
|
202
|
+
const targets =
|
|
203
|
+
!explicit && !yes && process.stdin.isTTY && process.stdout.isTTY
|
|
204
|
+
? await promptForTargets({})
|
|
205
|
+
: resolveTargets({ global: isGlobal, dir, harness });
|
|
206
|
+
|
|
120
207
|
const results = installSkills({ skills: wanted, targets, force });
|
|
121
208
|
for (const r of results) console.log(`${r.status === "installed" ? "✓" : "-"} ${r.skill} → ${r.dir} [${r.status}]`);
|
|
122
209
|
const installed = results.filter((r) => r.status === "installed").length;
|
|
123
210
|
console.log(`\n${installed} skill(s) installed${installed ? ". Restart your agent session to pick them up." : "."}`);
|
|
124
211
|
}
|
|
125
212
|
|
|
126
|
-
module.exports = {
|
|
213
|
+
module.exports = {
|
|
214
|
+
cmdSkills,
|
|
215
|
+
resolveTargets,
|
|
216
|
+
promptForTargets,
|
|
217
|
+
installSkills,
|
|
218
|
+
listBundledSkills,
|
|
219
|
+
bundledSkillsDir,
|
|
220
|
+
HARNESSES,
|
|
221
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cloudglue/tinycloud",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.4",
|
|
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
|
|
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,13 +89,29 @@ 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
|
-
#
|
|
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
|
|
@@ -110,6 +126,13 @@ Evaluating a video the host project's code rendered (render → evaluate →
|
|
|
110
126
|
edit → rerender): the render-review loop in
|
|
111
127
|
[reference/pipelines.md](reference/pipelines.md).
|
|
112
128
|
|
|
129
|
+
Isolation & scope (0.3.3+): `--home <dir>` / `$TINYCLOUD_HOME` and
|
|
130
|
+
`--profile <name>` are leading flags (before the verb) that run against an
|
|
131
|
+
isolated state home; the agent also takes `--skills <list>` alongside
|
|
132
|
+
`--tools <list>`, and a project-local `.tinycloud/config.json` can pin those
|
|
133
|
+
allowlists and an output base. Sessions are scoped per project. Details:
|
|
134
|
+
[reference/setup.md](reference/setup.md).
|
|
135
|
+
|
|
113
136
|
## 3. Workflows (packaged recipes)
|
|
114
137
|
|
|
115
138
|
Repeatable pipelines run with one command and write outputs into a run
|
|
@@ -170,7 +193,7 @@ Authoring your own recipes: [reference/workflow-authoring.md](reference/workflow
|
|
|
170
193
|
|
|
171
194
|
## 5. Reference (load on demand)
|
|
172
195
|
|
|
173
|
-
- [reference/setup.md](reference/setup.md) — install, credentials, env vars, preflight
|
|
196
|
+
- [reference/setup.md](reference/setup.md) — install, credentials, env vars, preflight, profiles & project scope
|
|
174
197
|
- [reference/verbs.md](reference/verbs.md) — every verb, flag, and cost class
|
|
175
198
|
- [reference/envelope.md](reference/envelope.md) — full envelope schema, statuses, error codes, exit codes
|
|
176
199
|
- [reference/pipelines.md](reference/pipelines.md) — pipes, batching, jobs, cache/spend-control flags
|
|
@@ -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
|
|
@@ -88,3 +96,17 @@ connector?" or an envelope field needs explaining.
|
|
|
88
96
|
events re-dispatched on the element) for custom site HTML, and plays
|
|
89
97
|
standalone or inside the container components (`<cg-playlist>`,
|
|
90
98
|
`<cg-grid>`, `<cg-chapters>`) — see reference/verbs.md.
|
|
99
|
+
|
|
100
|
+
## State and isolation (0.3.3+)
|
|
101
|
+
|
|
102
|
+
- **Home** — the directory holding all tinycloud state for a run: config,
|
|
103
|
+
sessions, cache, jobs, artifacts, and skills. Default `~/.tinycloud`;
|
|
104
|
+
relocate it with `--home <dir>` or `$TINYCLOUD_HOME`.
|
|
105
|
+
- **Profile** — a named, fully isolated home, selected with `--profile <name>`
|
|
106
|
+
and managed by `tinycloud profile list|show|create|use|remove`. Lets multiple
|
|
107
|
+
accounts or installs run side by side without cross-contamination. (Distinct
|
|
108
|
+
from `watch --profile`, which selects an analysis profile.)
|
|
109
|
+
- **Project scope** — sessions and capabilities keyed to a project (its git
|
|
110
|
+
root). Sessions live under `<home>/projects/<project-key>/sessions`, and a
|
|
111
|
+
project-local `.tinycloud/config.json` can pin tool/skill allowlists and an
|
|
112
|
+
output base — precedence is CLI flags > project config > global config.
|
|
@@ -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
|
-
#
|
|
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
|
|
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
|
|
|
@@ -95,9 +96,57 @@ binary reports in `--version --json`.
|
|
|
95
96
|
| `CLOUDGLUE_API_KEY` | Cloudglue API key (alternative to `tinycloud setup cloudglue`) |
|
|
96
97
|
| `TINYCLOUD_VERSION` | npm launcher: run a specific binary version |
|
|
97
98
|
| `TINYCLOUD_INSTALL_DIR` | npm launcher: cache root (default `~/.tinycloud`) |
|
|
99
|
+
| `TINYCLOUD_HOME` | Isolated state home — config, sessions, cache, jobs, artifacts, skills (default `~/.tinycloud`; same as `--home`). 0.3.3+ |
|
|
100
|
+
| `TINYCLOUD_OUT` | Output base for generated files (wins over a config `outputBase`) |
|
|
98
101
|
| `TINYCLOUD_HTTP_TIMEOUT_MS` | Hard deadline per Cloudglue request (default 120s; `0` disables) |
|
|
99
102
|
| `TINYCLOUD_UPLOAD_TIMEOUT_MS` | Deadline for upload-shaped requests (default 60min; `0` disables) |
|
|
100
103
|
|
|
101
104
|
Every Cloudglue request carries a hard deadline, so a stalled route can never
|
|
102
105
|
hang the CLI indefinitely; a timeout surfaces as a retryable `upstream` error
|
|
103
106
|
envelope whose message names the knob to adjust.
|
|
107
|
+
|
|
108
|
+
## Profiles & isolated homes (0.3.3+)
|
|
109
|
+
|
|
110
|
+
Every piece of tinycloud state — config, sessions, cache, jobs, artifacts, and
|
|
111
|
+
skills — lives under one home (default `~/.tinycloud`). Relocate it to run
|
|
112
|
+
multiple accounts or installs side by side without cross-contamination. Both
|
|
113
|
+
options are *leading* (before the verb) and work with any command:
|
|
114
|
+
|
|
115
|
+
- `--home <dir>` (or `$TINYCLOUD_HOME`) — use that directory as the home.
|
|
116
|
+
- `--profile <name>` — use a named profile's home (from the profiles registry).
|
|
117
|
+
|
|
118
|
+
Named profiles are managed by the host-level `profile` verb (a CLI/host
|
|
119
|
+
concern, so it is not in `commands --json`):
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
tinycloud profile list # profiles and their homes (active marked *)
|
|
123
|
+
tinycloud profile show [<name>] # home path + exists/default/active
|
|
124
|
+
tinycloud profile create <name> [--home <dir>] [--copy-from <name>] \
|
|
125
|
+
[--description <text>] [--default]
|
|
126
|
+
tinycloud profile use <name> # set the default profile
|
|
127
|
+
tinycloud profile remove <name> # unregister (does not delete the home)
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
`--copy-from` seeds the new profile's home from an existing one. The registry
|
|
131
|
+
lives at `$XDG_CONFIG_HOME/tinycloud/profiles.json`; `default` is reserved.
|
|
132
|
+
This global `--profile <name>` is unrelated to `watch --profile
|
|
133
|
+
default|light|custom` (that flag selects an analysis profile).
|
|
134
|
+
|
|
135
|
+
## Project scope (0.3.3+)
|
|
136
|
+
|
|
137
|
+
Within a home, sessions are scoped per project — keyed by the canonical git
|
|
138
|
+
root — under `<home>/projects/<project-key>/sessions`. In the interactive
|
|
139
|
+
agent, `/sessions` lists the current project's sessions (`/sessions all` spans
|
|
140
|
+
every project); `-c` resumes the most recent and still falls back to legacy
|
|
141
|
+
flat sessions (read-only, migrated forward on resume).
|
|
142
|
+
|
|
143
|
+
A project can also carry a local `.tinycloud/config.json` that scopes a run:
|
|
144
|
+
|
|
145
|
+
- `preferences.tools` / `preferences.skills` — allowlists of agent tool / skill
|
|
146
|
+
names (omit = all; the `--tools` / `--skills` flags override them).
|
|
147
|
+
- `preferences.outputBase` — where generated files land (a relative path is
|
|
148
|
+
anchored to the project root; `$TINYCLOUD_OUT` still wins).
|
|
149
|
+
|
|
150
|
+
Precedence is **CLI flags > project-local `.tinycloud/config.json` > global
|
|
151
|
+
config**; a more specific scope replaces (does not merge) a broader one.
|
|
152
|
+
Read-only mode always keeps the `read` and `bash` tools.
|
|
@@ -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
|
-
| `
|
|
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 |
|
|
@@ -23,6 +24,24 @@ every verb. Regenerate doubts from it instead of trusting prose.
|
|
|
23
24
|
Cloud verbs run through the configured Cloudglue API key.
|
|
24
25
|
`caption`/`library`/`workflow` vary by what they end up doing.
|
|
25
26
|
|
|
27
|
+
## Global flags (0.3.3+)
|
|
28
|
+
|
|
29
|
+
Leading options (placed *before* the verb) and agent-level allowlists, separate
|
|
30
|
+
from the per-verb flags below. `--home`/`--profile` and the `profile` verb are
|
|
31
|
+
host concerns and are intentionally absent from `commands --json`.
|
|
32
|
+
|
|
33
|
+
- `--home <dir>` / `$TINYCLOUD_HOME` — run against an isolated state home
|
|
34
|
+
(config, sessions, cache, jobs, artifacts, skills) instead of `~/.tinycloud`.
|
|
35
|
+
- `--profile <name>` — use a named profile's home. Managed by
|
|
36
|
+
`tinycloud profile list|show|create|use|remove`
|
|
37
|
+
(`create <name> [--home <dir>] [--copy-from <name>] [--description <text>] [--default]`).
|
|
38
|
+
Unrelated to `watch --profile default|light|custom` (an analysis profile).
|
|
39
|
+
- `--skills <list>` (0.3.3+) / `--tools <list>` — comma-separated agent skill /
|
|
40
|
+
tool allowlists (omit = all); also settable per project via
|
|
41
|
+
`.tinycloud/config.json`.
|
|
42
|
+
|
|
43
|
+
Profiles, project-scoped sessions, and `.tinycloud/config.json`: [setup.md](setup.md).
|
|
44
|
+
|
|
26
45
|
## Per-verb flags
|
|
27
46
|
|
|
28
47
|
Flags shared by most verbs are listed once at the bottom.
|
|
@@ -108,17 +127,84 @@ tinycloud clip cut --from-findings -o clips/ # cut timestamped findings p
|
|
|
108
127
|
tinycloud grab <url> [-o <file-or-dir>] [--audio-only] [--format <yt-dlp-selector>]
|
|
109
128
|
```
|
|
110
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
|
+
|
|
111
159
|
### library — collections and connectors
|
|
112
160
|
|
|
113
161
|
```bash
|
|
114
162
|
tinycloud library collections list --json
|
|
115
|
-
tinycloud library collections show <col_id> --json
|
|
163
|
+
tinycloud library collections show <col_id> --json # files[].status: pending|processing|completed (readiness)
|
|
116
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
|
|
117
171
|
tinycloud library connectors list --json
|
|
118
172
|
tinycloud library connectors files <connector-id> [--limit 25] [--page-token <t>] --json
|
|
119
173
|
tinycloud library connectors sync [<connector-id>] <uri-share-link-or-public-url> --json
|
|
120
174
|
```
|
|
121
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
|
+
|
|
122
208
|
`connectors sync` materializes its argument into a Cloudglue file without
|
|
123
209
|
starting analysis (idempotent). The connector id is optional — with just a
|
|
124
210
|
URI or link, sync routes through the matching connector type. Connector URIs
|
|
@@ -257,11 +343,16 @@ Output: `--json` (force JSONL envelopes), `--pretty` (one JSON array),
|
|
|
257
343
|
`--data raw`, `--raw-output` (raw backend payload; disables pipe protocol),
|
|
258
344
|
`--quiet`, `--verbose`.
|
|
259
345
|
|
|
260
|
-
Cache
|
|
346
|
+
Cache — on `watch`, `extract`, `caption`, `face`, and `workflow` only:
|
|
261
347
|
`--refresh` (recompute), `--no-cache` (no persistence), `--cached` (reuse
|
|
262
|
-
exact-match history)
|
|
263
|
-
|
|
264
|
-
|
|
348
|
+
exact-match history). `ask`/`probe` always call the cloud; use `search` for a
|
|
349
|
+
free cached lookup.
|
|
350
|
+
|
|
351
|
+
Upload/download refusal — on every verb that resolves a source:
|
|
352
|
+
`--no-upload` (refuse cloud upload → `needs_upload`) on `watch`/`extract`/
|
|
353
|
+
`caption`/`face`/`workflow`/`publish` and `library collections add`;
|
|
354
|
+
`--no-download` (refuse local materialization → `needs_download`) on the same
|
|
355
|
+
set minus `publish`.
|
|
265
356
|
|
|
266
357
|
Source reuse (`watch`/`extract`/`caption`): `--source-id <id>`, `--result-id <id>`.
|
|
267
358
|
|
|
@@ -141,5 +141,9 @@ are not implemented in 0.3.x — treat `partial`/`paused` as terminal.
|
|
|
141
141
|
The tinycloud agent picks it up on next start; from any shell it runs by
|
|
142
142
|
path: `tinycloud workflow run ~/.tinycloud/skills/my-skill/my-skill.yaml demo.mp4 --allow-command --json`.
|
|
143
143
|
|
|
144
|
+
With `--home`/`--profile` (0.3.3+) the global skills dir moves under the active
|
|
145
|
+
home (`<home>/skills/`); a project-local `.tinycloud/config.json` can also pin
|
|
146
|
+
which skills load via a `preferences.skills` allowlist.
|
|
147
|
+
|
|
144
148
|
To wrap a recipe as a skill for *this* host agent instead, see the
|
|
145
149
|
`tinycloud-skill-creator` skill in this repo.
|
|
@@ -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.
|
|
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.
|
|
2
|
+
"skill_version": "0.3.4",
|
|
3
3
|
"tinycloud": {
|
|
4
|
-
"min_version": "0.3.
|
|
5
|
-
"supported_range": ">=0.3.
|
|
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.
|
|
26
|
-
|
|
27
|
-
they
|
|
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
|
|
@@ -75,6 +77,9 @@ Report what's now working and point forward:
|
|
|
75
77
|
uses the API key)
|
|
76
78
|
- One-command workflows: `tinycloud workflow list --json` (sales-coaching,
|
|
77
79
|
blog-post, ad-analysis, meeting-breakdown, youtube-publish, …)
|
|
80
|
+
- Multiple accounts or isolated installs (0.3.3+): `tinycloud profile create
|
|
81
|
+
<name> --default`, then `--profile <name>` (or `--home <dir>` /
|
|
82
|
+
`$TINYCLOUD_HOME`) on any command to switch state homes
|
|
78
83
|
- If the general `tinycloud` skill is installed alongside this one, it
|
|
79
84
|
documents the full CLI, envelope contract, and a glossary; its
|
|
80
85
|
`scripts/preflight.sh` re-checks this setup any time.
|
|
@@ -44,6 +44,8 @@ Before writing anything, establish:
|
|
|
44
44
|
`.claude/skills/<name>/`) whose SKILL.md runs the recipe **by path**.
|
|
45
45
|
- *The tinycloud agent*: `~/.tinycloud/skills/<name>/` (global) or
|
|
46
46
|
`.tinycloud/skills/<name>/` (project), picked up as `/skills:<name>`.
|
|
47
|
+
(With `--home`/`--profile`, 0.3.3+, the global dir is the active home's
|
|
48
|
+
`skills/`; a project's `.tinycloud/config.json` can allowlist skills.)
|
|
47
49
|
|
|
48
50
|
## 2. Scaffold
|
|
49
51
|
|