@gobi-ai/cli 0.9.4 → 0.9.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.
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
"name": "gobi-ai"
|
|
5
5
|
},
|
|
6
6
|
"description": "Claude Code plugin for the Gobi collaborative knowledge platform CLI",
|
|
7
|
-
"version": "0.9.
|
|
7
|
+
"version": "0.9.5",
|
|
8
8
|
"plugins": [
|
|
9
9
|
{
|
|
10
10
|
"name": "gobi",
|
|
11
11
|
"description": "Manage the Gobi collaborative knowledge platform from the command line. Search and ask brains, publish brain documents, create threads, manage sessions, generate images and videos.",
|
|
12
|
-
"version": "0.9.
|
|
12
|
+
"version": "0.9.5",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "gobi-ai"
|
|
15
15
|
},
|
package/dist/commands/media.js
CHANGED
|
@@ -122,7 +122,9 @@ export function registerMediaCommand(program) {
|
|
|
122
122
|
.requiredOption("--script <script>", "Script for the avatar to read")
|
|
123
123
|
.option("--background-media-id <backgroundMediaId>", "Background media ID (from upload)")
|
|
124
124
|
.option("--wait", "Poll until generation completes")
|
|
125
|
+
.option("-o, --output <path>", "Download video to this path when done (implies --wait)")
|
|
125
126
|
.action(async (opts) => {
|
|
127
|
+
const shouldWait = opts.wait || !!opts.output;
|
|
126
128
|
const body = {
|
|
127
129
|
name: opts.name,
|
|
128
130
|
avatarId: opts.avatarId,
|
|
@@ -134,10 +136,56 @@ export function registerMediaCommand(program) {
|
|
|
134
136
|
const resp = (await apiPost("/media-gen/videos", body));
|
|
135
137
|
let data = unwrapResp(resp);
|
|
136
138
|
const videoId = data.id || data.videoId;
|
|
137
|
-
if (
|
|
139
|
+
if (shouldWait && videoId) {
|
|
138
140
|
console.log(`Video ${videoId} queued — polling for completion…`);
|
|
139
141
|
data = await pollStatus(`/media-gen/videos/${videoId}/status`, ["inference_complete", "inference_failed"]);
|
|
140
142
|
}
|
|
143
|
+
// Download video to file if -o specified
|
|
144
|
+
if (opts.output && videoId && data.status === "inference_complete") {
|
|
145
|
+
const token = await getValidToken();
|
|
146
|
+
const dlUrl = `${BASE_URL}/media-gen/videos/${videoId}/download`;
|
|
147
|
+
const dlRes = await fetch(dlUrl, {
|
|
148
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
149
|
+
redirect: "follow",
|
|
150
|
+
});
|
|
151
|
+
if (dlRes.ok) {
|
|
152
|
+
const { writeFile, mkdir } = await import("fs/promises");
|
|
153
|
+
const { dirname } = await import("path");
|
|
154
|
+
const buffer = Buffer.from(await dlRes.arrayBuffer());
|
|
155
|
+
await mkdir(dirname(opts.output), { recursive: true });
|
|
156
|
+
await writeFile(opts.output, buffer);
|
|
157
|
+
const contentType = dlRes.headers.get("content-type") || "video/mp4";
|
|
158
|
+
if (isJsonMode(media)) {
|
|
159
|
+
jsonOut({ ...data, filename: opts.output, contentType, size: buffer.length });
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
console.log(`Video saved to ${opts.output} (${buffer.length} bytes)`);
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
// If direct download fails, try getting the URL and fetching that
|
|
166
|
+
const dlRes2 = await fetch(dlUrl, {
|
|
167
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
168
|
+
redirect: "manual",
|
|
169
|
+
});
|
|
170
|
+
const location = dlRes2.headers.get("location");
|
|
171
|
+
if (location) {
|
|
172
|
+
const videoRes = await fetch(location);
|
|
173
|
+
if (videoRes.ok) {
|
|
174
|
+
const { writeFile, mkdir } = await import("fs/promises");
|
|
175
|
+
const { dirname } = await import("path");
|
|
176
|
+
const buffer = Buffer.from(await videoRes.arrayBuffer());
|
|
177
|
+
await mkdir(dirname(opts.output), { recursive: true });
|
|
178
|
+
await writeFile(opts.output, buffer);
|
|
179
|
+
const contentType = videoRes.headers.get("content-type") || "video/mp4";
|
|
180
|
+
if (isJsonMode(media)) {
|
|
181
|
+
jsonOut({ ...data, filename: opts.output, contentType, size: buffer.length });
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
console.log(`Video saved to ${opts.output} (${buffer.length} bytes)`);
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
141
189
|
if (isJsonMode(media)) {
|
|
142
190
|
jsonOut(data);
|
|
143
191
|
return;
|
package/package.json
CHANGED
|
@@ -30,20 +30,48 @@ gobi --json media image-generate --prompt "a sunset over mountains"
|
|
|
30
30
|
Single command — generate and download in one step:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
gobi --json media image-generate --prompt "
|
|
33
|
+
gobi --json media image-generate --prompt "<PROMPT>" -o media/<NAME>.png
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
Replace `<NAME>` with a short descriptive slug derived from the prompt (e.g., `happy-family`, `sunset-mountains`).
|
|
37
|
+
|
|
36
38
|
The `-o` flag implies `--wait` and downloads the image when done.
|
|
37
39
|
|
|
38
|
-
|
|
40
|
+
**IMPORTANT: After downloading, show the image using Obsidian wiki-link syntax EXACTLY like this:**
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
![[media/<NAME>.png]]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Do NOT use markdown image syntax `` or `gobi://` URLs. Always use `![[media/<NAME>.png]]`.
|
|
39
47
|
|
|
40
48
|
### Key rules
|
|
41
|
-
-
|
|
49
|
+
- Replace `<NAME>` with a descriptive slug — NEVER use example names like `sunset.png` literally.
|
|
42
50
|
- `--name` is **optional** — auto-derived from prompt if omitted.
|
|
43
51
|
- Do NOT use the `downloadUrl` from the response — it is a frontend path, not a direct download link.
|
|
44
52
|
- `image-download` takes a **positional** jobId (NOT `--job-id`): `gobi media image-download <jobId>`
|
|
45
53
|
- The `jobId` (or `id`) field is what you pass to `image-download` / `image-status` — NOT `mediaId`.
|
|
46
54
|
|
|
55
|
+
## Typical Workflow (Video Generation)
|
|
56
|
+
|
|
57
|
+
Single command — create and download in one step:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
gobi --json media video-create --name "<NAME>" --avatar-id "<AVATAR_ID>" --voice-id "<VOICE_ID>" --script "<SCRIPT>" -o media/<NAME>.mp4
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Replace `<NAME>` with a short descriptive slug. Use `gobi media avatars` and `gobi media voices` to list available IDs.
|
|
64
|
+
|
|
65
|
+
The `-o` flag implies `--wait` and downloads the video when done.
|
|
66
|
+
|
|
67
|
+
**IMPORTANT: After downloading, show the video using Obsidian wiki-link syntax EXACTLY like this:**
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
![[media/<NAME>.mp4]]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Do NOT use markdown image/link syntax `` or `gobi://` URLs. Always use `![[media/<NAME>.mp4]]`.
|
|
74
|
+
|
|
47
75
|
## Available Commands
|
|
48
76
|
|
|
49
77
|
### Upload
|