bailian-cli-commands 1.6.0 → 1.6.1

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.
Files changed (2) hide show
  1. package/dist/index.mjs +1 -1
  2. package/package.json +3 -3
package/dist/index.mjs CHANGED
@@ -29,7 +29,7 @@ Omni output voices:
29
29
  `),process.exit(1)),a=e}let o=n.model||`happyhorse-1.0-video-edit`,s=C(t.output),c=await F(t),l=[{type:`video`,url:await I(r,c.token,o)}],u=n.refImage;if(u){let e=u.split(`,`).map(e=>e.trim()).filter(Boolean);for(let t of e){let e=await I(t,c.token,o);l.push({type:`reference_image`,url:e})}}let d=N(n.promptExtend,void 0,`prompt-extend`),f=R(n.watermark),p={model:o,input:{prompt:a||void 0,negative_prompt:n.negativePrompt||void 0,media:l},parameters:{resolution:n.resolution||void 0,ratio:n.ratio||void 0,duration:n.duration||void 0,audio_setting:n.audioSetting||void 0,prompt_extend:d,watermark:f,seed:n.seed}};if(t.dryRun){G({request:p},s);return}let m=(await M(t,{url:qe(t.baseUrl),method:`POST`,body:p,async:!0})).output.task_id;if(t.quiet||(process.stderr.write(`[Model: ${o}]\n`),process.stderr.write(`Note: Video editing typically takes 5-8 minutes. Please be patient.
