@9000ai/cli 0.6.1 → 0.6.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.
@@ -3,11 +3,21 @@ export function registerTaskCommands(parent) {
3
3
  const cmd = parent.command("task").description("Query task status and results");
4
4
  cmd
5
5
  .command("status")
6
- .description("Check task status")
7
- .requiredOption("--task-id <id>", "Task ID")
6
+ .description("Check task or batch status")
7
+ .option("--task-id <id>", "Task ID")
8
+ .option("--batch-id <id>", "Batch ID (shows batch progress + task list)")
8
9
  .option("--fields <list>", "Comma-separated fields to extract (e.g. desc,video_url,likes)")
9
10
  .option("--compact", "One JSON object per line, no indentation")
10
11
  .action(async (opts) => {
12
+ if (!opts.taskId && !opts.batchId) {
13
+ console.error("Error: must provide --task-id or --batch-id");
14
+ process.exit(1);
15
+ }
16
+ if (opts.batchId) {
17
+ const data = await request({ method: "GET", path: `/api/v1/tasks/batch/${opts.batchId}` });
18
+ printJson(data, { fields: opts.fields, compact: opts.compact });
19
+ return;
20
+ }
11
21
  const data = await request({ method: "GET", path: `/api/v1/tasks/${opts.taskId}` });
12
22
  printJson(data, { fields: opts.fields, compact: opts.compact });
13
23
  });
@@ -1,5 +1,7 @@
1
1
  import { request, printJson, pollUntilDone } from "../client.js";
2
2
  import { loadJsonFile } from "../utils/format.js";
3
+ import { mkdirSync, writeFileSync } from "node:fs";
4
+ import { join, resolve } from "node:path";
3
5
  /** Extract unique video_ids from monitor task output */
4
6
  function extractVideoIdsFromMonitorOutput(output) {
5
7
  const data = (output.data ?? output);
@@ -72,39 +74,52 @@ export function registerTranscribeCommands(parent) {
72
74
  });
73
75
  cmd
74
76
  .command("text")
75
- .description("Extract transcription text from completed task")
77
+ .description("Extract transcription text and save to local file")
76
78
  .requiredOption("--task-id <id>", "Task ID")
79
+ .option("--no-save", "Print text to stdout instead of saving to file")
77
80
  .action(async (opts) => {
78
81
  const taskData = await request({ method: "GET", path: `/api/v1/tasks/${opts.taskId}` });
79
82
  const inner = taskData.data;
80
83
  if (!inner || inner.status !== "SUCCESS") {
81
- console.log(`Task status: ${inner?.status ?? "unknown"}`);
82
- if (inner?.status !== "SUCCESS") {
83
- printJson(inner);
84
- return;
85
- }
84
+ console.error(`Task status: ${inner?.status ?? "unknown"}`);
85
+ process.exit(1);
86
86
  }
87
87
  const output = (typeof inner.output === "string" ? JSON.parse(inner.output) : inner.output);
88
88
  const jsonUrl = output?.json_url;
89
89
  if (!jsonUrl) {
90
90
  console.error("No json_url in task output");
91
- printJson(inner);
92
- return;
91
+ process.exit(1);
93
92
  }
94
93
  const controller = new AbortController();
95
94
  const timer = setTimeout(() => controller.abort(), 60_000);
96
95
  try {
97
96
  const res = await fetch(jsonUrl, { signal: controller.signal });
98
97
  const transcript = await res.json();
99
- const text = transcript.text ?? "";
100
- const sentences = (transcript.timecodes?.sentences ?? []);
98
+ const text = String(transcript.text ?? "");
99
+ if (!text) {
100
+ console.error("Transcript text is empty");
101
+ process.exit(1);
102
+ }
103
+ // 用 third_party_task_id (video_id) 或 task_id 做文件名
104
+ const videoId = (inner.third_party_task_id ?? opts.taskId);
105
+ if (!opts.save) {
106
+ // --no-save: 直接输出
107
+ console.log(text);
108
+ return;
109
+ }
110
+ // 落盘到 output/transcripts/{video_id}.txt
111
+ const dir = resolve("output", "transcripts");
112
+ mkdirSync(dir, { recursive: true });
113
+ const filepath = join(dir, `${videoId}.txt`);
114
+ writeFileSync(filepath, text, "utf-8");
115
+ // 只返回摘要给 AI
116
+ const preview = text.length > 100 ? text.slice(0, 100) + "..." : text;
101
117
  printJson({
102
118
  task_id: opts.taskId,
103
- text_field: "text",
104
- sentence_field: "timecodes.sentences[*].text",
105
- text,
106
- sentence_count: sentences.length,
107
- duration_ms: transcript.duration_ms,
119
+ video_id: videoId,
120
+ file: filepath,
121
+ char_count: text.length,
122
+ preview,
108
123
  });
109
124
  }
110
125
  finally {
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ const program = new Command();
14
14
  program
15
15
  .name("9000ai")
16
16
  .description("9000AI Toolbox CLI — unified interface for 9000AI platform")
17
- .version("0.6.1");
17
+ .version("0.6.2");
18
18
  registerConfigCommands(program);
19
19
  registerAuthCommands(program);
20
20
  registerSearchCommands(program);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@9000ai/cli",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "9000AI Toolbox CLI — unified command-line interface for 9000AI platform",
5
5
  "type": "module",
6
6
  "bin": {