@gobi-ai/cli 0.9.6 → 0.9.7
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.7",
|
|
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.7",
|
|
13
13
|
"author": {
|
|
14
14
|
"name": "gobi-ai"
|
|
15
15
|
},
|
package/dist/commands/media.js
CHANGED
|
@@ -116,7 +116,7 @@ export function registerMediaCommand(program) {
|
|
|
116
116
|
media
|
|
117
117
|
.command("video-create")
|
|
118
118
|
.description("Create an avatar video generation job.")
|
|
119
|
-
.
|
|
119
|
+
.option("--name <name>", "Name for the video (auto-generated if omitted)")
|
|
120
120
|
.requiredOption("--avatar-id <avatarId>", "Avatar to use")
|
|
121
121
|
.requiredOption("--voice-id <voiceId>", "Voice to use")
|
|
122
122
|
.requiredOption("--script <script>", "Script for the avatar to read")
|
|
@@ -125,8 +125,9 @@ export function registerMediaCommand(program) {
|
|
|
125
125
|
.option("-o, --output <path>", "Download video to this path when done (implies --wait)")
|
|
126
126
|
.action(async (opts) => {
|
|
127
127
|
const shouldWait = opts.wait || !!opts.output;
|
|
128
|
+
const autoName = opts.name || `video-${new Date().toISOString().replace(/[:.]/g, "-").slice(0, 19)}`;
|
|
128
129
|
const body = {
|
|
129
|
-
name:
|
|
130
|
+
name: autoName,
|
|
130
131
|
avatarId: opts.avatarId,
|
|
131
132
|
voiceId: opts.voiceId,
|
|
132
133
|
script: opts.script,
|
|
@@ -236,9 +237,57 @@ export function registerMediaCommand(program) {
|
|
|
236
237
|
.command("video-status <id>")
|
|
237
238
|
.description("Poll video generation status.")
|
|
238
239
|
.option("--wait", "Poll until a terminal state is reached")
|
|
240
|
+
.option("-o, --output <path>", "Download video to this path when complete (implies --wait)")
|
|
239
241
|
.action(async (id, opts) => {
|
|
240
|
-
|
|
242
|
+
const shouldWait = opts.wait || !!opts.output;
|
|
243
|
+
if (shouldWait) {
|
|
241
244
|
const data = await pollStatus(`/media-gen/videos/${id}/status`, ["inference_complete", "inference_failed"]);
|
|
245
|
+
// Download if -o specified and completed
|
|
246
|
+
if (opts.output && data.status === "inference_complete") {
|
|
247
|
+
const token = await getValidToken();
|
|
248
|
+
const dlUrl = `${BASE_URL}/media-gen/videos/${id}/download`;
|
|
249
|
+
const dlRes = await fetch(dlUrl, {
|
|
250
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
251
|
+
redirect: "follow",
|
|
252
|
+
});
|
|
253
|
+
if (dlRes.ok) {
|
|
254
|
+
const { writeFile, mkdir } = await import("fs/promises");
|
|
255
|
+
const { dirname } = await import("path");
|
|
256
|
+
const buffer = Buffer.from(await dlRes.arrayBuffer());
|
|
257
|
+
await mkdir(dirname(opts.output), { recursive: true });
|
|
258
|
+
await writeFile(opts.output, buffer);
|
|
259
|
+
const contentType = dlRes.headers.get("content-type") || "video/mp4";
|
|
260
|
+
if (isJsonMode(media)) {
|
|
261
|
+
jsonOut({ ...data, filename: opts.output, contentType, size: buffer.length });
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
console.log(`Video ${id} — ${data.status}\nSaved to ${opts.output} (${buffer.length} bytes)`);
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
// Try manual redirect
|
|
268
|
+
const dlRes2 = await fetch(dlUrl, {
|
|
269
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
270
|
+
redirect: "manual",
|
|
271
|
+
});
|
|
272
|
+
const location = dlRes2.headers.get("location");
|
|
273
|
+
if (location) {
|
|
274
|
+
const videoRes = await fetch(location);
|
|
275
|
+
if (videoRes.ok) {
|
|
276
|
+
const { writeFile, mkdir } = await import("fs/promises");
|
|
277
|
+
const { dirname } = await import("path");
|
|
278
|
+
const buffer = Buffer.from(await videoRes.arrayBuffer());
|
|
279
|
+
await mkdir(dirname(opts.output), { recursive: true });
|
|
280
|
+
await writeFile(opts.output, buffer);
|
|
281
|
+
const contentType = videoRes.headers.get("content-type") || "video/mp4";
|
|
282
|
+
if (isJsonMode(media)) {
|
|
283
|
+
jsonOut({ ...data, filename: opts.output, contentType, size: buffer.length });
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
console.log(`Video ${id} — ${data.status}\nSaved to ${opts.output} (${buffer.length} bytes)`);
|
|
287
|
+
return;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
242
291
|
if (isJsonMode(media)) {
|
|
243
292
|
jsonOut(data);
|
|
244
293
|
return;
|
|
@@ -256,10 +305,57 @@ export function registerMediaCommand(program) {
|
|
|
256
305
|
});
|
|
257
306
|
media
|
|
258
307
|
.command("video-download <id>")
|
|
259
|
-
.description("
|
|
260
|
-
.
|
|
308
|
+
.description("Download a completed video (or get its URL).")
|
|
309
|
+
.option("-o, --output <path>", "Save video to this file path")
|
|
310
|
+
.action(async (id, opts) => {
|
|
261
311
|
const token = await getValidToken();
|
|
262
312
|
const url = `${BASE_URL}/media-gen/videos/${id}/download`;
|
|
313
|
+
// If -o specified, download directly to file
|
|
314
|
+
if (opts.output) {
|
|
315
|
+
const res = await fetch(url, {
|
|
316
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
317
|
+
redirect: "follow",
|
|
318
|
+
});
|
|
319
|
+
if (res.ok) {
|
|
320
|
+
const { writeFile, mkdir } = await import("fs/promises");
|
|
321
|
+
const { dirname } = await import("path");
|
|
322
|
+
const buffer = Buffer.from(await res.arrayBuffer());
|
|
323
|
+
await mkdir(dirname(opts.output), { recursive: true });
|
|
324
|
+
await writeFile(opts.output, buffer);
|
|
325
|
+
const contentType = res.headers.get("content-type") || "video/mp4";
|
|
326
|
+
if (isJsonMode(media)) {
|
|
327
|
+
jsonOut({ filename: opts.output, contentType, size: buffer.length });
|
|
328
|
+
return;
|
|
329
|
+
}
|
|
330
|
+
console.log(`Video saved to ${opts.output} (${buffer.length} bytes)`);
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
// If direct follow didn't work, try manual redirect
|
|
334
|
+
const res2 = await fetch(url, {
|
|
335
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
336
|
+
redirect: "manual",
|
|
337
|
+
});
|
|
338
|
+
const location = res2.headers.get("location");
|
|
339
|
+
if (location) {
|
|
340
|
+
const videoRes = await fetch(location);
|
|
341
|
+
if (videoRes.ok) {
|
|
342
|
+
const { writeFile, mkdir } = await import("fs/promises");
|
|
343
|
+
const { dirname } = await import("path");
|
|
344
|
+
const buffer = Buffer.from(await videoRes.arrayBuffer());
|
|
345
|
+
await mkdir(dirname(opts.output), { recursive: true });
|
|
346
|
+
await writeFile(opts.output, buffer);
|
|
347
|
+
const contentType = videoRes.headers.get("content-type") || "video/mp4";
|
|
348
|
+
if (isJsonMode(media)) {
|
|
349
|
+
jsonOut({ filename: opts.output, contentType, size: buffer.length });
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
console.log(`Video saved to ${opts.output} (${buffer.length} bytes)`);
|
|
353
|
+
return;
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
throw new ApiError(res.status, `/media-gen/videos/${id}/download`, "Failed to download video");
|
|
357
|
+
}
|
|
358
|
+
// No -o: just return the URL (existing behavior)
|
|
263
359
|
const res = await fetch(url, {
|
|
264
360
|
headers: { Authorization: `Bearer ${token}` },
|
|
265
361
|
redirect: "manual",
|
package/package.json
CHANGED
|
@@ -57,13 +57,27 @@ Do NOT use markdown image syntax `` or `gobi://` URLs. Always use `` or `gobi://` URLs. Always use `
|
|
|
90
104
|
- `gobi media video-list` — List all videos.
|
|
91
105
|
- `gobi media video-get` — Get video metadata.
|
|
92
106
|
- `gobi media video-status` — Poll video generation status.
|
|
93
|
-
- `gobi media video-download` —
|
|
107
|
+
- `gobi media video-download` — Download a completed video (`-o` to save to file).
|
|
94
108
|
|
|
95
109
|
### Images
|
|
96
110
|
|
|
@@ -17,7 +17,7 @@ Commands:
|
|
|
17
17
|
video-list List all videos.
|
|
18
18
|
video-get <id> Get video metadata.
|
|
19
19
|
video-status [options] <id> Poll video generation status.
|
|
20
|
-
video-download <id>
|
|
20
|
+
video-download [options] <id> Download a completed video (or get its URL).
|
|
21
21
|
image-generate [options] Generate an image from a text prompt. Types: image (default), thumbnail (YouTube-optimized), asset (logo/product). Aspect ratios: 1:1, 16:9, 9:16, 4:3, 3:4
|
|
22
22
|
image-edit [options] Edit an existing image with a prompt (image-to-image).
|
|
23
23
|
image-inpaint [options] Inpaint an image region using a mask.
|
|
@@ -82,12 +82,13 @@ Usage: gobi media video-create [options]
|
|
|
82
82
|
Create an avatar video generation job.
|
|
83
83
|
|
|
84
84
|
Options:
|
|
85
|
-
--name <name> Name for the video
|
|
85
|
+
--name <name> Name for the video (auto-generated if omitted)
|
|
86
86
|
--avatar-id <avatarId> Avatar to use
|
|
87
87
|
--voice-id <voiceId> Voice to use
|
|
88
88
|
--script <script> Script for the avatar to read
|
|
89
89
|
--background-media-id <backgroundMediaId> Background media ID (from upload)
|
|
90
90
|
--wait Poll until generation completes
|
|
91
|
+
-o, --output <path> Download video to this path when done (implies --wait)
|
|
91
92
|
-h, --help display help for command
|
|
92
93
|
```
|
|
93
94
|
|
|
@@ -121,8 +122,9 @@ Usage: gobi media video-status [options] <id>
|
|
|
121
122
|
Poll video generation status.
|
|
122
123
|
|
|
123
124
|
Options:
|
|
124
|
-
--wait
|
|
125
|
-
-
|
|
125
|
+
--wait Poll until a terminal state is reached
|
|
126
|
+
-o, --output <path> Download video to this path when complete (implies --wait)
|
|
127
|
+
-h, --help display help for command
|
|
126
128
|
```
|
|
127
129
|
|
|
128
130
|
## video-download
|
|
@@ -130,10 +132,11 @@ Options:
|
|
|
130
132
|
```
|
|
131
133
|
Usage: gobi media video-download [options] <id>
|
|
132
134
|
|
|
133
|
-
|
|
135
|
+
Download a completed video (or get its URL).
|
|
134
136
|
|
|
135
137
|
Options:
|
|
136
|
-
-
|
|
138
|
+
-o, --output <path> Save video to this file path
|
|
139
|
+
-h, --help display help for command
|
|
137
140
|
```
|
|
138
141
|
|
|
139
142
|
## image-generate
|