30
30
  `)),n.noWait||t.async){G({task_id:m},s);return}let h=n.pollInterval??15,g=await Y(t,{url:z(t.baseUrl,m),intervalSec:h,timeoutSec:Math.max(t.timeout,600),isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}}),_=g.output.video_url||g.output.results&&g.output.results[0]?.url;if(!_)throw new e(`Task completed but no video URL returned.`,i.GENERAL);if(n.download){let e=n.download,{size:r}=await U(_,e,{quiet:t.quiet});t.quiet?W(e):G({task_id:m,video_url:_,status:`SUCCEEDED`,saved:e,size:st(r)},s);return}let v=await import(`path`),y=L(t,{subDir:`videos`}),b=v.join(y,`${m}.mp4`);await U(_,b,{quiet:t.quiet}),G({task_id:m,video_url:_,saved:b},s)}}),Pn=y({description:`Reference-to-video generation (happyhorse-1.1-r2v / wan2.6-r2v): multi-subject, multi-shot with voice`,usageArgs:`--prompt <text> --image <url>... [--ref-video <url>...] [flags]`,options:[{flag:`--model <model>`,description:`Model ID (default: happyhorse-1.1-r2v)`},{flag:`--prompt <text>`,description:`Video description with reference markers (image1, video1, etc.)`,required:!0},{flag:`--image <url>`,description:`Reference image URL or local file (repeatable for multiple subjects)`,type:`array`},{flag:`--ref-video <url>`,description:`Reference video URL or local file (repeatable)`,type:`array`},{flag:`--image-voice <url>`,description:`Voice URL for corresponding image (pairs by position)`,type:`array`},{flag:`--video-voice <url>`,description:`Voice URL for corresponding ref-video (pairs by position)`,type:`array`},{flag:`--resolution <res>`,description:`Resolution: 720P or 1080P (default: 1080P)`},{flag:`--ratio <ratio>`,description:`Aspect ratio (16:9, 9:16, 1:1)`},{flag:`--duration <seconds>`,description:`Video duration in seconds (default: 5)`,type:`number`},{flag:`--prompt-extend <bool>`,description:Xe},{flag:`--watermark <bool>`,description:B},{flag:`--seed <n>`,description:`Random seed for reproducible generation`,type:`number`},{flag:`--download <path>`,description:`Save video to file on completion`},{flag:`--no-wait`,description:`Return task ID immediately without waiting`},{flag:`--async`,description:`Return task ID immediately (agent/CI mode, same as --no-wait)`},{flag:`--poll-interval <seconds>`,description:`Polling interval when waiting (default: 15)`,type:`number`}],exampleArgs:[`--prompt "Image1 running on the grass" --image person.jpg`,`--prompt "Video 1 plays guitar, Image 1 walks over" --ref-video scene.mp4 --image person.jpg`,`--prompt "Image 1 speaks" --image person.jpg --image-voice voice.mp3 --resolution 1080P`,`--prompt "Image 1 and Image 2 have a conversation" --image a.jpg --image b.jpg --image-voice va.mp3 --image-voice vb.mp3`,`--prompt "Image 1 drinks water" --image person.jpg --watermark false`],async run(t,n){let r=n.prompt;if(!r)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter your video prompt (use Image1, Video1 to reference inputs):`});e||(process.stderr.write(`Video generation cancelled.
31
31
  `),process.exit(1)),r=e}else K(`prompt`,V(t,`--prompt <text> --image <url>`));let a=n.image||[],o=n.refVideo||[];if(a.length===0&&o.length===0)throw new e(`At least one --image or --ref-video is required.`,i.USAGE,V(t,`--prompt "description" --image person.jpg`));let s=n.imageVoice||[],c=n.videoVoice||[],l=n.model||`happyhorse-1.1-r2v`,u=C(t.output),d=await F(t),f=[];for(let e=0;e<a.length;e++){let t={type:`reference_image`,url:await I(a[e],d.token,l)};s[e]&&(t.reference_voice=await I(s[e],d.token,l)),f.push(t)}for(let e=0;e<o.length;e++){let t={type:`reference_video`,url:await I(o[e],d.token,l)};c[e]&&(t.reference_voice=await I(c[e],d.token,l)),f.push(t)}let p=N(n.promptExtend,void 0,`prompt-extend`),m=R(n.watermark),h={model:l,input:{prompt:r,media:f},parameters:{resolution:n.resolution||void 0,ratio:n.ratio||void 0,duration:n.duration||void 0,prompt_extend:p,watermark:m,seed:n.seed}};if(t.dryRun){G({request:h},u);return}let g=(await M(t,{url:qe(t.baseUrl),method:`POST`,body:h,async:!0})).output.task_id;if(t.quiet||(process.stderr.write(`[Model: ${l}]\n`),process.stderr.write(`Note: Reference-to-video typically takes 5-10 minutes. Please be patient.
32
- `)),n.noWait||t.async){G({task_id:g},u);return}let _=n.pollInterval??15,v=await Y(t,{url:z(t.baseUrl,g),intervalSec:_,timeoutSec:Math.max(t.timeout,600),isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}}),y=v.output.video_url||v.output.results&&v.output.results[0]?.url;if(!y)throw new e(`Task completed but no video URL returned.`,i.GENERAL);if(n.download){let e=n.download,{size:r}=await U(y,e,{quiet:t.quiet});t.quiet?W(e):G({task_id:g,video_url:y,status:`SUCCEEDED`,saved:e,size:st(r)},u);return}let{join:b}=await import(`path`),x=b(L(t,{subDir:`videos`}),`${g}.mp4`);await U(y,x,{quiet:t.quiet}),G({task_id:g,video_url:y,saved:x},u)}}),Fn=y({description:`Query async task status`,usageArgs:`--task-id <id>`,options:[{flag:`--task-id <id>`,description:`Async task ID`}],exampleArgs:[`--task-id 3b256896-3e70-xxxx-xxxx-xxxxxxxxxxxx`,`--task-id 3b256896-3e70-xxxx --output json`],async run(e,t){let n=t.taskId;n||K(`task-id`,V(e,`--task-id <id>`));let r=C(e.output);if(e.dryRun){G({task_id:n},r);return}let i=await M(e,{url:z(e.baseUrl,n)});if(e.quiet){W(i.output.task_status);return}G({task_id:i.output.task_id,task_status:i.output.task_status,video_url:i.output.video_url,results:i.output.results,submit_time:i.output.submit_time,end_time:i.output.end_time},r)}}),In=y({description:`Download a completed video by task ID`,usageArgs:`--task-id <id> --out <path>`,options:[{flag:`--task-id <id>`,description:`Task ID to download from`},{flag:`--out <path>`,description:`Output file path`}],exampleArgs:[`--task-id 3b256896-xxxx --out video.mp4`,`--task-id 3b256896-xxxx --out video.mp4 --quiet`],async run(t,n){let r=n.taskId;r||K(`task-id`,V(t,`--task-id <id> --out <path>`));let a=n.out;a||K(`out`,V(t,`--task-id <id> --out video.mp4`));let o=C(t.output);if(t.dryRun){G({task_id:r,action:`download`,out:a},o);return}let s=await M(t,{url:z(t.baseUrl,r)});if(s.output.task_status!==`SUCCEEDED`)throw new e(`Task is not complete (status: ${s.output.task_status}).`,i.GENERAL,`Wait for the task to complete before downloading.`);let c=s.output.video_url||s.output.results&&s.output.results[0]?.url;if(!c)throw new e(`No download URL available for this task.`,i.GENERAL);let{size:l}=await U(c,a,{quiet:t.quiet});if(t.quiet){W(a);return}G({saved:a,size:st(l)},o)}});const Ln={".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".png":`image/png`,".webp":`image/webp`},Rn=new Set([`.mp4`,`.mov`,`.avi`,`.mkv`,`.webm`,`.flv`,`.wmv`]);function zn(e){let t=Tt(e).toLowerCase().split(`?`)[0];return!!(Rn.has(t)||/\.(mp4|mov|avi|mkv|webm|flv|wmv)(\?|$)/i.test(e))}async function Bn(t){if(t.startsWith(`data:`)||t.startsWith(`http://`)||t.startsWith(`https://`)||t.startsWith(`oss://`))return t;if(!bt(t))throw new e(`File not found: ${t}`,i.USAGE);let n=Tt(t).toLowerCase(),r=Ln[n];if(!r)throw new e(`Unsupported image format "${n}". Supported: jpg, jpeg, png, webp`,i.USAGE);return`data:${r};base64,${xt(t).toString(`base64`)}`}var Vn=y({description:`Describe an image or video using Qwen-VL`,usageArgs:`--image <path-or-url> [--video <url>] [--prompt <text>]`,options:[{flag:`--image <path-or-url>`,description:`Local image path or URL`},{flag:`--video <url>`,description:`Video file URL or local path (mp4/mov/avi/mkv/webm)`,type:`array`},{flag:`--prompt <text>`,description:`Question about the content (default: auto-detected)`},{flag:`--model <model>`,description:`Vision model (default: qwen3-vl-plus)`}],exampleArgs:[`--image photo.jpg`,`--image https://example.com/photo.jpg --prompt "What breed is this dog?"`,`--video https://example.com/video.mp4 --prompt "Summarize the video content"`,`--video ./local-video.mp4`,`--image photo.png --prompt "Extract the text" --model qwen-vl-plus`],async run(t,n){let r=n.image??n._positional?.[0],a=n.video??[],o=n.model||`qwen3-vl-plus`;r&&zn(r)&&(a.push(r),r=void 0);let s=a.length>0,c=s?`Describe the video.`:`Describe the image.`,l=n.prompt||c;if(!r&&!s)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter image/video path or URL:`});e||(process.stderr.write(`Vision describe cancelled.
32
+ `)),n.noWait||t.async){G({task_id:g},u);return}let _=n.pollInterval??15,v=await Y(t,{url:z(t.baseUrl,g),intervalSec:_,timeoutSec:Math.max(t.timeout,600),isComplete:e=>e.output.task_status===`SUCCEEDED`,isFailed:e=>e.output.task_status===`FAILED`,getStatus:e=>e.output.task_status,getErrorMessage:e=>{let t=e.output;return t.message||t.code||void 0}}),y=v.output.video_url||v.output.results&&v.output.results[0]?.url;if(!y)throw new e(`Task completed but no video URL returned.`,i.GENERAL);if(n.download){let e=n.download,{size:r}=await U(y,e,{quiet:t.quiet});t.quiet?W(e):G({task_id:g,video_url:y,status:`SUCCEEDED`,saved:e,size:st(r)},u);return}let{join:b}=await import(`path`),x=b(L(t,{subDir:`videos`}),`${g}.mp4`);await U(y,x,{quiet:t.quiet}),G({task_id:g,video_url:y,saved:x},u)}}),Fn=y({description:`Query async task status`,usageArgs:`--task-id <id>`,options:[{flag:`--task-id <id>`,description:`Async task ID`}],exampleArgs:[`--task-id 3b256896-3e70-xxxx-xxxx-xxxxxxxxxxxx`,`--task-id 3b256896-3e70-xxxx --output json`],async run(e,t){let n=t.taskId;n||K(`task-id`,V(e,`--task-id <id>`));let r=C(e.output);if(e.dryRun){G({task_id:n},r);return}let i=await M(e,{url:z(e.baseUrl,n)});if(e.quiet){W(i.output.task_status);return}G({task_id:i.output.task_id,task_status:i.output.task_status,video_url:i.output.video_url,results:i.output.results,submit_time:i.output.submit_time,end_time:i.output.end_time},r)}}),In=y({description:`Download a completed video by task ID`,usageArgs:`--task-id <id> --out <path>`,options:[{flag:`--task-id <id>`,description:`Task ID to download from`},{flag:`--out <path>`,description:`Output file path`}],exampleArgs:[`--task-id 3b256896-xxxx --out video.mp4`,`--task-id 3b256896-xxxx --out video.mp4 --quiet`],async run(t,n){let r=n.taskId;r||K(`task-id`,V(t,`--task-id <id> --out <path>`));let a=n.out;a||K(`out`,V(t,`--task-id <id> --out video.mp4`));let o=C(t.output);if(t.dryRun){G({task_id:r,action:`download`,out:a},o);return}let s=await M(t,{url:z(t.baseUrl,r)});if(s.output.task_status!==`SUCCEEDED`)throw new e(`Task is not complete (status: ${s.output.task_status}).`,i.GENERAL,`Wait for the task to complete before downloading.`);let c=s.output.video_url||s.output.results&&s.output.results[0]?.url;if(!c)throw new e(`No download URL available for this task.`,i.GENERAL);let{size:l}=await U(c,a,{quiet:t.quiet});if(t.quiet){W(a);return}G({saved:a,size:st(l)},o)}});const Ln={".jpg":`image/jpeg`,".jpeg":`image/jpeg`,".png":`image/png`,".webp":`image/webp`},Rn=new Set([`.mp4`,`.mov`,`.avi`,`.mkv`,`.webm`,`.flv`,`.wmv`]);function zn(e){let t=Tt(e).toLowerCase().split(`?`)[0];return!!(Rn.has(t)||/\.(mp4|mov|avi|mkv|webm|flv|wmv)(\?|$)/i.test(e))}async function Bn(t){if(t.startsWith(`data:`)||t.startsWith(`http://`)||t.startsWith(`https://`)||t.startsWith(`oss://`))return t;if(!bt(t))throw new e(`File not found: ${t}`,i.USAGE);let n=Tt(t).toLowerCase(),r=Ln[n];if(!r)throw new e(`Unsupported image format "${n}". Supported: jpg, jpeg, png, webp`,i.USAGE);return`data:${r};base64,${xt(t).toString(`base64`)}`}var Vn=y({description:`Describe an image or video using Qwen-VL`,usageArgs:`--image <path-or-url> [--video <url>] [--prompt <text>]`,options:[{flag:`--image <path-or-url>`,description:`Local image path or URL`},{flag:`--video <url>`,description:`Video file URL or local path (mp4/mov/avi/mkv/webm)`,type:`array`},{flag:`--prompt <text>`,description:`Question about the content (default: auto-detected)`},{flag:`--model <model>`,description:`Vision model (default: qwen3-vl-plus)`}],exampleArgs:[`--image photo.jpg`,`--image https://example.com/photo.jpg --prompt "What breed is this dog?"`,`--video https://example.com/video.mp4 --prompt "Summarize the video content"`,`--video ./local-video.mp4`,`--image photo.png --prompt "Extract the text" --model qwen3-vl-plus`],async run(t,n){let r=n.image??n._positional?.[0],a=n.video??[],o=n.model||`qwen3-vl-plus`;r&&zn(r)&&(a.push(r),r=void 0);let s=a.length>0,c=s?`Describe the video.`:`Describe the image.`,l=n.prompt||c;if(!r&&!s)if(D({nonInteractive:t.nonInteractive})){let e=await Z({message:`Enter image/video path or URL:`});e||(process.stderr.write(`Vision describe cancelled.
33
33
  `),process.exit(1)),zn(e)?a.push(e):r=e}else throw new e(`Missing required argument --image or --video.`,i.USAGE,`${V(t,`--image <path-or-url>`)}\n${V(t,`--video <url-or-path>`)}`);let u=C(t.output);if(t.dryRun){G({request:{prompt:l,image:r,video:a.length?a:void 0,model:o}},u);return}let d=[];if(a.length>0)for(let n of a){let r=n;if(fe(n)){if(!bt(n))throw new e(`Video file not found: ${n}`,i.USAGE);r=await I(n,(await F(t)).token,o)}d.push({type:`video_url`,video_url:{url:r}})}if(r){let e=await Bn(r),n=e;if(fe(r)&&e.startsWith(`data:`)){let{statSync:e}=await import(`fs`);if(e(r).size>5*1024*1024){let e=await F(t);n=await I(r,e.token,o)}}d.push({type:`image_url`,image_url:{url:n}})}d.push({type:`text`,text:l});let f={model:o,messages:[{role:`user`,content:d}]},p=await M(t,{url:h(t.baseUrl),method:`POST`,body:f}),m=p.choices?.[0]?.message?.content;if(u!==`text`){G(p,u);return}W(m||``)}}),Hn=y({description:`Display current configuration`,skipDefaultApiKeySetup:!0,exampleArgs:[``,`--output json`],async run(e,t){let n=A(),r=C(e.output),i={...n,base_url:e.baseUrl,output:e.output,timeout:e.timeout,config_file:ie()};typeof i.api_key==`string`&&(i.api_key=O(i.api_key)),typeof i.access_token==`string`&&(i.access_token=O(i.access_token)),typeof i.access_key_id==`string`&&(i.access_key_id=O(i.access_key_id)),typeof i.access_key_secret==`string`&&(i.access_key_secret=O(i.access_key_secret)),G(i,r)}});const Un=[`base_url`,`output`,`output_dir`,`timeout`,`api_key`,`access_token`,`default_text_model`,`default_video_model`,`default_image_model`,`default_speech_model`,`default_omni_model`,`access_key_id`,`access_key_secret`,`workspace_id`],Wn=new Set([`api_key`,`access_token`,`access_key_id`,`access_key_secret`]),Gn={"base-url":`base_url`,"output-dir":`output_dir`,"api-key":`api_key`,"access-token":`access_token`,"default-text-model":`default_text_model`,"default-video-model":`default_video_model`,"default-image-model":`default_image_model`,"default-speech-model":`default_speech_model`,"default-omni-model":`default_omni_model`,"access-key-id":`access_key_id`,"access-key-secret":`access_key_secret`,"workspace-id":`workspace_id`};var Kn=y({description:`Set a config value`,skipDefaultApiKeySetup:!0,usageArgs:`--key <key> --value <value>`,options:[{flag:`--key <key>`,description:`Config key (base_url, output, output_dir, timeout, api_key, access_token, default_*_model, access_key_id, access_key_secret, workspace_id)`},{flag:`--value <value>`,description:`Value to set`}],exampleArgs:[`--key output --value json`,`--key timeout --value 600`,`--key base_url --value https://dashscope.aliyuncs.com`],async run(t,n){let r=n.key,a=n.value;if(!r||a===void 0)throw new e(`--key and --value are required.`,i.USAGE,V(t,`--key <key> --value <value>`));let o=Gn[r]||r;if(!Un.includes(o))throw new e(`Invalid config key "${r}". Valid keys: ${Un.join(`, `)}`,i.USAGE);if(o===`output`&&![`text`,`json`].includes(a))throw new e(`Invalid output format "${a}". Valid values: text, json`,i.USAGE);if(o===`timeout`){let t=Number(a);if(isNaN(t)||t<=0)throw new e(`Invalid timeout "${a}". Must be a positive number.`,i.USAGE)}let s=C(t.output);if(t.dryRun){G({would_set:{[o]:a}},s);return}let c=A();if(c[o]=o===`timeout`?Number(a):a,await Je(c),!t.quiet){let e=Wn.has(o)?O(String(c[o])):c[o];G({[o]:e},s)}}});const qn=`npx skills add modelstudioai/cli --all -g -y`;function Jn(e){return{cmd:`npm install -g ${e}@latest`,label:`npm`}}function Yn(e){let{green:t,yellow:n,reset:r}=e;process.stderr.write(`
34
34
  Updating agent skill...
35
35
  `);try{Dt(qn,{stdio:`inherit`}),process.stderr.write(`${t}\u2713 Agent skill updated.${r}\n`)}catch{process.stderr.write(`${n}Agent skill update skipped. Run manually: ${qn}${r}\n`)}}var Xn=y({description:`Update the CLI to the latest version`,skipDefaultApiKeySetup:!0,exampleArgs:[``],async run(e){let t=e.npmPackage,n=e.binName,r=e.clientVersion,i=process.stderr.isTTY,a=i?`\x1B[32m`:``,o=i?`\x1B[33m`:``,s=i?`\x1B[0m`:``;process.stderr.write(`Current version: ${o}${r}${s}\n`),process.stderr.write(`Checking for updates...
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bailian-cli-commands",
3
- "version": "1.6.0",
3
+ "version": "1.6.1",
4
4
  "description": "Command library for bailian-cli products (knowledge, memory, media, …). See https://www.npmjs.com/package/bailian-cli for usage.",
5
5
  "homepage": "https://bailian.console.aliyun.com/cli",
6
6
  "bugs": {
@@ -30,8 +30,8 @@
30
30
  "boxen": "^8.0.1",
31
31
  "chalk": "^5.6.2",
32
32
  "yaml": "^2.8.3",
33
- "bailian-cli-core": "1.6.0",
34
- "bailian-cli-runtime": "1.6.0"
33
+ "bailian-cli-core": "1.6.1",
34
+ "bailian-cli-runtime": "1.6.1"
35
35
  },
36
36
  "devDependencies": {
37
37
  "@types/node": "^24",