@pippit-dev/cli 0.0.4 → 0.0.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.
package/README.md CHANGED
@@ -13,7 +13,7 @@ export XYQ_ACCESS_KEY="<access-key>"
13
13
  pippit-cli short-drama +submit-run --message "写一个赛博朋克短剧开头"
14
14
  pippit-cli short-drama +upload-file --path ./story.md
15
15
  pippit-cli short-drama +get-thread --thread-id thread_123 --run-id run_456 --after-seq 0
16
- pippit-cli short-drama +download-result --output-dir ./thread_123/results/result.mp4 --url URL
16
+ pippit-cli short-drama +download-result --output-path ./thread_123/results/result.mp4 --url URL
17
17
  ```
18
18
 
19
19
  NPM package names must be lowercase, so the publishable package name is
@@ -26,7 +26,7 @@ export XYQ_ACCESS_KEY="<access-key>"
26
26
  go run . short-drama +submit-run --message "写一个赛博朋克短剧开头"
27
27
  go run . short-drama +upload-file --path ./story.md
28
28
  go run . short-drama +get-thread --thread-id thread_123 --run-id run_456 --after-seq 0
29
- go run . short-drama +download-result --output-dir ./thread_123/results/result.mp4 --url URL
29
+ go run . short-drama +download-result --output-path ./thread_123/results/result.mp4 --url URL
30
30
  ```
31
31
 
32
32
  `+submit-run` calls `/api/biz/v1/skill/submit_run` and prints `thread_id`,
@@ -34,7 +34,7 @@ go run . short-drama +download-result --output-dir ./thread_123/results/result.m
34
34
  `+get-thread` calls
35
35
  `/api/biz/v1/skill/get_thread` and prints extracted `messages`.
36
36
  `+download-result` downloads the result URL to
37
- the `--output-dir` file path. `+upload-file` is still mocked while
37
+ the `--output-path` file path. `+upload-file` is still mocked while
38
38
  its real service contract is wired.
39
39
 
40
40
  ## HTTP Client
package/checksums.txt ADDED
@@ -0,0 +1,6 @@
1
+ 2d6ebc213dd8401622a5315846a1f2125b321ca55ed3689b661268ae0cdc7bb4 pippit-cli-0.0.6-darwin-amd64.tar.gz
2
+ 2bedf7ed2f9afd313e8b983763e90e66a835b2f340fcda905cae8c82ba553735 pippit-cli-0.0.6-darwin-arm64.tar.gz
3
+ 37ecf71b5d701dc257c0287983b511e403ff0cfc7690a07a0c4bcd32837c365e pippit-cli-0.0.6-linux-amd64.tar.gz
4
+ b6e41054960723d18809e1bad498f59fb7f68550e07c11e867f9580ac91a42da pippit-cli-0.0.6-linux-arm64.tar.gz
5
+ 2103cb871134ec47f34b53b53e93d95d7190888bc035b8c78d48b925a3ace9eb pippit-cli-0.0.6-windows-amd64.zip
6
+ 263fbabede0ad9c266ef23cdad2292297a35b67d2301c14f400308198bab4655 pippit-cli-0.0.6-windows-arm64.zip
@@ -96,9 +96,9 @@ func newShortDramaDownloadResultCommand(stdout, stderr io.Writer, runner *common
96
96
  Short: "Download a generated result URL",
97
97
  Args: cobra.NoArgs,
98
98
  RunE: func(cmd *cobra.Command, _ []string) error {
99
- opts.OutputDir = strings.TrimSpace(opts.OutputDir)
100
- if opts.OutputDir == "" {
101
- return fmt.Errorf("--output-dir is required")
99
+ opts.OutputPath = strings.TrimSpace(opts.OutputPath)
100
+ if opts.OutputPath == "" {
101
+ return fmt.Errorf("--output-path is required")
102
102
  }
103
103
  opts.URL = strings.TrimSpace(opts.URL)
104
104
  if opts.URL == "" {
@@ -118,7 +118,7 @@ func newShortDramaDownloadResultCommand(stdout, stderr io.Writer, runner *common
118
118
  cmd.SetOut(stdout)
119
119
  cmd.SetErr(stderr)
120
120
  cmd.Flags().StringVar(&opts.URL, "url", "", "URL to download")
121
- cmd.Flags().StringVar(&opts.OutputDir, "output-dir", "", "output file path")
121
+ cmd.Flags().StringVar(&opts.OutputPath, "output-path", "", "local output file path")
122
122
  cmd.Flags().IntVar(&opts.Workers, "workers", 5, "parallel download workers")
123
123
  return cmd
124
124
  }
@@ -181,7 +181,7 @@ func TestShortDramaDownloadResult(t *testing.T) {
181
181
  outputPath := filepath.Join("results", "cover.jpeg")
182
182
  root.SetArgs([]string{
183
183
  "short-drama", "+download-result",
184
- "--output-dir", outputPath,
184
+ "--output-path", outputPath,
185
185
  "--workers", "2",
186
186
  "--url", server.URL + "/image?filename=ignored.jpeg",
187
187
  })
@@ -191,8 +191,8 @@ func TestShortDramaDownloadResult(t *testing.T) {
191
191
  }
192
192
 
193
193
  got := decodeJSON(t, stdout.Bytes())
194
- if got["output_dir"] != outputPath {
195
- t.Fatalf("output_dir = %v, want %s", got["output_dir"], outputPath)
194
+ if got["output_path"] != outputPath {
195
+ t.Fatalf("output_path = %v, want %s", got["output_path"], outputPath)
196
196
  }
197
197
  if got["total"] != float64(1) {
198
198
  t.Fatalf("total = %v, want 1", got["total"])
@@ -233,7 +233,7 @@ func TestShortDramaDownloadResultSkipsExistingFile(t *testing.T) {
233
233
  root := NewRootCommand(&stdout, &stderr)
234
234
  root.SetArgs([]string{
235
235
  "short-drama", "+download-result",
236
- "--output-dir", outputPath,
236
+ "--output-path", outputPath,
237
237
  "--url", server.URL + "/image",
238
238
  })
239
239
 
@@ -245,8 +245,8 @@ func TestShortDramaDownloadResultSkipsExistingFile(t *testing.T) {
245
245
  }
246
246
 
247
247
  got := decodeJSON(t, stdout.Bytes())
248
- if got["output_dir"] != outputPath {
249
- t.Fatalf("output_dir = %v, want %s", got["output_dir"], outputPath)
248
+ if got["output_path"] != outputPath {
249
+ t.Fatalf("output_path = %v, want %s", got["output_path"], outputPath)
250
250
  }
251
251
  if got["total"] != float64(0) {
252
252
  t.Fatalf("total = %v, want 0", got["total"])
@@ -258,7 +258,7 @@ func TestShortDramaDownloadResultSkipsExistingFile(t *testing.T) {
258
258
  assertFileContent(t, outputPath, "existing-data")
259
259
  }
260
260
 
261
- func TestShortDramaDownloadResultRequiresOutputDir(t *testing.T) {
261
+ func TestShortDramaDownloadResultRequiresOutputPath(t *testing.T) {
262
262
  var stdout, stderr bytes.Buffer
263
263
  root := NewRootCommand(&stdout, &stderr)
264
264
  root.SetArgs([]string{"short-drama", "+download-result", "--url", "https://example.com/image.png"})
@@ -267,15 +267,33 @@ func TestShortDramaDownloadResultRequiresOutputDir(t *testing.T) {
267
267
  if err == nil {
268
268
  t.Fatal("Execute() error = nil, want validation error")
269
269
  }
270
- if !strings.Contains(err.Error(), "--output-dir is required") {
271
- t.Fatalf("error = %q, want output-dir validation", err)
270
+ if !strings.Contains(err.Error(), "--output-path is required") {
271
+ t.Fatalf("error = %q, want output-path validation", err)
272
+ }
273
+ }
274
+
275
+ func TestShortDramaDownloadResultRejectsOutputDirFlag(t *testing.T) {
276
+ var stdout, stderr bytes.Buffer
277
+ root := NewRootCommand(&stdout, &stderr)
278
+ root.SetArgs([]string{
279
+ "short-drama", "+download-result",
280
+ "--output-dir", filepath.Join("results", "image.png"),
281
+ "--url", "https://example.com/image.png",
282
+ })
283
+
284
+ err := root.Execute()
285
+ if err == nil {
286
+ t.Fatal("Execute() error = nil, want unknown flag error")
287
+ }
288
+ if !strings.Contains(err.Error(), "unknown flag: --output-dir") {
289
+ t.Fatalf("error = %q, want output-dir rejection", err)
272
290
  }
273
291
  }
274
292
 
275
293
  func TestShortDramaDownloadResultRequiresURL(t *testing.T) {
276
294
  var stdout, stderr bytes.Buffer
277
295
  root := NewRootCommand(&stdout, &stderr)
278
- root.SetArgs([]string{"short-drama", "+download-result", "--output-dir", filepath.Join("results", "image.png")})
296
+ root.SetArgs([]string{"short-drama", "+download-result", "--output-path", filepath.Join("results", "image.png")})
279
297
 
280
298
  err := root.Execute()
281
299
  if err == nil {
@@ -289,7 +307,7 @@ func TestShortDramaDownloadResultRequiresURL(t *testing.T) {
289
307
  func TestShortDramaDownloadResultRejectsInvalidScheme(t *testing.T) {
290
308
  var stdout, stderr bytes.Buffer
291
309
  root := NewRootCommand(&stdout, &stderr)
292
- root.SetArgs([]string{"short-drama", "+download-result", "--output-dir", filepath.Join("results", "image.png"), "--url", "file:///etc/passwd"})
310
+ root.SetArgs([]string{"short-drama", "+download-result", "--output-path", filepath.Join("results", "image.png"), "--url", "file:///etc/passwd"})
293
311
 
294
312
  err := root.Execute()
295
313
  if err == nil {
@@ -311,7 +329,7 @@ func TestShortDramaDownloadResultAllFailed(t *testing.T) {
311
329
  root := NewRootCommand(&stdout, &stderr)
312
330
  root.SetArgs([]string{
313
331
  "short-drama", "+download-result",
314
- "--output-dir", filepath.Join("results", "missing.png"),
332
+ "--output-path", filepath.Join("results", "missing.png"),
315
333
  "--url", server.URL + "/notfound",
316
334
  })
317
335
 
@@ -337,7 +355,7 @@ func TestShortDramaDownloadResultOutputPath(t *testing.T) {
337
355
  outputPath := filepath.Join("custom", "nested", "cover.png")
338
356
  root.SetArgs([]string{
339
357
  "short-drama", "+download-result",
340
- "--output-dir", outputPath,
358
+ "--output-path", outputPath,
341
359
  "--url", server.URL + "/image.png",
342
360
  })
343
361
 
@@ -346,8 +364,8 @@ func TestShortDramaDownloadResultOutputPath(t *testing.T) {
346
364
  }
347
365
 
348
366
  got := decodeJSON(t, stdout.Bytes())
349
- if got["output_dir"] != outputPath {
350
- t.Fatalf("output_dir = %v, want %s", got["output_dir"], outputPath)
367
+ if got["output_path"] != outputPath {
368
+ t.Fatalf("output_path = %v, want %s", got["output_path"], outputPath)
351
369
  }
352
370
  assertFileContent(t, outputPath, "image-data")
353
371
  }
@@ -21,9 +21,9 @@ import (
21
21
 
22
22
  // DownloadResultOptions is the command-facing shape for downloading one result URL.
23
23
  type DownloadResultOptions struct {
24
- URL string `json:"url"`
25
- OutputDir string `json:"output_dir"`
26
- Workers int `json:"workers"`
24
+ URL string `json:"url"`
25
+ OutputPath string `json:"output_path"`
26
+ Workers int `json:"workers"`
27
27
  }
28
28
 
29
29
  type DownloadResultError struct {
@@ -33,7 +33,7 @@ type DownloadResultError struct {
33
33
 
34
34
  // DownloadResultResponse is the JSON envelope printed by `pippit-cli short-drama +download-result`.
35
35
  type DownloadResultResponse struct {
36
- OutputDir string `json:"output_dir"`
36
+ OutputPath string `json:"output_path"`
37
37
  Downloaded []string `json:"downloaded"`
38
38
  AlreadyExist []string `json:"already_exist,omitempty"`
39
39
  Total int `json:"total"`
@@ -64,9 +64,9 @@ func DownloadResult(ctx context.Context, opts DownloadResultOptions, runner *Run
64
64
  return nil, fmt.Errorf("download url is required")
65
65
  }
66
66
 
67
- outputPath := strings.TrimSpace(opts.OutputDir)
67
+ outputPath := strings.TrimSpace(opts.OutputPath)
68
68
  if outputPath == "" {
69
- return nil, fmt.Errorf("output_dir is required")
69
+ return nil, fmt.Errorf("output_path is required")
70
70
  }
71
71
  // check if the output path exists and is a file
72
72
  if info, err := os.Stat(outputPath); err == nil {
@@ -74,7 +74,7 @@ func DownloadResult(ctx context.Context, opts DownloadResultOptions, runner *Run
74
74
  return nil, fmt.Errorf("output path %q is a directory", outputPath)
75
75
  }
76
76
  return &DownloadResultResponse{
77
- OutputDir: outputPath,
77
+ OutputPath: outputPath,
78
78
  AlreadyExist: []string{outputPath},
79
79
  Total: 0,
80
80
  }, nil
@@ -159,7 +159,7 @@ func DownloadResult(ctx context.Context, opts DownloadResultOptions, runner *Run
159
159
  })
160
160
 
161
161
  result := &DownloadResultResponse{
162
- OutputDir: outputPath,
162
+ OutputPath: outputPath,
163
163
  Downloaded: downloaded,
164
164
  Total: len(downloaded),
165
165
  Errors: errorList,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pippit-dev/cli",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "description": "Pippit CLI",
5
5
  "bin": {
6
6
  "pippit-cli": "scripts/run.js"
@@ -27,7 +27,7 @@ metadata:
27
27
  2. **查询会话进展** - 根据 `thread_id`、`run_id`、`after_seq` 拉取短剧任务消息列表。
28
28
  3. **上传文件** - 上传短剧相关参考文件,得到文件 ID,供后续任务引用。
29
29
  4. **获取会话文件** - 根据 `thread_id` 拉取会话文件列表,得到 `file_path`、`file_name`、`download_url`。
30
- 5. **下载文件资源** - 使用文件列表中的 `download_url` 下载资源,并按 `file_path` 写入用户本地目录。
30
+ 5. **下载文件资源** - 使用文件列表中的 `download_url` 下载资源,并按 `file_path` 写入用户本地目标文件路径。
31
31
 
32
32
  ## 前置要求
33
33
 
@@ -90,11 +90,11 @@ pippit-cli short-drama +list-thread-file --thread-id THREAD_ID --page-num 1 --pa
90
90
  ### 5. 下载文件资源
91
91
 
92
92
  ```bash
93
- # 下载文件资源到指定目录
94
- pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-dir FILE_PATH
93
+ # 下载文件资源到指定文件路径
94
+ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PATH
95
95
  ```
96
96
 
97
- `+download-result` 负责把会话产生的文件,通过URL下载到 `file_path`目录中,如果目标文件已存在,跳过下载。
97
+ `FILE_PATH` 必须直接使用 `+list-thread-file` 返回的完整 `file_path`,包含文件名,不要取父目录。`+download-result` 负责把会话产生的文件通过 URL 下载到该目标文件路径;如果目标文件已存在,跳过下载。
98
98
 
99
99
  ## 典型工作流
100
100
 
@@ -112,11 +112,11 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-dir FILE_PAT
112
112
  - 如果后端 Agent 提出问题:展示问题,等待用户回复
113
113
  5. 解析 `list-thread-file` 返回的 files,只获取文件元信息:
114
114
  - 对每个文件取 file_path、file_name、download_url
115
- - file_path 在用户本地环境构建目录
116
- - 如果在工作目录中 file_name 已存在:跳过下载
115
+ - file_path 作为本地目标文件路径,包含文件名
116
+ - 如果 file_path 已存在:跳过下载
117
117
  6. 对缺失的本地文件,调用 +download-result 并行下载资源:
118
118
  - 使用第 5 步获取的 download_url 作为 --url
119
- - 使用第 5 步获取的 file_path 作为 --output-dir
119
+ - 使用第 5 步获取的完整 file_path 作为 --output-path
120
120
  7. 如用户继续追加需求,使用同一 thread_id 再次 submit-run
121
121
  ```
122
122
 
@@ -212,8 +212,8 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-dir FILE_PAT
212
212
 
213
213
  ```json
214
214
  {
215
- "output_dir": "/path/to/output-dir",
216
- "downloaded": ["/path/to/output-dir/01.md"],
215
+ "output_path": "./{thread-id}/{file_path}/{file_name}",
216
+ "downloaded": ["./{thread-id}/{file_path}/{file_name}"],
217
217
  "total": 1
218
218
  }
219
219
  ```
@@ -231,14 +231,14 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-dir FILE_PAT
231
231
  → 跳过
232
232
  2. file_path在本地不存在
233
233
  → 记录该file_path和URL
234
- 多个待下载的文件 → 使用 +download-result 工具并行下载文件到本地
234
+ → 使用 +download-result 将URL资源下载到该file_path
235
235
  ```
236
236
 
237
237
  ### 并行下载文件资源
238
238
 
239
239
  只对目标路径不存在的文件调用下载工具,可并行:
240
240
 
241
- 1. 调用 `pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-dir FILE_PATH`。
241
+ 1. 调用 `pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-path FILE_PATH`。
242
242
  2. 下载完成后,向用户展示本地文件路径;如果某个文件下载失败,只报告该文件错误,不阻塞已成功落盘的文件展示。
243
243
 
244
244
  ## 向用户展示内容
@@ -276,5 +276,5 @@ pippit-cli short-drama +download-result --url DOWNLOAD_URL --output-dir FILE_PAT
276
276
  - `--after-seq` 用于增量拉取消息,首次查询可设置为 `0`。
277
277
  - `+upload-file` 当前用于短剧场景文件上传链路,上传后将返回可传给 `+submit-run` 的文件 ID。
278
278
  - `+list-thread-file` 只需要 `thread_id`;分页参数默认 `--page-num 1 --page-size 100`。
279
- - `+list-thread-file` 和 `+download-result` 是两个不同的 CLI 指令:前者获取会话文件元信息,后者下载 URL 资源并写入到本地目录。
280
- - `+download-result` 接收 `--url`、`--output-dir`、`--workers`。
279
+ - `+list-thread-file` 和 `+download-result` 是两个不同的 CLI 指令:前者获取会话文件元信息,后者下载 URL 资源并写入到本地目标文件路径。
280
+ - `+download-result` 接收 `--url`、`--output-path`、`--workers`;`--output-path` 必须是包含文件名的目标文件路径。